/* * "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 (); }
/** * "switch" statement */ void doswitch(void) { WHILE ws; WHILE *ptr; ws.symbol_idx = local_table_index; ws.stack_pointer = stkp; ws.type = WSSWITCH; ws.case_test = swstp; ws.body_tab = getlabel (); ws.incr_def = ws.while_exit = getlabel (); addwhile (&ws); gen_immediate (); print_label (ws.body_tab); newline (); gen_push (HL_REG); needbrack ("("); expression (YES); needbrack (")"); stkp = stkp + INTSIZE; // '?case' will adjust the stack gen_jump_case (); statement (NO); ptr = readswitch (); gen_jump (ptr->while_exit); dumpsw (ptr); generate_label (ptr->while_exit); local_table_index = ptr->symbol_idx; stkp = gen_modify_stack (ptr->stack_pointer); swstp = ptr->case_test; delwhile (); }
/** * "switch" statement */ doswitch() { loop_t loop; loop_t *ptr; loop.symbol_idx = local_table_index; loop.stack_pointer = stkp; loop.type = WSSWITCH; loop.test_label = swstp; loop.body_label = getlabel (); loop.cont_label = loop.exit_label = getlabel (); addloop (&loop); gen_immediate_a (); print_label (loop.body_label); newline (); gen_push (); needbrack ("("); expression (YES); needbrack (")"); stkp = stkp + INTSIZE; // '?case' will adjust the stack gen_jump_case (); statement (NO); ptr = readswitch (); gen_jump (ptr->exit_label); dumpsw (ptr); generate_label (ptr->exit_label); local_table_index = ptr->symbol_idx; stkp = gen_modify_stack (ptr->stack_pointer); swstp = ptr->test_label; delloop (); }
void test (INTPTR_T label, int ft) /* int label, ft; */ { needbrack ("("); expression (YES); needbrack (")"); testjump (label, ft); }
int define_struct (char *sname, int storage, int is_struct) { TAG_SYMBOL *symbol; char *buffer_ptr; int tti; // tag_table_index++; if (tag_table_index >= NUMTAG) { error("struct table overflow"); return (0); } tti = tag_table_index++; symbol = &tag_table[tti]; buffer_ptr = symbol->name; while (an(*buffer_ptr++ = *sname++)) ; symbol->size = 0; symbol->member_idx = member_table_index; needbrack("{"); while (!match("}")) { if (!dodcls(storage, &tag_table[tti], is_struct)) break; /* We need to keep number_of_members up-to-date to make sure that find_member() works so we can catch duplicate member names. */ symbol->number_of_members = member_table_index - symbol->member_idx; } ; /* XXX: still necessary? */ symbol->number_of_members = member_table_index - symbol->member_idx; return (tti); }
/** * perform a function call * called from "hier11", this routine will either call the named * function, or if the supplied ptr is zero, will call the contents * of HL * @param ptr name of the function */ void callfunction(char *ptr) { int nargs; nargs = 0; blanks (); if (ptr == 0) gen_push (HL_REG); while (!streq (line + lptr, ")")) { if (endst ()) break; expression (NO); if (ptr == 0) gen_swap_stack (); gen_push (HL_REG); nargs = nargs + INTSIZE; if (!match (",")) break; } needbrack (")"); if (aflag) gnargs(nargs / INTSIZE); if (ptr) gen_call (ptr); else callstk (); stkp = gen_modify_stack (stkp + nargs); }
void do_asm_func(int type) { /* syntax is name of the data : identifier */ char n[NAMESIZE]; char *ptr; /* get identifier */ if (!symname(n)) { error("invalid identifier"); kill_line(); return; } /* close function */ needbrack(")"); /* duplicate identifier */ ptr = new_string(1, n); /* gen code */ if (ptr) out_ins(I_LDWI, type, (INTPTR_T)ptr); else error("out of memory"); }
void doload_backgroundstatement(void) { /* syntax is name of the beginning of the data pattern : identifier name of the 16 palettes : identifier name of the bat : identifier width (in tiles [8x8] ) : integer height (in tiles [8x8] ) : integer */ flush_ins(); /* David, optimize.c related */ ot("_load_background\t"); if (outnameunderline()) return; if (outcomma()) return; if (outnameunderline()) return; if (outcomma()) return; if (outnameunderline()) return; if (outcomma()) return; if (outconst()) return; if (outcomma()) return; if (outconst()) return; newl(); needbrack(")"); }
void doload_spritesstatement(void) { /* syntax is offset in vram to load data at : integer name of the data to transfert : identifier number of sprites (of size 32x64) to load : integer */ flush_ins(); /* David, optimize.c related */ ot("load_sprites\t"); outconst(); if (outcomma()) return; if (outnameunderline()) return; if (!match(",")) { outstr(",#"); outdec(1); } else { outbyte(','); outconst(); } newl(); needbrack(")"); }
void doset_sprpalstatement(void) { /* syntax is number of the first palette to alter : integer name of the data for loading palettes : identifier [ number of palette to load : integer ] if last argument is missing, 1 is assumed */ flush_ins(); /* David, optimize.c related */ ot("_set_sprpal\t"); outconst(); if (outcomma()) return; if (outnameunderline()) return; if (!match(",")) { outstr(",#"); outdec(1); } else { outbyte(','); outconst(); } newl(); needbrack(")"); }
/* * "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 (); }
/** * "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 (); }
asmfunc () { char c; needbrack ("("); if (!match (quote)) { error ("Missing opening \" in asm call"); return; } do { while (ch () != '"') { if (ch () == 0) break; c = gch(); outbyte (c == '\\' ? spechar() : c); } gch (); } while (match (quote)); needbrack (")"); ns (); }
/** * get required array size. [xx] * @return array size */ int needsub(void) { int num[1]; if (match ("]")) return (0); if (!number (num)) { error ("must be constant"); num[0] = 1; } if (num[0] < 0) { error ("negative size illegal"); num[0] = (-num[0]); } needbrack ("]"); return (num[0]); }
/** * initialize global objects * @param symbol_name * @param type char or integer or struct * @param identity * @param dim * @return 1 if variable is initialized */ int initials(char *symbol_name, int type, int identity, int dim, int otag) { int dim_unknown = 0; int n; if(dim == 0) { // allow for xx[] = {..}; declaration dim_unknown = 1; } if (!(type & CCHAR) && !(type & CINT) && !(type == STRUCT)) { error("unsupported storage size"); } data_segment_gdata(); glabel(symbol_name); if(match("=")) { // an array or struct if(match("{")) { // aggregate initialiser if ((identity == POINTER || identity == VARIABLE) && type == STRUCT) { // aggregate is structure or pointer to structure dim = 0; struct_init(&tag_table[otag], symbol_name); } else { while((dim > 0) || (dim_unknown)) { if (identity == ARRAY && type == STRUCT) { // array of struct needbrack("{"); struct_init(&tag_table[otag], symbol_name); --dim; needbrack("}"); } else { if (init(symbol_name, type, identity, &dim, 0)) { dim_unknown++; } } if(match(",") == 0) { break; } } if(--dim_unknown == 0) identity = POINTER; else { /* Pad any missing objects */ n = dim; gen_def_storage(); if (identity != ARRAY && type != STRUCT) { if (!(type & CCHAR)) n *= 2; } else n = tag_table[otag].size; output_number(n); newline(); } } needbrack("}"); // single constant } else { init(symbol_name, type, identity, &dim, 0); } } code_segment_gtext(); return identity; }
primary (lvalue_t *lval) { char sname[NAMESIZE]; int num[1], k, symbol_table_idx, offset, reg; symbol_t *symbol; lval->ptr_type = 0; /* clear pointer/array type */ if (match ("(")) { k = hier1 (lval); needbrack (")"); return (k); } if (amatch("sizeof", 6)) { needbrack("("); gen_immediate_c(); if (amatch("int", 3)) output_number(INTSIZE); else if (amatch("char", 4)) output_number(1); else if (symname(sname)) { if ((symbol_table_idx = findloc(sname)) || (symbol_table_idx = findglb(sname))) { symbol = &symbol_table[symbol_table_idx]; if (symbol->storage == LSTATIC) error("sizeof local static"); offset = symbol->count; if ((symbol->type & CINT) || (symbol->identity == POINTER)) offset *= INTSIZE; output_number(offset); } else { error("sizeof undeclared variable"); output_number(0); } } else { error("sizeof only on simple type or variable"); } needbrack(")"); newline(); lval->symbol = 0; lval->indirect = 0; return(0); } if (symname (sname)) { if (symbol_table_idx = findloc (sname)) { symbol = &symbol_table[symbol_table_idx]; reg = gen_get_location (symbol); lval->symbol = symbol; lval->indirect = symbol->type; if (symbol->identity == ARRAY) { //lval->ptr_type = symbol->type; lval->ptr_type = 0; return 0; } if (symbol->identity == POINTER) { lval->indirect = UINT; lval->ptr_type = symbol->type; } return reg; } if (symbol_table_idx = findglb (sname)) { symbol = &symbol_table[symbol_table_idx]; lval->symbol = symbol; switch (symbol->identity) { case ARRAY: gen_immediate_a (); output_string (symbol->name); newline (); /* Fall through */ case FUNCTION: lval->indirect = lval->ptr_type = symbol_table[symbol_table_idx].type; lval->ptr_type = 0; return 0; default: lval->indirect = 0; if (symbol->identity == POINTER) { lval->ptr_type = symbol->type; } return 1; } } blanks (); if (ch() != '(') error("undeclared variable"); symbol_table_idx = add_global (sname, FUNCTION, CINT, 0, PUBLIC, 1); symbol = &symbol_table[symbol_table_idx]; lval->symbol = symbol; lval->indirect = 0; return 0; } if (constant (num)) { lval->symbol = 0; lval->indirect = 0; return 0; } error ("invalid expression"); gen_immediate_c (); output_number(0); newline (); junk (); return 0; }
int primary(LVALUE *lval) { char sname[NAMESIZE]; int num[1], k, symbol_table_idx, offset, reg; SYMBOL *symbol; lval->ptr_type = 0; // clear pointer/array type lval->tagsym = 0; if (match ("(")) { k = hier1 (lval); needbrack (")"); return (k); } if (amatch("sizeof", 6)) { needbrack("("); gen_immediate(); if (amatch("int", 3)) output_number(INTSIZE); else if (amatch("char", 4)) output_number(1); else if (symname(sname)) { if (((symbol_table_idx = find_locale(sname)) > -1) || ((symbol_table_idx = find_global(sname)) > -1)) { symbol = &symbol_table[symbol_table_idx]; if (symbol->storage == LSTATIC) error("sizeof local static"); offset = symbol->offset; if ((symbol->type & CINT) || (symbol->identity == POINTER)) offset *= INTSIZE; else if (symbol->type == STRUCT) offset *= tag_table[symbol->tagidx].size; output_number(offset); } else { error("sizeof undeclared variable"); output_number(0); } } else { error("sizeof only on type or variable"); } needbrack(")"); newline(); lval->symbol = 0; lval->indirect = 0; return(0); } if (symname (sname)) { if ((symbol_table_idx = find_locale(sname)) > -1) { symbol = &symbol_table[symbol_table_idx]; reg = gen_get_locale(symbol); lval->symbol = symbol; lval->indirect = symbol->type; if (symbol->type == STRUCT) { lval->tagsym = &tag_table[symbol->tagidx]; } if (symbol->identity == ARRAY || (symbol->identity == VARIABLE && symbol->type == STRUCT)) { lval->ptr_type = symbol->type; return reg; } if (symbol->identity == POINTER) { lval->indirect = CINT; lval->ptr_type = symbol->type; } return FETCH | reg; } if ((symbol_table_idx = find_global(sname)) > -1) { symbol = &symbol_table[symbol_table_idx]; if (symbol->identity != FUNCTION) { lval->symbol = symbol; lval->indirect = 0; if (symbol->type == STRUCT) { lval->tagsym = &tag_table[symbol->tagidx]; } if (symbol->identity != ARRAY && (symbol->identity != VARIABLE || symbol->type != STRUCT)) { if (symbol->identity == POINTER) { lval->ptr_type = symbol->type; } return FETCH | HL_REG; } gen_immediate(); output_string(symbol->name); newline(); lval->indirect = symbol->type; lval->ptr_type = symbol->type; return 0; } } blanks(); if (ch() != '(') error("undeclared variable"); symbol_table_idx = add_global(sname, FUNCTION, CINT, 0, PUBLIC); symbol = &symbol_table[symbol_table_idx]; lval->symbol = symbol; lval->indirect = 0; return 0; } lval->symbol = 0; lval->indirect = 0; if (constant(num)) return 0; else { error("invalid expression"); gen_immediate(); output_number(0); newline(); junk(); return 0; } }