diff --git a/src/docode.c b/src/docode.c index 20cb71dbcedc2b56987254dbaf8b1dd595006611..b9a9016fb42d28fa9379771c86707dcf407fced5 100644 --- a/src/docode.c +++ b/src/docode.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: docode.c,v 1.6 1996/12/04 00:27:10 hubbe Exp $"); +RCSID("$Id: docode.c,v 1.7 1997/01/16 05:00:43 hubbe Exp $"); #include "las.h" #include "program.h" #include "language.h" @@ -267,6 +267,7 @@ static int do_docode2(node *n,int flags) case F_GLOBAL: case F_IDENTIFIER: case F_INDEX: + case F_ARROW: case F_ARG_LIST: break; } @@ -926,12 +927,34 @@ static int do_docode2(node *n,int flags) case F_LVALUE_LIST: return do_docode(CAR(n),DO_LVALUE)+do_docode(CDR(n),DO_LVALUE); + case F_ARROW: + if(CDR(n)->token != F_CONSTANT || CDR(n)->u.sval.type!=T_STRING) + fatal("Bugg in F_ARROW, index not string."); + if(flags & DO_LVALUE) + { + /* FIXME!!!! */ + tmp1=do_docode(CAR(n), 0); + emit(F_ARROW_STRING, store_prog_string(CDR(n)->u.sval.u.string)); + return 2; + }else{ + tmp1=do_docode(CAR(n), DO_NOT_COPY); + emit(F_ARROW, store_prog_string(CDR(n)->u.sval.u.string)); + if(!(flags & DO_NOT_COPY)) + { + while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n); + if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND)) + emit2(F_COPY_VALUE); + } + } + return tmp1; + case F_INDEX: if(flags & DO_LVALUE) { tmp1=do_docode(CAR(n), 0); if(do_docode(CDR(n),0) != 1) fatal("Internal compiler error, please report this (1)."); + if(CDR(n)->token != F_CONSTANT) emit2(F_CLEAR_STRING_SUBTYPE); return 2; }else{ tmp1=do_docode(CAR(n), DO_NOT_COPY); @@ -940,7 +963,7 @@ static int do_docode2(node *n,int flags) emit2(F_INDEX); if(!(flags & DO_NOT_COPY)) { - while(n && n->token==F_INDEX) n=CAR(n); + while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n); if(n->token==F_CONSTANT && !(n->node_info & OPT_EXTERNAL_DEPEND)) emit2(F_COPY_VALUE); } diff --git a/src/interpret.c b/src/interpret.c index 63268aee30f4551d1ff1127b9b8ff83d3dbbe99a..ef4286a52d65e65e2e9a7b6597f0aae5e6f06141 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: interpret.c,v 1.18 1996/12/06 08:30:16 per Exp $"); +RCSID("$Id: interpret.c,v 1.19 1997/01/16 05:00:44 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -558,6 +558,15 @@ static void eval_instruction(unsigned char *pc) CASE(F_STRING); copy_shared_string(sp->u.string,fp->context.prog->strings[GET_ARG()]); sp->type=T_STRING; + sp->subtype=0; + sp++; + print_return_value(); + break; + + CASE(F_ARROW_STRING); + copy_shared_string(sp->u.string,fp->context.prog->strings[GET_ARG()]); + sp->type=T_STRING; + sp->subtype=1; /* Magic */ sp++; print_return_value(); break; @@ -784,6 +793,10 @@ static void eval_instruction(unsigned char *pc) CASE(F_MARK2); *(mark_sp++)=sp; CASE(F_MARK); *(mark_sp++)=sp; break; + CASE(F_CLEAR_STRING_SUBTYPE); + if(sp[-1].type==T_STRING) sp[-1].subtype=0; + break; + /* Jumps */ CASE(F_BRANCH); DOJUMP(); @@ -1007,6 +1020,7 @@ static void eval_instruction(unsigned char *pc) print_return_value(); goto do_index; + CASE(F_ARROW); CASE(F_STRING_INDEX); copy_shared_string(sp->u.string,fp->context.prog->strings[GET_ARG()]); sp->type=T_STRING; @@ -1333,15 +1347,20 @@ void safe_apply_low(struct object *o,int fun,int args) JMP_BUF recovery; sp-=args; + free_svalue(& throw_value); + throw_value.type=T_INT; if(SETJMP(recovery)) { - ONERROR tmp; - SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); - assign_svalue_no_free(sp++, & throw_value); - APPLY_MASTER("handle_error", 1); - pop_stack(); - UNSET_ONERROR(tmp); - + if(throw_value.type == T_ARRAY) + { + ONERROR tmp; + SET_ONERROR(tmp,exit_on_error,"Error in handle_error in master object!"); + assign_svalue_no_free(sp++, & throw_value); + APPLY_MASTER("handle_error", 1); + pop_stack(); + UNSET_ONERROR(tmp); + } + sp->u.integer = 0; sp->subtype=NUMBER_NUMBER; sp->type = T_INT; diff --git a/src/language.yacc b/src/language.yacc index 3a07e4aa64134aaf01219c64d1c8cb8dd1311d3d..5be58913c23555aaeed459f4f078f65ae678f437 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -22,7 +22,7 @@ %token F_INC_LOOP F_DEC_LOOP %token F_INC_NEQ_LOOP F_DEC_NEQ_LOOP -%token F_INDEX F_INDIRECT F_STRING_INDEX F_LOCAL_INDEX +%token F_INDEX F_ARROW F_INDIRECT F_STRING_INDEX F_LOCAL_INDEX %token F_POS_INT_INDEX F_NEG_INT_INDEX %token F_LTOSVAL F_LTOSVAL2 %token F_PUSH_ARRAY @@ -33,8 +33,8 @@ */ %token F_LFUN F_GLOBAL F_LOCAL %token F_GLOBAL_LVALUE F_LOCAL_LVALUE -%token F_CLEAR_LOCAL -%token F_CONSTANT F_FLOAT F_STRING +%token F_CLEAR_LOCAL F_CLEAR_STRING_SUBTYPE +%token F_CONSTANT F_FLOAT F_STRING F_ARROW_STRING %token F_NUMBER F_NEG_NUMBER F_CONST_1 F_CONST0 F_CONST1 F_BIGNUM /* * These are the predefined functions that can be accessed from Pike. @@ -74,7 +74,6 @@ %token F_APPLY %token F_ARG_LIST %token F_ARRAY_ID -%token F_ARROW %token F_BREAK %token F_CASE %token F_CLASS @@ -156,7 +155,7 @@ /* This is the grammar definition of Pike. */ #include "global.h" -RCSID("$Id: language.yacc,v 1.16 1996/12/11 00:48:38 neotron Exp $"); +RCSID("$Id: language.yacc,v 1.17 1997/01/16 05:00:44 hubbe Exp $"); #ifdef HAVE_MEMORY_H #include <memory.h> #endif @@ -1143,7 +1142,7 @@ expr4: string { $$=mkefuncallnode("aggregate_multiset",$2); } | expr4 F_ARROW F_IDENTIFIER { - $$=mknode(F_INDEX,$1,mkstrnode($3)); + $$=mknode(F_ARROW,$1,mkstrnode($3)); free_string($3); } ; @@ -1158,10 +1157,27 @@ idents: F_IDENTIFIER }else if((i=isidentifier($1))>=0){ $$=mkidentifiernode(i); }else if((f=lookup_efun($1))){ - $$=mkconstantsvaluenode(&f->function); + $$=mkconstantsvaluenode(&f->function); }else{ - my_yyerror("'%s' undefined.",$1->str); - $$=0; + $$=0; + if( get_master() ) + { + reference_shared_string($1); + push_string($1); + reference_shared_string(current_file); + push_string(current_file); + SAFE_APPLY_MASTER("resolv", 2); + + if(throw_value.type == T_STRING) + { + my_yyerror("%s",throw_value.u.string->str); + }else{ + $$=mkconstantsvaluenode(sp-1); + pop_stack(); + } + }else{ + my_yyerror("'%s' undefined.", $1->str); + } } free_string($1); } @@ -1171,10 +1187,10 @@ idents: F_IDENTIFIER f=lookup_efun($3); if(!f) { - my_yyerror("Unknown efun: %s.",$3->str); - $$=mkintnode(0); + my_yyerror("Unknown efun: %s.",$3->str); + $$=mkintnode(0); }else{ - $$=mksvaluenode(&f->function); + $$=mksvaluenode(&f->function); } free_string($3); } @@ -1188,10 +1204,10 @@ idents: F_IDENTIFIER idp=fake_program.identifier_references+f; if (f<0 || ID_FROM_PTR(&fake_program,idp)->func.offset == -1) { - my_yyerror("Undefined identifier %s::%s", $1->str,$3->str); - $$=mkintnode(0); + my_yyerror("Undefined identifier %s::%s", $1->str,$3->str); + $$=mkintnode(0); } else { - $$=mkidentifiernode(f); + $$=mkidentifiernode(f); } free_string($1); diff --git a/src/las.c b/src/las.c index d68ecec038f066e3a6b48d0191aa77cac64993ba..d49cf595cb91d26c301c5b745848c41d8f30e144 100644 --- a/src/las.c +++ b/src/las.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: las.c,v 1.10 1996/12/05 00:47:14 hubbe Exp $"); +RCSID("$Id: las.c,v 1.11 1997/01/16 05:00:45 hubbe Exp $"); #include "language.h" #include "interpret.h" @@ -916,6 +916,7 @@ static void find_written_vars(node *n, break; case F_INDEX: + case F_ARROW: find_written_vars(CAR(n), p, lvalue); find_written_vars(CDR(n), p, 0); break; @@ -1072,6 +1073,7 @@ void fix_type_field(node *n) break; case F_INDEX: + case F_ARROW: type_a=CAR(n)->type; type_b=CDR(n)->type; if(!check_indexing(type_a, type_b)) diff --git a/src/lex.c b/src/lex.c index 7f26c52d6ceb3c718778b3e4cd0376678e34ce54..ede5f8cca928e8231b12ee819a8c771e618892d5 100644 --- a/src/lex.c +++ b/src/lex.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: lex.c,v 1.9 1996/12/06 04:26:57 hubbe Exp $"); +RCSID("$Id: lex.c,v 1.10 1997/01/16 05:00:46 hubbe Exp $"); #include "language.h" #include "array.h" #include "lex.h" @@ -1587,7 +1587,6 @@ static int do_lex2(int literal, YYSTYPE *yylval) switch(GETC()) { case '+': tmp="`+"; break; - case '-': tmp="`-"; break; case '/': tmp="`/"; break; case '%': tmp="`%"; break; case '*': tmp="`*"; break; @@ -1595,6 +1594,16 @@ static int do_lex2(int literal, YYSTYPE *yylval) case '|': tmp="`|"; break; case '^': tmp="`^"; break; case '~': tmp="`~"; break; + case '-': + if(GOBBLE('>')) + { + tmp="`->"; + if(GOBBLE('=')) tmp="`->="; + }else{ + tmp="`-"; + } + break; + case '[': if(GOBBLE(']')) { diff --git a/src/object.c b/src/object.c index 913d259aae2ebca1a0ba7e490b931739424a5f92..51e299feddae8c28e74397f20dfd03b7c4c5d70f 100644 --- a/src/object.c +++ b/src/object.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: object.c,v 1.7 1996/12/05 01:29:45 hubbe Exp $"); +RCSID("$Id: object.c,v 1.8 1997/01/16 05:00:46 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -349,7 +349,7 @@ void low_object_index_no_free(struct svalue *to, } } -void object_index_no_free(struct svalue *to, +void object_index_no_free2(struct svalue *to, struct object *o, struct svalue *index) { @@ -376,27 +376,30 @@ void object_index_no_free(struct svalue *to, } } +#define ARROW_INDEX_P(X) ((X)->type==T_STRING && (X)->subtype) -void object_index_no_free2(struct svalue *to, +void object_index_no_free(struct svalue *to, struct object *o, struct svalue *index) { struct program *p; + int lfun; if(!o || !(p=o->prog)) { error("Lookup in destructed object.\n"); return; /* make gcc happy */ } + lfun=ARROW_INDEX_P(index) ? LFUN_ARROW : LFUN_INDEX; - if(p->lfuns[LFUN_INDEX] != -1) + if(p->lfuns[lfun] != -1) { push_svalue(index); - apply_lfun(o,LFUN_INDEX,1); + apply_lfun(o,lfun,1); to=sp; sp--; } else { - object_index_no_free(to,o,index); + object_index_no_free2(to,o,index); } } @@ -435,7 +438,7 @@ static void object_low_set_index(struct object *o, } } -void object_set_index(struct object *o, +void object_set_index2(struct object *o, struct svalue *index, struct svalue *from) { @@ -460,11 +463,12 @@ void object_set_index(struct object *o, } } -void object_set_index2(struct object *o, +void object_set_index(struct object *o, struct svalue *index, struct svalue *from) { struct program *p; + int lfun; if(!o || !(p=o->prog)) { @@ -472,14 +476,16 @@ void object_set_index2(struct object *o, return; /* make gcc happy */ } - if(p->lfuns[LFUN_ASSIGN_INDEX] != -1) + lfun=ARROW_INDEX_P(index) ? LFUN_ASSIGN_ARROW : LFUN_ASSIGN_INDEX; + + if(p->lfuns[lfun] != -1) { push_svalue(index); push_svalue(from); - apply_lfun(o,LFUN_ASSIGN_INDEX,2); + apply_lfun(o,lfun,2); pop_stack(); } else { - object_set_index(o,index,from); + object_set_index2(o,index,from); } } @@ -530,12 +536,13 @@ union anything *object_get_item_ptr(struct object *o, return 0; /* make gcc happy */ } + f=ARROW_INDEX_P(index) ? LFUN_ASSIGN_ARROW : LFUN_ASSIGN_INDEX; + if(p->lfuns[f] != -1) + error("Cannot do incremental operations on overloaded index (yet).\n"); + if(index->type != T_STRING) error("Lookup on non-string value.\n"); - if(p->lfuns[LFUN_ASSIGN_INDEX] != -1) - error("Cannot do incremental operations on overloaded index (yet).\n"); - f=find_shared_string_identifier(index->u.string, p); if(f < 0) { diff --git a/src/peep.c b/src/peep.c index d68d59cda0434168e7b7200374ce76d44404b535..cf262eb450fb70976594a4bd77a23976000e7740 100644 --- a/src/peep.c +++ b/src/peep.c @@ -54,6 +54,8 @@ static int hasarg(int opcode) case F_LFUN: case F_STRING: + case F_ARROW: + case F_ARROW_STRING: case F_STRING_INDEX: case F_LOCAL_INDEX: case F_POS_INT_INDEX: diff --git a/src/peep.in b/src/peep.in index 6358766217e624a3e9d7fe1ce783c9c8718235c5..1663a3fba3635ffd2c9fb3e380c49be0addaf69e 100644 --- a/src/peep.in +++ b/src/peep.in @@ -98,12 +98,12 @@ LE NOT: GT GE NOT: LT LOCAL SIZEOF: SIZEOF_LOCAL ($1a) - STRING INDEX: STRING_INDEX ($1a) LOCAL INDEX: LOCAL_INDEX ($1a) CONST0 INDEX: POS_INT_INDEX (0) CONST_1 INDEX: NEG_INT_INDEX (1) CONST1 INDEX: POS_INT_INDEX (1) + NUMBER [$1a < 0] INDEX: NEG_INT_INDEX (-$1a) NUMBER [$1a >= 0] INDEX: POS_INT_INDEX ($1a) NEG_NUMBER [$1a >= 0] INDEX: NEG_INT_INDEX ($1a) diff --git a/src/program.c b/src/program.c index 5d58844d27796bf4cb71b07e03e6e1ece5bae32f..0a70679f0d17f641f5b5fadaf9b62c8e68d782c3 100644 --- a/src/program.c +++ b/src/program.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: program.c,v 1.11 1996/12/05 00:47:18 hubbe Exp $"); +RCSID("$Id: program.c,v 1.12 1997/01/16 05:00:48 hubbe Exp $"); #include "program.h" #include "object.h" #include "dynamic_buffer.h" @@ -64,6 +64,8 @@ char *lfun_names[] = { "`!", "`[]", "`[]=", + "`->", + "`->=", }; struct program *first_program = 0; diff --git a/src/program.h b/src/program.h index 590861e5a8279a2f0e9f217cdee5ee2350b96696..93f8f869f0afae026ccd1bb37bafb59b05573612 100644 --- a/src/program.h +++ b/src/program.h @@ -33,8 +33,10 @@ #define LFUN_NOT 19 #define LFUN_INDEX 20 #define LFUN_ASSIGN_INDEX 21 +#define LFUN_ARROW 22 +#define LFUN_ASSIGN_ARROW 23 -#define NUM_LFUNS 22 +#define NUM_LFUNS 24 extern char *lfun_names[];