/** * "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 (); }
/** * "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 */ 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 (); }
/** * 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; }
/** * 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); }
/* Address of the source must already have been loaded in PRI, the * destination address in ALT. * This routine makes a loop that copies the minor dimension vector * by vector. */ SC_FUNC void copyarray2d(int majordim,int minordim) { int looplbl=getlabel(); stgwrite("\tpush.alt\n"); stgwrite("\tpush.pri\n"); stgwrite("\tzero.alt\n"); /* ALT = index = 0 */ setlabel(looplbl); stgwrite("\tpush.alt\n"); /* save index */ stgwrite("\tpick 8\n"); /* PRI = dest */ stgwrite("\txchg\n"); /* ALT = dest, PRI = index */ stgwrite("\tidxaddr\n"); /* PRI = dest + index * sizeof(cell) */ stgwrite("\tmove.alt\n"); /* ALT = dest + index * sizeof(cell) */ stgwrite("\tload.i\n"); /* PRI = dest[index * sizeof(cell)] */ stgwrite("\tadd\n"); /* PRI = dest + index * sizeof(cell) + dest[index * sizeof(cell)] */ stgwrite("\tpush.pri\n"); stgwrite("\tpick 8\n"); /* PRI = source */ stgwrite("\tmove.alt\n"); /* ALT = source */ stgwrite("\tpick 4\n"); /* PRI = index */ stgwrite("\tidxaddr\n"); /* PRI = source + index * sizeof(cell) */ stgwrite("\tmove.alt\n"); /* ALT = source + index * sizeof(cell) */ stgwrite("\tload.i\n"); /* PRI = source[index * sizeof(cell)] */ stgwrite("\tadd\n"); /* PRI = source + index * sizeof(cell) + source[index * sizeof(cell)] */ stgwrite("\tpop.alt\n"); /* ALT = source + index * sizeof(cell) + source[index * sizeof(cell)] */ stgwrite("\tmovs "); outval(minordim*sizeof(cell),TRUE,TRUE); stgwrite("\tpop.alt\n"); /* ALT = saved index */ stgwrite("\tinc.alt\n"); /* ALT = index + 1 */ stgwrite("\teq.c.alt "); outval(majordim,TRUE,TRUE); stgwrite("\tjzer "); outval(looplbl,TRUE,TRUE); stgwrite("\tpop.pri\n"); /* restore stack & registers */ stgwrite("\tpop.alt\n"); code_idx+=opcodes(26)+opargs(6); }
// Function Draw // Draws 2-input AND gate void AND2::Draw(Output* pOut) { //Call output class and pass gate drawing info to it. pOut->DrawAND2(m_GfxInfo,getHI()); //feryal pOut->Clear_string_from_D_A(m_GfxInfo.x1, m_GfxInfo.y1 - 20); pOut->Printstring_in_D_A(getlabel(), pOut, m_GfxInfo.x1, m_GfxInfo.y1 - 20); }
int dolabel() { int savelptr; char sname[NAMESIZE]; SYMBOL* ptr; blanks(); savelptr = lptr; if (symname(sname)) { if (gch() == ':') { if ((ptr = findgoto(sname)) && ptr->ident == ID_GOTOLABEL) { /* Label already goto'd, find some others with * same stack */ debug(DBG_GOTO, "Starting chase %s\n", sname); ChaseGoto(ptr); ptr->type = KIND_PTR; } else { ptr = addgotosym(sname); ptr->type = KIND_PTR; } debug(DBG_GOTO, "Adding label not called %s\n", sname); ptr->offset.i = Zsp; /* Save stack for label */ postlabel(ptr->size = getlabel()); return (1); } } lptr = savelptr; return (0); }
void comparator(char op){ bool eq = false; if(look == '='){ eq = true; match("="); } term(); emitln("cmp ebx, eax"); char* lbltrue = getlabel(); char* lblend = getlabel(); if(eq) switch(op){ case '>': emitln("jge %s", lbltrue); break; case '<': emitln("jle %s", lbltrue); break; case '=': emitln("je %s", lbltrue); break; default: error("Fatal comparator"); } else switch(op){ case '>': emitln("jg %s", lbltrue); break; case '<': emitln("jl %s", lbltrue); break; default: error("Use of assignment operator in comparison"); } emitln("xor eax, eax"); emitln("jmp %s", lblend); putlabel(lbltrue); emitln("mov eax, 1"); putlabel(lblend); }
/** * compile one file if filename is NULL redirect do to stdin/stdout * @param file filename * @return */ void compile(char *file) { if (file == NULL || filename_typeof(file) == 'c') { global_table_index = 0; local_table_index = NUMBER_OF_GLOBALS; while_table_index = 0; tag_table_index = 0; inclsp = iflevel = skiplevel = swstp = litptr = stkp = errcnt = ncmp = lastst = //quote[1] = 0; input2 = -1; //quote[0] = '"'; cmode = 1; glbflag = 1; nxtlab = 0; litlab = getlabel(); defmac("end\tmemory"); //add_global("memory", ARRAY, CCHAR, 0, EXTERN); //add_global("stack", ARRAY, CCHAR, 0, EXTERN); rglobal_table_index = global_table_index; //rglbptr = glbptr; //add_global("etext", ARRAY, CCHAR, 0, EXTERN); //add_global("edata", ARRAY, CCHAR, 0, EXTERN); defmac("short\tint"); initmac(); // compiler body if (file == NULL) { input = 0; } else if (!openin(file)) return; if (file == NULL) { output = 1; } else if (!openout()) return; header(); code_segment_gtext(); parse(); close(input); data_segment_gdata(); dumplits(); dumpglbs(); errorsummary(); trailer(); oflush(); close(output); pl(""); errs = errs || errfile; } else { writee("Don't understand file "); writee(file); errs = 1; } }
/** * "while" statement */ dowhile() { loop_t loop; loop.symbol_idx = local_table_index; loop.stack_pointer = stkp; loop.type = WSWHILE; loop.test_label = getlabel (); loop.exit_label = getlabel (); addloop (&loop); generate_label (loop.test_label); test (loop.exit_label, FALSE); statement (NO); gen_jump (loop.test_label); generate_label (loop.exit_label); local_table_index = loop.symbol_idx; stkp = gen_modify_stack (loop.stack_pointer); delloop (); }
/** * "while" statement */ void dowhile(void) { WHILE ws; ws.symbol_idx = local_table_index; ws.stack_pointer = stkp; ws.type = WSWHILE; ws.case_test = getlabel (); ws.while_exit = getlabel (); addwhile (&ws); generate_label (ws.case_test); test (ws.while_exit, FALSE); statement (NO); gen_jump (ws.case_test); generate_label (ws.while_exit); local_table_index = ws.symbol_idx; stkp = gen_modify_stack (ws.stack_pointer); delwhile (); }
/* * "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 (); }
/** * "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 (); }
/** * "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 (); }
/** * "default" label */ dodefault() { loop_t *ptr; int lab; if (ptr = readswitch ()) { ptr->cont_label = lab = getlabel (); generate_label (lab); if (!match (":")) error ("missing colon"); } else error ("no active switch"); }
/** * "default" label */ void dodefault(void) { WHILE *ptr; int lab; if ((ptr = readswitch ()) != 0) { ptr->incr_def = lab = getlabel (); generate_label (lab); if (!match (":")) error ("missing colon"); } else error ("no active switch"); }
/** * "if" statement */ void doif(void) { int fstkp, flab1, flab2; int flev; flev = local_table_index; fstkp = stkp; flab1 = getlabel (); test (flab1, FALSE); statement (NO); stkp = gen_modify_stack (fstkp); local_table_index = flev; if (!amatch ("else", 4)) { generate_label (flab1); return; } gen_jump (flab2 = getlabel ()); generate_label (flab1); statement (NO); stkp = gen_modify_stack (fstkp); local_table_index = flev; generate_label (flab2); }
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 (); } }
/* * "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); }
/** * "do" statement */ void dodo(void) { WHILE ws; ws.symbol_idx = local_table_index; ws.stack_pointer = stkp; ws.type = WSDO; ws.body_tab = getlabel (); ws.case_test = getlabel (); ws.while_exit = getlabel (); addwhile (&ws); generate_label (ws.body_tab); statement (NO); if (!match ("while")) { error ("missing while"); return; } generate_label (ws.case_test); test (ws.body_tab, TRUE); generate_label (ws.while_exit); local_table_index = ws.symbol_idx; stkp = gen_modify_stack (ws.stack_pointer); delwhile (); }
/* * "default" label */ void dodefault (void ) { INTPTR_T *ptr, lab; ptr = readswitch (); if (ptr) { ptr[WSDEF] = lab = getlabel (); gnlabel (lab); if (!match (":")) error ("missing colon"); } else error ("no active switch"); }
/** * "do" statement */ dodo() { loop_t loop; loop.symbol_idx = local_table_index; loop.stack_pointer = stkp; loop.type = WSDO; loop.body_label = getlabel (); loop.test_label = getlabel (); loop.exit_label = getlabel (); addloop (&loop); generate_label (loop.body_label); statement (NO); if (!match ("while")) { error ("missing while"); return; } generate_label (loop.test_label); test (loop.body_label, TRUE); generate_label (loop.exit_label); local_table_index = loop.symbol_idx; stkp = gen_modify_stack (loop.stack_pointer); delloop (); }
/* * "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 (); }
WORD getadr(const char *prog, const char *str, PASS pass) { WORD adr = 0; if(str[0] == '=') { adr = getliteral(str, pass); } else if(isdigit(str[0]) || str[0] == '-' || str[0] == '#') { adr = nh2word(str); } else { if(pass == SECOND) { if((adr = getlabel(prog, str)) == 0xFFFF) { setcerr(103, str); /* label not found */ } } } return adr; }
void add_method(type_t type, char* name, type_t return_type, arg_list* args){ type_container* tp = (type_container*) get(types, type); if(tp == NULL) error("No type to add method '%s' to", name); //Fill the container method_t* method = MKNEW(method_t); method->name = name; method->return_type = return_type; method->arguments = args; method->label_start = getlabel(); //Add it to the type list append(tp->methods, method); //Throw down a label putlabel(method->label_start); }
int AddGoto(SYMBOL* ptr) { GOTO_TAB* gptr; int gqptr = 0; /* Pointer int goto queue */ debug(DBG_GOTO, "Adding goto label: %s\n", ptr->name); if (ptr->more) gqptr = ptr->more; if ((gptr = SearchGoto(ptr))) return (gptr->label); if (++gotocnt > NUMGOTO) errorfmt("Maximum number of gotos reached (%d)", 1, NUMGOTO); gptr = gotoq + gotocnt; /* Ref for our label */ gptr->next = gqptr; /* store next in chain */ ptr->more = gotocnt; /* Make us first */ gptr->sp = Zsp; /* Store current stack */ gptr->sym = ptr; /* What label do we reference */ gptr->lineno = lineno; gptr->label = getlabel(); return (gptr->label); }
ask() { int k,num[1]; kill(); /* clear input line */ outbyte(12); /* clear the screen */ nl();nl();nl(); /* print banner */ pl(" * * * small-c compiler * * *"); nl(); pl(" by Ron Cain"); nl();nl(); /* see if user wants to interleave the c-text */ /* in form of comments (for clarity) */ pl("Do you want the c-text to appear? "); gets(line); /* get answer */ ctext=0; /* assume no */ if((ch()=='Y')|(ch()=='y')) ctext=1; /* user said yes */ /* see if user wants us to allocate static */ /* variables by name in this module */ /* (pseudo external capability) */ pl("Do you wish the globals to be defined? "); gets(line); glbflag=0; if((ch()=='Y')|(ch()=='y')) glbflag=1; /* user said yes */ /* get first allowable number for compiler-generated */ /* labels (in case user will append modules) */ while(1){ pl("Starting number for labels? "); gets(line); if(ch()==0){num[0]=0;break;} if(k=number(num))break; } nxtlab=num[0]; litlab=getlabel(); /* first label=literal pool */ kill(); /* erase line */ }
int dadsm_setup( CIFBLK *cif, char *pdsn[], DADSM *dadsm, int verbose) { DSXTENT *f1x; BYTE *pcchhr; int numx = MAX_EXTENTS; // # extent slots available int rc; // Read dasd volume label record rc = getlabel(cif, &dadsm->volrec, verbose); if (rc) return rc; // Read F4 DSCB, save VTOC extent info rc = getF4dscb(cif, &dadsm->f4buf, &dadsm->volrec, &dadsm->f4ext, verbose); if (rc) return rc; // Read F1 DSCB, save first three extents from F1 DSCB rc = getF1dscb(cif, pdsn, &dadsm->f1buf, (void *)&dadsm->f4ext, verbose); if (rc) return rc; f1x = &dadsm->f1ext[0]; // @ extent # 0 numx -= 3; // will use 3 slots (if available) if (numx < 0) { fprintf(stderr, "dadsm_setup exhausted extent slots\n"); return 1; } memcpy(f1x, &dadsm->f1buf.ds1ext1, sizeof(DSXTENT) * 3); f1x += 3; // @ extent # 3 dadsm->f1numx = dadsm->f1buf.ds1noepv; // # extents alloc'd to dataset if (dadsm->f1numx < 4) { if (verbose > 1) fprintf(stderr, "dadsm_setup " "no F3 DSCB required, only %d extent(s); all in F1\n", dadsm->f1numx); return 0; } // When more than 3 extents, get additional extent info from F3 DSCB(s). // Chase the F3 chain starting with the CCHHR in the F1, accumulating // extent information for the dataset as we progress. pcchhr = (BYTE *)&dadsm->f1buf.ds1ptrds; // @ F1 ptr to F3 while (pcchhr[0] || pcchhr[1] || pcchhr[2] || pcchhr[3] || pcchhr[4]) { rc = getF3dscb(cif, pcchhr, &dadsm->f3buf, verbose); if (rc) return rc; numx -= 4; // use extent slots if (numx < 0) { fprintf(stderr, "dadsm_setup exhausted extent slots\n"); return 2; } memcpy(f1x, &dadsm->f3buf.ds3extnt[0], sizeof(DSXTENT) * 4); f1x += 4; numx -= 9; // use extent slots if (numx < 0) { fprintf(stderr, "dadsm_setup exhausted extent slots\n"); fprintf(stderr, "Maximum supported extents %d\n", MAX_EXTENTS); return 3; } memcpy(f1x, &dadsm->f3buf.ds3adext[0], sizeof(DSXTENT) * 9); f1x += 9; pcchhr = (BYTE *)&dadsm->f3buf.ds3ptrds; // @ next F3 CCHHR } return 0; } /* dadsm_setup */