diff --git a/lib/modules/Yabu.pmod/test.pike b/lib/modules/Yabu.pmod/test.pike index a30780a77b8166dfe6d7ff86510f8f3cb1b4b983..6f9fb39b83bcc3b6141fd0fb8b47601016773876 100644 --- a/lib/modules/Yabu.pmod/test.pike +++ b/lib/modules/Yabu.pmod/test.pike @@ -64,6 +64,5 @@ int main(int argc, array argv) // Remove test database. db->purge(); - write("Yabu test program says everything is A OK.\n"); - return 1; + return 0; } diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 316dd9b72c0f116526a3aff67639ca6eb31715dd..b0c85a48c68563ffd4ef584fd727ec789be096d7 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.110 1998/05/19 18:47:41 grubba Exp $"); +RCSID("$Id: builtin_functions.c,v 1.111 1998/05/25 10:38:44 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -2919,8 +2919,6 @@ void f__locate_references(INT32 args) void init_builtin_efuns(void) { - init_operators(); - add_efun("gethrtime", f_gethrtime,"function(int|void:int)", OPT_EXTERNAL_DEPEND); #ifdef HAVE_GETHRVTIME diff --git a/src/docode.c b/src/docode.c index 765c6392cb7f38b2527da9783d2886e9312b7d9d..3866fb9e1a1af303b7beeeee806607fa33d85d05 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.37 1998/05/17 20:06:43 grubba Exp $"); +RCSID("$Id: docode.c,v 1.38 1998/05/25 10:38:44 hubbe Exp $"); #include "las.h" #include "program.h" #include "language.h" @@ -206,7 +206,7 @@ static int do_docode2(node *n,int flags) emit(F_NUMBER,0); emit(F_NUMBER,0); return 2; - + case F_ARRAY_LVALUE: case F_LVALUE_LIST: case F_LOCAL: @@ -216,15 +216,23 @@ static int do_docode2(node *n,int flags) case F_ARROW: case F_ARG_LIST: case F_EXTERNAL: - break; - } + break; + } + } + + if(flags & DO_LVALUE_IF_POSSIBLE) + { + flags|=DO_INDIRECT; + flags &=~DO_LVALUE_IF_POSSIBLE; + }else{ + flags &=~DO_INDIRECT; } switch(n->token) { case F_EXTERNAL: emit(F_LDA, n->u.integer.a); - if(flags & DO_LVALUE) + if(flags & WANT_LVALUE) { emit(F_EXTERNAL_LVALUE, n->u.integer.b); return 2; @@ -686,7 +694,7 @@ static int do_docode2(node *n,int flags) } case F_ARG_LIST: - tmp1=do_docode(CAR(n),flags & ~DO_LVALUE); + tmp1=do_docode(CAR(n),flags & ~WANT_LVALUE); tmp1+=do_docode(CDR(n),flags); return tmp1; @@ -944,7 +952,7 @@ static int do_docode2(node *n,int flags) 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) + if(flags & WANT_LVALUE) { /* FIXME!!!! ??? I wonder what needs fixing... /Hubbe */ tmp1=do_docode(CAR(n), 0); @@ -963,9 +971,20 @@ static int do_docode2(node *n,int flags) return tmp1; case F_INDEX: - if(flags & DO_LVALUE) + if(flags & WANT_LVALUE) { - tmp1=do_docode(CAR(n), 0); + int mklval=CAR(n) && match_types(CAR(n)->type, string_type_string); + tmp1=do_docode(CAR(n), + mklval ? DO_LVALUE_IF_POSSIBLE : 0); + if(tmp1==2) + { +#ifdef DEBUG + if(!mklval) + fatal("Unwanted lvalue!\n"); +#endif + emit2(F_INDIRECT); + } + if(do_docode(CDR(n),0) != 1) fatal("Internal compiler error, please report this (1)."); if(CDR(n)->token != F_CONSTANT && @@ -975,7 +994,9 @@ static int do_docode2(node *n,int flags) }else{ tmp1=do_docode(CAR(n), DO_NOT_COPY); code_expression(CDR(n), DO_NOT_COPY, "index"); + emit2(F_INDEX); + if(!(flags & DO_NOT_COPY)) { while(n && (n->token==F_INDEX || n->token==F_ARROW)) n=CAR(n); @@ -1046,7 +1067,7 @@ static int do_docode2(node *n,int flags) case F_LOCAL: if(n->u.number >= compiler_frame->max_number_of_locals) yyerror("Illegal to use local variable here."); - if(flags & DO_LVALUE) + if(flags & WANT_LVALUE) { emit(F_LOCAL_LVALUE,n->u.number); return 2; @@ -1058,14 +1079,14 @@ static int do_docode2(node *n,int flags) case F_IDENTIFIER: if(IDENTIFIER_IS_FUNCTION(ID_FROM_INT(new_program, n->u.number)->identifier_flags)) { - if(flags & DO_LVALUE) + if(flags & WANT_LVALUE) { yyerror("Cannot assign functions.\n"); }else{ emit(F_LFUN,n->u.number); } }else{ - if(flags & DO_LVALUE) + if(flags & WANT_LVALUE) { emit(F_GLOBAL_LVALUE,n->u.number); return 2; diff --git a/src/docode.h b/src/docode.h index 69e3a03377907813ebfdddb11d786f753e56fcd2..f249782b39e9f2303fdfc1547663be14690b4be6 100644 --- a/src/docode.h +++ b/src/docode.h @@ -5,15 +5,18 @@ \*/ /* - * $Id: docode.h,v 1.6 1998/04/27 10:00:27 hubbe Exp $ + * $Id: docode.h,v 1.7 1998/05/25 10:38:45 hubbe Exp $ */ #ifndef DOCODE_H #define DOCODE_H - #define DO_LVALUE 1 #define DO_NOT_COPY 2 #define DO_POP 4 +#define DO_INDIRECT 8 +#define DO_LVALUE_IF_POSSIBLE 16 + +#define WANT_LVALUE (DO_LVALUE | DO_INDIRECT) extern int store_linenumbers; diff --git a/src/interpret.c b/src/interpret.c index 8151f6bfb78825f616fcdaebb1a7f87ae6883a4c..1228002c26c7b02a007c1302e922e8227f22a7cd 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.84 1998/05/24 08:44:30 hubbe Exp $"); +RCSID("$Id: interpret.c,v 1.85 1998/05/25 10:38:45 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -1584,7 +1584,13 @@ static int eval_instruction(unsigned char *pc) CASE(F_INDEX); do_index: - o_index(); + { + struct svalue s; + index_no_free(&s,sp-2,sp-1); + pop_n_elems(2); + *sp=s; + sp++; + } print_return_value(); break; @@ -1600,6 +1606,29 @@ static int eval_instruction(unsigned char *pc) } break; + CASE(F_INDIRECT); + { + struct svalue s; + lvalue_to_svalue_no_free(&s,sp-2); + if(s.type != T_STRING) + { + pop_n_elems(2); + *sp=s; + sp++; + }else{ + struct object *o; + o=low_clone(string_assignment_program); + ((struct string_assignment_storage *)o->storage)->lval[0]=sp[-2]; + ((struct string_assignment_storage *)o->storage)->lval[1]=sp[-1]; + ((struct string_assignment_storage *)o->storage)->s=s.u.string; + sp-=2; + push_object(o); + } + } + print_return_value(); + break; + + CASE(F_SIZEOF); instr=pike_sizeof(sp-1); pop_stack(); diff --git a/src/main.c b/src/main.c index aadbf7b0788f5020d9dfb39fed228b85e4cdc072..db2699e7690534b09b3e399ea3cd3deed24899de 100644 --- a/src/main.c +++ b/src/main.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: main.c,v 1.52 1998/05/12 16:53:17 grubba Exp $"); +RCSID("$Id: main.c,v 1.53 1998/05/25 10:38:45 hubbe Exp $"); #include "fdlib.h" #include "backend.h" #include "module.h" @@ -26,6 +26,7 @@ RCSID("$Id: main.c,v 1.52 1998/05/12 16:53:17 grubba Exp $"); #include "mapping.h" #include "cpp.h" #include "main.h" +#include "operators.h" #include <errno.h> @@ -395,6 +396,7 @@ void do_exit(int num) ATTRIBUTE((noreturn)) void low_init_main(void) { th_init(); + init_operators(); init_builtin_efuns(); init_signals(); init_dynamic_load(); @@ -424,6 +426,7 @@ void low_exit_main(void) exit_cpp(); cleanup_interpret(); cleanup_added_efuns(); + exit_operators(); cleanup_pike_types(); cleanup_program(); cleanup_compiler(); diff --git a/src/module_support.c b/src/module_support.c index 186ab37af9e13adcf67404d2fbe96bb2f6850d5b..18a85a08e40c7cd88997971f6414ae1ba341cc2d 100644 --- a/src/module_support.c +++ b/src/module_support.c @@ -6,7 +6,7 @@ #include "pike_types.h" #include "error.h" -RCSID("$Id: module_support.c,v 1.11 1998/04/12 12:20:12 grubba Exp $"); +RCSID("$Id: module_support.c,v 1.12 1998/05/25 10:38:45 hubbe Exp $"); /* Checks that args_to_check arguments are OK. * Returns 1 if everything worked ok, zero otherwise. @@ -155,7 +155,8 @@ int va_get_args(struct svalue *s, break; case 'i': if(s->type != T_INT) return ret; - *va_arg(ap, INT32 *)=s->u.integer; break; + *va_arg(ap, INT32 *)=s->u.integer; + break; case 's': if(s->type != T_STRING) return ret; *va_arg(ap, char **)=s->u.string->str; diff --git a/src/object.c b/src/object.c index afe58ce5076d3e3df454b8858407b5c71fffde07..f0c32330fa4ec582edaa1be29be3f26589a0c243 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.51 1998/05/17 20:43:01 grubba Exp $"); +RCSID("$Id: object.c,v 1.52 1998/05/25 10:38:46 hubbe Exp $"); #include "object.h" #include "dynamic_buffer.h" #include "interpret.h" @@ -748,8 +748,15 @@ union anything *object_get_item_ptr(struct object *o, } f=ARROW_INDEX_P(index) ? LFUN_ASSIGN_ARROW : LFUN_ASSIGN_INDEX; + if(FIND_LFUN(p,f) != -1) - error("Cannot do incremental operations on overloaded index (yet).\n"); + { + return 0; + + /* error("Cannot do incremental operations on overloaded index (yet).\n"); + */ + } + switch(index->type) { diff --git a/src/operators.c b/src/operators.c index b553b4dbf53d6c756467dc7eb5a7464502e0f638..5198f538b8e1c6de987170fea7fce38d201b67ef 100644 --- a/src/operators.c +++ b/src/operators.c @@ -5,7 +5,7 @@ \*/ #include <math.h> #include "global.h" -RCSID("$Id: operators.c,v 1.32 1998/04/17 05:08:02 hubbe Exp $"); +RCSID("$Id: operators.c,v 1.33 1998/05/25 10:38:46 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "multiset.h" @@ -24,6 +24,7 @@ RCSID("$Id: operators.c,v 1.32 1998/04/17 05:08:02 hubbe Exp $"); #include "program.h" #include "object.h" #include "pike_types.h" +#include "module_support.h" #define COMPARISON(ID,NAME,FUN) \ void ID(INT32 args) \ @@ -1729,6 +1730,67 @@ static int generate_call_function(node *n) return 1; } +struct program *string_assignment_program; + +#undef THIS +#define THIS ((struct string_assignment_storage *)(fp->current_storage)) +static void f_string_assignment_index(INT32 args) +{ + INT32 i; + get_all_args("string[]",args,"%i",&i); + if(i<0) i+=THIS->s->len; + if(i<0) + i+=THIS->s->len; + if(i<0 || i>=THIS->s->len) + error("Index %d is out of range 0 - %d.\n", i, THIS->s->len-1); + else + i=EXTRACT_UCHAR(THIS->s->str + i); + pop_n_elems(args); + push_int(i); +} + +static void f_string_assignment_assign_index(INT32 args) +{ + INT32 i,j; + union anything *u; + get_all_args("string[]=",args,"%i%i",&i,&j); + if((u=get_pointer_if_this_type(THIS->lval, T_STRING))) + { + free_string(THIS->s); + if(i<0) i+=u->string->len; + if(i<0 || i>=u->string->len) + error("String index out of range %ld\n",(long)i); + u->string=modify_shared_string(u->string,i,j); + copy_shared_string(THIS->s, u->string); + }else{ + lvalue_to_svalue_no_free(sp,THIS->lval); + sp++; + if(sp[-1].type != T_STRING) error("string[]= failed.\n"); + if(i<0) i+=sp[-1].u.string->len; + if(i<0 || i>=sp[-1].u.string->len) + error("String index out of range %ld\n",(long)i); + sp[-1].u.string=modify_shared_string(sp[-1].u.string,i,j); + assign_lvalue(THIS->lval, sp-1); + pop_stack(); + } + pop_n_elems(args); + push_int(j); +} + + +static void init_string_assignment_storage(struct object *o) +{ + THIS->lval[0].type=T_INT; + THIS->lval[1].type=T_INT; + THIS->s=0; +} + +static void exit_string_assignment_storage(struct object *o) +{ + free_svalues(THIS->lval, 2, BIT_MIXED); + if(THIS->s) + free_string(THIS->s); +} void init_operators(void) { @@ -1819,4 +1881,23 @@ void init_operators(void) /* This one should be removed */ add_efun2("call_function",f_call_function,"function(mixed,mixed ...:mixed)",OPT_SIDE_EFFECT | OPT_EXTERNAL_DEPEND,0,generate_call_function); + + + start_new_program(); + add_storage(sizeof(struct string_assignment_storage)); + add_function("`[]",f_string_assignment_index,"function(int:int)",0); + add_function("`[]=",f_string_assignment_assign_index,"function(int,int:int)",0); + set_init_callback(init_string_assignment_storage); + set_exit_callback(exit_string_assignment_storage); + string_assignment_program=end_program(); +} + + +void exit_operators() +{ + if(string_assignment_program) + { + free_program(string_assignment_program); + string_assignment_program=0; + } } diff --git a/src/operators.h b/src/operators.h index f85f1a081d489f98d4c98662bd9eff5ffd80ec8f..d148275a7e9dbfd008084cde47f148ffdfde06bb 100644 --- a/src/operators.h +++ b/src/operators.h @@ -5,20 +5,27 @@ \*/ /* - * $Id: operators.h,v 1.4 1998/03/28 15:07:37 grubba Exp $ + * $Id: operators.h,v 1.5 1998/05/25 10:38:46 hubbe Exp $ */ #ifndef OPERATORS_H #define OPERATORS_H #define COMPARISON(ID,NAME,X) void ID(INT32 num_arg); +extern struct program *string_assignment_program; +struct string_assignment_storage +{ + struct svalue lval[2]; + struct pike_string *s; +}; + /* Prototypes begin here */ -COMPARISON(f_eq,"`==", is_eq(sp-2,sp-1)) -COMPARISON(f_ne,"`!=",!is_eq(sp-2,sp-1)) -COMPARISON(f_lt,"`<" , is_lt(sp-2,sp-1)) -COMPARISON(f_le,"`<=",!is_gt(sp-2,sp-1)) -COMPARISON(f_gt,"`>" , is_gt(sp-2,sp-1)) -COMPARISON(f_ge,"`>=",!is_lt(sp-2,sp-1)) +void f_ne(INT32 args); +COMPARISON(f_eq,"`==", is_eq) +COMPARISON(f_lt,"`<" , is_lt) +COMPARISON(f_le,"`<=",!is_gt) +COMPARISON(f_gt,"`>" , is_gt) +COMPARISON(f_ge,"`>=",!is_lt) void f_add(INT32 args); void o_subtract(void); @@ -49,6 +56,7 @@ void f_index(INT32 args); void f_arrow(INT32 args); void f_sizeof(INT32 args); void init_operators(void); +void exit_operators(); /* Prototypes end here */ #undef COMPARISON diff --git a/src/stralloc.c b/src/stralloc.c index b64ae337f18b4b8e46b28f7893b21c55ff3ab63a..64ff0a111dd0170c18d90ec08b2eb5eb8f1a35f5 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -15,7 +15,7 @@ #include <ctype.h> -RCSID("$Id: stralloc.c,v 1.35 1998/04/24 00:09:35 hubbe Exp $"); +RCSID("$Id: stralloc.c,v 1.36 1998/05/25 10:38:46 hubbe Exp $"); #define BEGIN_HASH_SIZE 997 #define MAX_AVG_LINK_LENGTH 3 @@ -639,14 +639,14 @@ struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size) */ struct pike_string *modify_shared_string(struct pike_string *a, INT32 index, - char c) + int c) { #ifdef DEBUG if(index<0 || index>=a->len) fatal("Index out of range in modify_shared_string()\n"); #endif - if(a->str[index]==c) return a; + if(EXTRACT_UCHAR(a->str+index)==c) return a; if(a->refs==1) { @@ -663,7 +663,7 @@ struct pike_string *modify_shared_string(struct pike_string *a, struct pike_string *r; r=begin_shared_string(a->len); MEMCPY(r->str, a->str, a->len); - a->str[index]=c; + r->str[index]=c; free_string(a); return end_shared_string(r); } diff --git a/src/stralloc.h b/src/stralloc.h index 23d76dc1cbd78628c895617a2bfdeb6b0ddf17c3..243a8606f0ec77a7e5bca3c9401af7b3b16d6571 100644 --- a/src/stralloc.h +++ b/src/stralloc.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: stralloc.h,v 1.15 1998/03/28 15:09:14 grubba Exp $ + * $Id: stralloc.h,v 1.16 1998/05/25 10:38:46 hubbe Exp $ */ #ifndef STRALLOC_H #define STRALLOC_H @@ -99,7 +99,7 @@ struct pike_string *realloc_unlinked_string(struct pike_string *a, INT32 size); struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size); struct pike_string *modify_shared_string(struct pike_string *a, INT32 index, - char c); + int c); struct pike_string *add_shared_strings(struct pike_string *a, struct pike_string *b); struct pike_string *add_and_free_shared_strings(struct pike_string *a, diff --git a/src/testsuite.in b/src/testsuite.in index b3eb6ba505255781b17d7dc70ee1be965478fa17..51b16eafdc8d4981826016be98aa687b1f064e30 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,4 @@ -stest_true([["$Id: testsuite.in,v 1.113 1998/05/24 23:21:00 marcus Exp $"]]) +stest_true([["$Id: testsuite.in,v 1.114 1998/05/25 10:38:47 hubbe Exp $"]]) cond([[all_constants()->_verify_internals]], [[ test_do(_verify_internals()) @@ -2375,6 +2375,21 @@ test_equal(Array.everynth("0123456789"/"",3,4), test_equal(Array.transpose( ({ ({ 1,2,3}), ({4,5,6}) }) ), ({ ({1,4}), ({2,5}), ({3,6}) })) + +test_true(!Yabu.test()->main(1,({"test"}))) +test_do([[ + string s; + for(s="foobar";strlen(s)<78;s+=s) + { + for(int e=0;e<strlen(s);e++) + { + s[e]++; + } + } +]]) + +test_any([[string s="foo"; s[2]='t'; s[0]--; return s;]],"eot") + cond([[all_constants()->_verify_internals]], [[ test_do(_verify_internals())