diff --git a/src/main.c b/src/main.c index 103525c..e83403c 100644 --- a/src/main.c +++ b/src/main.c @@ -4,7 +4,7 @@ #include "parser.h" #include "syntax.h" #include "printtree.h" - +#include "process.h" int main(int argc, char *argv[]) { FILE *file; @@ -25,6 +25,10 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Error during parsing.\n"); return 1; } + printf("Parsed: \n"); + printtree(code,0); + printf("\nProcessed: \n"); + process(code, NULL); printtree(code,0); se_free(code); code = NULL; diff --git a/src/parser.c b/src/parser.c index 46b92cd..0c15e4e 100644 --- a/src/parser.c +++ b/src/parser.c @@ -3,13 +3,16 @@ #include #include +#ifdef DEBUG +#include "printtree.h" +#endif #include "parser.h" #include "extstring.h" tSyntaxElement* parse(FILE* file) { tSyntaxElement* syntaxtree = se_create(); tSyntaxElement* syntaxtreestart = syntaxtree; - syntaxtree->type = TREE; + syntaxtree->type = NEWTREE; char symbol; bool intree = false; bool incomment = false; @@ -19,6 +22,13 @@ tSyntaxElement* parse(FILE* file) { tExtstring* extstring = NULL; while (1) { symbol = fgetc(file); + #ifdef DEBUG + if (!isspace(symbol)) + printf("In parsing. Current symbol: %c\n", symbol); + else + printf("In parsing. Current symbol: %d\n", symbol); + printtree(syntaxtreestart, 0); + #endif if (feof(file)) break; if (incomment) { @@ -27,6 +37,7 @@ tSyntaxElement* parse(FILE* file) { continue; } if (instring) { + syntaxtree = se_next(syntaxtree); if (symbol == '"') { if (extstring == NULL) { extstring = malloc(sizeof(tExtstring)); @@ -38,7 +49,6 @@ tSyntaxElement* parse(FILE* file) { syntaxtree->content = string; es_free(extstring); extstring = NULL; - syntaxtree = se_next(syntaxtree); } else { if (extstring == NULL) { extstring = malloc(sizeof(tExtstring)); @@ -51,6 +61,7 @@ tSyntaxElement* parse(FILE* file) { continue; } if (intoken) { + syntaxtree = se_next(syntaxtree); if (isspace(symbol) || symbol == '(' || symbol == ')') { intoken = false; syntaxtree->type = TOKEN; @@ -58,7 +69,6 @@ tSyntaxElement* parse(FILE* file) { syntaxtree->content = string; es_free(exttoken); exttoken = NULL; - syntaxtree = se_next(syntaxtree); } else { es_addsymbol(exttoken, symbol); continue; @@ -69,19 +79,15 @@ tSyntaxElement* parse(FILE* file) { if (intree) { switch (symbol) { case '(': + syntaxtree = se_next(syntaxtree); + syntaxtree->type = TREE; syntaxtree = se_bottom(syntaxtree); + syntaxtree->type = NEWTREE; break; case ')': - if (syntaxtree->top->type == TREE) { + syntaxtree = syntaxtree->top; + if (syntaxtree->top == NULL) intree = false; - syntaxtree = syntaxtree->top; - syntaxtree = se_next(syntaxtree); - syntaxtree->type = NONE; - } else { - syntaxtree = syntaxtree->top; - syntaxtree = se_next(syntaxtree); - syntaxtree->type = TREE; - } break; case ';': incomment = true; @@ -107,9 +113,10 @@ tSyntaxElement* parse(FILE* file) { continue; case '(': intree = true; + syntaxtree = se_next(syntaxtree); syntaxtree->type = TREE; syntaxtree = se_bottom(syntaxtree); - syntaxtree->type = TREE; + syntaxtree->type = NEWTREE; continue; default: fprintf(stderr, "Expression outside of brackets.\n"); @@ -121,6 +128,5 @@ tSyntaxElement* parse(FILE* file) { fprintf(stderr, "Unexpected EOF.\n"); return NULL; } - se_clean(syntaxtreestart); return syntaxtreestart; } diff --git a/src/printtree.c b/src/printtree.c index cb01238..84edae0 100644 --- a/src/printtree.c +++ b/src/printtree.c @@ -2,6 +2,7 @@ #include #include "syntax.h" +#include "printtree.h" void printtree(tSyntaxElement* syntaxtree, int depth) { if (syntaxtree == NULL) @@ -19,13 +20,12 @@ void printtree(tSyntaxElement* syntaxtree, int depth) { case STRING: printf("STRING: %s\n", (char*)syntaxtree->content); break; - case NUMBER: - // TODO: printtree NUMBER - fprintf(stderr,"TODO: printtree NUMBER\n"); - exit(1); case NONE: printf("NONE\n"); break; + case NEWTREE: + printf("NEWTREE\n"); + break; } if (syntaxtree->next != NULL) printtree(syntaxtree->next, depth); diff --git a/src/printtree.h b/src/printtree.h index 899e49a..27221de 100644 --- a/src/printtree.h +++ b/src/printtree.h @@ -1,2 +1,2 @@ #include "parser.h" -void printtree(tSyntaxElement* syntaxtree, int depth); +void printtree(tSyntaxElement*, int); diff --git a/src/process.c b/src/process.c new file mode 100644 index 0000000..7699273 --- /dev/null +++ b/src/process.c @@ -0,0 +1,52 @@ +#include +#include +#include + +#include "syntax.h" +#include "process.h" + +void process(tSyntaxElement* tree, tProcessingData* pdata) { + tProcessingData* pd = pdata; + bool deffound = false; + if (pd == NULL) { + pd = calloc(1,sizeof(tProcessingData)); + } + if (se_istraversable(tree)) + if (((tSyntaxElement*)tree->content)->type == TOKEN && ((tSyntaxElement*)tree->content)->next != NULL) { + tSyntaxElement* token = (tSyntaxElement*)tree->content; + if (strcmp((char*)token->content,"def") == 0) { + char* replacethis = token->next->content; + tSyntaxElement* replacewiththis = token->next->next; + tProcessingData* npd = malloc(sizeof(tSyntaxElement)); + npd->replacethis = replacethis; + npd->replacewiththis = replacewiththis; + npd->prev = pd; + pd = npd; + deffound = true; + } + } + if (tree->next != NULL) { + process(tree->next, pd); + } + if (!deffound) { + if (se_istraversable(tree)) { + process((tSyntaxElement*)tree->content, pd); + } + while (1) { + if (pd->replacethis == NULL) + break; + // Да блядь. + if (tree->type == TOKEN) + if (strcmp(tree->content, pd->replacethis) == 0) { + free(tree->content); + tSyntaxElement* clone = se_clone_no_next(pd->replacewiththis, tree); + tree->content = clone->content; + tree->type = clone->type; + } + if (pd->prev != NULL) + pd = pd->prev; + else + break; + } + } +} diff --git a/src/process.h b/src/process.h new file mode 100644 index 0000000..881802c --- /dev/null +++ b/src/process.h @@ -0,0 +1,10 @@ +#include +#include "syntax.h" + +typedef struct ProcessingData { + struct ProcessingData* prev; + char* replacethis; + tSyntaxElement* replacewiththis; +} tProcessingData; + +void process(tSyntaxElement*, tProcessingData*); diff --git a/src/syntax.c b/src/syntax.c index 91560ec..b3758f8 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -1,4 +1,5 @@ #include +#include #include "syntax.h" @@ -23,9 +24,13 @@ tSyntaxElement* se_bottom(tSyntaxElement* syntaxelement) { } tSyntaxElement* se_next(tSyntaxElement* syntaxelement) { - syntaxelement->next = se_create(); - syntaxelement->next->top = syntaxelement->top; - return syntaxelement->next; + if (syntaxelement->type != NEWTREE) { + syntaxelement->next = se_create(); + syntaxelement->next->top = syntaxelement->top; + return syntaxelement->next; + } else { + return syntaxelement; + } } void se_free(tSyntaxElement* syntaxtree) { @@ -48,29 +53,45 @@ void se_free(tSyntaxElement* syntaxtree) { free(syntaxtree); } -// Remove NONEs from the syntax tree. -void se_clean(tSyntaxElement* syntaxtree) { - if (syntaxtree->next != NULL) { - switch (syntaxtree->next->type) { - case NONE: - free(syntaxtree->next); - syntaxtree->next = NULL; - break; - default: - se_clean(syntaxtree->next); - break; - } - } - if (syntaxtree->content != NULL && (syntaxtree->type == TREE)) { - switch (((tSyntaxElement*)syntaxtree->content)->type) { - case NONE: - free(syntaxtree->content); - syntaxtree->content = NULL; - break; - default: - se_clean((tSyntaxElement*)syntaxtree->content); - break; - } +tSyntaxElement* se_clone(tSyntaxElement* syntaxelement, tSyntaxElement* newtop) { + tSyntaxElement* clone = NULL; + switch (syntaxelement->type) { + case TREE: + clone = se_create(); + clone->type = TREE; + if (syntaxelement->content != NULL) + clone->content = se_clone(syntaxelement->content, clone); + if (syntaxelement->next != NULL) + clone->next = se_clone(syntaxelement->next, newtop); + break; + case TOKEN: + case STRING: + clone = se_create(); + clone->type = syntaxelement->type; + clone->content = malloc(strlen(syntaxelement->content)); + strcpy(clone->content, syntaxelement->content); + if (syntaxelement->next != NULL) + clone->next = se_clone(syntaxelement->next, newtop); + break; + case NONE: + case NEWTREE: + clone = se_create(); + clone->type = syntaxelement->type; + clone->top = newtop; + if (syntaxelement->next != NULL) + clone->next = se_clone(syntaxelement->next, newtop); + break; } + return clone; } +tSyntaxElement* se_clone_no_next(tSyntaxElement* syntaxelement, tSyntaxElement* newtop) { + tSyntaxElement* se = malloc(sizeof(tSyntaxElement)); + se->content = syntaxelement->content; + se->top = syntaxelement->top; + se->type = syntaxelement->type; + se->next = NULL; + tSyntaxElement* clone = se_clone(se, newtop); + free(se); + return clone; +} diff --git a/src/syntax.h b/src/syntax.h index 099f331..7a17636 100644 --- a/src/syntax.h +++ b/src/syntax.h @@ -3,10 +3,10 @@ #include enum SyntaxElementType { + NEWTREE, TREE, TOKEN, STRING, - NUMBER, NONE }; @@ -17,11 +17,12 @@ typedef struct SyntaxElement { struct SyntaxElement* top; } tSyntaxElement; -void se_clean(tSyntaxElement* syntaxtree); -bool se_istraversable(tSyntaxElement* syntaxtree); +void se_free(tSyntaxElement*); +bool se_istraversable(tSyntaxElement*); tSyntaxElement* se_create(void); tSyntaxElement* se_init(void); -tSyntaxElement* se_bottom(tSyntaxElement* syntaxelement); -tSyntaxElement* se_next(tSyntaxElement* syntaxelement); -void se_free(tSyntaxElement* syntaxtree); +tSyntaxElement* se_bottom(tSyntaxElement*); +tSyntaxElement* se_next(tSyntaxElement*); +tSyntaxElement* se_clone(tSyntaxElement*, tSyntaxElement*); +tSyntaxElement* se_clone_no_next(tSyntaxElement*, tSyntaxElement*); #endif