From 9f6847cc6479f4d6aa15e36b8b50b31c30e7326b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Sat, 8 Mar 1997 04:54:09 -0800 Subject: [PATCH] type handling bugs fixed (function/program) Rev: src/ChangeLog:1.84 Rev: src/interpret.c:1.29 Rev: src/lex.c:1.16 Rev: src/opcodes.c:1.4 Rev: src/opcodes.h:1.2 Rev: src/operators.c:1.10 Rev: src/pike_types.c:1.18 Rev: src/testsuite.in:1.33 --- src/ChangeLog | 7 +++++ src/interpret.c | 4 +-- src/lex.c | 4 +-- src/opcodes.c | 2 +- src/opcodes.h | 3 ++- src/operators.c | 46 +++++++++++++++++++++++++++++++- src/pike_types.c | 69 ++++++++++++++++++++++++++++++++++++++++-------- src/testsuite.in | 3 ++- 8 files changed, 119 insertions(+), 19 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 2f9260b147..41124fce84 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 aa29707fae..8bb77beff2 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 1531d9898f..01e9e894a3 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 0d3d6a2183..65cba86019 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 67e1db71fe..5993d54a06 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 42f525efeb..66e82299e0 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 e1cb7f6516..0f18b28531 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 d6cdb7f52c..7dd2e80402 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();]]) -- GitLab