foxp/src/compile.c

288 lines
5.8 KiB
C
Raw Normal View History

2024-06-10 18:27:08 +00:00
#include <stdlib.h>
2024-06-10 21:40:36 +00:00
#include <stdbool.h>
2024-06-10 18:27:08 +00:00
#include <string.h>
#include "syntax.h"
2024-06-10 21:40:36 +00:00
void string_append(char** string, char* append) {
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
int len = strlen(*string);
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
*string = realloc(*string, len + strlen(append) + sizeof(char));
strcpy(*string + len, append);
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
}
2024-06-10 18:27:08 +00:00
void compile_enter_tag(char** string) {
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
int len = strlen(*string);
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
*string = realloc(*string, len + 3 * sizeof(char));
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
string[0][len + 0] = '{';
string[0][len + 1] = '%';
string[0][len + 2] = '\0';
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
}
void compile_exit_tag(char** string) {
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
int len = strlen(*string);
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
*string = realloc(*string, len + 3 * sizeof(char));
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
string[0][len + 0] = '%';
string[0][len + 1] = '}';
string[0][len + 2] = '\0';
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
}
2024-06-10 21:40:36 +00:00
bool compile_isop(char* string) {
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
if (strcmp(string, "+") == 0) return true;
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
else if (strcmp(string, "-") == 0) return true;
else if (strcmp(string, "*") == 0) return true;
else if (strcmp(string, "/") == 0) return true;
2024-06-10 21:45:45 +00:00
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;
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
else return false;
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
}
2024-06-10 22:55:11 +00:00
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,token->content.string);
if (token->next != NULL)
string_append(result,",");
token = token->next;
} else break;
}
string_append(result,")");
}
2024-06-10 21:40:36 +00:00
char* compile_expression(tSyntaxElement* syntaxelement) {
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
char* result = calloc(1,sizeof(char));
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
switch (syntaxelement->type) {
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
case TOKEN:
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
string_append(&result, syntaxelement->content.string);
break;
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
case STRING:
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
string_append(&result, "\"");
string_append(&result, syntaxelement->content.string);
string_append(&result, "\"");
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
break;
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
case TREE:
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
if (se_istraversable(syntaxelement)) {
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
switch (syntaxelement->content.syntax->type) {
case TOKEN: {
tSyntaxElement* token = syntaxelement->content.syntax;
if (compile_isop(token->content.string)) {
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
char* operator = token->content.string;
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
while (1) {
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
if (token->next != NULL) {
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
if (token->next->type == TOKEN)
string_append(&result,token->next->content.string);
else
string_append(&result,compile_expression_wrapped(token->next));
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
if (token->next->next != NULL)
string_append(&result,operator);
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
token = token->next;
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
} else break;
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
}
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
} else {
string_append(&result,token->content.string);
compile_genexec(&result, token);
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
}
2024-06-10 22:55:11 +00:00
break;
}
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
case TREE: {
tSyntaxElement* token = syntaxelement->content.syntax;
string_append(&result, compile_expression(syntaxelement->content.syntax));
compile_genexec(&result, token);
break;
2024-06-10 21:40:36 +00:00
}
2024-06-10 21:43:06 +00:00
2024-06-10 22:55:11 +00:00
case STRING:
case NONE:
case NEWTREE:
return NULL;
2024-06-10 21:40:36 +00:00
}
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
}
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
break;
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
case NEWTREE:
case NONE:
free(result);
return NULL;
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
}
2024-06-10 21:43:06 +00:00
2024-06-10 21:40:36 +00:00
return result;
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
}
char* compile(tSyntaxElement* syntaxtree) {
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
char* result = calloc(1,sizeof(char));
2024-06-10 21:43:06 +00:00
2024-06-10 21:53:49 +00:00
while (1) {
2024-06-10 21:43:06 +00:00
2024-06-10 21:53:49 +00:00
if (se_istraversable(syntaxtree)) {
2024-06-10 21:43:06 +00:00
2024-06-10 21:53:49 +00:00
if (syntaxtree->content.syntax->type == TOKEN) {
2024-06-10 21:43:06 +00:00
2024-06-10 21:53:49 +00:00
tSyntaxElement* token = syntaxtree->content.syntax;
2024-06-10 21:43:06 +00:00
2024-06-10 21:53:49 +00:00
if (strcmp(token->content.string, "def") == 0) {
} else
2024-06-10 21:43:06 +00:00
2024-06-10 21:53:49 +00:00
if (strcmp(token->content.string, "set") == 0) {
2024-06-10 21:43:06 +00:00
2024-06-10 21:53:49 +00:00
compile_enter_tag(&result);
2024-06-10 21:43:06 +00:00
2024-06-10 21:53:49 +00:00
string_append(&result, "set ");
string_append(&result,token->next->content.string);
string_append(&result,"=");
2024-06-10 22:55:11 +00:00
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));
2024-06-10 21:43:06 +00:00
2024-06-10 21:53:49 +00:00
compile_exit_tag(&result);
2024-06-10 21:51:37 +00:00
2024-06-10 21:53:49 +00:00
} else
2024-06-10 21:51:37 +00:00
2024-06-11 00:14:22 +00:00
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));
compile_enter_tag(&result);
string_append(&result, "endif");
compile_exit_tag(&result);
} else
2024-06-10 21:53:49 +00:00
if (strcmp(token->content.string, "print") == 0) {
string_append(&result, "{{");
string_append(&result,compile_expression(token->next));
string_append(&result, "}}");
}
2024-06-10 21:51:37 +00:00
2024-06-10 18:27:08 +00:00
}
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
}
2024-06-10 21:53:49 +00:00
if (syntaxtree->next != NULL)
syntaxtree = syntaxtree->next;
else break;
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
}
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
return result;
2024-06-10 21:43:06 +00:00
2024-06-10 18:27:08 +00:00
}