From: Peep P. <so...@us...> - 2004-03-28 18:09:37
|
Update of /cvsroot/agd/server/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31649 Modified Files: lang.h interpret.c interpret.h Log Message: Changed make_lvalue into a function; added string ranges. Index: lang.h =================================================================== RCS file: /cvsroot/agd/server/src/lang.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- lang.h 21 Mar 2004 14:06:36 -0000 1.6 +++ lang.h 28 Mar 2004 17:58:15 -0000 1.7 @@ -47,33 +47,33 @@ L_CLOSE_ARRAY = 273, L_OPEN_FUNP = 274, L_CLOSE_FUNP = 275, - L_ASSIGN = 276, - L_ME = 277, - L_PE = 278, - L_DE = 279, - L_MOE = 280, - L_MUE = 281, - L_POWE = 282, - L_AND = 283, - L_OR = 284, - L_NE = 285, - L_EQ = 286, - L_MINUS = 287, - L_PLUS = 288, - L_GE = 289, - L_LE = 290, - L_GT = 291, - L_LT = 292, - L_MOD = 293, - L_DIV = 294, - L_MUL = 295, - L_POW = 296, - L_DEREF = 297, - L_DEC = 298, - L_INC = 299, - L_NOT = 300, - L_NEG = 301, - L_TYPECAST = 302 + L_RANGE = 276, + L_ASSIGN = 277, + L_ME = 278, + L_PE = 279, + L_DE = 280, + L_MOE = 281, + L_MUE = 282, + L_POWE = 283, + L_AND = 284, + L_OR = 285, + L_NE = 286, + L_EQ = 287, + L_MINUS = 288, + L_PLUS = 289, + L_GE = 290, + L_LE = 291, + L_GT = 292, + L_LT = 293, + L_MOD = 294, + L_DIV = 295, + L_MUL = 296, + L_POW = 297, + L_DEREF = 298, + L_DEC = 299, + L_INC = 300, + L_NOT = 301, + L_NEG = 302 }; #endif #define L_RETURN 258 @@ -94,39 +94,39 @@ #define L_CLOSE_ARRAY 273 #define L_OPEN_FUNP 274 #define L_CLOSE_FUNP 275 -#define L_ASSIGN 276 -#define L_ME 277 -#define L_PE 278 -#define L_DE 279 -#define L_MOE 280 -#define L_MUE 281 -#define L_POWE 282 -#define L_AND 283 -#define L_OR 284 -#define L_NE 285 -#define L_EQ 286 -#define L_MINUS 287 -#define L_PLUS 288 -#define L_GE 289 -#define L_LE 290 -#define L_GT 291 -#define L_LT 292 -#define L_MOD 293 -#define L_DIV 294 -#define L_MUL 295 -#define L_POW 296 -#define L_DEREF 297 -#define L_DEC 298 -#define L_INC 299 -#define L_NOT 300 -#define L_NEG 301 -#define L_TYPECAST 302 +#define L_RANGE 276 +#define L_ASSIGN 277 +#define L_ME 278 +#define L_PE 279 +#define L_DE 280 +#define L_MOE 281 +#define L_MUE 282 +#define L_POWE 283 +#define L_AND 284 +#define L_OR 285 +#define L_NE 286 +#define L_EQ 287 +#define L_MINUS 288 +#define L_PLUS 289 +#define L_GE 290 +#define L_LE 291 +#define L_GT 292 +#define L_LT 293 +#define L_MOD 294 +#define L_DIV 295 +#define L_MUL 296 +#define L_POW 297 +#define L_DEREF 298 +#define L_DEC 299 +#define L_INC 300 +#define L_NOT 301 +#define L_NEG 302 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 34 "lang.y" +#line 33 "lang.y" typedef union YYSTYPE { char *str; int i; Index: interpret.c =================================================================== RCS file: /cvsroot/agd/server/src/interpret.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- interpret.c 21 Mar 2004 10:35:53 -0000 1.15 +++ interpret.c 28 Mar 2004 17:58:15 -0000 1.16 @@ -24,15 +24,6 @@ int *cp; /* Code pointer into code->data */ array_t *code; -typedef struct { - variable_t *sp, *fp; - int *cp; - array_t *code; - object_t *this_ob, *previous_ob; - player_t *this_player; - int num_arg; -} control_stack_t; - control_stack_t control_stack[CONTROL_STACK_SIZE]; control_stack_t *csp = control_stack; @@ -45,17 +36,20 @@ void call_function(object_t *ob, int index); void do_assign(variable_t *lval, variable_t *rval); +void pop_control_stack(int pop_sp); +void free_value(variable_t *v); /* Need the F_NEWLINE operation for this. */ -static void runtime(char *s) +void runtime(char *s) { - char buf[512]; + char *buf; if(!this_ob) { printf("%s on line %d (function %d)\n", s, lineno, funcno); goto out; } + buf = xmalloc(strlen(this_ob->name) + strlen(s) + 64); sprintf(buf, "%s: %s on line %d (function %d)\n", this_ob->name, s, lineno, funcno); printf(buf); @@ -64,7 +58,13 @@ net_disconnect(this_player); } + xfree(buf); + out: + if(csp > &control_stack[0]) { + /*pop_locals();*/ + pop_control_stack(1); + } longjmp(error_context, 1); } @@ -120,7 +120,6 @@ CHECK_SP() } -void free_value(variable_t *v); void push_var(variable_t *v) { if(v) @@ -151,8 +150,6 @@ } } -#define pop_locals() while(sp > fp) { sp--; free_value(sp); } - void do_assign(variable_t *lval, variable_t *rval) { *lval = *rval; @@ -161,7 +158,7 @@ ref_ob(lval->u.ob, lval); break; case T_STRING: - if(lval->string_type != ST_STATIC) { + if(rval->string_type != ST_STATIC && rval->u.s) { lval->u.s = stringdup(rval->u.s); } break; @@ -250,18 +247,23 @@ #define CHECK_OVERRUN() if((int *) cp >= (int *) code->data + code->length) {\ debug("interpret", "Ran over end of array: returning\n"); return; } -#define GET_ARGS() tmpi = 0; while(tmpi < 2) { \ +/*#define GET_ARGS() tmpi = 0; while(tmpi < 2) { \ tmp = --sp; if(tmp->type == T_LVALUE) tmp = tmp->u.v;\ - arg[tmpi] = tmp->u.i; tmpi++; free_value(sp); } + arg[tmpi] = tmp->u.i; tmpi++; free_value(sp); }*/ +#define GET_ARGS() arg[0] = sp[-1].u.i; pop_stack(); arg[1] = sp[-1].u.i; pop_stack(); #define SETUP_CALL_FRAME() tmpi = *++cp; cp++; push_control_stack(); \ csp->num_arg = *cp; fp = sp - csp->num_arg +#define TAKE_SLICE() GET_ARGS() if(!sp[-1].u.s) runtime("taking substring of NULL string"); \ + if(arg[1] >= strlen(sp[-1].u.s) || arg[1] < 0 || arg[1] > arg[0]) runtime("substring out of range"); \ + void eval_instruction(void) { - variable_t *tmp; + variable_t *tmpvp, tmpv; control_stack_t *saved_csp; int tmpi, arg[2]; + char *tmps; /* csp is never at &control_stack[0] when we get here, so this is safe. */ saved_csp = csp - 1; @@ -309,13 +311,13 @@ push_lvalue(this_ob->variables.data[*cp]); break; case F_ADD: - tmp = add_vars(sp-2, sp-1); + tmpvp = add_vars(sp-2, sp-1); pop_stack(); pop_stack(); - push_var(tmp); + push_var(tmpvp); break; case F_SUB: GET_ARGS() - push_int(arg[1]-arg[0]); + push_int(arg[1] - arg[0]); break; case F_MUL: GET_ARGS() @@ -330,54 +332,79 @@ push_int(arg[1] % arg[0]); break; case F_ASSIGN: - { - variable_t tmp; do_assign(sp[-2].u.v, sp-1); - do_assign(&tmp, sp-1); + do_assign(&tmpv, sp-1); pop_stack(); pop_stack(); - push_var(&tmp); - } + push_var(&tmpv); break; case F_POSTINC: - tmp = sp[-1].u.v; - tmpi = tmp->u.i++; + tmpvp = sp[-1].u.v; + tmpi = tmpvp->u.i++; pop_stack(); push_int(tmpi); break; case F_PREINC: - tmp = sp[-1].u.v; - tmpi = ++tmp->u.i; + tmpvp = sp[-1].u.v; + tmpi = ++tmpvp->u.i; pop_stack(); push_int(tmpi); break; case F_POSTDEC: - tmp = sp[-1].u.v; - tmpi = tmp->u.i--; + tmpvp = sp[-1].u.v; + tmpi = tmpvp->u.i--; push_int(tmpi); break; case F_PREDEC: - tmp = sp[-1].u.v; - tmpi = --tmp->u.i; + tmpvp = sp[-1].u.v; + tmpi = --tmpvp->u.i; push_int(tmpi); break; - case F_RANGE: - tmpi = sp[-2].u.s[sp[-1].u.i]; - pop_stack(); pop_stack(); - push_int(tmpi); + case F_INDEX: + if(!sp[-2].u.s) { + runtime("taking element of NULL string"); + } + arg[0] = sp[-1].u.i; + pop_stack(); + arg[1] = sp[-1].u.s[arg[0]]; + pop_stack(); + push_int(arg[1]); break; - case F_RANGE_LVALUE: + case F_INDEX_LVALUE: /* A bit hacky. */ - *sp = sp[-2]; - sp->u.s += sp[-1].u.i; - pop_stack(); pop_stack(); - push_var(sp+2); + arg[0] = sp[-1].u.i; + pop_stack(); + if(!sp[-1].u.s) { + runtime("taking element of NULL string"); + } + do_assign(sp, &sp[-1]); + sp->u.s += arg[0]; + pop_stack(); + push_var(sp+1); + push_lvalue(sp-1); + break; + case F_SLICE: + TAKE_SLICE() + tmps = xmalloc(arg[0] - arg[1] + 1); + for(tmpi=0;tmpi<arg[0];tmpi++) + tmps[tmpi] = sp[-1].u.s[tmpi+arg[1]]; + tmps[tmpi] = '\0'; + pop_stack(); + push_string(tmps, ST_MALLOC); + break; + case F_SLICE_LVALUE: + TAKE_SLICE() + tmpvp = sp[-1].u.v; + tmps = tmpvp->u.s + arg[0]; /* begin */ + tmpi = tmpvp->string_type; + pop_stack(); + push_string(tmps, tmpi); push_lvalue(sp-1); break; case F_JMPF: sp--; if(!test_var(sp)) { - int amount = cp[1]; - cp += amount; + tmpi = cp[1]; + cp += tmpi; } else { cp++; } @@ -444,51 +471,40 @@ pop_control_stack(0); break; case F_CALL_OTHER: - { - char *name; - int index; - variable_t *ref; - object_t *ob; - - name = (char *) *++cp; + tmps = (char *) *++cp; ++cp; sp--; if(sp->type == T_OBJECT) { - ob = sp->u.ob; - } else { - char *s; - /* T_STRING */ - s = sp->u.s; - ob = find_object(s); - if(!ob) { - ob = load_object(s); + tmpv.u.ob = sp->u.ob; /* A little hack so we don't + need an object_t variable in this scope. + Saves some overhead. */ + } else { /* T_STRING */ + tmpv.u.ob = find_object(sp->u.s); + if(!tmpv.u.ob) { + tmpv.u.ob = load_object(sp->u.s); } } - if(!ob) { + if(!tmpv.u.ob) { runtime("call_other on NULL object"); } - index = get_fun_index(ob, name); + tmpi = get_fun_index(tmpv.u.ob, tmps); free_value(sp); push_control_stack(); csp->num_arg = *cp; fp = sp - csp->num_arg; - call_function(ob, index); + call_function(tmpv.u.ob, tmpi); goto again; - } break; case F_RETURN: - { - variable_t tmp; - do_assign(&tmp, sp-1); + do_assign(&tmpv, sp-1); pop_locals(); - push_var(&tmp); + push_var(&tmpv); if(csp == saved_csp + 1) pop_control_stack(1); else pop_control_stack(0); - } break; default: printf("Unknown instruction %d\n", *cp); @@ -525,7 +541,8 @@ function_t *f; f = ob->prog->functions.data[index]; if(!f) { - char buf[256]; + char buf[512]; /* Can't use dynamic memory + because of runtime()'s longjmp() */ sprintf(buf, "function %d doesn't exist in object \"%s\"", index, ob->name); runtime(buf); } Index: interpret.h =================================================================== RCS file: /cvsroot/agd/server/src/interpret.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- interpret.h 21 Mar 2004 13:02:37 -0000 1.9 +++ interpret.h 28 Mar 2004 17:58:16 -0000 1.10 @@ -48,18 +48,34 @@ #define F_PREINC 41 #define F_POSTDEC 42 #define F_PREDEC 43 -#define F_RANGE 44 -#define F_RANGE_LVALUE 45 -#define F_COMM 46 -#define F_POW 47 -#define F_POWE 48 +#define F_INDEX 44 /* Single index into an array or string. */ +#define F_INDEX_LVALUE 45 +#define F_SLICE 46 +#define F_SLICE_LVALUE 47 +#define F_COMM 48 +#define F_POW 49 +#define F_POWE 50 -#define F_HIGHEST F_RANGE_LVALUE +#define F_HIGHEST F_POWE -#define F_NEWLINE 50 /* Increases the line number. Not used ATM. */ +#define F_NEWLINE 51 /* Increases the line number. Not used ATM. */ variable_t *apply(object_t *ob, char *fun, char *argfmt, ...); +void runtime(char *s); #define pop_stack() sp--; free_value(sp) +#define pop_locals() while(sp > fp) { sp--; free_value(sp); } + +typedef struct { + variable_t *sp, *fp; + int *cp; + array_t *code; + object_t *this_ob, *previous_ob; + player_t *this_player; + int num_arg; +} control_stack_t; + +extern control_stack_t *csp; +extern variable_t *sp, *fp; #endif |