#define HALT_CODE (0) #define PLUS_CODE (1) #define MINUS_CODE (2) #define TIMES_CODE (3) #define MOVE_CODE (4) #define MOVE_CLEAR_CODE (5) #define JUMP_CODE (6) #define JUMP_IF_CODE (7) #define JUMP_IF_NOT_CODE (8) #define STRINGLEN 1024 #define BEGIN_COMMENT ';' #define SPACE ' ' #define NUMBER_DELIMITER " ,:\t\n" \ #define BANNER "; Simple v. Neumann Machine Simulator\n" #define COPYRIGHT "; (c) M. Meiler, J.-P. Kuska 1998\n" \ /*1:*/ #line 4 "simneu.w" /*32:*/ #line 449 "simneu.w" #include #include #include #if !defined(True) # define True (1) # define False (0) #endif/*:32*/ #line 5 "simneu.w" /*3:*/ #line 47 "simneu.w" unsigned long MaxMemoryCells= 10000ul; unsigned long MaxOperations= 4000ul; /*:3*//*6:*/ #line 82 "simneu.w" const int CommandBits= 4; /*:6*/ #line 6 "simneu.w" /*5:*/ #line 59 "simneu.w" typedef struct _VirtualMachine{ long int operationCount; long int operationRegister; long int stateRegister; long int resultRegister; long int*memory; int halt; }VirtualMachine; /*:5*/ #line 7 "simneu.w" /*29:*/ #line 426 "simneu.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); } /*:29*//*30:*/ #line 435 "simneu.w" void ErrorMsg(char*what,char*msg) { fprintf(stderr,"Error :: %s :: %s\n",what,msg); } /*:30*/ #line 8 "simneu.w" /*21:*/ #line 280 "simneu.w" /*23:*/ #line 297 "simneu.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->stateRegister= 0L; m->resultRegister= 0L; m->halt= False; /*18:*/ #line 266 "simneu.w" m->memory= (long int*)calloc(maxMem,sizeof(long int)); if(!(m->memory)){ PanicMsg("InitMachine","Out of memory."); } for(i= 0;imemory[i]= 0L; /*:18*/ #line 263 "simneu.w" } /*:17*/ #line 10 "simneu.w" /*7:*/ #line 86 "simneu.w" unsigned long int EncodeInstruction(char*inst,long int addr) {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,"->"))todo= MOVE_CODE; else if(0==strcmp(inst,"=>"))todo= MOVE_CLEAR_CODE; else if(0==strcmp(inst,"S"))todo= JUMP_CODE; else if(0==strcmp(inst,"S>"))todo= JUMP_IF_CODE; else if(0==strcmp(inst,"S<="))todo= JUMP_IF_NOT_CODE; else if(0==strcmp(inst,"J"))todo= JUMP_CODE; else if(0==strcmp(inst,"JGT"))todo= JUMP_IF_CODE; else if(0==strcmp(inst,"JLE"))todo= JUMP_IF_NOT_CODE; else{ fprintf(stderr,"Syntax :: Can't convert instruction code.\n"); exit(1); } return(addr<operationRegister>>CommandBits; doWhat= vm->operationRegister-(doWith<operationCount); switch(doWhat){ case HALT_CODE: printf(" { H, %6ld } ",doWith); break; case PLUS_CODE: printf(" { +, %6ld } ",doWith); break; case MINUS_CODE: printf(" { -, %6ld } ",doWith); break; case TIMES_CODE: printf(" { *, %6ld } ",doWith); break; case MOVE_CODE: printf(" { ->, %6ld } ",doWith); break; case MOVE_CLEAR_CODE: printf(" { =>, %6ld } ",doWith); break; case JUMP_CODE: printf(" { S, %6ld } ",doWith); break; case JUMP_IF_CODE: printf(" { S>, %6ld } ",doWith); break; case JUMP_IF_NOT_CODE: printf(" { S<=, %6ld } ",doWith); break; } printf(" %6ld %6ld ", vm->resultRegister,vm->stateRegister); /*:13*/ #line 115 "simneu.w" switch(doWhat){ case HALT_CODE: vm->halt= True; break; case PLUS_CODE: vm->resultRegister+= vm->memory[doWith]; /*11:*/ #line 175 "simneu.w" vm->stateRegister= (vm->resultRegister>0)?1:0; /*:11*/ #line 122 "simneu.w" /*10:*/ #line 171 "simneu.w" vm->operationCount++; vm->operationRegister= vm->memory[vm->operationCount]; /*:10*/ #line 123 "simneu.w" break; case MINUS_CODE: vm->resultRegister-= vm->memory[doWith]; /*11:*/ #line 175 "simneu.w" vm->stateRegister= (vm->resultRegister>0)?1:0; /*:11*/ #line 127 "simneu.w" /*10:*/ #line 171 "simneu.w" vm->operationCount++; vm->operationRegister= vm->memory[vm->operationCount]; /*:10*/ #line 128 "simneu.w" break; case TIMES_CODE: vm->resultRegister*= vm->memory[doWith]; /*11:*/ #line 175 "simneu.w" vm->stateRegister= (vm->resultRegister>0)?1:0; /*:11*/ #line 132 "simneu.w" /*10:*/ #line 171 "simneu.w" vm->operationCount++; vm->operationRegister= vm->memory[vm->operationCount]; /*:10*/ #line 133 "simneu.w" break; case MOVE_CODE: vm->memory[doWith]= vm->resultRegister; /*10:*/ #line 171 "simneu.w" vm->operationCount++; vm->operationRegister= vm->memory[vm->operationCount]; /*:10*/ #line 137 "simneu.w" break; case MOVE_CLEAR_CODE: vm->memory[doWith]= vm->resultRegister; vm->resultRegister= 0L; /*10:*/ #line 171 "simneu.w" vm->operationCount++; vm->operationRegister= vm->memory[vm->operationCount]; /*:10*/ #line 142 "simneu.w" break; case JUMP_CODE: /*12:*/ #line 179 "simneu.w" vm->operationCount= doWith; vm->operationRegister= vm->memory[doWith]; /*:12*/ #line 145 "simneu.w" break; case JUMP_IF_CODE: if(vm->stateRegister>0){ /*12:*/ #line 179 "simneu.w" vm->operationCount= doWith; vm->operationRegister= vm->memory[doWith]; /*:12*/ #line 149 "simneu.w" } else{ /*10:*/ #line 171 "simneu.w" vm->operationCount++; vm->operationRegister= vm->memory[vm->operationCount]; /*:10*/ #line 152 "simneu.w" } break; case JUMP_IF_NOT_CODE: if(vm->stateRegister<=0){ /*12:*/ #line 179 "simneu.w" vm->operationCount= doWith; vm->operationRegister= vm->memory[doWith]; /*:12*/ #line 157 "simneu.w" } else{ /*10:*/ #line 171 "simneu.w" vm->operationCount++; vm->operationRegister= vm->memory[vm->operationCount]; /*:10*/ #line 160 "simneu.w" } break; } } /*:8*/ #line 12 "simneu.w" /*14:*/ #line 221 "simneu.w" int Execute(VirtualMachine*vm, long int trace[],long int traceNo) {unsigned long int opCount= 0L; long int i; /*16:*/ #line 240 "simneu.w" printf("; Begin execution trace\n"); printf(";--------------------------------------------------\n"); printf("; oc { op , addr } rr zr "); for(i= 0;ihalt)){ ApplyInstruction(vm); /*15:*/ #line 235 "simneu.w" for(i= 0;imemory[trace[i]]); printf("\n"); /*:15*/ #line 230 "simneu.w" } return 0; } /*:14*/ #line 13 "simneu.w" /*26:*/ #line 361 "simneu.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; src= fopen(filename,"r"); if(!src) PanicMsg("ParseAndCompileSource","Can't open input file."); fgets(line,STRINGLEN,src); sscanf(line,".START %ld",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) instr= EncodeInstruction(symInstr,instr); else /*28:*/ #line 413 "simneu.w" if(addr>0L&&addr0L&&addr1)strcpy(source,argv[1]); else gets(source); if(*source){ InitMachine(&vm,MaxMemoryCells); /*19:*/ #line 274 "simneu.w" trace= (long int*)calloc(MaxMemoryCells,sizeof(long int)); traceNo= 0L; /*:19*/ #line 29 "simneu.w" ParseAndCompileSource( source,&codeBegin, vm.memory,trace,&traceNo); /*2:*/ #line 39 "simneu.w" vm.operationCount= codeBegin; vm.operationRegister= vm.memory[codeBegin]; /*:2*/ #line 33 "simneu.w" Execute(&vm,trace,traceNo); } return 0; } /*:1*/