Created
September 5, 2011 16:20
-
-
Save shawntan/1195374 to your computer and use it in GitHub Desktop.
Interpreter
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
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
/*Symbol linked list*/ | |
typedef struct Symbol{ | |
char* identifier; | |
int value; | |
struct Symbol* next; | |
} Symbol; | |
Symbol* list = NULL; | |
Symbol* lookup_symbols(char* varn) { | |
Symbol* curr = list; | |
while(curr) { | |
if(!strcmp(varn,curr->identifier)) return curr; | |
curr = curr->next; | |
} | |
curr = malloc(sizeof(Symbol)); | |
curr->identifier = varn; | |
curr->value = 0; | |
curr->next=list; | |
list=curr; | |
} | |
void print_symbols() { | |
Symbol* curr = list; | |
while(curr) { | |
printf("%s=\t%d\n",curr->identifier,curr->value); | |
curr = curr->next; | |
} | |
} | |
/*end of Symbol crap*/ | |
typedef void (*action)(char); | |
struct Context{ | |
int current_state; | |
char buffer[256]; | |
unsigned char buf_c; | |
char operator; | |
char* var_name; | |
int value; | |
} Context; | |
/*Utility methods*/ | |
int in(char* arr, char c){ | |
int size = strlen(arr),i; | |
for(i=0;i<size;i++) if (arr[i] == c) return 1; | |
return 0; | |
} | |
void clear_buffer(){ | |
Context.buffer[Context.buf_c] = '\0'; | |
Context.buf_c=0; | |
} | |
void eval() { | |
Symbol* variable = lookup_symbols(Context.var_name); | |
switch(Context.operator) { | |
case '+': variable->value+=Context.value;break; | |
case '*': variable->value*=Context.value;break; | |
case '/': variable->value/=Context.value;break; | |
case '-': variable->value-=Context.value;break; | |
} | |
} | |
/*end*/ | |
/*State transition methods*/ | |
void write_buf(char a){ | |
Context.buffer[Context.buf_c]=a; | |
Context.buf_c++; | |
} | |
void clear_push_to_table(char a){ | |
clear_buffer(); | |
Context.var_name = (char*) malloc(strlen((Context.buffer))+1); | |
strcpy(Context.var_name,Context.buffer); | |
Context.operator = a; | |
} | |
void clear_push_to_int(char a) { | |
clear_buffer(); | |
Context.value = atoi(Context.buffer); | |
eval(); | |
} | |
void clear_push_lookup_table(char a) { | |
clear_buffer(); | |
Context.value = lookup_symbols(Context.buffer)->value; | |
eval(); | |
} | |
void noop(char a){} | |
void explode(char a){ | |
printf("Explode!\n"); | |
exit(1); | |
} | |
/*state transition methods*/ | |
const unsigned int STATES = 6; | |
const unsigned int ALPHABET = 5; | |
action** fun; | |
unsigned int** delta; | |
char** alphabet; | |
void construct_dfa() { | |
unsigned int i=0; | |
unsigned int alpha,num,op,delim,eq; | |
alphabet = (char**)malloc(ALPHABET*(sizeof alphabet)); | |
alphabet[alpha=i++]="_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
alphabet[num=i++]="0123456789"; | |
alphabet[op=i++]="+-*/"; | |
alphabet[delim=i++]=";"; | |
alphabet[eq=i++]="="; | |
delta = malloc((STATES+1)*(sizeof delta)); | |
fun = malloc((STATES+1)*(sizeof fun)); | |
unsigned int d=ALPHABET*(sizeof(*delta)); | |
unsigned int f=ALPHABET*(sizeof(*fun)); | |
for(i=0;i<STATES+1;i++) { | |
delta[i] = memset(malloc(d),0,d); | |
fun[i] = malloc(f); | |
int j=0; | |
for(j=0;j<ALPHABET;j++) fun[i][j] = explode; | |
} | |
delta[1][alpha] = delta[2][alpha] = delta[2][num] = 2; | |
delta[2][op] = 3; | |
delta[3][eq] = 4; | |
delta[4][num] = delta[5][num] = 5; | |
delta[4][alpha] = delta[6][alpha] = delta[6][num] = 6; | |
delta[5][delim] = delta[6][delim] = 1; | |
fun[1][alpha] = fun[2][alpha] = fun[2][num] = write_buf; | |
fun[2][op] = clear_push_to_table; | |
fun[3][eq] = noop; | |
fun[4][alpha] = fun[4][num] = fun[5][num] = fun[6][alpha] = fun[6][num] = write_buf; | |
fun[5][delim] = clear_push_to_int; | |
fun[6][delim] = clear_push_lookup_table; | |
} | |
int main() { | |
construct_dfa(); | |
Context.current_state = 1; | |
while(1) { | |
char t = fgetc(stdin); | |
if(t=='\n') break; | |
int i=0; | |
while(i<ALPHABET && !in(alphabet[i],t)) i++; | |
printf("%d -'%c'-> %d\n",Context.current_state,t,delta[Context.current_state][i]); | |
(*(fun[Context.current_state][i]))(t); | |
Context.current_state = delta[Context.current_state][i]; | |
} | |
print_symbols(); | |
int i; | |
int j; | |
for(i=0;i<6;i++) { | |
for(j=0;j<5;j++) printf(" %d",delta[i][j]); | |
printf("\n"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment