void generate_first_pass() { int tok = 0, i = 0; unsigned short temp = 0; int label_pc = -1; while( (tok=yylex()) ) { switch(tok) { case LODD: emit_label_op(12, "LODD", "0000"); break; case STOD: emit_label_op(12, "STOD", "0001"); break; case ADDD: emit_label_op(12, "ADDD", "0010"); break; case SUBD: emit_label_op(12, "SUBD", "0011"); break; case JPOS: emit_label_op(12, "JPOS", "0100"); break; case JZER: emit_label_op(12, "JZER", "0101"); break; case JUMP: emit_label_op(12, "JUMP", "0110"); break; case LOCO: emit_label_op(12, "LOCO", "0111"); break; case LODL: emit_int_op(12, "LODL", "1000"); break; case STOL: emit_int_op(12, "STOL", "1001"); break; case ADDL: emit_int_op(12, "ADDL", "1010"); break; case SUBL: emit_int_op(12, "SUBL", "1011"); break; case JNEG: emit_label_op(12, "JNEG", "1100"); break; case JNZE: emit_label_op(12, "JNZE", "1101"); break; case CALL: emit_label_op(12, "CALL", "1110"); break; case PSHI: emit_fixed_op( 0, "PSHI", "1111000"); break; case POPI: emit_fixed_op( 0, "POPI", "1111001"); break; case PUSH: emit_fixed_op( 0, "PUSH", "1111010"); break; case POP: emit_fixed_op( 0, "POP", "1111011"); break; case RETN: emit_fixed_op( 0, "RETN", "1111100"); break; case SWAP: emit_fixed_op( 0, "SWAP", "1111101"); break; case INSP: emit_int_op( 8, "INSP", "11111100"); break; case DESP: emit_int_op( 8, "DESP", "11111110"); break; case HALT: emit_fixed_op( 0, "HALT", "11111111"); break; case INTEG: str_16(yytext); fprintf(p1,"%d %.16s\n", pc, cstr_16); break; case LABEL: if (label_pc == pc) { /* for < lbx: lby: > */ fprintf(p1,"%d U0000000000000000 %s\n", pc, yytext); break; } search_sym_table(yytext); update_sym_table(yytext); label_pc = pc; pc--; break; case LOC: require_int(12, ".LOC"); if((temp = ((unsigned short)atoi(yytext) )) < pc) { fprintf(stderr,"Bad operand after .LOC is %s, TOO SMALL !\n",yytext); exit(1); } pc = temp - 1; break; case STR: i=1; do { if(*(yytext+i) == '\"') { bstr_16(0); fprintf(p1,"%d %.16s\n", pc, cstr_16); break; } temp = (unsigned short)*(yytext+i++); if(*(yytext+i) != '\"') { temp = (temp | ((unsigned short)*(yytext+i) << 8)); } bstr_16(temp); fprintf(p1,"%d %.16s\n", pc, cstr_16); } while (*(yytext+i++) != '\"' && ++pc); break; case JUNK: fprintf(stderr,"Unrecognized token is %s\n",yytext); exit(26); default: fprintf(stderr,"Default case, unrecoverable error\n"); exit(26); } pc++; } }
int main(int argc, char *argv[]) { int tok, i, dump_tab=0, linum=0; unsigned short temp; // if -s is included on masm command, set up to // dump the symbol table after the binary code if(argc > 1 && (strcmp(argv[1], "-s") == 0)) dump_tab = linum = 1; p1 = fopen("/tmp/passone", "w+"); unlink("/tmp/passone"); while(tok=yylex()){ switch(tok){ case LODD: switch(tok=yylex()){ case INTEG: str_12(yytext); fprintf(p1,"%d 0000%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U0000000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after LODD is %s on line %d\n",yytext, pc); exit(1); } break; case STOD: switch(tok=yylex()){ case INTEG: str_12(yytext); fprintf(p1,"%d 0001%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U0001000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after STOD is %s on line %d\n",yytext, pc); exit(1); } break; case ADDD: switch(tok=yylex()){ case INTEG: str_12(yytext); fprintf(p1,"%d 0010%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U0010000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after ADDD is %s on line %d\n",yytext, pc); exit(1); } break; case SUBD: switch(tok=yylex()){ case INTEG: str_12(yytext); fprintf(p1,"%d 0011%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U0011000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after SUBD is %s on line %d\n",yytext, pc); exit(1); } break; case JPOS: switch(tok=yylex()){ case INTEG: str_12(yytext); fprintf(p1,"%d 0100%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U0100000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after JPOS is %s on line %d\n",yytext, pc); exit(1); } break; case JZER: switch(tok=yylex()){ case INTEG: str_12(yytext); fprintf(p1,"%d 0101%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U0101000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after JZER is %s on line %d\n",yytext, pc); exit(1); } break; case JUMP: switch(tok=yylex()){ case INTEG: str_12(yytext); fprintf(p1,"%d 0110%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U0110000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after JUMP is %s on line %d\n",yytext, pc); exit(1); } break; case LOCO: switch(tok=yylex()){ case INTEG: if(yytext[0] == '-'){ fprintf(stderr,"Negative operand after LOCO is %s on line %d, must be positive !\n",yytext, pc); exit(1); } str_12(yytext); fprintf(p1,"%d 0111%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U0111000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after LOCO is %s on line %d\n",yytext, pc); exit(1); } break; case LODL: if((tok=yylex()) != INTEG){ fprintf(stderr,"Bad operand after LODL is %s\n",yytext); exit(1); } str_12(yytext); fprintf(p1,"%d 1000%s\n", pc, cstr_12); break; case STOL: if((tok=yylex()) != INTEG){ fprintf(stderr,"Bad operand after STOL is %s\n",yytext); exit(1); } str_12(yytext); fprintf(p1,"%d 1001%s\n", pc, cstr_12); break; case ADDL: if((tok=yylex()) != INTEG){ fprintf(stderr,"Bad operand after ADDL is %s\n",yytext); exit(1); } str_12(yytext); fprintf(p1,"%d 1010%s\n", pc, cstr_12); break; case SUBL: if((tok=yylex()) != INTEG){ fprintf(stderr,"Bad operand after SUBL is %s\n",yytext); exit(1); } str_12(yytext); fprintf(p1,"%d 1011%s\n", pc, cstr_12); break; case JNEG: switch(tok=yylex()){ case INTEG: str_12(yytext); fprintf(p1,"%d 1100%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U1100000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after JNEG is %s on line %d\n",yytext, pc); exit(1); } break; case JNZE: switch(tok=yylex()){ case INTEG: str_12(yytext); fprintf(p1,"%d 1101%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U11010000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after JNZE is %s on line %d\n",yytext, pc); exit(1); } break; case CALL: switch(tok=yylex()){ case INTEG: str_12(yytext); fprintf(p1,"%d 1110%s\n", pc, cstr_12); break; case LABEL: fprintf(p1,"%d U1110000000000000 %s\n", pc, yytext); break; default: fprintf(stderr,"Bad operand after CALL is %s on line %d\n",yytext, pc); exit(1); } break; case PSHI: fprintf(p1,"%d 1111000000000000\n",pc); break; case POPI: fprintf(p1,"%d 1111001000000000\n",pc); break; case PUSH: fprintf(p1,"%d 1111010000000000\n",pc); break; case POP: fprintf(p1,"%d 1111011000000000\n",pc); break; case RETN: fprintf(p1,"%d 1111100000000000\n",pc); break; case SWAP: fprintf(p1,"%d 1111101000000000\n",pc); break; case INSP: if((tok=yylex()) != INTEG){ fprintf(stderr,"Bad operand after INSP is %s\n",yytext); exit(1); } str_8(yytext); fprintf(p1,"%d 11111100%s\n", pc, cstr_8); break; case DESP: if((tok=yylex()) != INTEG){ fprintf(stderr,"Bad operand after DESP is %s\n",yytext); exit(1); } str_8(yytext); fprintf(p1,"%d 11111110%s\n", pc, cstr_8); break; case HALT: fprintf(p1,"%d 1111111111000000\n",pc); break; // case for MULT case MULT: if((tok=yylex()) != INTEG){ //trips if issue with mult call fprintf(stderr,"Bad operand after MULT is %s\n",yytext); exit(1); } str_6(yytext); //otherwise the bits are written fprintf(p1,"%d 1111111100%s\n", pc, cstr_6); break; //case for RSHIFT case RSHIFT: if((tok=yylex()) != INTEG){ // trips if issues with rshift call fprintf(stderr,"Bad operand after RSHIFT is %s\n",yytext); exit(1); } str_6(yytext); //else bits are written fprintf(p1,"%d 1111111101%s\n", pc, cstr_6); break; case DIV: fprintf(p1,"%d 1111111110000000\n",pc); // case for DIV break; //no error case for div, takes no input from .asm all from stack case INTEG: str_16(yytext); fprintf(p1,"%d %s\n", pc, cstr_16); break; case LABEL: if (label_pc == pc){/* for < lbx: lby: > */ fprintf(p1,"%d U0000000000000000 %s\n", pc, yytext); break; } search_sym_table(yytext); update_sym_table(yytext); label_pc = pc; pc--; break; case LOC: if((tok=yylex()) != INTEG){ fprintf(stderr,"Bad operand after .LOC is %s\n",yytext); exit(1); } if((temp = ((unsigned short)atoi(yytext) )) < pc){ fprintf(stderr,"Bad operand after .LOC is %s, TOO SMALL !\n",yytext); exit(1); } pc = temp - 1; break; case STR: i=1; do{ if(*(yytext+i) == '\"'){ bstr_16(0); fprintf(p1,"%d %s\n", pc, binstr_16); break; } temp = (unsigned short)*(yytext+i++); if(*(yytext+i) != '\"'){ temp = (temp | ((unsigned short)*(yytext+i) << 8)); } bstr_16(temp); fprintf(p1,"%d %s\n", pc, binstr_16); }while(*(yytext+i++) != '\"' && ++pc); break; case JUNK: fprintf(stderr,"Unrecognized token is %s\n",yytext); exit(26); default: fprintf(stderr,"Default case, unrecoverable error\n"); exit(26); } // end while pc++; } // end switch generate_code(linum); if(dump_tab)dump_table(); return; } // end main