From dffa0194fd40a258b0719704b911bfb88b78562a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Wed, 15 Jan 1997 21:00:48 -0800 Subject: [PATCH] overloading for -> and [] implemented Rev: src/docode.c:1.7 Rev: src/interpret.c:1.19 Rev: src/language.yacc:1.17 Rev: src/las.c:1.11 Rev: src/lex.c:1.10 Rev: src/object.c:1.8 Rev: src/peep.c:1.4 Rev: src/peep.in:1.2 Rev: src/program.c:1.12 Rev: src/program.h:1.6 --- src/docode.c | 27 +++++++++++++++++++++++++-- src/interpret.c | 35 +++++++++++++++++++++++++++-------- src/language.yacc | 46 +++++++++++++++++++++++++++++++--------------- src/las.c | 4 +++- src/lex.c | 13 +++++++++++-- src/object.c | 35 +++++++++++++++++++++-------------- src/peep.c | 2 ++ src/peep.in | 2 +- src/program.c | 4 +++- src/program.h | 4 +++- 10 files changed, 127 insertions(+), 45 deletions(-) diff --git a/src/docode.c b/src/docode.c index 20cb71dbce..b9a9016fb4 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 63268aee30..ef4286a52d 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 3a07e4aa64..5be58913c2 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 d68ecec038..d49cf595cb 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 7f26c52d6c..ede5f8cca9 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 913d259aae..51e299fedd 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 d68d59cda0..cf262eb450 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 6358766217..1663a3fba3 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 5d58844d27..0a70679f0d 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 590861e5a8..93f8f869f0 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[]; -- GitLab