void _stack_genusage(memuse_list_t *stack, int dofree) { memuse_t *cur = stack->head; memuse_t *tmp; while (cur) { if (cur->type == MEMUSE_DYNAMIC) { /* no idea yet */ assert(0); } else { modstk(cur->size * sizeof(cell)); } if (dofree) { tmp = cur->prev; free(cur); cur = tmp; } else { cur = cur->prev; } } if (dofree) { stack->head = NULL; } }
void dogoto() { SYMBOL* ptr; char sname[NAMESIZE]; int stkmod = 0; int label; /* * Should find symbol, and if a goto expr obtain the level from * ptr->size, and modify the stack accordingly.. */ if (symname(sname) == 0) illname(sname); debug(DBG_GOTO, "goto is -->%s<--\n", sname); if ((ptr = findgoto(sname)) && ptr->ident == ID_GOTOLABEL) { /* Label found, but is it actually defined? */ if (ptr->type == KIND_PTR) { label = ptr->size; stkmod = ptr->offset.i; } else { debug(DBG_GOTO, "Sym found but still on goto\n"); /* Not defined, add into the goto queue */ label = AddGoto(ptr); } } else { ptr = addgotosym(sname); debug(DBG_GOTO, "Adding symbol to table\n"); ptr->offset.i = 0; label = AddGoto(ptr); } if (stkmod) modstk(stkmod, NO, NO); jump(label); }
/* * "switch" statement */ void doswitch (void ) { INTPTR_T ws[7]; INTPTR_T *ptr; ws[WSSYM] = (INTPTR_T)locptr; ws[WSSP] = stkp; ws[WSTYP] = WSSWITCH; ws[WSCASEP] = swstp; ws[WSTAB] = getlabel (); ws[WSDEF] = ws[WSEXIT] = getlabel (); addwhile (ws); immed (T_LABEL, ws[WSTAB]); gpush (); needbrack ("("); expression (YES); needbrack (")"); stkp = stkp + INTSIZE; /* '?case' will adjust the stack */ gjcase (); statement (NO); ptr = readswitch (); jump (ptr[WSEXIT]); dumpsw (ptr); gnlabel (ptr[WSEXIT]); locptr = (char*)ptr[WSSYM]; stkp = modstk (ptr[WSSP]); swstp = ptr[WSCASEP]; delwhile (); }
/* * "break" statement */ void dobreak (void ) { INTPTR_T *ptr; if ((ptr = readwhile ()) == 0) return; modstk (ptr[WSSP]); jump (ptr[WSEXIT]); }
void modstk_for_scope(const MemoryScope& scope) { cell_t total = 0; for (const auto& use : scope.usage) { assert(use.type == MEMUSE_STATIC); total += use.size; } modstk(total * sizeof(cell)); }
/* * "continue" statement */ void docont (void ) { INTPTR_T *ptr; if ((ptr = findwhile ()) == 0) return; modstk (ptr[WSSP]); if (ptr[WSTYP] == WSFOR) jump (ptr[WSINCR]); else jump (ptr[WSTEST]); }
/* * "if" statement */ void doif (void ) { int fstkp, flab1, flab2; char *flev; flev = locptr; fstkp = stkp; flab1 = getlabel (); test (flab1, FALSE); statement (NO); stkp = modstk (fstkp); locptr = flev; if (!amatch ("else", 4)) { gnlabel (flab1); return; } jump (flab2 = getlabel ()); gnlabel (flab1); statement (NO); stkp = modstk (fstkp); locptr = flev; gnlabel (flab2); }
/* * "while" statement */ void dowhile (void ) { INTPTR_T ws[7]; ws[WSSYM] = (INTPTR_T)locptr; ws[WSSP] = stkp; ws[WSTYP] = WSWHILE; ws[WSTEST] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); gnlabel (ws[WSTEST]); test (ws[WSEXIT], FALSE); statement (NO); jump (ws[WSTEST]); gnlabel (ws[WSEXIT]); locptr = (char*)ws[WSSYM]; stkp = modstk (ws[WSSP]); delwhile (); }
/* * "for" statement */ void dofor (void ) { INTPTR_T ws[7]; INTPTR_T *pws; ws[WSSYM] = (INTPTR_T)locptr; ws[WSSP] = stkp; ws[WSTYP] = WSFOR; ws[WSTEST] = getlabel (); ws[WSINCR] = getlabel (); ws[WSBODY] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); pws = readwhile (); needbrack ("("); if (!match (";")) { expression (YES); ns (); } gnlabel (pws[WSTEST]); if (!match (";")) { expression (YES); testjump (pws[WSBODY], TRUE); jump (pws[WSEXIT]); ns (); } else pws[WSTEST] = pws[WSBODY]; gnlabel (pws[WSINCR]); if (!match (")")) { expression (YES); needbrack (")"); jump (pws[WSTEST]); } else pws[WSINCR] = pws[WSTEST]; gnlabel (pws[WSBODY]); statement (NO); jump (pws[WSINCR]); gnlabel (pws[WSEXIT]); locptr = (char *)pws[WSSYM]; stkp = modstk (pws[WSSP]); delwhile (); }
void goto_cleanup(void) { int i; GOTO_TAB* gptr; if (gotocnt == 0) return; gptr = gotoq + 1; for (i = 0; i < gotocnt; i++) { if (gptr->sym) { debug(DBG_GOTO, "Cleaning %s #%d\n", gptr->sym->name, i); postlabel(gptr->label); modstk((gptr->sym->offset.i) - (gptr->sp), NO, NO); jump(gptr->sym->size); /* label label(!) */ } gptr++; } /* Wipe out reference to our goto labels in symbol table */ gotocnt = 0; }
/* * "do" statement */ void dodo (void ) { INTPTR_T ws[7]; ws[WSSYM] = (INTPTR_T)locptr; ws[WSSP] = stkp; ws[WSTYP] = WSDO; ws[WSBODY] = getlabel (); ws[WSTEST] = getlabel (); ws[WSEXIT] = getlabel (); addwhile (ws); gnlabel (ws[WSBODY]); statement (NO); if (!match ("while")) { error ("missing while"); return; } gnlabel (ws[WSTEST]); test (ws[WSBODY], TRUE); gnlabel (ws[WSEXIT]); locptr = (char*)ws[WSSYM]; stkp = modstk (ws[WSSP]); delwhile (); }
newfunc () { char n[NAMESIZE], *ptr; fexitlab = getlabel(); if (!symname (n) ) { error ("illegal function or declaration"); kill (); return; } if (ptr = findglb (n)) { if (ptr[IDENT] != FUNCTION) multidef (n); else if (ptr[OFFSET] == FUNCTION) multidef (n); else ptr[OFFSET] = FUNCTION; } else addglb (n, FUNCTION, CINT, FUNCTION, PUBLIC); prologue (); if (!match ("(")) error ("missing open paren"); prefix (); outstr (n); col (); nl (); locptr = STARTLOC; argstk = 0; while (!match (")")) { if (symname (n)) { if (findloc (n)) multidef (n); else { addloc (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 (amatch ("register", 8)) { if (amatch("char", 4)) getarg(CCHAR); else if (amatch ("int", 3)) getarg(CINT); else getarg(CINT); ns(); } else if (amatch ("char", 4)) { getarg (CCHAR); ns (); } else if (amatch ("int", 3)) { getarg (CINT); ns (); } else { error ("wrong number args"); break; } } statement(YES); printlabel(fexitlab); col(); nl(); modstk (0); gret (); stkp = 0; locptr = STARTLOC; }