Last active
August 29, 2015 14:08
-
-
Save yunchih/5bd67cad5ae075d25b01 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Problem statement at https://github.com/pangfengliu/programmingtasks/issues/270 */ | |
#include<stdio.h> | |
#include<ctype.h> | |
#include<string.h> | |
#include<stdlib.h> | |
#include<assert.h> | |
#define MAX_VAR_LEN 8 | |
#define MAX_VAR_NUM 100 | |
#define MAX_LINE_NUM 1000 | |
#define MAX_LINE_TOKENS 6 | |
#define MAX_TOKEN_LEN 8 | |
#define CODE_ZERO 48 | |
typedef struct { | |
char name[MAX_VAR_LEN]; | |
int value; | |
} var; | |
enum { NAME,VAR,EQSIGN }; | |
enum { IF,GOTO,PRINT,ASSIGN,STOP }; | |
int numOfOprand[5] = {5,1,1,4,0}; | |
enum { EQ,LT,GT,ELT,EGT,NEQ}; | |
const char* cmp[6] = {"==","<",">","<=",">=","!="}; | |
int numOfCmp = 6 ; | |
enum {ADD,SUB,MUL,DIV,MOD}; | |
const char* op[5] = {"+","-","*","/","%"}; | |
int numOfOp = 5 ; | |
char tokens[MAX_LINE_NUM*MAX_LINE_TOKENS][MAX_TOKEN_LEN]; | |
int lineFirstTokIndex[MAX_LINE_NUM+1] = {0}; | |
var vars[MAX_VAR_NUM] ; | |
int numOfVars ; | |
int parseInt(char* s){ | |
int result = 0 ; | |
while(*s!='\0'){ | |
result = result*10 + *s - CODE_ZERO; | |
s++; | |
} | |
return result; | |
} | |
int classifyVar(char* token){ | |
if(*token == '=') | |
return EQSIGN; | |
if(*token == '-' ) | |
return VAR; | |
int i; | |
int len = strlen(token); | |
for(i=0;i<len;i++) | |
if(!isdigit(token[i])) | |
return NAME; | |
return VAR; | |
} | |
int classifyCmd(char* cmd){ | |
if(!strcmp(cmd,"IF")) | |
return IF; | |
if(!strcmp(cmd,"GOTO")) | |
return GOTO; | |
if(!strcmp(cmd,"PRINT")) | |
return PRINT; | |
if(!strcmp(cmd,"STOP")) | |
return STOP; | |
return ASSIGN; | |
} | |
int do_Op(char* inOp,int a,int b){ | |
if(!strcmp(inOp,"+")) | |
return a+b; | |
if(!strcmp(inOp,"-")) | |
return a-b; | |
if(!strcmp(inOp,"*")) | |
return a*b; | |
if(!strcmp(inOp,"/")) | |
return a/b; | |
if(!strcmp(inOp,"%")) | |
return a%b; | |
printf("Operation no match!\n"); | |
return 0; | |
} | |
int do_Cmp(char* inCmp,int a,int b){ | |
if(!strcmp(inCmp,"==")) | |
return a==b; | |
if(!strcmp(inCmp,"<")) | |
return a<b; | |
if(!strcmp(inCmp,">")) | |
return a>b; | |
if(!strcmp(inCmp,"<=")) | |
return a<=b; | |
if(!strcmp(inCmp,">=")) | |
return a>=b; | |
if(!strcmp(inCmp,"!=")) | |
return a!=b; | |
printf("Compare no match!\n"); | |
return 0; | |
} | |
var* findVar(char* target){ | |
int i; | |
for (i = 0; i < numOfVars; ++i) | |
if(!strcmp(vars[i].name,target)) | |
return &vars[i]; | |
printf( "Target:%s, not found",target ); | |
} | |
int do_assignment(int index){ | |
var* target = findVar(tokens[index]); | |
var* oprand1 = findVar(tokens[index+2]); | |
var* oprand2 = findVar(tokens[index+4]); | |
(*target).value = do_Op(tokens[index+3],(*oprand1).value,(*oprand2).value); | |
return index + numOfOprand[ ASSIGN ] + 1; | |
} | |
int do_print(int index){ | |
var* target = findVar(tokens[index+1]); | |
printf("%d\n",(*target).value); | |
return index + numOfOprand[ PRINT ] + 1; | |
} | |
int do_goto(int index){ | |
int goToLine = parseInt(tokens[index+1]); | |
return lineFirstTokIndex[ goToLine ] ; | |
} | |
int do_if(int index){ | |
var* oprand1 = findVar(tokens[index+1]); | |
var* oprand2 = findVar(tokens[index+3]); | |
if( do_Cmp(tokens[index+2],(*oprand1).value,(*oprand2).value) ) | |
return do_goto(index+4); | |
else | |
return index + numOfOprand[ IF ] + 1; | |
} | |
void readLine(int n,int i){ | |
while(n--){ | |
scanf("%s",tokens[i++]); | |
} | |
} | |
int main(int argc, char const *argv[]) | |
{ | |
char token[MAX_VAR_LEN]; | |
numOfVars = 0; | |
// read variable | |
while( scanf("%s",token) && strcmp(token,"END")!=0 ){ | |
switch(classifyVar(token)){ | |
case NAME: | |
strcpy(vars[numOfVars].name,token); | |
break; | |
case VAR: | |
vars[numOfVars++].value = parseInt(token); | |
break; | |
} | |
} | |
int lineNum = 1; | |
int i = 0 ; | |
int cmdType; | |
//Read the first token of a line | |
while( scanf("%s",tokens[i]) ){ | |
cmdType = classifyCmd(tokens[i]); | |
//Depending on the type of first token , read its operants | |
readLine(numOfOprand[ cmdType ],i+1); | |
//Mark line number | |
lineFirstTokIndex[lineNum++] = i; | |
i+=numOfOprand[ cmdType ]+1; | |
if(cmdType == STOP ) | |
break; | |
} | |
i = 0; | |
int done = 0 ; | |
while(!done){ | |
switch(classifyCmd(tokens[i])){ | |
case ASSIGN: | |
i = do_assignment(i); | |
break; | |
case GOTO: | |
i = do_goto(i); | |
break; | |
case PRINT: | |
i = do_print(i); | |
break; | |
case IF: | |
i = do_if(i); | |
break; | |
case STOP: | |
done = 1; | |
break; | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment