void as_environment::set_variable_raw ( const tu_string &varname, const as_value &val, const array<with_stack_entry>& with_stack ) // No path rigamarole. { // Check the with-stack. for ( int i = with_stack.size() - 1; i >= 0; i-- ) { as_object *obj = with_stack[i].m_object.get_ptr(); as_value unused; if ( obj && obj->get_member ( varname, &unused ) ) { // This object has the member; so set it here. obj->set_member ( varname, val ); return; } } // Check locals. int local_index = find_local ( varname, true ); if ( local_index >= 0 ) { // Set local var. m_local_frames[local_index].m_value = val; return; } if ( m_target != NULL ) { m_target->set_member ( varname, val ); } else { // assume local var // This case happens for example so // class myclass // { // function myfunc() // { // for (i=0;...) should be for (var i=0; ...) // { // } // } // } add_local ( varname, val ); IF_VERBOSE_ACTION ( log_error ( "can't set_variable_raw %s=%s, target is NULL, it's assumed as local\n", varname.c_str(), val.to_string() ) ); IF_VERBOSE_ACTION ( log_error ( "probably you forgot to declare variable '%s'\n", varname.c_str() ) ); } }
void as_environment::declare_local ( const tu_string &varname ) // Create the specified local var if it doesn't exist already. { // Is it in the current frame already? int index = find_local ( varname, false ); if ( index < 0 ) { // Not in frame; create a new local var. add_local ( varname, as_value() ); } else { // In frame already; don't mess with it. } }
void as_environment::set_local ( const tu_string &varname, const as_value &val ) // Set/initialize the value of the local variable. { // Is it in the current frame already? int index = find_local ( varname, false ); if ( index < 0 ) { // Not in frame; create a new local var. add_local ( varname, val ); } else { // In frame already; modify existing var. m_local_frames[index].m_value = val; } }
void doLocalAnsiArgument(int type) { char symbol_name[NAMESIZE]; int identity, address, argptr, ptr; if (match("*")) { identity = POINTER; } else { if (type == STRUCT) { error("cannot pass struct"); return; } identity = VARIABLE; if (type == VOID) return; } if (symname(symbol_name)) { if (find_locale(symbol_name) > -1) { multidef(symbol_name); } else { argptr = add_local (symbol_name, identity, type, 0, AUTO); argstk = argstk + INTSIZE; ptr = local_table_index; while (ptr != NUMBER_OF_GLOBALS) { // modify stack offset as we push more params ptr = ptr - 1; address = symbol_table[ptr].offset; symbol_table[ptr].offset = address + INTSIZE; /* Struct etc FIXME */ } } } else { error("illegal argument name"); junk(); } if (match("[")) { while (inbyte() != ']') { if (endst()) { break; } } identity = POINTER; symbol_table[argptr].identity = identity; } }
void newfunc_typed(int storage, char *n, int type) { int idx; SYMBOL *symbol; char an[NAMESIZE]; fexitlab = getlabel(); if ((idx = find_global(n)) > -1) { symbol = &symbol_table[idx]; if (symbol->identity != FUNCTION) multidef(n); } else { /* extern implies global scope */ idx = add_global(n, FUNCTION, CINT, 0, storage == EXTERN ? PUBLIC : storage); symbol = &symbol_table[idx]; } local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; argstk = 0; // ANSI style argument declaration if (doAnsiArguments()) { if (storage == EXTERN) { need_semicolon(); return; } /* No body .. just a definition */ if (match(";")) return; } else { // K&R style argument declaration while (!match(")")) { if (symname(an)) { if (find_locale(an) > -1) multidef(an); else { /* FIXME: struct */ add_local(an, 0, 0, argstk, AUTO); argstk = argstk + INTSIZE; } } else { error("illegal argument name"); junk(); } blanks(); if (!streq(line + lptr, ")")) { if (!match(",")) error("expected comma"); } if (endst()) break; } if (storage == EXTERN) { need_semicolon(); return; } /* No body .. just a definition */ if (match(";")) return; stkp = 0; argtop = argstk; while (argstk) { if ((type = get_type()) != -1) { notvoid(type); getarg(type); need_semicolon(); } else { error("wrong number args"); break; } } } if (symbol->offset == FUNCTION) multidef(n); symbol->offset = FUNCTION; output_string(n); output_label_terminator(); newline(); gen_prologue(); statement(YES); print_label(fexitlab); output_label_terminator(); newline(); gen_epilogue(); gen_modify_stack(0); gen_ret(); stkp = 0; local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; }
/** * declare local variables * works just like "declglb", but modifies machine stack and adds * symbol table entry with appropriate stack offset to find it again * @param typ * @param stclass * @param otag index of tag in tag_table */ void declare_local(int typ, int stclass, int otag) { int k, j; char sname[NAMESIZE]; FOREVER { FOREVER { if (endst()) return; if (match("*")) j = POINTER; else j = VARIABLE; if (!symname(sname)) illname(); if (-1 != find_locale(sname)) multidef (sname); if (match("[")) { k = needsub(); if (k) { j = ARRAY; if (typ & CINT) { k = k * INTSIZE; } else if (typ == STRUCT) { k = k * tag_table[otag].size; } } else { j = POINTER; k = INTSIZE; } } else { if (j == POINTER) { k = INTSIZE; } else { switch (typ) { case CCHAR: case UCHAR: k = 1; break; case STRUCT: k = tag_table[otag].size; break; default: k = INTSIZE; } } } if (stclass == LSTATIC) { add_local(sname, j, typ, k, LSTATIC); break; } if (stclass == REGISTER) { int r = gen_register(j, k, typ); if (r != -1) { add_local(sname, j, typ, r, REGISTER); break; } } if (match("=")) { gen_modify_stack(stkp); expression(0); gen_push(0); } else stkp = gen_defer_modify_stack(stkp - k); add_local(sname, j, typ, stkp, AUTO); break; } if (!match(",")) return; } }
/** * begin a function * called from "parse", this routine tries to make a function out * of what follows * modified version. p.l. woods */ newfunc() { char n[NAMESIZE]; int idx, type; fexitlab = getlabel(); if (!symname(n)) { error("illegal function or declaration"); kill(); return; } if (idx = findglb(n)) { if (symbol_table[idx].identity != FUNCTION) multidef(n); else if (symbol_table[idx].offset == FUNCTION) multidef(n); else symbol_table[idx].offset = FUNCTION; } else add_global(n, FUNCTION, CINT, FUNCTION, PUBLIC); if (!match("(")) error("missing open paren"); output_string(n); output_label_terminator(); newline(); local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; argstk = 0; // ANSI style argument declaration if (doAnsiArguments() == 0) { // K&R style argument declaration while (!match(")")) { if (symname(n)) { if (findloc(n)) multidef(n); else { add_local(n, 0, 0, argstk, AUTO); argstk = argstk + INTSIZE; } } else { error("illegal argument name"); junk(); } blanks(); if (!streq(line + lptr, ")")) { if (!match(",")) error("expected comma"); } if (endst()) break; } stkp = 0; argtop = argstk; while (argstk) { if (type = get_type()) { getarg(type); need_semicolon(); } else { error("wrong number args"); break; } } } statement(YES); print_label(fexitlab); output_label_terminator(); newline(); gen_modify_stack(0); gen_ret(); stkp = 0; local_table_index = NUMBER_OF_GLOBALS; //locptr = STARTLOC; }
static bool gather_locals( bool initted, int *counter ) { signed long wlen; bool retval = FALSE; while ( TRUE ) { wlen = get_word(); if ( wlen <= 0 ) { warn_unterm( TKERROR, "Local-Values Declaration", l_d_lineno); break; } /* Allow comments to be interspersed among the declarations. */ if ( filter_comments( statbuf) ) { /* Unterminated and Multi-line checking already handled */ continue; } /* Is this the terminator or the separator? */ if ( wlen == 1 ) /* Maybe */ { /* Check for separator */ if (locals_separator( statbuf[0] ) ) { /* If gathering initted Local names, separator is legit */ if ( initted ) { retval = TRUE; break; }else{ tokenization_error ( TKERROR, "Excess separator -- %s -- found " "in Local-Values declaration", statbuf); in_last_colon( TRUE); continue; } } /* Haven't found the separator. Check for the terminator */ if ( statbuf[0] == '}' ) { break; } } /* It was not the terminator or the separator */ { long tmp; char *where_pt1; char *where_pt2; /* Error-check for duplicated names */ if ( word_exists ( statbuf, &where_pt1, &where_pt2 ) ) { tokenization_error ( TKERROR, "Cannot declare %s " "as a Local-Name; it's already defined %s%s", statbuf, where_pt1, where_pt2 ); show_node_start(); continue; } /* Error-check for numbers. */ if ( get_number(&tmp) ) { tokenization_error ( TKERROR, "Cannot declare %s " "as a Local-Name; it's a number.\n", statbuf ); continue; } /* We've got a valid new local-name */ /* Don't need to check name length; it won't go into the FCode */ /* Increment our counting-v'ble */ *counter += 1; /* Define our new local-name in the Locals' vocabulary */ add_local( localno, statbuf ); /* Bump the running Local-Number */ localno++; } } return ( retval ); }