From: Peep P. <so...@us...> - 2004-03-28 18:09:09
|
Update of /cvsroot/agd/server/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31561 Modified Files: lang.y Log Message: Changed make_lvalue into a function; added string ranges. Index: lang.y =================================================================== RCS file: /cvsroot/agd/server/src/lang.y,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- lang.y 21 Mar 2004 14:06:36 -0000 1.13 +++ lang.y 28 Mar 2004 17:57:49 -0000 1.14 @@ -3,9 +3,13 @@ #include "lpc_incl.h" #include "lex.h" -/* Used during compilation, replaced with F_JMP. */ -#define F_BREAK -5 -#define F_CONTINUE -6 +/* Used during compilation, replaced with F_JMP. + Need to use two separate numbers for both, because one + could easily appear on it's own in code. */ +#define F_BREAK_MAGIC1 -1 +#define F_BREAK_MAGIC2 -2 +#define F_CONTINUE_MAGIC1 -3 +#define F_CONTINUE_MAGIC2 -4 YYLTYPE yylloc; @@ -19,13 +23,8 @@ void add_function(def_id_t *idp, int lineno, array_t *code); void redeclaration_error(def_id_t *id, int new_type); int compare_args(array_t *arg1, array_t *arg2); +void make_lvalue(expr_t *e); -#define MAKE_LVALUE(x) if((int)x.arr.data[0] == F_PUSH_LVAR)\ - x.arr.data[0] = (void *)F_PUSH_LVAR_LVALUE;\ - else if((int)x.arr.data[0] == F_PUSH_GVAR)\ - x.arr.data[0] = (void*)F_PUSH_GVAR_LVALUE;\ - else if((int)x.arr.data[x.arr.length-1] == F_RANGE)\ - x.arr.data[x.arr.length-1] = (void*)F_RANGE_LVALUE %} %expect 1 @@ -55,6 +54,7 @@ %token L_OPEN_FUNP L_CLOSE_FUNP /* operators */ +%nonassoc L_RANGE %right L_ASSIGN %left L_PE /* Pluq-equals */ L_ME /* Minus-equals */ %left L_MUE /* Multiply-equals */ L_MOE /* Modulo-equals */ L_DE /* Divide-equals */ @@ -73,7 +73,7 @@ %right '[' ']' %nonassoc L_NEG L_NOT L_INC L_DEC /*%left L_COMM*/ -%nonassoc L_TYPECAST +/*%nonassoc L_TYPECAST*/ %type <str> string string_con2 %type <id> defined_name @@ -84,7 +84,8 @@ %type <var> var_def %type <arr> call_args call_arg_list -%type <expr> expr optional_expr range_expr +%type <expr> expr optional_expr +%type <arr> slice_expr %type <arr> return if else do_while while for break continue %type <arr> fun_call call_other %type <arr> statements statement @@ -161,9 +162,10 @@ if($9.length) { def_id_t *idp = $<id>4; if(idp->lpc_type != $1 || compare_args(idp->args, &$6)) { - char buf[256]; + char *buf = xmalloc(strlen($2) + 41); sprintf(buf, "definition doesn't match declaration for %s", $2); comp_error(buf); + xfree(buf); } idp->type = ID_FUN; @@ -202,9 +204,10 @@ } else { def_id_t *idp = $<id>4; if(idp->type == ID_FUN_PROT && !$<i>3) { - char buf[256]; + char *buf = xmalloc(strlen($2) + 59); sprintf(buf, "warning: repeated prototype for %s; using existing prototype", $2); display_error(buf); + xfree(buf); compile_warnings++; } else { add_function(idp, $<i>8, NULL); @@ -273,9 +276,10 @@ if($8.length) { def_id_t *idp = $<id>3; if(idp->lpc_type != DEFAULT_FUNCTION_TYPE || compare_args(idp->args, &$5)) { - char buf[256]; + char *buf = xmalloc(strlen($1) + 42); sprintf(buf, "definition doesn't match declaration for %s", $1); comp_error(buf); + xfree(buf); } idp->type = ID_FUN; @@ -315,9 +319,10 @@ } else { def_id_t *idp = $<id>3; if(idp->type == ID_FUN_PROT && !$<i>2) { - char buf[256]; + char *buf = xmalloc(strlen($1) + 59); sprintf(buf, "warning: repeated prototype for %s; using existing prototype", $1); display_error(buf); + xfree(buf); compile_warnings++; } else { add_function(idp, $<i>8, NULL); @@ -398,9 +403,11 @@ { $$ = find_id($1); if(!$$) { - char buf[256]; + char *buf; + buf = xmalloc(strlen($1) + 25); sprintf(buf, "undeclared identifier '%s'", $1); comp_error(buf); + xfree(buf); xfree($1); /* WATCH OUT */ } } @@ -535,7 +542,7 @@ comp_error("improper use of void type"); } $$.type = $1; - init_var(&$$); + /*init_var(&$$);*/ $$.name = $2; } | L_IDENTIFIER @@ -551,9 +558,11 @@ id = find_id($1); if(id) { if(id->type == ID_ARG) { - char buf[256]; + char *buf; + buf = xmalloc(strlen($1) + 51); sprintf(buf, "warning: declaration of %s shadows function argument", $1); display_error(buf); + xfree(buf); compile_warnings++; } else if(id->type == ID_DFUN || id->base_scope >= scope_level) { redeclaration_error(id, ID_LVAR); @@ -570,15 +579,21 @@ id = find_id($1); if(id) { if(id->type == ID_ARG) { - char buf[256]; + char *buf; + buf = xmalloc(strlen($1) + 51); sprintf(buf, "warning: declaration of %s shadows function argument", $1); display_error(buf); + xfree(buf); compile_warnings++; } else if(id->base_scope >= scope_level) { redeclaration_error(id, ID_LVAR); } } + if($3.type && $3.type != global_type) { + comp_error("type mismatch"); + } + lval = type_xmalloc(variable_t); lval->name = $1; lval->type = global_type; @@ -684,7 +699,7 @@ init_array(&$$.arr); /* Once for F_ADD, once for F_ASSIGN. */ array_concat(&$$.arr, &$1.arr); - MAKE_LVALUE($$); + make_lvalue(&$$); array_concat(&$$.arr, &$1.arr); array_concat(&$$.arr, &$3.arr); array_push(&$$.arr, (void *) F_ADD); @@ -695,12 +710,8 @@ $$.lval = $$.direct_type = 0; $$.side_effect = $1.side_effect || $3.side_effect; - if(check_operand(F_SUB, $1.type, $3.type)) { - if($1.type != $3.type) { - comp_error("type mismatch"); - } - } - + check_operand(F_SUB, $1.type, $3.type); + $$.type = $1.type; init_array(&$$.arr); @@ -729,7 +740,7 @@ init_array(&$$.arr); /* Once for F_SUB, once for F_ASSIGN. */ array_concat(&$$.arr, &$1.arr); - MAKE_LVALUE($$); + make_lvalue(&$$); array_concat(&$$.arr, &$1.arr); array_concat(&$$.arr, &$3.arr); array_push(&$$.arr, (void *) F_SUB); @@ -769,7 +780,7 @@ init_array(&$$.arr); /* Once for F_MUL, once for F_ASSIGN. */ array_concat(&$$.arr, &$1.arr); - MAKE_LVALUE($$); + make_lvalue(&$$); array_concat(&$$.arr, &$1.arr); array_concat(&$$.arr, &$3.arr); array_push(&$$.arr, (void *) F_MUL); @@ -810,7 +821,7 @@ init_array(&$$.arr); /* Once for F_DIV, once for F_ASSIGN. */ array_concat(&$$.arr, &$1.arr); - MAKE_LVALUE($$); + make_lvalue(&$$); array_concat(&$$.arr, &$1.arr); array_concat(&$$.arr, &$3.arr); array_push(&$$.arr, (void *) F_DIV); @@ -850,7 +861,7 @@ init_array(&$$.arr); /* Once for F_MOD, once for F_ASSIGN. */ array_concat(&$$.arr, &$1.arr); - MAKE_LVALUE($$); + make_lvalue(&$$); array_concat(&$$.arr, &$1.arr); array_concat(&$$.arr, &$3.arr); array_push(&$$.arr, (void *) F_MOD); @@ -913,7 +924,7 @@ $$.lval = $$.direct_type = 0; $$.type = $1.type; init_array(&$$.arr); - MAKE_LVALUE($1); + make_lvalue(&$1); array_concat(&$$.arr, &$1.arr); array_push(&$$.arr, (void *) F_POSTINC); } @@ -927,7 +938,7 @@ $$.lval = $$.direct_type = 0; $$.type = $2.type; init_array(&$$.arr); - MAKE_LVALUE($2); + make_lvalue(&$2); array_concat(&$$.arr, &$2.arr); array_push(&$$.arr, (void *) F_PREINC); } @@ -941,7 +952,7 @@ $$.lval = $$.direct_type = 0; $$.type = $1.type; init_array(&$$.arr); - MAKE_LVALUE($1); + make_lvalue(&$1); array_concat(&$$.arr, &$1.arr); array_push(&$$.arr, (void *) F_POSTDEC); } @@ -956,7 +967,7 @@ $$.type = $2.type; init_array(&$$.arr); - MAKE_LVALUE($2); + make_lvalue(&$2); array_concat(&$$.arr, &$2.arr); array_push(&$$.arr, (void *) F_PREDEC); } @@ -1048,6 +1059,7 @@ init_array(&$$.arr); array_concat(&$$.arr, &$1.arr); + array_concat(&$$.arr, &$3.arr); array_push(&$$.arr, (void *) F_NE); } @@ -1055,11 +1067,13 @@ { check_operand(F_EQ, $1.type, $3.type); - $$.lval = $$.side_effect = $$.direct_type = 0; + $$.lval = $$.direct_type = 0; + $$.side_effect = $1.side_effect || $3.side_effect; $$.type = T_INT; - + init_array(&$$.arr); array_concat(&$$.arr, &$1.arr); + array_concat(&$$.arr, &$3.arr); array_push(&$$.arr, (void *) F_EQ); } @@ -1112,7 +1126,7 @@ array_push(&$$.arr, (void *) F_PUSH_INT); array_push(&$$.arr, (void *) 0); } - | expr '?' expr ':' expr + | expr '?' expr L_RANGE expr { $$.lval = $3.lval && $5.lval; $$.side_effect = $3.side_effect || $5.side_effect; @@ -1134,15 +1148,27 @@ { $$ = $2; /* Could cause problems. */ } - | '(' type ')' expr %prec L_TYPECAST +/* | '(' type ')' expr %prec L_TYPECAST { $$.side_effect = $4.side_effect; $$.lval = $4.lval; $$.direct_type = $4.direct_type; $$.type = $2; + + switch($2.type) { + case T_INT: + if($4.type != T_INT) { + comp_error("invalid cast to int"); + } + break; + case T_OBJECT: + comp_error("invalid cast to object"); + break; + } + init_array(&$$.arr); array_concat(&$$.arr, &$4.arr); - } + }*/ | call_other { $$.side_effect = 1; @@ -1185,18 +1211,20 @@ $$.type = $1->lpc_type; } } - | expr '[' range_expr ']' + | expr '[' slice_expr ']' { $$.lval = 1; - $$.direct_type = 0; - $$.side_effect = 0; - $$.type = T_INT; - check_operand(F_RANGE, $1.type, 0); + $$.direct_type = $$.side_effect = 0; + if((int)$3.data[$3.length-1] == F_INDEX) + $$.type = T_INT; + else + $$.type = T_STRING; + + check_operand(F_INDEX, $1.type, 0); init_array(&$$.arr); array_concat(&$$.arr, &$1.arr); - array_concat(&$$.arr, &$3.arr); - array_push(&$$.arr, (void *) F_RANGE); + array_concat(&$$.arr, &$3); } | expr L_ASSIGN expr { @@ -1207,12 +1235,20 @@ if($1.type && $3.type && $1.type != $3.type) { comp_error("type mismatch"); } + + if((int)$1.arr.data[$1.arr.length-1] == F_SLICE_LVALUE) { + comp_error("assigning to string slices unimplemented"); + } + + /* Check if we are assigning to a slice, then check + the resulting string's length. If bigger, error. + Else allows for some nasty buffer overflows. */ $$.side_effect = 1; $$.type = $1.type; $$.lval = $$.direct_type = 0; init_array(&$$.arr); - MAKE_LVALUE($1); + make_lvalue(&$1); array_concat(&$$.arr, &$1.arr); array_concat(&$$.arr, &$3.arr); array_push(&$$.arr, (void *) F_ASSIGN); @@ -1240,25 +1276,38 @@ } ; -range_expr: +slice_expr: expr { if($1.type != T_INT) { comp_error("index must be integer"); } - $$ = $1; + init_array(&$$); + array_concat(&$$, &$1.arr); + array_push(&$$, (void *) F_INDEX); +/* $$ = $1;*/ } -/* | L_INTEGER '..' L_INTEGER + | expr L_RANGE expr { - if($3 > $1) { - comp_error("range second element should be bigger than first"); + if($1.type != T_INT || $3.type != T_INT) { + + } else { + if($1.direct_type && $3.direct_type) { + int i1, i2; + i1 = (int) $1.arr.data[1]; + i2 = (int) $3.arr.data[1]; + if(i1 > i2) { + comp_error("slice second element should be bigger than first"); + } + } } - array_push(&$$, (void *) F_BEGIN); - array_push(&$$, (void *) $1); - array_push(&$$, (void *) F_END); - array_push(&$$, (void *) $3); + + init_array(&$$); + array_concat(&$$, &$1.arr); + array_concat(&$$, &$3.arr); + array_push(&$$, (void *) F_SLICE); } -*/ + ; string: @@ -1379,11 +1428,13 @@ { int i; for(i=0;i<$6.length;i++) { - if((int)$6.data[i] == F_BREAK) { + if((int)$6.data[i] == F_BREAK_MAGIC1 + && (int)$6.data[i+1] == F_BREAK_MAGIC2) { $6.data[i] = (void *) F_JMP; i++; $6.data[i] = (void *) $6.length - i + 2; - } else if((int)$6.data[i] == F_CONTINUE) { + } else if((int)$6.data[i] == F_CONTINUE_MAGIC1 + && (int)$6.data[i+1] == F_CONTINUE_MAGIC2) { $6.data[i] = (void *) F_JMP; i++; $6.data[i] = (void *) -(i + $4.arr.length + 2); @@ -1410,11 +1461,13 @@ { int i; for(i=0;i<$10.length;i++) { - if((int)$10.data[i] == F_BREAK) { + if((int)$10.data[i] == F_BREAK_MAGIC1 + && (int)$10.data[i+1] == F_BREAK_MAGIC2) { $10.data[i] = (void *) F_JMP; i++; $10.data[i] = (void *) $10.length + $7.arr.length - i - 1; - } else if((int)$10.data[i] == F_CONTINUE) { + } else if((int)$10.data[i] == F_CONTINUE_MAGIC1 && + (int)$10.data[i+1] == F_CONTINUE_MAGIC2) { $10.data[i] = (void *) F_JMP; i++; $10.data[i] = (void *) -(i + $5.arr.length + 5); @@ -1444,8 +1497,8 @@ L_BREAK { init_array(&$$); - array_push(&$$, (void *) F_BREAK); - array_push(&$$, (void *) 0); + array_push(&$$, (void *) F_BREAK_MAGIC1); + array_push(&$$, (void *) F_BREAK_MAGIC2); } ; @@ -1453,8 +1506,8 @@ L_CONTINUE { init_array(&$$); - array_push(&$$, (void *) F_CONTINUE); - array_push(&$$, (void *) 0); + array_push(&$$, (void *) F_CONTINUE_MAGIC1); + array_push(&$$, (void *) F_CONTINUE_MAGIC2); } ; @@ -1477,38 +1530,45 @@ i = compare_args($1->args, &tempargs); switch(i) { - char buf[256]; - case -2: - sprintf(buf, "Too many arguments to %s", $1->name); - comp_error(buf); - break; - case -1: - sprintf(buf, "Too few arguments to %s", $1->name); - comp_error(buf); - break; - case 0: - /* went okay */ - break; - default: /* > 0 */ - sprintf(buf, "Argument %d type mismatch for %s - expected %s, got %s", - i, $1->name, type2str($1->args->data[i]), - type2str(tempargs.data[i])); - comp_error(buf); - break; + char *buf; + case -2: + buf = xmalloc(strlen($1->name) + 23); + sprintf(buf, "Too many arguments to %s", + $1->name); + comp_error(buf); + xfree(buf); + break; + case -1: + buf = xmalloc(strlen($1->name) + 22); + sprintf(buf, "Too few arguments to %s", + $1->name); + comp_error(buf); + xfree(buf); + break; + case 0: + /* went okay */ + break; + default: /* > 0 */ + { + variable_t *v; + char *ts1, *ts2; + + v = tempargs.data[i]; + ts1 = type2str((int)$1->args->data[i]); + ts2 = type2str((int)tempargs.data[i]); + buf = xmalloc(strlen($1->name) + strlen(ts1) + strlen(ts2) + 64); + sprintf(buf, "Argument %d type mismatch for %s " + "- expected %s, got %s", i, $1->name, ts1, ts2); + comp_error(buf); + xfree(buf); + } + break; } if(tempargs.data) xfree(tempargs.data); init_array(&$$); -#if 0 - if($1->type == ID_FUN_PROT) { - char buf[256]; - sprintf(buf, "Function '%s' is called, but not defined", $1->name); - comp_error(buf); - /*goto out;*/ - } -#endif if($1->type == ID_FUN_PROT) $1->has_been_called = 1; @@ -1597,7 +1657,6 @@ e = type_xmalloc(expr_t); *e = $1; array_push(&$$, e); - } | call_arg_list ',' expr { @@ -1645,3 +1704,31 @@ } } ; +%% + +void make_lvalue(expr_t *e) +{ + int len, *begin, *end; + len = e->arr.length-1; + begin = (int *) e->arr.data; + end = (int *) e->arr.data + len; + switch(*end) { + case F_SLICE: + *end = F_SLICE_LVALUE; + goto out; + return; + case F_INDEX: + *end = F_INDEX_LVALUE; + return; + } + +out: + switch(*begin) { + case F_PUSH_LVAR: + *begin = F_PUSH_LVAR_LVALUE; + break; + case F_PUSH_GVAR: + *begin = F_PUSH_GVAR_LVALUE; + } +} + |