#include #include #include #include "syntax.h" void string_append(char** string, char* append) { int len = strlen(*string); *string = realloc(*string, len + strlen(append) + sizeof(char)); strcpy(*string + len, append); } void compile_enter_tag(char** string) { int len = strlen(*string); *string = realloc(*string, len + 3 * sizeof(char)); string[0][len + 0] = '{'; string[0][len + 1] = '%'; string[0][len + 2] = '\0'; } void compile_exit_tag(char** string) { int len = strlen(*string); *string = realloc(*string, len + 3 * sizeof(char)); string[0][len + 0] = '%'; string[0][len + 1] = '}'; string[0][len + 2] = '\0'; } bool compile_isop(char* string) { if (strcmp(string, "+") == 0) return true; else if (strcmp(string, "-") == 0) return true; else if (strcmp(string, "*") == 0) return true; else if (strcmp(string, "/") == 0) return true; else if (strcmp(string, "**") == 0) return true; else if (strcmp(string, "//") == 0) return true; else if (strcmp(string, "%") == 0) return true; else if (strcmp(string, ".") == 0) return true; else if (strcmp(string, "~") == 0) return true; else if (strcmp(string, "<") == 0) return true; else if (strcmp(string, ">") == 0) return true; else if (strcmp(string, "<=") == 0) return true; else if (strcmp(string, ">=") == 0) return true; else if (strcmp(string, "==") == 0) return true; else if (strcmp(string, "!=") == 0) return true; else if (strcmp(string, "and") == 0) return true; else if (strcmp(string, "or") == 0) return true; else if (strcmp(string, "|") == 0) return true; else return false; } char* compile_bracket_wrap(char* string) { char* new = malloc(sizeof(char)); new[0] = '\0'; string_append(&new,"("); string_append(&new,string); string_append(&new,")"); free(string); return new; } char* compile_expression(tSyntaxElement* syntaxelement); char* compile_expression_wrapped(tSyntaxElement* syntaxelement) { return compile_bracket_wrap(compile_expression(syntaxelement)); } void compile_genexec(char** result, tSyntaxElement* se){ tSyntaxElement* token = se; string_append(result,"("); token = token->next; while (1) { if (token != NULL) { string_append(result,compile_expression(token)); if (token->next != NULL) string_append(result,","); token = token->next; } else break; } string_append(result,")"); } char* compile_expression(tSyntaxElement* syntaxelement) { char* result = calloc(1,sizeof(char)); switch (syntaxelement->type) { case TOKEN: string_append(&result, syntaxelement->content.string); break; case STRING: string_append(&result, "\""); string_append(&result, syntaxelement->content.string); string_append(&result, "\""); break; case TREE: if (se_istraversable(syntaxelement)) { switch (syntaxelement->content.syntax->type) { case TOKEN: { tSyntaxElement* token = syntaxelement->content.syntax; if (compile_isop(token->content.string)) { char* operator = token->content.string; while (1) { if (token->next != NULL) { if (token->next->type == TOKEN) string_append(&result,token->next->content.string); else string_append(&result,compile_expression_wrapped(token->next)); if (token->next->next != NULL) string_append(&result,operator); token = token->next; } else break; } } else { if (strcmp(token->content.string, "if") == 0) { string_append(&result,compile_expression_wrapped(token->next)); string_append(&result,"?"); string_append(&result,compile_expression_wrapped(token->next->next)); string_append(&result,":"); string_append(&result,compile_expression_wrapped(token->next->next->next)); } else if (strcmp(token->content.string, "get") == 0) { string_append(&result,compile_expression(token->next)); string_append(&result,"["); string_append(&result,compile_expression(token->next->next)); string_append(&result,"]"); } else if (strcmp(token->content.string, "neg") == 0) { string_append(&result,"-"); string_append(&result,compile_expression_wrapped(token->next)); } else if (strcmp(token->content.string, "not") == 0) { string_append(&result,"not"); string_append(&result,compile_expression_wrapped(token->next)); } else { string_append(&result,token->content.string); compile_genexec(&result, token); } } break; } case TREE: { tSyntaxElement* token = syntaxelement->content.syntax; string_append(&result, compile_expression(syntaxelement->content.syntax)); compile_genexec(&result, token); break; } case STRING: case NONE: case NEWTREE: return NULL; } } break; case NEWTREE: case NONE: free(result); return NULL; } return result; } char* compile(tSyntaxElement* syntaxtree) { char* result = calloc(1,sizeof(char)); while (1) { if (se_istraversable(syntaxtree)) { if (syntaxtree->content.syntax->type == TOKEN) { tSyntaxElement* token = syntaxtree->content.syntax; if (strcmp(token->content.string, "def") == 0) { } else if (strcmp(token->content.string, "set") == 0) { compile_enter_tag(&result); string_append(&result, "set "); string_append(&result,token->next->content.string); string_append(&result,"="); string_append(&result,compile_expression_wrapped(token->next->next)); compile_exit_tag(&result); } else if (strcmp(token->content.string, "global") == 0) { compile_enter_tag(&result); string_append(&result, "global "); string_append(&result,token->next->content.string); string_append(&result,"="); string_append(&result,compile_expression_wrapped(token->next->next)); compile_exit_tag(&result); } else if (strcmp(token->content.string, "do") == 0) { compile_enter_tag(&result); string_append(&result, "do "); string_append(&result,compile_expression(token->next)); compile_exit_tag(&result); } else if (strcmp(token->content.string, "if") == 0) { compile_enter_tag(&result); string_append(&result, "if "); string_append(&result,compile_expression(token->next)); compile_exit_tag(&result); string_append(&result,compile(token->next->next)); if (token->next->next->next != NULL) { compile_enter_tag(&result); string_append(&result, "else"); compile_exit_tag(&result); string_append(&result,compile(token->next->next->next)); } compile_enter_tag(&result); string_append(&result, "endif"); compile_exit_tag(&result); } else if (strcmp(token->content.string, "print") == 0) { string_append(&result, "{{"); string_append(&result,compile_expression(token->next)); string_append(&result, "}}"); } } } if (syntaxtree->next != NULL) syntaxtree = syntaxtree->next; else break; } return result; }