Skip to content

Instantly share code, notes, and snippets.

@yunchih
Last active August 29, 2015 14:08
Show Gist options
  • Save yunchih/5bd67cad5ae075d25b01 to your computer and use it in GitHub Desktop.
Save yunchih/5bd67cad5ae075d25b01 to your computer and use it in GitHub Desktop.
/* 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