diff --git a/src/ChangeLog b/src/ChangeLog index de000c9bf87a2745d56bc3676b45faba540eceab..1574e91eab0599e9bb4364efc1bf1671cd669bd8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +Sun Feb 25 22:42:48 1996 Fredrik Hubinette <hubbe@tymin.signum.se> + + * operator functions implemented + * typeof() added + Sat Feb 24 04:12:52 1996 Fredrik Hubinette <hubbe@tymin.signum.se> * program.c, array.c, object.c, gc.c: diff --git a/src/Makefile.in b/src/Makefile.in index fbfd057af6a905fd05479c34eee0d9c5e3d2bed8..41e2f32f64fb0cd51a571ad52bdbf19c8cc58c48 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -172,6 +172,12 @@ depend: language.c gcc -MM $(PREFLAGS) *.c $(SRCDIR)/*.c | $(FIXDEP) $(SRCDIR)/Makefile.in for a in $(MODULES) ; do ( cd $$a ; ${MAKE} $(MAKE_FLAGS) depend ) ; done +docs: + mkdir docs + +html_docs: docs + $(RUNULPC) $(TMP_BINDIR)/htmlify_docs $(TMP_DOCDIR) docs + # # uLPC internal targets # diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c index 992553c9cfacea3a9bf5fdcd11ea3ddc30c6df1e..81cc0404a1ba94a70ec418fb91bff22e213d0e6d 100644 --- a/src/builtin_efuns.c +++ b/src/builtin_efuns.c @@ -579,7 +579,14 @@ void f_sizeof(INT32 args) tmp=sp[-1].u.list->ind->size; free_list(sp[-1].u.list); break; - + + case T_OBJECT: + if(!sp[-1].u.object->prog) + error("sizeof() on destructed object.\n"); + tmp=sp[-1].u.object->prog->num_identifier_indexes; + free_object(sp[-1].u.object); + break; + default: error("Bad argument 1 to sizeof().\n"); return; /* make apcc happy */ @@ -1263,7 +1270,7 @@ void init_builtin_efuns() add_efun("reverse",f_reverse,"function(int:int)|function(string:string)|function(array:array)",0); add_efun("rusage", f_rusage, "function(:int *)",OPT_EXTERNAL_DEPEND); add_efun("search",f_search,"function(string,string,void|int:int)|function(array,mixed,void|int:int)|function(mapping,mixed:mixed)",0); - add_efun("sizeof", f_sizeof, "function(string|list|array|mapping:int)",0); + add_efun("sizeof", f_sizeof, "function(string|list|array|mapping|object:int)",0); add_efun("sleep", f_sleep, "function(int:void)",OPT_SIDE_EFFECT); add_efun("stringp", f_stringp, "function(mixed:int)",0); diff --git a/src/language.y b/src/language.y index 528e4714a8898c35089169963a155dbf8f1d2089..0c4ef11bf4e56087691861b69e349aa994453d88 100644 --- a/src/language.y +++ b/src/language.y @@ -113,6 +113,7 @@ %token F_STRING_ID %token F_SUBSCRIPT %token F_SUB_EQ +%token F_TYPEOF %token F_VAL_LVAL %token F_VARARGS %token F_VOID_ID @@ -223,7 +224,7 @@ void fix_comp_stack(int sp) %type <n> for do cond optional_else_part while statements %type <n> local_name_list class catch_arg %type <n> unused2 foreach unused switch case return expr_list default -%type <n> continue break block_or_semi +%type <n> continue break block_or_semi typeof %% all: program; @@ -920,6 +921,7 @@ expr4: string | F_FLOAT { $$=mkfloatnode($1); } | catch | gauge + | typeof | sscanf | lambda | class @@ -1029,8 +1031,15 @@ gauge: F_GAUGE '(' unused ')' mkintnode(GAUGE_RUSAGE_INDEX)))),0); } ; +typeof: F_TYPEOF '(' expr0 ')' + { + node *tmp; + tmp=mknode(F_ARG_LIST,$3,0); + $$=mkstrnode(describe_type($3->type)); + free_node(tmp); + } ; -catch_arg: '(' unused ')' { $$=$2; } +catch_arg: '(' comma_expr ')' { $$=$2; } | block ; diff --git a/src/lex.c b/src/lex.c index a1ad1fdb7ee2da8b70fa58f1930f601856fb1b86..9738a418ce8b344dd06d6c714a717b5db3855392 100644 --- a/src/lex.c +++ b/src/lex.c @@ -124,6 +124,7 @@ struct keyword reserved_words[] = { "static", F_STATIC, }, { "string", F_STRING_ID, }, { "switch", F_SWITCH, }, +{ "typeof", F_TYPEOF, }, { "varargs", F_VARARGS, }, { "void", F_VOID_ID, }, { "while", F_WHILE, }, @@ -1532,8 +1533,6 @@ static int do_lex2(int literal, YYSTYPE *yylval) case '|': tmp="`|"; break; case '^': tmp="`^"; break; case '~': tmp="`~"; break; - case '(': - if(GOBBLE(')')) { tmp="`()"; break; } default: yyerror("Illegal ` identifier."); diff --git a/src/lpc_types.c b/src/lpc_types.c index 4cf28ef1201393cba59d9545c3e23d1b90d276d6..e2186c79741998ca054d12d1790eea4140138152 100644 --- a/src/lpc_types.c +++ b/src/lpc_types.c @@ -18,6 +18,8 @@ #include "macros.h" #include "error.h" +static void internal_parse_type(char **s); + /* * basic types are represented by just their value in a string * basic type are string, int, float, object and program @@ -80,10 +82,12 @@ static int type_length(char *t) case T_MAPPING: case T_OR: + case T_AND: t+=type_length(t); case T_ARRAY: case T_LIST: + case T_NOT: t+=type_length(t); case T_INT: @@ -99,7 +103,7 @@ static int type_length(char *t) return t-q; } -static void internal_parse_type(char **s) +static void internal_parse_typeA(char **s) { char buf[80]; unsigned int len; @@ -169,8 +173,8 @@ static void internal_parse_type(char **s) type_stack_reverse(); if(**s != ')') error("Missing ')' in function type.\n"); ++*s; - type_stack_reverse(); - }else{ + type_stack_reverse(); + }else{ push_type(T_MIXED); push_type(T_MIXED); push_type(T_MANY); @@ -227,19 +231,81 @@ static void internal_parse_type(char **s) error("Couldn't parse type. (%s)\n",buf); while(isspace(**s)) ++*s; +} + + +static void internal_parse_typeB(char **s) +{ + while(isspace(**s)) ++*s; + switch(**s) + { + case '!': + ++*s; + internal_parse_typeB(s); + push_type(T_NOT); + break; + + case '(': + ++*s; + internal_parse_typeB(s); + while(isspace(**s)) ++*s; + if(**s != ')') error("Expecting ')'.\n"); + break; + + default: + + internal_parse_typeA(s); + } +} + +static void internal_parse_typeCC(char **s) +{ + internal_parse_typeB(s); + + while(isspace(**s)) ++*s; + while(**s == '*') { ++*s; - push_type(T_ARRAY); while(isspace(**s)) ++*s; + push_type(T_ARRAY); } +} + +static void internal_parse_typeC(char **s) +{ + type_stack_mark(); + + type_stack_mark(); + internal_parse_typeCC(s); + type_stack_reverse(); + while(isspace(**s)) ++*s; + + if(**s == '&') + { + ++*s; + type_stack_mark(); + internal_parse_typeC(s); + type_stack_reverse(); + type_stack_reverse(); + push_type(T_AND); + }else{ + type_stack_reverse(); + } +} + +static void internal_parse_type(char **s) +{ + internal_parse_typeC(s); + + while(isspace(**s)) ++*s; + while(**s == '|') { ++*s; - internal_parse_type(s); + internal_parse_typeC(s); push_type(T_OR); - while(isspace(**s)) ++*s; } } @@ -280,6 +346,8 @@ void stupid_describe_type(char *a,INT32 len) case T_UNKNOWN: printf("unknown"); break; case T_MANY: printf("many"); break; case T_OR: printf("or"); break; + case T_AND: printf("and"); break; + case T_NOT: printf("not"); break; case T_VOID: printf("void"); break; case T_MIXED: printf("mixed"); break; @@ -299,33 +367,14 @@ char *low_describe_type(char *t) { switch(EXTRACT_UCHAR(t++)) { - case T_VOID: - my_strcat("void"); - break; - - case T_MIXED: - my_strcat("mixed"); - break; - - case T_UNKNOWN: - my_strcat("unknown"); - break; - - case T_INT: - my_strcat("int"); - break; - - case T_FLOAT: - my_strcat("float"); - break; - - case T_PROGRAM: - my_strcat("program"); - break; - - case T_OBJECT: - my_strcat("object"); - break; + case T_VOID: my_strcat("void"); break; + case T_MIXED: my_strcat("mixed"); break; + case T_UNKNOWN: my_strcat("unknown"); break; + case T_INT: my_strcat("int"); break; + case T_FLOAT: my_strcat("float"); break; + case T_PROGRAM: my_strcat("program"); break; + case T_OBJECT: my_strcat("object"); break; + case T_STRING: my_strcat("string"); break; case T_FUNCTION: { @@ -335,36 +384,49 @@ char *low_describe_type(char *t) while(EXTRACT_UCHAR(t) != T_MANY) { if(s++) my_strcat(", "); - low_describe_type(t); - t+=type_length(t); + t=low_describe_type(t); } t++; - if(EXTRACT_UCHAR(t) != T_VOID) + if(EXTRACT_UCHAR(t) == T_VOID) { + t++; + }else{ if(s++) my_strcat(", "); - low_describe_type(t); + t=low_describe_type(t); my_strcat(" ..."); } - t+=type_length(t); my_strcat(" : "); - low_describe_type(t); + t=low_describe_type(t); my_strcat(")"); break; } - case T_STRING: - my_strcat("string"); - break; - case T_ARRAY: - t=low_describe_type(t); - my_strcat("*"); + if(EXTRACT_UCHAR(t)==T_MIXED) + { + my_strcat("array"); + t++; + }else{ + t=low_describe_type(t); + my_strcat("*"); + } break; case T_LIST: - my_strcat("list ("); + my_strcat("list"); + if(EXTRACT_UCHAR(t)!=T_MIXED) + { + my_strcat("("); + t=low_describe_type(t); + my_strcat(")"); + }else{ + t++; + } + break; + + case T_NOT: + my_strcat("!"); t=low_describe_type(t); - my_strcat(")"); break; case T_OR: @@ -372,28 +434,53 @@ char *low_describe_type(char *t) my_strcat(" | "); t=low_describe_type(t); break; - - case T_MAPPING: - my_strcat("mapping ("); + + case T_AND: t=low_describe_type(t); - my_strcat(":"); + my_strcat(" & "); t=low_describe_type(t); - my_strcat(")"); + break; + + case T_MAPPING: + my_strcat("mapping"); + if(EXTRACT_UCHAR(t)==T_MIXED && EXTRACT_UCHAR(t+1)==T_MIXED) + { + t+=2; + }else{ + my_strcat("("); + t=low_describe_type(t); + my_strcat(":"); + t=low_describe_type(t); + my_strcat(")"); + } break; } return t; } -TYPE_T compile_type_to_runtime_type(struct lpc_string *s) +struct lpc_string *describe_type(struct lpc_string *type) { - char *t; - t=s->str; - + if(!type) return make_shared_string("mixed"); + init_buf(); + low_describe_type(type->str); + return free_buf(); +} + +static TYPE_T low_compile_type_to_runtime_type(char *t) +{ + TYPE_T tmp; switch(EXTRACT_UCHAR(t)) { case T_OR: + t++; + tmp=low_compile_type_to_runtime_type(t); + if(tmp == low_compile_type_to_runtime_type(t+type_length(t))) + return tmp; + case T_MANY: case T_UNKNOWN: + case T_AND: + case T_NOT: return T_MIXED; default: @@ -401,36 +488,70 @@ TYPE_T compile_type_to_runtime_type(struct lpc_string *s) } } +TYPE_T compile_type_to_runtime_type(struct lpc_string *s) +{ + return low_compile_type_to_runtime_type(s->str); +} + +#define A_EXACT 1 +#define B_EXACT 2 + /* * match two type strings, return zero if they don't match, and return * the part of 'a' that _did_ match if it did. */ -static char *low_match_types(char *a,char *b) +static char *low_match_types(char *a,char *b, int flags) { char *ret; if(a == b) return a; - if(EXTRACT_UCHAR(a) == T_OR) + switch(EXTRACT_UCHAR(a)) { + case T_AND: a++; - ret=low_match_types(a,b); + ret=low_match_types(a,b,flags); + if(!ret) return 0; + a+=type_length(a); + return low_match_types(a,b,flags); + + case T_OR: + a++; + ret=low_match_types(a,b,flags); if(ret) return ret; a+=type_length(a); - return low_match_types(a,b); + return low_match_types(a,b,flags); + + case T_NOT: + if(low_match_types(a+1,b,flags | B_EXACT)) + return 0; + return a; } - if(EXTRACT_UCHAR(b) == T_OR) + switch(EXTRACT_UCHAR(b)) { + case T_AND: b++; - ret=low_match_types(a,b); + ret=low_match_types(a,b,flags); + if(!ret) return 0; + b+=type_length(b); + return low_match_types(a,b,flags); + + case T_OR: + b++; + ret=low_match_types(a,b,flags); if(ret) return ret; b+=type_length(b); - return low_match_types(a,b); + return low_match_types(a,b,flags); + + case T_NOT: + if(low_match_types(a,b+1, flags | A_EXACT)) + return 0; + return a; } /* 'mixed' matches anything */ - if(EXTRACT_UCHAR(a) == T_MIXED) return a; - if(EXTRACT_UCHAR(b) == T_MIXED) return a; + if(EXTRACT_UCHAR(a) == T_MIXED && !(flags & A_EXACT)) return a; + if(EXTRACT_UCHAR(b) == T_MIXED && !(flags & B_EXACT)) return a; if(EXTRACT_UCHAR(a) != EXTRACT_UCHAR(b)) return 0; ret=a; @@ -458,7 +579,7 @@ static char *low_match_types(char *a,char *b) b+=type_length(b); } - if(!low_match_types(a_tmp, b_tmp)) return 0; + if(!low_match_types(a_tmp, b_tmp, flags)) return 0; } /* check the 'many' type */ a++; @@ -468,20 +589,20 @@ static char *low_match_types(char *a,char *b) a+=type_length(a); b+=type_length(b); }else{ - if(!low_match_types(a,b)) return 0; + if(!low_match_types(a,b,flags)) return 0; } /* check the returntype */ - if(!low_match_types(a,b)) return 0; + if(!low_match_types(a,b,flags)) return 0; break; case T_MAPPING: - if(!low_match_types(++a,++b)) return 0; - if(!low_match_types(a+type_length(a),b+type_length(b))) return 0; + if(!low_match_types(++a,++b,flags)) return 0; + if(!low_match_types(a+type_length(a),b+type_length(b),flags)) return 0; break; case T_LIST: case T_ARRAY: - if(!low_match_types(++a,++b)) return 0; + if(!low_match_types(++a,++b,flags)) return 0; case T_INT: case T_FLOAT: @@ -503,19 +624,25 @@ static char *low_match_types(char *a,char *b) */ static int low_get_return_type(char *a,char *b) { - if(EXTRACT_UCHAR(a) == T_OR) + int tmp; + switch(EXTRACT_UCHAR(a)) { - int tmp; + case T_OR: a++; tmp=low_get_return_type(a,b); tmp+=low_get_return_type(a+type_length(a),b); if(tmp==2) push_type(T_OR); return tmp>0; - } - if(EXTRACT_UCHAR(a) == T_ARRAY) - { - int tmp; + case T_AND: + a++; + type_stack_mark(); + tmp=low_get_return_type(a,b); + type_stack_pop_to_mark(); + if(!tmp) return 0; + return low_get_return_type(a+type_length(a),b); + + case T_ARRAY: a++; tmp=low_get_return_type(a,b); if(!tmp) return 0; @@ -523,7 +650,7 @@ static int low_get_return_type(char *a,char *b) return 1; } - a=low_match_types(a,b); + a=low_match_types(a,b,0); if(a) { switch(EXTRACT_UCHAR(a)) @@ -547,7 +674,7 @@ static int low_get_return_type(char *a,char *b) int match_types(struct lpc_string *a,struct lpc_string *b) { - return 0!=low_match_types(a->str, b->str); + return 0!=low_match_types(a->str, b->str,0); } @@ -585,6 +712,12 @@ void pop_type_stack() fatal("Type stack underflow\n"); } +void type_stack_pop_to_mark() +{ + pop_stack_mark(); + type_stackp=*mark_stackp; +} + void type_stack_reverse() { unsigned char *a,*b,tmp; @@ -651,6 +784,8 @@ static struct lpc_string *low_index_type(char *t) return pop_type(); } + case T_AND: + return low_index_type(t+type_length(t)); case T_STRING: /* always int */ case T_LIST: /* always int */ @@ -680,17 +815,24 @@ static int low_check_indexing(char *type, char *index_type) case T_OR: return low_check_indexing(type,index_type) || low_check_indexing(type+type_length(type),index_type); - + + case T_AND: + return low_check_indexing(type,index_type) && + low_check_indexing(type+type_length(type),index_type); + + case T_NOT: + return !low_check_indexing(type,index_type); + case T_STRING: case T_ARRAY: - return !!low_match_types(int_type_string->str, index_type); + return !!low_match_types(int_type_string->str, index_type,0); case T_OBJECT: - return !!low_match_types(string_type_string->str, index_type); + return !!low_match_types(string_type_string->str, index_type,0); case T_LIST: case T_MAPPING: - return !!low_match_types(type,index_type); + return !!low_match_types(type,index_type,0); case T_MIXED: return 1; @@ -741,7 +883,6 @@ struct lpc_string *check_call(struct lpc_string *args, } } - void check_array_type(struct array *a) { push_type(T_MIXED); diff --git a/src/lpc_types.h b/src/lpc_types.h index 01ef1497344b7dba569e2d9435d7a4eb53a86ed1..1e898a8f14c0fd7595025f5eba7322ac226d689d 100644 --- a/src/lpc_types.h +++ b/src/lpc_types.h @@ -23,13 +23,16 @@ extern struct lpc_string *any_type_string; void init_types(); struct lpc_string *parse_type(char *s); void stupid_describe_type(char *a,INT32 len); +void simple_describe_type(struct lpc_string *s); char *low_describe_type(char *t); +struct lpc_string *describe_type(struct lpc_string *type); TYPE_T compile_type_to_runtime_type(struct lpc_string *s); int match_types(struct lpc_string *a,struct lpc_string *b); void reset_type_stack(); void type_stack_mark(); void pop_stack_mark(); void pop_type_stack(); +void type_stack_pop_to_mark(); void type_stack_reverse(); void push_type(unsigned char tmp); void push_unfinished_type(char *s); diff --git a/src/object.c b/src/object.c index 9d6e0ff0876f9a54d9937de3d1cb016c4baa737b..86174658e9593168b002d1de02bcc8480135464f 100644 --- a/src/object.c +++ b/src/object.c @@ -657,13 +657,13 @@ void gc_check_object(struct object *o) i=ID_FROM_INT(o->prog, e); - if(i->run_time_type & IDENTIFIER_FUNCTION) continue; + if(i->flags & IDENTIFIER_FUNCTION) continue; if(i->run_time_type == T_MIXED) { gc_check_svalues((struct svalue *)LOW_GET_GLOBAL(o,e,i),1); }else{ - gc_check_short_svalue((struct svalue *)LOW_GET_GLOBAL(o,e,i), + gc_check_short_svalue((union anything *)LOW_GET_GLOBAL(o,e,i), i->run_time_type); } } diff --git a/src/operators.c b/src/operators.c index ca9bdbce4003a011ab2dc94356a7f212eb32b324..3a21b0d51f0052e715aa4497294e5d5e42dff2aa 100644 --- a/src/operators.c +++ b/src/operators.c @@ -169,6 +169,24 @@ void f_add(INT32 args) break; } + case BIT_FLOAT | BIT_INT: + { + FLOAT_TYPE sum; + sum=0.0; + for(e=-args; e<0; e++) + { + if(sp[e].type==T_FLOAT) + { + sum+=sp[e].u.float_number; + }else{ + sum+=(FLOAT_TYPE)sp[e].u.integer; + } + } + sp-=args-1; + sp[-1].u.float_number=sum; + break; + } + case BIT_ARRAY: { struct array *a; @@ -231,7 +249,8 @@ static node *optimize_binary(node *n) fatal("Couldn't find argument!\n"); #endif - if((*second_arg)->type == (*first_arg)->type) + if((*second_arg)->type == (*first_arg)->type && + compile_type_to_runtime_type((*second_arg)->type) != T_MIXED) { if((*first_arg)->token == F_APPLY && CAR(*first_arg)->token == F_CONSTANT && @@ -295,10 +314,26 @@ static int generate_comparison(node *n) return 0; } +static int float_promote() +{ + if(sp[-2].type==T_INT) + { + sp[-2].u.float_number=(FLOAT_TYPE)sp[-2].u.integer; + sp[-2].type=T_FLOAT; + } + + if(sp[-1].type==T_INT) + { + sp[-1].u.float_number=(FLOAT_TYPE)sp[-1].u.integer; + sp[-1].type=T_FLOAT; + } + + return sp[-2].type == sp[-1].type; +} void o_subtract() { - if (sp[-2].type != sp[-1].type ) + if (sp[-2].type != sp[-1].type && !float_promote()) error("Subtract on different types.\n"); switch(sp[-1].type) @@ -659,15 +694,14 @@ static int generate_rsh(node *n) return 0; } + +#define TWO_TYPES(X,Y) (((X)<<8)|(Y)) void o_multiply() { - switch(sp[-2].type) + switch(TWO_TYPES(sp[-2].type,sp[-1].type)) { - case T_ARRAY: - if(sp[-1].type!=T_STRING) + case TWO_TYPES(T_ARRAY,T_STRING): { - error("Bad argument 2 to multiply.\n"); - }else{ struct lpc_string *ret; sp--; ret=implode(sp[-1].u.array,sp[0].u.string); @@ -678,20 +712,30 @@ void o_multiply() return; } - case T_FLOAT: - if(sp[-1].type!=T_FLOAT) error("Bad argument 2 to multiply.\n"); + case TWO_TYPES(T_FLOAT,T_FLOAT): sp--; sp[-1].u.float_number *= sp[0].u.float_number; return; - case T_INT: - if(sp[-1].type!=T_INT) error("Bad argument 2 to multiply.\n"); + case TWO_TYPES(T_FLOAT,T_INT): + sp--; + sp[-1].u.float_number *= (FLOAT_TYPE)sp[0].u.integer; + return; + + case TWO_TYPES(T_INT,T_FLOAT): + sp--; + sp[-1].u.float_number= + (FLOAT_TYPE) sp[-1].u.integer * (FLOAT_TYPE)sp[0].u.float_number; + sp[-1].type=T_FLOAT; + return; + + case TWO_TYPES(T_INT,T_INT): sp--; sp[-1].u.integer *= sp[0].u.integer; return; default: - error("Bad argument 1 to multiply.\n"); + error("Bad arguments to multiply.\n"); } } @@ -726,7 +770,7 @@ static int generate_multiply(node *n) void o_divide() { - if(sp[-2].type!=sp[-1].type) + if(sp[-2].type!=sp[-1].type && !float_promote()) error("Division on different types.\n"); switch(sp[-2].type) @@ -782,7 +826,7 @@ static int generate_divide(node *n) void o_mod() { - if(sp[-2].type != sp[-1].type) + if(sp[-2].type != sp[-1].type && !float_promote()) error("Modulo on different types.\n"); switch(sp[-1].type) @@ -956,14 +1000,14 @@ void init_operators() { add_efun2("`==",f_eq,"function(mixed,mixed:int)",0,0,generate_comparison); add_efun2("`!=",f_ne,"function(mixed,mixed:int)",0,0,generate_comparison); - add_efun2("`<", f_lt,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison); - add_efun2("`<=",f_le,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison); - add_efun2("`>", f_gt,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison); - add_efun2("`>=",f_ge,"function(int,int:int)|function(float,float:int)|function(string,string:int)",0,0,generate_comparison); + add_efun2("`<", f_lt,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison); + add_efun2("`<=",f_le,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison); + add_efun2("`>", f_gt,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison); + add_efun2("`>=",f_ge,"function(int|float,int|float:int)|function(string,string:int)",0,0,generate_comparison); - add_efun2("`+",f_add,"function(int ...:int)|function(float ...:float)|function(string,string|int|float ...:string)|function(string,string|int|float ...:string)|function(int|float,string,string|int|float:string)|function(array ...:array)|function(mapping ...:mapping)|function(list...:list)",0,optimize_binary,generate_sum); + add_efun2("`+",f_add,"function(int...:int)|!function(int...:mixed)&function(int|float...:float)|!function(int|float...:mixed)&function(string|int|float...:string)|function(array...:array)|function(mapping...:mapping)|function(list...:list)",0,optimize_binary,generate_sum); - add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float,float:float)|function(int,int:int)|function(string,string:string)",0,0,generate_minus); + add_efun2("`-",f_minus,"function(int:int)|function(float:float)|function(array,array:array)|function(mapping,mapping:mapping)|function(list,list:list)|function(float|int,float:float)|function(float,int:float)|function(int,int:int)|function(string,string:string)",0,0,generate_minus); add_efun2("`&",f_and,"function(int...:int)|function(mapping...:mapping)|function(list...:list)|function(array...:array)",0,optimize_binary,generate_and); @@ -974,13 +1018,12 @@ void init_operators() add_efun2("`<<",f_lsh,"function(int,int:int)",0,0,generate_lsh); add_efun2("`>>",f_rsh,"function(int,int:int)",0,0,generate_rsh); - add_efun2("`*",f_multiply,"function(int...:int)|function(float...:float)|function(string*,string:string)",0,optimize_binary,generate_multiply); + add_efun2("`*",f_multiply,"function(int...:int)|!function(int...:mixed)&function(float|int...:float)|function(string*,string:string)",0,optimize_binary,generate_multiply); - add_efun2("`/",f_divide,"function(int,int:int)|function(float,float:float)|function(string,string:string*)",0,0,generate_divide); + add_efun2("`/",f_divide,"function(int,int:int)|function(float|int,float:float)|function(float,int:float)|function(string,string:string*)",0,0,generate_divide); add_efun2("`%",f_mod,"function(int,int:int)|function(float,float:float)",0,0,generate_mod); add_efun2("`!",f_not,"function(mixed:int)",0,0,generate_not); add_efun2("`~",f_compl,"function(int:int)",0,0,generate_compl); - } diff --git a/src/svalue.c b/src/svalue.c index 612ab00302229ed296953c159a555c9ca85971f7..6793c90527bf8e231fe64010267aa287e77d3ff1 100644 --- a/src/svalue.c +++ b/src/svalue.c @@ -366,7 +366,6 @@ int is_eq(struct svalue *a, struct svalue *b) } } - int low_is_equal(struct svalue *a, struct svalue *b, struct processing *p) @@ -443,8 +442,7 @@ int is_equal(struct svalue *a,struct svalue *b) return low_is_equal(a,b,0); } - -int is_gt(const struct svalue *a,const struct svalue *b) +int is_lt(const struct svalue *a,const struct svalue *b) { check_type(a->type); check_type(b->type); @@ -453,39 +451,18 @@ int is_gt(const struct svalue *a,const struct svalue *b) if (a->type != b->type) { - error("Cannot compare different types.\n"); - } - switch(a->type) - { - default: - error("Bad argument 1 to '>'.\n"); - - case T_INT: - return a->u.integer > b->u.integer; - - case T_STRING: - return my_strcmp(a->u.string, b->u.string) > 0; + if(a->type == T_FLOAT && b->type==T_INT) + return a->u.float_number < (FLOAT_TYPE)b->u.integer; - case T_FLOAT: - return a->u.float_number > b->u.float_number; - } -} - -int is_lt(const struct svalue *a,const struct svalue *b) -{ - check_type(a->type); - check_type(b->type); - check_refs(a); - check_refs(b); + if(a->type == T_INT && b->type==T_FLOAT) + return (FLOAT_TYPE)a->u.integer < b->u.float_number; - if (a->type != b->type) - { error("Cannot compare different types.\n"); } switch(a->type) { default: - error("Bad arg 1 to '<'.\n"); + error("Bad type to comparison.\n"); case T_INT: return a->u.integer < b->u.integer; diff --git a/src/svalue.h b/src/svalue.h index 9e536ff2f14ca6db4848639f5ff48241ef7cb008..80bf0c88f6fdc01752e7d2e0005359878dce2ae5 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -55,6 +55,8 @@ struct svalue #define T_FLOAT 7 #define T_INT 8 +#define T_NOT 247 +#define T_AND 248 #define T_UNKNOWN 249 #define T_MANY 250 #define T_OR 251 @@ -87,6 +89,7 @@ struct svalue #define NUMBER_UNDEFINED 1 #define NUMBER_DESTRUCTED 2 +#define is_gt(a,b) is_lt(b,a) #define IS_ZERO(X) ((X)->type==T_INT && (X)->u.integer==0) #define check_destructed(S) \ @@ -163,7 +166,6 @@ int low_short_is_equal(const union anything *a, TYPE_T type, struct processing *p); int is_equal(struct svalue *a,struct svalue *b); -int is_gt(const struct svalue *a,const struct svalue *b); int is_lt(const struct svalue *a,const struct svalue *b); void describe_svalue(struct svalue *s,int indent,struct processing *p); void clear_svalues(struct svalue *s, INT32 num); @@ -173,6 +175,8 @@ void copy_svalues_recursively_no_free(struct svalue *to, struct processing *p); void check_short_svalue(union anything *u,TYPE_T type); void check_svalue(struct svalue *s); +void gc_check_svalues(struct svalue *s, int num); +void gc_check_short_svalue(union anything *u, TYPE_T type); /* Prototypes end here */ #endif