diff --git a/src/ChangeLog b/src/ChangeLog index 2f9260b147d6894e42de5f19f5369429aca00f88..41124fce848bf58e67ff11e10cc336c510793fce 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +Sat Mar 8 04:31:29 1997 Fredrik Hubinette <hubbe@cytocin.hubbe.net> + + * added new efuns `[] and `-> + * type checking improved: + * function and program are now almost interchangeable. + * function and object are now almost interchangeable. + Thu Mar 6 21:19:28 1997 Fredrik Hubinette <hubbe@cytocin.hubbe.net> * pike_types.c: recurseive compiling bugs fixed diff --git a/src/interpret.c b/src/interpret.c index aa29707faee22bd210dc806f1476de630cfece83..8bb77beff294465888e7d256de194629cfe66f64 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.28 1997/03/07 05:21:45 hubbe Exp $"); +RCSID("$Id: interpret.c,v 1.29 1997/03/08 12:54:06 hubbe Exp $"); #include "interpret.h" #include "object.h" #include "program.h" @@ -1072,7 +1072,7 @@ static void eval_instruction(unsigned char *pc) CASE(F_INDEX); do_index: - f_index(); + o_index(); print_return_value(); break; diff --git a/src/lex.c b/src/lex.c index 1531d9898f2c762053cb04d7d4d315b142495e6e..01e9e894a39ddddc121c6944cf0b5717b7f67112 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.15 1997/01/31 23:09:02 hubbe Exp $"); +RCSID("$Id: lex.c,v 1.16 1997/03/08 12:54:06 hubbe Exp $"); #include "language.h" #include "array.h" #include "lex.h" @@ -1832,7 +1832,7 @@ static void calcC() { low_lex(); calc1(); - f_index(); + f_index(2); if(lookahead!=']') error("Missing ']'\n"); else diff --git a/src/opcodes.c b/src/opcodes.c index 0d3d6a21836829523593740ac8baf061bf3b038b..65cba860193749752e3983aa19bcedc6a42419fe 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -65,7 +65,7 @@ void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind) } } -void f_index() +void o_index() { index_no_free(sp,sp-2,sp-1); sp++; diff --git a/src/opcodes.h b/src/opcodes.h index 67e1db71fe63afc75f3c479b5ead795c2a34fba9..5993d54a06604b759582799e8e072ef6e8cb3e76 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -8,7 +8,8 @@ /* Prototypes begin here */ void index_no_free(struct svalue *to,struct svalue *what,struct svalue *ind); -void f_index(); +void o_index(); +void cast(struct pike_string *s); void f_cast(); void f_sscanf(INT32 args); /* Prototypes end here */ diff --git a/src/operators.c b/src/operators.c index 42f525efeb78189bcfeb8d2aa5919fc6f0c3bde1..66e82299e06eb87188539d46175532089a587fe8 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.9 1997/02/19 05:04:19 hubbe Exp $"); +RCSID("$Id: operators.c,v 1.10 1997/03/08 12:54:07 hubbe Exp $"); #include "interpret.h" #include "svalue.h" #include "multiset.h" @@ -1217,6 +1217,44 @@ void o_range() } } +void f_index(INT32 args) +{ + switch(args) + { + case 0: + case 1: + error("Too few arguments to `[]\n"); + break; + case 2: + if(sp[-1].type==T_STRING) sp[-1].subtype=0; + o_index(); + break; + case 3: + o_range(); + break; + default: + error("Too manu arguments to `[]\n"); + } +} + +void f_arrow(INT32 args) +{ + switch(args) + { + case 0: + case 1: + error("Too few arguments to `->\n"); + break; + case 2: + if(sp[-1].type==T_STRING) + sp[-1].subtype=1; + o_index(); + break; + default: + error("Too manu arguments to `->\n"); + } +} + void f_sizeof(INT32 args) { INT32 tmp; @@ -1241,6 +1279,12 @@ static int generate_sizeof(node *n) void init_operators() { + add_efun2("`[]",f_index, + "function(string,int:int)|function(object,string:mixed)|function(array,int:mixed)|function(mapping,mixed:mixed)|function(multiset,mixed:int)|function(string,int,int:string)|function(array,int,int:array)",OPT_TRY_OPTIMIZE,0,0); + + add_efun2("`->",f_arrow, + "function(object|mapping|multiset,string:mixed)",OPT_TRY_OPTIMIZE,0,0); + add_efun2("`==",f_eq,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison); add_efun2("`!=",f_ne,"function(mixed,mixed:int)",OPT_TRY_OPTIMIZE,0,generate_comparison); add_efun2("`!",f_not,"function(mixed:int)",OPT_TRY_OPTIMIZE,0,generate_not); diff --git a/src/pike_types.c b/src/pike_types.c index e1cb7f65162e66bf8de9838d7dcea7e908336798..0f18b28531c432c904a015a5e31043f1d5dc3cec 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: pike_types.c,v 1.17 1997/03/07 05:21:46 hubbe Exp $"); +RCSID("$Id: pike_types.c,v 1.18 1997/03/08 12:54:08 hubbe Exp $"); #include <ctype.h> #include "svalue.h" #include "pike_types.h" @@ -26,6 +26,9 @@ int max_correct_args; static void internal_parse_type(char **s); static int type_length(char *t); +#define TWOT(X,Y) (((X) << 8)+(Y)) +#define EXTRACT_TWOT(X,Y) TWOT(EXTRACT_UCHAR(X), EXTRACT_UCHAR(Y)) + /* * basic types are represented by just their value in a string * basic type are string, int, float, object and program @@ -699,18 +702,13 @@ static char *low_match_types(char *a,char *b, int flags) if(EXTRACT_UCHAR(a) == T_MIXED && !(flags & A_EXACT)) return a; if(EXTRACT_UCHAR(b) == T_MIXED && !(flags & B_EXACT)) return a; - /* Special case (tm) */ - - /* Handle cloning with prog() */ - if(EXTRACT_UCHAR(a) == T_PROGRAM && - EXTRACT_UCHAR(b)==T_FUNCTION) + /* Special cases (tm) */ + switch(EXTRACT_TWOT(a,b)) { + case TWOT(T_PROGRAM, T_FUNCTION): + case TWOT(T_FUNCTION, T_PROGRAM): return a; - } - - /* Handle the `() operator */ - if(EXTRACT_UCHAR(a) == T_OBJECT && - EXTRACT_UCHAR(b)==T_FUNCTION) + case TWOT(T_OBJECT, T_FUNCTION): { struct program *p; if(p=id_to_program(EXTRACT_INT(a+1))) @@ -722,6 +720,19 @@ static char *low_match_types(char *a,char *b, int flags) return a; } + case TWOT(T_FUNCTION, T_OBJECT): + { + struct program *p; + if(p=id_to_program(EXTRACT_INT(b+1))) + { + int i=p->lfuns[LFUN_CALL]; + if(i == -1) return 0; + return low_match_types(a, ID_FROM_INT(p, i)->type->str, flags); + } + return a; + } + } + if(EXTRACT_UCHAR(a) != EXTRACT_UCHAR(b)) return 0; ret=a; @@ -1149,6 +1160,42 @@ struct pike_string *get_type_of_svalue(struct svalue *s) reference_shared_string(ret); return ret; + case T_PROGRAM: + { + char *a; + int id=s->u.program->lfuns[LFUN_CREATE]; + if(id>=0) + { + a=ID_FROM_INT(s->u.program, id)->type->str; + }else{ + a=function_type_string->str; + } + if(EXTRACT_UCHAR(a)==T_FUNCTION) + { + type_stack_mark(); + push_type_int(s->u.program->id); + push_type(T_OBJECT); + + type_stack_mark(); + a++; + while(EXTRACT_UCHAR(a)!=T_MANY) + { + type_stack_mark(); + push_unfinished_type(a); + type_stack_reverse(); + a+=type_length(a); + } + a++; + push_type(T_MANY); + type_stack_mark(); + push_unfinished_type(a); + type_stack_reverse(); + type_stack_reverse(); + push_type(T_FUNCTION); + return pop_unfinished_type(); + } + } + default: type_stack_mark(); push_type(s->type); diff --git a/src/testsuite.in b/src/testsuite.in index d6cdb7f52cca0bdd4e16ad64755b8949d17a143b..7dd2e80402cafab4d152808c3d486d717761ea22 100644 --- a/src/testsuite.in +++ b/src/testsuite.in @@ -1,4 +1,5 @@ -test_true([["$Id: testsuite.in,v 1.32 1997/03/01 03:30:49 hubbe Exp $"]]) +test_true([["$Id: testsuite.in,v 1.33 1997/03/08 12:54:09 hubbe Exp $"]]) +test_true([[lambda(function f) {return 1;}(object_program(this_object()));]]) test_eq([[class { int `()(){ return 4711; } }()(); ]],4711) teste_eval_error(mixed foo=({}); sort(@foo); ) test_compile_error([[int foo() { return 1} ; constant foo=(["foo":foo]); return foo->foo();]])