Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <vector>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <functional>
- typedef struct variable
- {
- char name[32];
- int value;
- } variable;
- char buffer[512];
- char raw[512];
- std::vector<variable *> variables;
- bool error;
- bool ret;
- int E();
- int T(const char *);
- void parseCode(FILE *f = stdin, const char *prefix = NULL);
- void removeCharacter(char c)
- {
- std::string str = buffer;
- str.erase(std::remove_if(str.begin(), str.end(), std::bind2nd(std::equal_to<char>(), c)), str.end());
- strcpy(buffer, str.c_str());
- }
- void readInput(FILE *f)
- {
- if (f == stdin)
- {
- printf("> ");
- fflush(stdout);
- }
- fgets(buffer, 512, f);
- //trim all whitespace
- removeCharacter('\n');
- strcpy(raw, buffer);
- removeCharacter(' ');
- removeCharacter('\t');
- }
- void printVariables()
- {
- for (int i = 0; i < variables.size(); i++)
- {
- variable *v = variables.at(i);
- printf("%s\t=\t%d\n", v->name, v->value);
- }
- }
- variable *findVariable(const char *name)
- {
- for (int i = 0; i < variables.size(); i++)
- {
- variable *v = variables.at(i);
- if (!strcmp(name, v->name))
- return v;
- }
- return NULL;
- }
- bool deleteVariable(const char *name)
- {
- for (int i = 0; i < variables.size(); i++)
- {
- variable *v = variables.at(i);
- if (!strcmp(name, v->name))
- {
- variables.erase(variables.begin() + i);
- return true;
- }
- }
- return false;
- }
- bool S()
- {
- char *pch;
- if (!strcmp(buffer, ".done"))
- {
- ret = true;
- return true;
- }
- else if (!strcmp(buffer, ".print"))
- {
- printVariables();
- return true;
- }
- else if (strstr(buffer, ".echo(") == buffer)
- {
- char *tmp = strdup(raw + strlen(".echo("));
- if ((pch = strtok(tmp, ")")) != NULL)
- {
- printf("%s\n", pch);
- free(tmp);
- return true;
- }
- free(tmp);
- return false;
- }
- else if (strstr(buffer, ".print(") == buffer)
- {
- char *tmp = strdup(buffer + strlen(".print("));
- if ((pch = strtok(tmp, ")")) != NULL)
- {
- variable *v = findVariable(pch);
- if (v != NULL)
- {
- printf("%s\t=\t%d\n", v->name, v->value);
- free(tmp);
- return true;
- }
- }
- free(tmp);
- return false;
- }
- else if (strstr(buffer, ".input(") == buffer)
- {
- char *tmp = strdup(buffer + strlen(".input("));
- if ((pch = strtok(tmp, ")")) != NULL)
- {
- int val;
- printf("? ");
- fflush(stdout);
- if (scanf("%d", &val) > 0)
- {
- char *t = strdup(pch);
- variable *var = findVariable(t);
- if (var == NULL)
- {
- var = new variable;
- strcpy(var->name, t);
- variables.push_back(var);
- }
- var->value = val;
- free(tmp);
- free(t);
- return true;
- }
- }
- free(tmp);
- return false;
- }
- else if (strstr(buffer, ".call(") == buffer)
- {
- char *tmp = strdup(buffer + strlen(".call("));
- if ((pch = strtok(tmp, ")")) != NULL)
- {
- FILE *f = fopen(pch, "r");
- if (f == NULL)
- return false;
- parseCode(f, pch);
- return true;
- }
- return false;
- }
- else if (strstr(buffer, ".ifcall(") == buffer)
- {
- char *proc;
- char *tmp = strdup(buffer + strlen(".ifcall("));
- if ((pch = strtok(tmp, ",")) != NULL)
- {
- proc = strdup(pch);
- if ((pch = strtok(NULL, ")")) != NULL)
- {
- strcpy(buffer, pch);
- int val = E();
- if (!error)
- {
- if (!val)
- {
- FILE *f = fopen(proc, "r");
- if (f == NULL)
- goto ifcallsynerr;
- parseCode(f, proc);
- }
- goto ifcallgood;
- }
- }
- ifcallsynerr:
- free(proc);
- free(tmp);
- return false;
- }
- ifcallgood:
- free(proc);
- free(tmp);
- return true;
- }
- else if (strstr(buffer, ".delete(") == buffer)
- {
- char *tmp = strdup(buffer + strlen(".delete("));
- if ((pch = strtok(tmp, ")")) != NULL)
- {
- if (deleteVariable(pch))
- {
- free(tmp);
- return true;
- }
- }
- free(tmp);
- return false;
- }
- pch = strtok(buffer, "=");
- bool newvar = false;
- variable *var = findVariable(pch);
- if (var == NULL)
- {
- var = new variable;
- strcpy(var->name, pch);
- newvar = true;
- }
- if ((pch = strtok(NULL, "\0")) == NULL)
- {
- if (newvar)
- delete var;
- return false;
- }
- strcpy(buffer, pch);
- int val = E();
- if (!error)
- {
- var->value = val;
- if (newvar)
- variables.push_back(var);
- return true;
- }
- return false;
- }
- bool isConstant(const char *buf, int *v)
- {
- return sscanf(buf, "%d", v) > 0;
- }
- #define ERR() free(tmp); error = true; return 0;
- int E()
- {
- int val;
- char *pch;
- char *tmp, *t1, *t2;
- error = false;
- //T
- val = T(buffer);
- if (!error)
- return val;
- //T + T
- tmp = strdup(buffer);
- if ((pch = strtok(tmp, "+")) != NULL)
- {
- val = T(pch);
- if (error)
- {
- free(tmp);
- goto minus;
- }
- if ((pch = strtok(NULL, "\0")) != NULL)
- {
- val += T(pch);
- if (error) { ERR() }
- free(tmp);
- return val;
- }
- }
- //T - T
- minus:
- tmp = strdup(buffer);
- if ((pch = strtok(tmp, "-")) != NULL)
- {
- val = T(pch);
- if (error)
- {
- free(tmp);
- goto multiply;
- }
- if ((pch = strtok(NULL, "\0")) != NULL)
- {
- val -= T(pch);
- if (error) { ERR() }
- free(tmp);
- return val;
- }
- }
- //T * T
- multiply:
- tmp = strdup(buffer);
- if ((pch = strtok(tmp, "*")) != NULL)
- {
- val = T(pch);
- if (error)
- {
- free(tmp);
- goto divide;
- }
- if ((pch = strtok(NULL, "\0")) != NULL)
- {
- val *= T(pch);
- if (error) { ERR() }
- free(tmp);
- return val;
- }
- }
- //T / T
- divide:
- tmp = strdup(buffer);
- if ((pch = strtok(tmp, "/")) != NULL)
- {
- val = T(pch);
- if (error)
- {
- free(tmp);
- goto modulo;
- }
- if ((pch = strtok(NULL, "\0")) != NULL)
- {
- val /= T(pch);
- if (error) { ERR() }
- free(tmp);
- return val;
- }
- }
- //T % T
- modulo:
- tmp = strdup(buffer);
- if ((pch = strtok(tmp, "%")) != NULL)
- {
- val = T(pch);
- if (error)
- {
- ERR()
- }
- if ((pch = strtok(NULL, "\0")) != NULL)
- {
- val %= T(pch);
- if (error) { ERR() }
- free(tmp);
- return val;
- }
- }
- error = true;
- return 0;
- }
- #undef ERR
- int T(const char *buf)
- {
- int val = 0;
- variable *v = findVariable(buf);
- error = false;
- if (v != NULL)
- {
- return v->value;
- }
- else
- {
- if (isConstant(buf, &val))
- return val;
- }
- error = true;
- }
- void transferVariables(const std::vector<variable *> l, const char *_p)
- {
- char *p = new char[strlen(_p) + 3];
- sprintf(p, "%s.", _p);
- for (int i = 0; i < l.size(); i++)
- {
- variable *v = l.at(i);
- if (strstr(v->name, p) == v->name)
- {
- variable *tv;
- if ((tv = findVariable(v->name)) != NULL)
- tv->value = v->value;
- else
- variables.push_back(v);
- }
- }
- delete[] p;
- }
- void parseCode(FILE *f, const char *prefix)
- {
- std::vector<variable *> save;
- ret = false;
- if (f != stdin)
- {
- save = variables;
- variables.clear();
- transferVariables(save, prefix);
- }
- for (; !ret;)
- {
- readInput(f);
- if (strlen(buffer) == 0)
- {
- printf("\r \r");
- continue;
- }
- if (!S())
- {
- printf("ERROR!\t%s\n", raw);
- }
- }
- if (f != stdin)
- {
- std::vector<variable *> save2 = variables;
- variables.clear();
- variables = save;
- transferVariables(save2, prefix);
- }
- fclose(f);
- ret = false;
- }
- int main(int argc, char ** argv)
- {
- if (argc > 1)
- {
- FILE *f = fopen(argv[1], "r");
- parseCode(f);
- }
- else
- parseCode();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement