#define HALT_CODE (0) #define PLUS_CODE (1) #define MINUS_CODE (2) #define TIMES_CODE (3) #define JUMP_CODE (4) \ #define STRINGLEN 1024 #define BEGIN_COMMENT ';' #define SPACE ' ' #define NUMBER_DELIMITER " ,:\t\n" \ #define BANNER "; 3 Register Machine Simulator\n" #define COPYRIGHT "; (c) M. Meiler, J.-P. Kuska 1998\n" \ /*1:*/ #line 4 "simreg3.w" #if !defined LONG_INT # define LONG_INT long int #endif /*31:*/ #line 417 "simreg3.w" #include #include #include #if !defined(True) # define True (1) # define False (0) #endif/*:31*/ #line 8 "simreg3.w" /*3:*/ #line 50 "simreg3.w" unsigned long MaxMemoryCells= 10000ul; unsigned long MaxOperations= 40ul; /*:3*//*6:*/ #line 83 "simreg3.w" const int CommandBits= 27; const int ShiftOp1= 18; const int ShiftOp2= 9; /*:6*/ #line 9 "simreg3.w" /*5:*/ #line 62 "simreg3.w" typedef struct _VirtualMachine{ long int operationCount; LONG_INT operationRegister; LONG_INT opRegister1; LONG_INT opRegister2; LONG_INT resultRegister; LONG_INT*memory; int halt; }VirtualMachine; /*:5*/ #line 10 "simreg3.w" /*28:*/ #line 394 "simreg3.w" void PanicMsg(char*what,char*msg) { fprintf(stderr,"Panic :: %s :: %s\n",what,msg); fprintf(stderr,"This was a critical error.\n" "Exit to system.\n"); exit(1); } /*:28*//*29:*/ #line 403 "simreg3.w" void ErrorMsg(char*what,char*msg) { fprintf(stderr,"Error :: %s :: %s\n",what,msg); } /*:29*/ #line 11 "simreg3.w" /*20:*/ #line 244 "simreg3.w" /*22:*/ #line 261 "simreg3.w" int FrontToken(char**l,char*delimiter,char*token) {register char*lline= *l; register unsigned int i,c; while((*lline)&&((*lline==SPACE)||strchr(delimiter,*lline))) lline++; i= 0; while((lline[i])&&(!strchr(delimiter,lline[i]))) i++; if(i>strlen(lline)) return False; for(c= 0;coperationCount= 0L; m->operationRegister= 0L; m->opRegister1= 0L; m->opRegister2= 0L; m->resultRegister= 0L; m->halt= False; /*17:*/ #line 229 "simreg3.w" m->memory= (LONG_INT*)calloc(maxMem,sizeof(LONG_INT)); if(!(m->memory)){ PanicMsg("InitMachine","Out of memory."); return 1; } for(i= 0;imemory[i]= 0L; /*:17*/ #line 225 "simreg3.w" return 0; } /*:16*/ #line 13 "simreg3.w" /*7:*/ #line 89 "simreg3.w" unsigned long int EncodeInstruction (char*inst,long int op1,long int op2,long int res) {long int todo; if(0==strcmp(inst,"H"))todo= HALT_CODE; else if(0==strcmp(inst,"+"))todo= PLUS_CODE; else if(0==strcmp(inst,"-"))todo= MINUS_CODE; else if(0==strcmp(inst,"*"))todo= TIMES_CODE; else if(0==strcmp(inst,"S"))todo= JUMP_CODE; else{ fprintf(stderr,"Syntax :: Can't convert instruction code.\n"); exit(1); } return(todo<operationRegister>>CommandBits; decode= vm->operationRegister-(doWhat<>ShiftOp1; decode= decode-(op1<>ShiftOp2; res= decode-(op2<operationCount); switch(doWhat){ case HALT_CODE: printf(" { H } "); break; case PLUS_CODE: printf(" { +, %6ld, %6ld, %6ld } ",op1,op2,res); break; case MINUS_CODE: printf(" { -, %6ld, %6ld, %6ld } ",op1,op2,res); break; case TIMES_CODE: printf(" { -, %6ld, %6ld, %6ld } ",op1,op2,res); break; case JUMP_CODE: printf(" { S, %6ld, %6ld } ",op1,op2); break; } printf(" %6ld ",vm->resultRegister); /*:12*/ #line 113 "simreg3.w" switch(doWhat){ case HALT_CODE: vm->halt= True; break; case PLUS_CODE: vm->resultRegister= vm->memory[res]= vm->memory[op1]+vm->memory[op2]; /*10:*/ #line 146 "simreg3.w" vm->operationCount++; vm->operationRegister= vm->memory[vm->operationCount]; /*:10*/ #line 120 "simreg3.w" break; case MINUS_CODE: vm->resultRegister= vm->memory[res]= vm->memory[op1]-vm->memory[op2]; /*10:*/ #line 146 "simreg3.w" vm->operationCount++; vm->operationRegister= vm->memory[vm->operationCount]; /*:10*/ #line 124 "simreg3.w" break; case TIMES_CODE: vm->resultRegister= vm->memory[res]= vm->memory[op1]*vm->memory[op2]; /*10:*/ #line 146 "simreg3.w" vm->operationCount++; vm->operationRegister= vm->memory[vm->operationCount]; /*:10*/ #line 128 "simreg3.w" break; case JUMP_CODE: /*11:*/ #line 151 "simreg3.w" if(vm->resultRegister<=0) vm->operationCount= op1; else vm->operationCount= op2; vm->operationRegister= vm->memory[vm->operationCount]; /*:11*/ #line 131 "simreg3.w" break; } } /*:8*/ #line 15 "simreg3.w" /*13:*/ #line 182 "simreg3.w" int Execute(VirtualMachine*vm, long int trace[],long int traceNo) {unsigned long int opCount= 0L; long int i; /*15:*/ #line 201 "simreg3.w" printf("; Begin execution trace\n"); printf(";--------------------------------------------------\n"); printf("; oc { ins , op1 op2 res } rr "); for(i= 0;ihalt)){ ApplyInstruction(vm); /*14:*/ #line 196 "simreg3.w" for(i= 0;imemory[trace[i]]); printf("\n"); /*:14*/ #line 191 "simreg3.w" } return 0; } /*:13*/ #line 16 "simreg3.w" /*25:*/ #line 325 "simreg3.w" int ParseAndCompileSource( char*filename,long int*codeStart, LONG_INT*memory,long int*trace,long int*traceNo) {FILE*src; char line[STRINGLEN],*l,symInstr[STRINGLEN]; int failed,lcount= 1; LONG_INT addr,instr,res,op1,op2; src= fopen(filename,"r"); if(!src) PanicMsg("ParseAndCompileSource","Can't open input file."); fgets(line,STRINGLEN,src); sscanf(line,".START %d",codeStart); printf("; Compiled code\n"); while(!feof(src)){ fgets(line,STRINGLEN,src); lcount++; PrepareLine(BEGIN_COMMENT,&l,line); if(*l&&'\n'!=*l){ addr= ScanLongInt(&l,0,&failed); if(failed){ fprintf(stderr, "Syntax :: Can't read target address in line %ld.\n",lcount); return 1; } if(!FrontToken(&l,NUMBER_DELIMITER,symInstr)){ fprintf(stderr, "Syntax :: Can't read instruction in line %ld.\n",lcount); return 1; } instr= ScanLongInt(&l,atol(symInstr),&failed); if(!failed){ op1= instr; op2= ScanLongInt(&l,0,&failed); res= ScanLongInt(&l,0,&failed); instr= EncodeInstruction(symInstr,op1,op2,res); } else /*27:*/ #line 381 "simreg3.w" if(addr>0L&&addr0L&&addr1)strcpy(source,argv[1]); else gets(source); if(*source){ InitMachine(&vm,MaxMemoryCells); /*18:*/ #line 238 "simreg3.w" trace= (long int*)calloc(MaxMemoryCells,sizeof(long int)); traceNo= 0L; /*:18*/ #line 32 "simreg3.w" ParseAndCompileSource( source,&codeBegin, vm.memory,trace,&traceNo); /*2:*/ #line 42 "simreg3.w" vm.operationCount= codeBegin; vm.operationRegister= vm.memory[codeBegin]; /*:2*/ #line 36 "simreg3.w" Execute(&vm,trace,traceNo); } return 0; } /*:1*/