/** * non-declaration statement */ do_statement () { if (amatch ("if", 2)) { doif (); lastst = STIF; } else if (amatch ("while", 5)) { dowhile (); lastst = STWHILE; } else if (amatch ("switch", 6)) { doswitch (); lastst = STSWITCH; } else if (amatch ("do", 2)) { dodo (); need_semicolon (); lastst = STDO; } else if (amatch ("for", 3)) { dofor (); lastst = STFOR; } else if (amatch ("return", 6)) { doreturn (); need_semicolon (); lastst = STRETURN; } else if (amatch ("break", 5)) { dobreak (); need_semicolon (); lastst = STBREAK; } else if (amatch ("continue", 8)) { docont (); need_semicolon (); lastst = STCONT; } else if (match (";")) ; else if (amatch ("case", 4)) { docase (); lastst = statement (NO); } else if (amatch ("default", 7)) { dodefault (); lastst = statement (NO); } else if (match ("__asm__")) { doasm (); lastst = STASM; } else if (match("#")) { kill(); } else if (match ("{")) do_compound (NO); else { expression (YES); /* if (match (":")) { dolabel (); lastst = statement (NO); } else { */ need_semicolon (); lastst = STEXP; /* } */ } }
/** * parse top level declarations * @param stclass storage * @param mtag * @param is_struct * @return */ int do_declarations(int stclass, TAG_SYMBOL *mtag, int is_struct) { int type; int otag; // tag of struct object being declared int sflag; // TRUE for struct definition, zero for union char sname[NAMESIZE]; int ns = 0; blanks(); if ((sflag=amatch("struct", 6)) || amatch("union", 5)) { if (symname(sname) == 0) { // legal name ? illname(); } if ((otag=find_tag(sname)) == -1) { // structure not previously defined otag = define_struct(sname, stclass, sflag); } declare_global(STRUCT, stclass, mtag, otag, is_struct); } else if ((type = get_type()) != 1) { ns = declare_global(type, stclass, mtag, 0, is_struct); } else if (stclass == PUBLIC) { return (0); } else { ns = declare_global(CINT, stclass, mtag, 0, is_struct); } if (!ns) need_semicolon(); return (1); }
/** * "for" statement */ void dofor(void) { WHILE ws; WHILE *pws; ws.symbol_idx = local_table_index; ws.stack_pointer = stkp; ws.type = WSFOR; ws.case_test = getlabel (); ws.incr_def = getlabel (); ws.body_tab = getlabel (); ws.while_exit = getlabel (); addwhile (&ws); pws = readwhile (); needbrack ("("); if (!match (";")) { expression (YES); need_semicolon (); } generate_label (pws->case_test); if (!match (";")) { expression (YES); gen_test_jump (pws->body_tab, TRUE); gen_jump (pws->while_exit); need_semicolon (); } else pws->case_test = pws->body_tab; generate_label (pws->incr_def); if (!match (")")) { expression (YES); needbrack (")"); gen_jump (pws->case_test); } else pws->incr_def = pws->case_test; generate_label (pws->body_tab); statement (NO); gen_jump (pws->incr_def); generate_label (pws->while_exit); local_table_index = pws->symbol_idx; stkp = gen_modify_stack (pws->stack_pointer); delwhile (); }
/** * "for" statement */ dofor() { loop_t loop; loop_t *p; loop.symbol_idx = local_table_index; loop.stack_pointer = stkp; loop.type = WSFOR; loop.test_label = getlabel (); loop.cont_label = getlabel (); loop.body_label = getlabel (); loop.exit_label = getlabel (); addloop (&loop); p = readloop (); needbrack ("("); if (!match (";")) { expression (YES); need_semicolon (); } generate_label (p->test_label); if (!match (";")) { expression (YES); gen_test_jump (p->body_label, TRUE); gen_jump (p->exit_label); need_semicolon (); } else p->test_label = p->body_label; generate_label (p->cont_label); if (!match (")")) { expression (YES); needbrack (")"); gen_jump (p->test_label); } else p->cont_label = p->test_label; generate_label (p->body_label); statement (NO); gen_jump (p->cont_label); generate_label (p->exit_label); local_table_index = p->symbol_idx; stkp = gen_modify_stack (p->stack_pointer); delloop (); }
/** * local declarations * @param stclass * @return */ do_local_declares(int stclass) { int type = 0; blanks(); if (type = get_type()) { declare_local(type, stclass); } else if (stclass == LSTATIC || stclass == DEFAUTO) { declare_local(CINT, stclass); } else { return(0); } need_semicolon(); return(1); }
/** * local declarations * @param stclass * @return */ int do_local_declares(int stclass) { int type = 0; int otag; // tag of struct object being declared int sflag; // TRUE for struct definition, zero for union char sname[NAMESIZE]; blanks(); if ((sflag=amatch("struct", 6)) || amatch("union", 5)) { if (symname(sname) == 0) { // legal name ? illname(); } if ((otag=find_tag(sname)) == -1) { // structure not previously defined otag = define_struct(sname, stclass, sflag); } declare_local(STRUCT, stclass, otag); } else if ((type = get_type()) != 0) { declare_local(type, stclass, -1); } else if (stclass == LSTATIC || stclass == DEFAUTO) { declare_local(CINT, stclass, -1); } else { return(0); } need_semicolon(); return(1); }
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; }