summaryrefslogtreecommitdiff
path: root/src/runner
diff options
context:
space:
mode:
Diffstat (limited to 'src/runner')
-rw-r--r--src/runner/runner.c143
-rw-r--r--src/runner/runner.h11
2 files changed, 154 insertions, 0 deletions
diff --git a/src/runner/runner.c b/src/runner/runner.c
new file mode 100644
index 0000000..790e6c5
--- /dev/null
+++ b/src/runner/runner.c
@@ -0,0 +1,143 @@
+#include "runner.h"
+#include "compiler/ast-tree.h"
+#include "utils/log.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+bool runAstTree(AstTreeRoot *root) {
+ constexpr char MAIN_STR[] = "main";
+ constexpr size_t MAIN_STR_SIZE =
+ (sizeof(MAIN_STR) / sizeof(*MAIN_STR)) - sizeof(*MAIN_STR);
+ for (size_t i = 0; i < root->variables.size; ++i) {
+ AstTreeVariable *variable = root->variables.data[i];
+ size_t name_size = variable->name_end - variable->name_begin;
+ if (name_size == MAIN_STR_SIZE &&
+ strncmp(variable->name_begin, MAIN_STR, MAIN_STR_SIZE) == 0 &&
+ variable->value->token == AST_TREE_TOKEN_FUNCTION) {
+
+ AstTree *main = variable->value;
+ AstTreeFunction *mainFunction = main->metadata;
+ return runAstTreeFunction(mainFunction) == &AST_TREE_VOID_VALUE;
+ }
+ }
+ printLog("main function is not found");
+ return false;
+}
+
+AstTree *runAstTreeFunction(AstTreeFunction *function) {
+ for (size_t i = 0; i < function->scope.expressions_size; ++i) {
+ AstTree expr = function->scope.expressions[i];
+ switch (expr.token) {
+ case AST_TREE_TOKEN_KEYWORD_PRINT_U64: {
+ AstTreeSingleChild *metadata = expr.metadata;
+ AstTree *tree = calcAstTreeValue(metadata);
+ printf("%ld", (AstTreeU64)tree->metadata);
+ astTreeDelete(tree);
+ }
+ continue;
+ case AST_TREE_TOKEN_FUNCTION_CALL: {
+ AstTree *ret = calcAstTreeValue(&expr);
+ if (ret != &AST_TREE_VOID_VALUE) {
+ astTreeDelete(ret);
+ }
+ }
+ continue;
+ case AST_TREE_TOKEN_OPERATOR_ASSIGN: {
+ AstTreeInfix *metadata = expr.metadata;
+ if (metadata->left.token == AST_TREE_TOKEN_VARIABLE) {
+ AstTreeVariable *left = metadata->left.metadata;
+ astTreeDelete(left->value);
+ left->value = calcAstTreeValue(&metadata->right);
+ } else {
+ UNREACHABLE;
+ }
+ }
+ continue;
+ case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_FUNCTION:
+ case AST_TREE_TOKEN_TYPE_TYPE:
+ case AST_TREE_TOKEN_TYPE_FUNCTION:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_U64:
+ case AST_TREE_TOKEN_VARIABLE:
+ case AST_TREE_TOKEN_VARIABLE_DEFINE:
+ case AST_TREE_TOKEN_VALUE_U64:
+ case AST_TREE_TOKEN_NONE:
+ }
+ printLog("%d", expr.token);
+ UNREACHABLE;
+ }
+
+ return &AST_TREE_VOID_VALUE;
+}
+
+AstTree *calcAstTreeValue(AstTree *tree) {
+ switch (tree->token) {
+ case AST_TREE_TOKEN_VALUE_U64: {
+ return deepCopyAstTree(tree);
+ }
+ case AST_TREE_TOKEN_VARIABLE: {
+ AstTreeVariable *variable = tree->metadata;
+ return calcAstTreeValue(variable->value);
+ }
+ case AST_TREE_TOKEN_FUNCTION_CALL: {
+ AstTreeFunctionCall *metadata = tree->metadata;
+ if (metadata->parameters_size != 0) {
+ UNREACHABLE;
+ } else if (metadata->function->token == AST_TREE_TOKEN_VARIABLE) {
+ AstTreeVariable *variable = metadata->function->metadata;
+ return runAstTreeFunction(variable->value->metadata);
+ } else {
+ UNREACHABLE;
+ }
+ }
+ case AST_TREE_TOKEN_OPERATOR_SUM: {
+ AstTreeInfix *metadata = tree->metadata;
+ AstTree *left = calcAstTreeValue(&metadata->left);
+ AstTree *right = calcAstTreeValue(&metadata->right);
+
+ if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
+ if (left->token == AST_TREE_TOKEN_VALUE_U64 &&
+ right->token == AST_TREE_TOKEN_VALUE_U64) {
+ left->metadata =
+ (void *)((AstTreeU64)left->metadata + (AstTreeU64)right->metadata);
+ astTreeDelete(right);
+ return left;
+ } else {
+ UNREACHABLE;
+ }
+ }
+ }
+ case AST_TREE_TOKEN_FUNCTION:
+ case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_TYPE_TYPE:
+ case AST_TREE_TOKEN_TYPE_FUNCTION:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_U64:
+ case AST_TREE_TOKEN_VARIABLE_DEFINE:
+ case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_NONE:
+ }
+ UNREACHABLE;
+}
+
+AstTree *deepCopyAstTree(AstTree *tree) {
+ switch (tree->token) {
+ case AST_TREE_TOKEN_VALUE_U64:
+ return newAstTree(tree->token, tree->metadata, copyAstTree(tree->type));
+ case AST_TREE_TOKEN_VARIABLE:
+ case AST_TREE_TOKEN_FUNCTION:
+ case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_TYPE_TYPE:
+ case AST_TREE_TOKEN_TYPE_FUNCTION:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_U64:
+ case AST_TREE_TOKEN_FUNCTION_CALL:
+ case AST_TREE_TOKEN_VARIABLE_DEFINE:
+ case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_NONE:
+ }
+ UNREACHABLE;
+}
diff --git a/src/runner/runner.h b/src/runner/runner.h
new file mode 100644
index 0000000..f143cbc
--- /dev/null
+++ b/src/runner/runner.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "compiler/ast-tree.h"
+#include <stdint.h>
+
+bool runAstTree(AstTreeRoot *root);
+
+AstTree *runAstTreeFunction(AstTreeFunction *function);
+
+AstTree *calcAstTreeValue(AstTree *tree);
+AstTree *deepCopyAstTree(AstTree *tree);