Skip to content

Instantly share code, notes, and snippets.

@revsic
Created June 12, 2017 04:32
Show Gist options
  • Save revsic/e318dd89a579a97ce284494586a38549 to your computer and use it in GitHub Desktop.
Save revsic/e318dd89a579a97ce284494586a38549 to your computer and use it in GitHub Desktop.
Pycala interpreter prototype.
#include <stdio.h>
#include <stdlib.h> //exit function
#include <string.h>
typedef void(* f)(char *arg);
typedef int(* c)(int i, int j);
void parse(char *inst);
void real(int index, int cnt);
char* trim(char *str);
char* cpyTrim(char *str);
int blankLine(char *src);
void print(char *arg);
void val(char *arg);
void calc(char *inst, int cpyFlag);
void input(char *arg);
void ifFunc(char *arg);
void whileFunc(char *arg);
void forFunc(char *arg);
void defDefine(char *arg);
void defExecute(char *arg);
int mul(int i, int j) {
return i * j;
}
int divide(int i, int j) {
return i / j;
}
int mod(int i, int j) {
return i % j;
}
int plus(int i, int j) {
return i + j;
}
int minus(int i, int j) {
return i - j;
}
int big(int i, int j) {
return i > j;
}
int ebig(int i, int j) {
return i >= j;
}
int less(int i, int j) {
return i < j;
}
int eless(int i, int j) {
return i <= j;
}
int equal(int i, int j) {
return i == j;
}
int notEq(int i, int j) {
return i != j;
}
FILE *fp;
int cmdCnt = 0;
int valueLen = 0;
char valueName[1024][1024] = { 0, };
char valueData[1024][1024] = { 0, };
int defLen = 0;
char defName[1024][1024] = { 0, };
char defData[1024][1024] = { 0, };
char *fName[] = { "print", "val", "input", "if", "while", "for", "def", "do" };
f fArray[] = { print, val, input, ifFunc, whileFunc, forFunc, defDefine, defExecute };
char *prior[] = { "(", ")", "*", "/", "%", "+", "-", ">", ">=", "<", "<=", "==", "!=" };
c priorF[] = { NULL, NULL, mul, divide, mod, plus, minus, big, ebig, less, eless, equal, notEq };
int tmpBufferFlag = -1;
char tmpBuffer[10][256][256];
char arr[512][512];
void main (int argc, char *argv[]) {
char buffer[1024];
if(argc < 2) {
printf("line 0 : invalid filename \n");
exit(0);
}
fp = fopen(argv[1], "r");
int i = 0;
while(fgets(buffer, 1024, fp)) parse(buffer);
}
void parse(char *inst) {
int len;
int index = 0;
char src[1024];
char name[1024];
++cmdCnt;
if(blankLine(inst)) return;
strchr(inst, ' ')[0] = '\0';
strcpy(name, cpyTrim(inst));
inst[strlen(inst)] = ' ';
len = sizeof(fName) / sizeof(fName[0]);
while(strcmp(fName[index], name)){
++index;
if(index == len) {
index = -1;
break;
}
}
if(index == -1) {
index = 0;
while(strcmp(defName[index], cpyTrim(inst))) {
++index;
if(index >= defLen) {
index = -1;
break;
}
}
if(index != -1)
defExecute(inst);
else {
strcpy(src, inst);
if(strchr(inst, '=') == 0) {
printf("line %d : unmatched command format \n", cmdCnt);
exit(0);
}
strchr(inst, '=')[0] = '\0';
strcpy(name, cpyTrim(inst));
index = 0;
while(strcmp(valueName[index], name)) {
++index;
if(index >= valueLen) {
index = -1;
break;
}
}
if(index != -1)
calc(src, 1);
else {
printf("line %d : undefined name \n", cmdCnt);
exit(0);
}
}
}
else fArray[index](trim(strchr(inst, ' ') + 1));
}
void real(int index, int cnt) {
int i, j, k, l, tmp;
int op[2];
int res;
for(i = 2; i < 13; ++i) {
for(j = index; j <= index + cnt; ++j) {
if(!strcmp(prior[i], arr[j])) {
tmp = j - 1;
for(k = 0; k < 2; ++k) {
l = 0;
while(strcmp(valueName[l], arr[tmp])) {
++l;
if(l >= valueLen) {
l = -1;
break;
}
}
if(l == -1) op[k] = atoi(arr[tmp]);
else op[k] = atoi(valueData[l]);
tmp += 2;
}
res = priorF[i](op[0], op[1]);
sprintf(arr[j-1], "%d", res);
for(k = j; k <= cnt-2; ++k) {
strcpy(arr[k], arr[k + 2]);
}
cnt -= 2;
--j;
}
}
}
}
void calc(char *inst, int cpyFlag) {
int i, j, index, cnt = -1;
char *addr, *min, *tmp;
char name[512], op[512];
strcpy(op, trim(strchr(inst, '=')+1));
tmp = strchr(op, ' ');
if(tmp != 0) tmp[0] = '\0';
i = 0;
j = sizeof(fName) / sizeof(fName[0]);
while(strcmp(fName[i], op)) {
++i;
if(i == j) {
i = -1;
break;
}
}
if(i != -1) {
fArray[i](inst);
return;
}
if(tmp != 0) tmp[0] = ' ';
strcpy(name, trim(strtok(inst, "=")));
tmp = op;
while(1) {
min = 0;
for(i = 0; i < 13; ++i) {
addr = strstr(tmp, prior[i]);
if(min == 0 && addr != 0) {
index = i;
min = addr;
}
if(min > addr && addr != 0) {
index = i;
min = addr;
}
}
if(min == 0) break;
min[0] = '\0';
if(prior[index][0] != '(' && arr[cnt][0] != ')')
strcpy(arr[++cnt], trim(tmp));
strcpy(arr[++cnt], prior[index]);
tmp = min + 1;
}
strcpy(arr[++cnt], trim(tmp));
real(0, cnt);
if(!cpyFlag) return;
i = 0;
while(strcmp(valueName[i], name)) {
if(++i >= valueLen) {
i = -1;
break;
}
}
if(i == -1) {
printf("line %d : undefined value \n", cmdCnt);
exit(0);
}
else
strcpy(valueData[i], arr[0]);
}
void val(char *arg){
char copy[1024];
char name[512];
strcpy(copy, arg);
if(strchr(arg, '=') == 0) {
printf("line %d : uninitialized value \n", cmdCnt);
exit(0);
}
strchr(arg, '=')[0] = '\0';
strcpy(valueName[valueLen++], trim(arg));
calc(copy, 1);
}
void print(char *arg) {
int i, opLen = 0;
int formatLen = 0;
int tmp, flag = 0;
int newLineFlag = 0;
char *tok = strtok(&arg[1], "\"");
char *tmpStr;
char op[500][1024] = { 0, };
char res[2048] = { 0, };
strcpy(op[0], tok);
while(tok = strtok(NULL, ",")) strcpy(op[++opLen], trim(tok));
if(op[opLen][0] == ':') {
newLineFlag = 1;
--opLen;
}
tok = arg;
while(tok = strstr(tok+1, "%f")) ++formatLen;
if(opLen != formatLen) {
printf("line %d : unmatched format string\n", cmdCnt);
exit(0);
}
if(strstr(arg, "%f")) {
tok = strtok(op[0], "%f");
if(tok == 0) {
strcpy(res, " ");
strcat(res, op[0]);
strcpy(op[0], res);
flag = 1;
tok = strtok(op[0], "%f");
}
strcpy(res, tok);
for(i = 1; i <= opLen; ++i) {
if(i != opLen)
tok = strtok(NULL, "%f");
else {
tok = strtok(NULL, "");
tok = &tok[1];
}
tmp = strlen(op[i]);
if(op[i][0] == '\"' && op[i][tmp - 1] == '\"') {
op[i][strlen(op[i]) - 1] = '\0';
tmpStr = &op[i][1];
} else {
tmp = 0;
while(strcmp(valueName[tmp], op[i])) {
++tmp;
if(tmp >= valueLen) {
tmp = -1;
break;
}
}
if(tmp == -1) {
printf("line %d : undefined value \n", cmdCnt);
exit(0);
}
tmpStr = valueData[tmp];
}
strcat(res, tmpStr);
strcat(res, tok);
}
if(flag) printf("%s", &res[1]);
else printf("%s", res);
} else {
printf("%s", op[0]);
}
if(!newLineFlag) printf("\n");
}
void input(char *arg) {
int i = 0;
char name[512];
char data[1024];
strchr(arg, '=')[0] = '\0';
strcpy(name, trim(arg));
while(strcmp(name, valueName)) {
++i;
if(i >= valueLen) {
i = -1;
break;
}
}
if(i == -1) {
printf("line %d : undefined value\n", cmdCnt);
exit(0);
}
else {
scanf("%s", data);
strcpy(valueData[i], data);
}
}
void ifFunc(char *arg) {
int oneLineFlag = 0, tmpInt = -1;
int i = 0, cnt = -1, flag = 1;
int finishCheckFlag = 0;
int len[2] = { -1, -1 };
char *tok;
char name[512] = "test";
char op[512];
char res[2][3096] = { 0, };
char tmp[512], elseStr[512], endStr[512];
if(strchr(arg, '?') == 0) {
printf("line %d : unmatched function format\n", cmdCnt);
exit(0);
}
tok = strchr(arg, '=');
oneLineFlag = tok && tok < strchr(arg, '?');
if(oneLineFlag) tok = &strstr(arg, "if")[2];
else tok = arg;
strchr(tok, '?')[0] = '\0';
strcpy(op, cpyTrim(tok));
tok[strlen(tok)] = '?';
if(oneLineFlag) {
strchr(arg, '=')[0] = '\0';
strcpy(name, cpyTrim(arg));
arg[strlen(arg)] = '=';
if(strstr(arg, "else") != 0) {
tok = &strchr(arg, '?')[1];
strstr(arg, "else")[0] = '\0';
strcpy(res[1], cpyTrim(tok));
tok[strlen(tok)] = 'e';
}
tok = &strstr(arg, "else")[4];
if(strstr(arg, "end") == 0) {
printf("line %d : unterminated function expected\n", cmdCnt);
exit(0);
}
strstr(arg, "end")[0] = '\0';
strcpy(res[0], cpyTrim(tok));
++len[0];
++len[1];
} else {
while(1) {
++finishCheckFlag;
if(tmpBufferFlag == -1) {
fgets(tmp, 1024, fp);
++cmdCnt;
}
else {
strcpy(tmp, tmpBuffer[tmpBufferFlag][++tmpInt]);
}
if(blankLine(tmp)) continue;
if(cnt == -1) {
while(tmp[++cnt] == '\t');
for(i = 0; i < cnt-1; ++i) elseStr[i] = '\t';
elseStr[cnt] = '\0';
strcat(elseStr, "else");
strchr(elseStr, 'e')[0] = '\0';
strcpy(endStr, elseStr);
strcat(endStr, "end");
elseStr[strlen(elseStr)] = 'e';
}
if(!strncmp(tmp, elseStr, cnt-1 + 4)) {
--flag;
continue;
}
if(!strncmp(tmp, endStr, cnt-1 + 3)) break;
if(finishCheckFlag >= 300) {
printf("line %d : unterminated function expected\n", cmdCnt);
exit(0);
}
strcat(res[flag], ";");
strcat(res[flag], tmp);
++len[flag];
}
if(tmpBufferFlag != -1) --tmpBufferFlag;
}
strcpy(tmp, name);
strcat(tmp, "=");
strcat(tmp, op);
calc(tmp, 0);
flag = atoi(arr[0]);
if(oneLineFlag) {
while(strcmp(valueName[i], name)) {
++i;
if(i >= valueLen) {
i = -1;
break;
}
}
if(i == -1) {
printf("line %d : undefined value\n", cmdCnt);
exit(0);
}
len[0] = strlen(res[flag]) - 1;
if(res[flag][len[0]] == '\"') res[flag][len[0]] = '\0';
if(res[flag][0] == '\"')
strcpy(valueData[i], &res[flag][1]);
else
strcpy(valueData[i], res[flag]);
} else {
tok = res[flag];
for(i = 0; i <= len[flag]; ++i) {
tok = &tok[1];
if(strchr(tok, ';')) strchr(tok, ';')[0] = '\0';
strcpy(tmp, tok);
if(strchr(tmp, '?') && strstr(tmp, "end") == 0) {
++tmpBufferFlag;
cnt = -1;
while(1) {
tok = &tok[strlen(tok)];
tok = &tok[1];
if(strchr(tok, ';')) strchr(tok, ';')[0] = '\0';
++i;
strcpy(tmpBuffer[tmpBufferFlag][++cnt], tok);
if(!strcmp(cpyTrim(tok), "end")) break;
}
}
parse(cpyTrim(tmp));
tok = &tok[strlen(tok)];
}
}
}
void whileFunc(char *arg) {
int i, j, index;
int finishCheckFlag = 0;
int len = -1, cnt = -1, cnt2, tmpInt = -1;
char op[512] = "test = ";
char op2[512];
char cmd[2048] = { 0, }, cmd2[2048] = { 0, };
char tmp[512];
char tmp2[512];
char endStr[128];
char *addr = op2;
char *tok;
strchr(arg, '?')[0] = '\0';
strcat(op, trim(arg));
while(1) {
++finishCheckFlag;
if(tmpBufferFlag == -1) {
fgets(tmp, 1024, fp);
++cmdCnt;
} else {
strcpy(tmp, tmpBuffer[tmpBufferFlag][++tmpInt]);
}
if(blankLine(tmp)) continue;
if(cnt == -1) {
while(tmp[++cnt] == '\t');
for(i = 0; i < cnt-1; ++i) endStr[i] = '\t';
endStr[cnt-1] = '\0';
strcat(endStr, "end");
}
if(!strncmp(tmp, endStr, cnt-1 + 3)) break;
if(finishCheckFlag >= 300) {
printf("line %d : unterminated function expected\n", cmdCnt);
exit(0);
}
strcat(cmd, ";");
strcat(cmd, tmp);
++len;
}
if(tmpBufferFlag != -1) --tmpBufferFlag;
while(1) {
strcpy(op2, op);
strcpy(cmd2, cmd);
calc(addr, 0);
tok = cmd2;
if(atoi(arr[0]) == 0) break;
for(i = 0; i <= len; ++i) {
tok = &tok[1];
if(strchr(tok, ';')) strchr(tok, ';')[0] = '\0';
strcpy(tmp, tok);
if(strchr(tmp, '?') && strstr(tmp, "end") == 0) {
++tmpBufferFlag;
cnt2 = -1;
for(j = 0; j < cnt; ++j) endStr[j] = '\t';
endStr[j] = '\0';
strcat(endStr, "end");
finishCheckFlag = 0;
while(1) {
++finishCheckFlag;
tok = &tok[strlen(tok)];
tok = &tok[1];
if(strchr(tok, ';')) strchr(tok, ';')[0] = '\0';
++i;
strcpy(tmpBuffer[tmpBufferFlag][++cnt2], tok);
if(!strncmp(tok, endStr, cnt + 3)) break;
if(finishCheckFlag >= 300) {
printf("line %d : unterminated function expected\n", cmdCnt);
exit(0);
}
}
}
parse(trim(tmp));
tok = &tok[strlen(tok)];
}
}
}
void forFunc(char *argv) {
int finishCheckFlag = 0;
int len = -1, tmpInt = -1;
int cnt = -1, cnt2;
int index, flag = 0;
int start, last;
int i = 0, j, k;
char *tok;
char name[512];
char tmp[512];
char cmd[4000] = { 0, }, cmd2[4000];
char endStr[256];
if(strstr(argv, "to") == 0 || strchr(argv, '?') == 0 || strstr(argv, "in") == 0) {
printf("line %d : unmatched function format \n", cmdCnt);
exit(0);
}
tok = &strstr(argv, "to")[2];
strchr(argv, '?')[0] = '\0';
strcpy(tmp, cpyTrim(tok));
tok[strlen(tok)] = '?';
i = 0;
while(strcmp(valueName[i], tmp)) {
++i;
if(i >= valueLen) {
i = -1;
break;
}
}
if(i == -1) last = atoi(tmp);
else last = atoi(valueData[i]);
tok = &strstr(argv, "in")[2];
strstr(argv, "to")[0] = '\0';
strcpy(tmp, cpyTrim(tok));
tok[strlen(tok)] = 't';
i = 0;
while(strcmp(valueName[i], tmp)) {
++i;
if(i >= valueLen) {
i = -1;
break;
}
}
if(i == -1) start = atoi(tmp);
else start = atoi(valueData[i]);
strstr(argv, "in")[0] = '\0';
strcpy(name, cpyTrim(argv));
argv[strlen(argv)] = 'i';
index = 0;
while(strcmp(valueName[index], name)) {
++index;
if(index >= valueLen) {
index = -1;
break;
}
}
if(index == -1) {
index = valueLen;
strcpy(valueName[valueLen++], name);
}
while(1) {
++finishCheckFlag;
if(tmpBufferFlag == -1) {
fgets(tmp, 1024, fp);
++cmdCnt;
} else {
strcpy(tmp, tmpBuffer[tmpBufferFlag][++tmpInt]);
}
if(blankLine(tmp)) continue;
if(cnt == -1) {
while(tmp[++cnt] == '\t');
for(i = 0; i < cnt-1; ++i) endStr[i] = '\t';
endStr[cnt-1] = '\0';
strcat(endStr, "end");
}
if(!strncmp(tmp, endStr, cnt-1 + 3)) break;
if(finishCheckFlag >= 300) {
printf("line %d : unterminated function expected\n", cmdCnt);
exit(0);
}
strcat(cmd, ";");
strcat(cmd, tmp);
++len;
}
if(tmpBufferFlag != -1) --tmpBufferFlag;
for(i = start; i <= last; ++i) {
sprintf(valueData[index], "%d", i);
strcpy(cmd2, cmd);
tok = cmd2;
for(j = 0; j <= len; ++j) {
tok = &tok[1];
if(strchr(tok, ';')) strchr(tok, ';')[0] = '\0';
strcpy(tmp, tok);
if(strchr(tmp, '?') && strstr(tmp, "end") == 0) {
++tmpBufferFlag;
cnt2 = -1;
for(k = 0; k < cnt; ++k) endStr[k] = '\t';
endStr[k] = '\0';
strcat(endStr, "end");
while(1) {
tok = &tok[strlen(tok)];
tok = &tok[1];
if(strchr(tok, ';')) strchr(tok, ';')[0] = '\0';
++j;
strcpy(tmpBuffer[tmpBufferFlag][++cnt2], tok);
if(!strncmp(tok, endStr, cnt + 3)) break;
}
}
parse(tmp);
tok = &tok[strlen(tok)];
}
}
}
void defDefine(char *argv) {
char name[512];
char tmp[1024];
char endStr[1024];
int finishCheckFlag = 0;
int i, cnt = -1;
if(strchr(argv, '?') == 0) {
printf("line %d : unmatched function format\n", cmdCnt);
exit(0);
}
strchr(argv, '?')[0] = '\0';
strcpy(defName[defLen], cpyTrim(argv));
argv[strlen(argv)] = '?';
while(1) {
fgets(tmp, 1024, fp);
++cmdCnt;
++finishCheckFlag;
if(blankLine(tmp)) continue;
if(cnt == -1) {
while(tmp[++cnt] == '\t');
for(i = 0; i < cnt-1; ++i) endStr[i] = '\t';
endStr[cnt-1] = '\0';
strcat(endStr, "end");
}
if(!strncmp(tmp, endStr, cnt-1 + 3)) break;
if(finishCheckFlag >= 300) {
printf("line %d : unterminated function expected\n", cmdCnt);
exit(0);
}
strcat(defData[defLen], ";");
strcat(defData[defLen], tmp);
}
++defLen;
}
void defExecute(char *argv) {
int index = 0;
int i, finishCheckFlag = 0;
int cnt = -1, cnt2;
char *tok;
char endStr[128];
char tmp[128];
while(strcmp(defName[index], argv)) {
++index;
if(index >= defLen) {
index = -1;
break;
}
}
tok = &defData[index][1];
while(tok[++cnt] == '\t');
tok = defData[index];
for(i = 0; i < cnt-1; ++i) endStr[i] = '\t';
endStr[i] = '\0';
strcat(endStr, "end");
while(1) {
if(*tok == 0) break;
tok = &tok[1];
if(strchr(tok, ';')) strchr(tok, ';')[0] = '\0';
strcpy(tmp, tok);
if(strchr(tmp, '?') && strstr(tmp, "end") == 0) {
++tmpBufferFlag;
cnt2 = -1;
for(i = 0; i < cnt; ++i) endStr[i] = '\t';
endStr[i] = '\0';
strcat(endStr, "end");
while(1) {
++finishCheckFlag;
tok = &tok[strlen(tok) + 1];
if(strchr(tok, ';')) strchr(tok, ';')[0] = '\0';
strcpy(tmpBuffer[tmpBufferFlag][++cnt2], tok);
if(!strncmp(tok, endStr, cnt + 3)) break;
if(finishCheckFlag >= 300) {
printf("line %d : unterminated function expected\n", cmdCnt);
exit(0);
}
}
}
parse(tmp);
tok = &tok[strlen(tok) + 1];
}
}
int blankLine(char *src) {
int i, flag = 0;
int len = strlen(src);
for(i = 0; i < len; ++i) {
if(src[i] != ' ' && src[i] != '\t' && src[i] != '\n')
return 0;
}
return 1;
}
char* trim(char *str) {
int len = strlen(str) - 1;
while(str[len] == '\n' || str[len] == '\t' || str[len] == ' ') str[len--] = '\0';
len = 0;
while(str[len] == '\n' || str[len] == '\t' || str[len] == ' ') ++len;
return &str[len];
}
char *cpyTrim(char *str) {
int len = strlen(str) - 1;
char src[512];
strcpy(src, str);
while(src[len] == '\n' || src[len] == '\t' || src[len] == ' ') src[len--] = '\0';
len = 0;
while(src[len] == '\n' || src[len] == '\t' || src[len] == ' ') ++len;
return &src[len];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment