/** * add new symbol to local table * @param sname * @param identity * @param type * @param offset size in bytes * @param storage_class * @return */ int add_local (char *sname, int identity, int type, int offset, int storage_class) { int k; SYMBOL *symbol; char *buffer_ptr; if ((current_symbol_table_idx = find_locale (sname)) > -1) { return (current_symbol_table_idx); } if (local_table_index >= NUMBER_OF_GLOBALS + NUMBER_OF_LOCALS) { error ("local symbol table overflow"); return (0); } current_symbol_table_idx = local_table_index; symbol = &symbol_table[current_symbol_table_idx]; buffer_ptr = symbol->name; /* FIXME: only copy so many bytes */ while (alphanumeric(*buffer_ptr++ = *sname++)); symbol->identity = identity; symbol->type = type; symbol->storage = storage_class; if (storage_class == LSTATIC) { data_segment_gdata(); print_label(k = getlabel()); output_label_terminator(); gen_def_storage(); output_number(offset); newline(); code_segment_gtext(); offset = k; } symbol->offset = offset; local_table_index++; return (current_symbol_table_idx); }
/** * evaluate one initializer, add data to table * @param symbol_name * @param type * @param identity * @param dim * @param tag * @return * returns size of initializer, or 0 for none (a null string is size 1) * */ int init(char *symbol_name, int type, int identity, int *dim, TAG_SYMBOL *tag) { int value, n; /* A pointer is initialized as a word holding the address of the struct or string etc that directly follows */ if(identity == POINTER) { int x = getlabel(); gen_def_word(); print_label(x); newline(); print_label(x); output_label_terminator(); newline(); } /* FIXME: may need to distinguish const string v data in future */ if(quoted_string(&n, NULL)) { if((identity == VARIABLE) || !(type & CCHAR)) error("found string: must assign to char pointer or array"); *dim = *dim - n; /* ??? FIXME arrays of char only */ return n; } if (type & CCHAR) gen_def_byte(); else gen_def_word(); if (!number(&value) && !quoted_char(&value)) return 0; *dim = *dim - 1; output_number(value); newline(); return (type & CCHAR) ? 1 : 2; }
/** * dump all static variables */ void dumpglbs(void) { int dim, i, list_size, line_count, value; if (!glbflag) return; current_symbol_table_idx = rglobal_table_index; while (current_symbol_table_idx < global_table_index) { SYMBOL *symbol = &symbol_table[current_symbol_table_idx]; if (symbol->identity != FUNCTION) { ppubext(symbol); if (symbol->storage != EXTERN) { output_string(symbol->name); output_label_terminator(); dim = symbol->offset; list_size = 0; line_count = 0; if (find_symbol_initials(symbol->name)) { // has initials list_size = get_size(symbol->name); if (dim == -1) { dim = list_size; } } for (i=0; i<dim; i++) { if (symbol->type == STRUCT) { dump_struct(symbol, i); } else { if (line_count % 10 == 0) { newline(); if ((symbol->type & CINT) || (symbol->identity == POINTER)) { gen_def_word(); } else { gen_def_byte(); } } if (i < list_size) { // dump data value = get_item_at(symbol->name, i, &tag_table[symbol->tagidx]); output_number(value); } else { // dump zero, no more data available output_number(0); } line_count++; if (line_count % 10 == 0) { line_count = 0; } else { if (i < dim-1) { output_byte( ',' ); } } } } newline(); } } else { fpubext(symbol); } current_symbol_table_idx++; } }
addcase (int val) { int lab; if (swstp == SWSTSZ) error ("too many case labels"); else { swstcase[swstp] = val; swstlab[swstp++] = lab = getlabel (); print_label (lab); output_label_terminator (); newline (); } }
/** * dump the literal pool */ void dumplits(void) { int j, k; if (litptr == 0) return; print_label(litlab); output_label_terminator(); k = 0; while (k < litptr) { gen_def_byte(); j = 8; while (j--) { output_number(litq[k++] & 127); if ((j == 0) | (k >= litptr)) { newline(); break; } output_byte(','); } } }
/** * declare entry point */ void declare_entry_point(char *symbol_name) { output_string(symbol_name); output_label_terminator(); //newline(); }
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; }
/** * 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; }