summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/ast-tree.c145
-rw-r--r--src/compiler/ast-tree.h16
-rw-r--r--src/compiler/parser.c18
-rw-r--r--src/compiler/parser.h1
-rw-r--r--src/main.c61
-rw-r--r--src/runner/runner.c31
-rw-r--r--src/runner/runner.h2
7 files changed, 198 insertions, 76 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 16b2682..c93b477 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -5,8 +5,10 @@
#include "utils/log.h"
#include "utils/memory.h"
#include "utils/string.h"
+#include "utils/type.h"
#include <stddef.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
AstTree AST_TREE_TYPE_TYPE = {
@@ -177,6 +179,12 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
const char *AST_TREE_BUILTIN_TOKEN_STRINGS[] = {
"cast",
"typeOf",
+ "import",
+};
+
+AstTreeRoots AST_TREE_ROOTS_ERROR = {
+ .data = NULL,
+ .size = -1ULL,
};
void astTreePrint(const AstTree *tree, int indent) {
@@ -823,6 +831,13 @@ void astTreeRootDelete(AstTreeRoot *root) {
free(root);
}
+void astTreeRootsDestroy(AstTreeRoots roots) {
+ for (size_t i = 0; i < roots.size; ++i) {
+ astTreeRootDelete(roots.data[i]);
+ }
+ free(roots.data);
+}
+
AstTree *newAstTree(AstTreeToken token, void *metadata, AstTree *type,
char *str_begin, char *str_end) {
AstTree *result = a404m_malloc(sizeof(*result));
@@ -1243,7 +1258,120 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables,
return result;
}
-AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
+AstTreeRoots makeAstTree(const char *filePath) {
+ size_t parserNodes_capacity = 1;
+ ParserNode **parserNodes =
+ a404m_malloc(parserNodes_capacity * sizeof(*parserNodes));
+ size_t parserNodes_size = 1;
+
+ parserNodes[0] = parserFromPath(filePath);
+
+ size_t roots_size = 0;
+ AstTreeRoots roots = {
+ .data = a404m_malloc(roots_size * sizeof(*roots.data)),
+ .size = 0,
+ };
+
+ for (size_t i = 0; i < parserNodes_size; ++i) {
+ ParserNode *parserNode = parserNodes[i];
+ AstTreeRoot *root = makeAstRoot(parserNode);
+ if (root == NULL) {
+ goto RETURN_ERROR;
+ }
+ for (size_t i = 0; i < root->trees.size; ++i) {
+ AstTree *tree = root->trees.data[i];
+ if (tree->token == AST_TREE_TOKEN_FUNCTION_CALL) {
+ AstTreeFunctionCall *tree_metadata = tree->metadata;
+ AstTree *operand = tree_metadata->function;
+ if (operand->token == AST_TREE_TOKEN_BUILTIN) {
+ AstTreeBuiltin *operand_metadata = operand->metadata;
+ if (operand_metadata->token == AST_TREE_BUILTIN_TOKEN_IMPORT) {
+ if (tree_metadata->parameters_size != 1) {
+ printError(tree->str_begin, tree->str_end,
+ "Too many or too few arguments");
+ goto RETURN_ERROR;
+ }
+ AstTreeSetTypesHelper helper = {
+ .lookingType = NULL,
+ .dependencies.data = NULL,
+ .dependencies.size = 0,
+ .variables = root->variables,
+ };
+ if (!setAllTypes(tree, helper, NULL, NULL)) {
+ goto RETURN_ERROR;
+ }
+ AstTree *parameter = tree_metadata->parameters[0].value;
+ if (!isConstByValue(parameter)) {
+ printError(parameter->str_begin, parameter->str_end,
+ "Is not constant");
+ goto RETURN_ERROR;
+ }
+ parameter = getValue(parameter);
+ if (parameter == NULL) {
+ goto RETURN_ERROR;
+ }
+
+ AstTreeBracket *type_metadata =
+ a404m_malloc(sizeof(*type_metadata));
+ type_metadata->operand = &AST_TREE_U8_TYPE;
+
+ type_metadata->parameters.size = 0;
+ type_metadata->parameters.data =
+ a404m_malloc(0 * sizeof(*type_metadata->parameters.data));
+
+ AstTree *type = newAstTree(AST_TREE_TOKEN_TYPE_ARRAY, type_metadata,
+ &AST_TREE_TYPE_TYPE, NULL, NULL);
+
+ if (!typeIsEqual(type, parameter->type)) {
+ printError(parameter->str_begin, parameter->str_end,
+ "Type mismatch (must be a []u8 aka string)");
+ goto RETURN_ERROR;
+ }
+
+ char *str = u8ArrayToCString(parameter);
+
+ const size_t imported_size =
+ a404m_malloc_usable_size(root->imported) /
+ sizeof(*root->imported);
+ if (imported_size == root->imported_size) {
+ root->imported = a404m_realloc(
+ root->imported, (imported_size + imported_size / 2 + 1) *
+ sizeof(*root->imported));
+ }
+ root->imported[root->imported_size++] = str;
+
+ astTreeDelete(type);
+ }
+ }
+ }
+ }
+
+ if (roots_size == roots.size) {
+ roots_size += roots_size / 2 + 13;
+ roots.data = a404m_realloc(roots.data, roots_size);
+ }
+ roots.data[roots.size++] = root;
+ }
+
+ for (size_t i = 0; i < roots.size; ++i) {
+ AstTreeRoot *root = roots.data[i];
+ if (!setAllTypesRoot(root)) {
+ goto RETURN_ERROR;
+ }
+ }
+
+ for (size_t i = 0; i < parserNodes_size; ++i) {
+ parserNodeDelete(parserNodes[i]);
+ }
+ free(parserNodes);
+
+ return roots;
+
+RETURN_ERROR:
+ return AST_TREE_ROOTS_ERROR;
+}
+
+AstTreeRoot *makeAstRoot(ParserNode *parsedRoot) {
if (parsedRoot->token != PARSER_TOKEN_ROOT) {
return NULL;
}
@@ -1255,6 +1383,8 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
root->variables.data =
a404m_malloc(nodes->size * sizeof(*root->variables.data));
root->variables.size = 0;
+ root->imported = a404m_malloc(0 * sizeof(*root->imported));
+ root->imported_size = 0;
AstTreeVariables *variables = &root->variables;
static const size_t variables_size = 1;
@@ -1450,10 +1580,6 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
}
}
- if (!setAllTypesRoot(root)) {
- goto RETURN_ERROR;
- }
-
return root;
RETURN_ERROR:
@@ -4712,3 +4838,12 @@ bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper _helper) {
return setAllTypes(infix->right, helper, NULL, NULL);
}
+
+char *u8ArrayToCString(AstTree *tree) {
+ AstTreeObject *object = tree->metadata;
+ char *str = a404m_malloc((object->variables.size + 1) * sizeof(*str));
+ for (size_t i = 0; i < object->variables.size; ++i) {
+ str[i] = *(AstTreeInt *)object->variables.data[i]->value->metadata;
+ }
+ return str;
+}
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 0360f7e..300be41 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -128,8 +128,17 @@ typedef struct AstTrees {
typedef struct AstTreeRoot {
AstTreeVariables variables;
AstTrees trees;
+ char **imported;
+ size_t imported_size;
} AstTreeRoot;
+typedef struct AstTreeRoots {
+ AstTreeRoot **data;
+ size_t size;
+} AstTreeRoots;
+
+extern AstTreeRoots AST_TREE_ROOTS_ERROR;
+
typedef struct AstTreeScope {
AstTreeVariables variables;
AstTree **expressions;
@@ -237,6 +246,7 @@ typedef struct AstTreeBracket {
typedef enum AstTreeBuiltinToken {
AST_TREE_BUILTIN_TOKEN_CAST,
AST_TREE_BUILTIN_TOKEN_TYPE_OF,
+ AST_TREE_BUILTIN_TOKEN_IMPORT,
AST_TREE_BUILTIN_TOKEN__SIZE__,
} AstTreeBuiltinToken;
@@ -256,6 +266,7 @@ void astTreeVariableDelete(AstTreeVariable *variable);
void astTreeDelete(AstTree *tree);
bool astTreeShouldDelete(AstTree *tree);
void astTreeRootDelete(AstTreeRoot *root);
+void astTreeRootsDestroy(AstTreeRoots roots);
AstTree *newAstTree(AstTreeToken token, void *metadata, AstTree *type,
char *str_begin, char *str_end);
@@ -268,7 +279,8 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables,
AstTreeVariables newVariables[],
size_t variables_size);
-AstTreeRoot *makeAstTree(ParserNode *parsedRoot);
+AstTreeRoots makeAstTree(const char *filePath);
+AstTreeRoot *makeAstRoot(ParserNode *parsedRoot);
bool pushVariable(AstTreeHelper *helper, AstTreeVariables *variables,
AstTreeVariable *variable);
@@ -368,3 +380,5 @@ bool setTypesArrayAccess(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesAstVariable(AstTreeVariable *variable,
AstTreeSetTypesHelper helper);
bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper);
+
+char *u8ArrayToCString(AstTree *tree);
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index f5009e5..f0d3e9b 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -1,6 +1,7 @@
#include "parser.h"
#include "compiler/lexer.h"
+#include "utils/file.h"
#include "utils/log.h"
#include "utils/memory.h"
#include "utils/string.h"
@@ -667,6 +668,23 @@ ParserNode *newParserNode(ParserToken token, char *str_begin, char *str_end,
return parserNode;
}
+ParserNode *parserFromPath(const char *filePath) {
+ char *code = readWholeFile(filePath);
+ if (code == NULL) {
+ return NULL;
+ }
+
+ LexerNodeArray lexed = lexer(code);
+ if (lexerNodeArrayIsError(lexed)) {
+ return NULL;
+ }
+
+ ParserNode *root = parser(lexed);
+ lexerNodeArrayDestroy(lexed);
+
+ return root;
+}
+
ParserNode *parser(LexerNodeArray lexed) {
ParserNode *root = newParserNode(PARSER_TOKEN_ROOT, NULL, NULL, NULL, NULL);
if (parserNodeArray(lexed.data, lexed.data + lexed.size, root)) {
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index 326849b..ecc6159 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -175,6 +175,7 @@ typedef struct ParserNodeBracketMetadata {
void parserNodePrint(const ParserNode *node, int indent);
void parserNodeDelete(ParserNode *node);
+ParserNode *parserFromPath(const char *filePath);
ParserNode *parser(LexerNodeArray lexed);
bool parserNodeArray(LexerNode *begin, LexerNode *end, ParserNode *parent);
diff --git a/src/main.c b/src/main.c
index 04640af..fad415b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,3 +1,4 @@
+#include "compiler/ast-tree.h"
#include "runner/runner.h"
#include "utils/file.h"
#include "utils/log.h"
@@ -34,52 +35,16 @@ static void printTime(struct timespec time) {
}
#endif
-static int runWithoutRead(char *code) {
+static int run(const char *filePath) {
#ifdef PRINT_STATISTICS
struct timespec start, end;
- struct timespec lexTime;
- struct timespec parseTime;
struct timespec astTime;
struct timespec runTime;
struct timespec totalTime = {0};
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
#endif
- LexerNodeArray lexed = lexer(code);
- if (lexerNodeArrayIsError(lexed)) {
- return 1;
- }
-#ifdef PRINT_STATISTICS
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
- lexTime = diff(end, start);
- totalTime = add(totalTime, lexTime);
-#endif
-#ifdef PRINT_COMPILE_TREE
- lexerNodeArrayPrint(lexed);
-#endif
-#ifdef PRINT_STATISTICS
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
-#endif
-
- ParserNode *parsedRoot = parser(lexed);
- lexerNodeArrayDestroy(lexed);
- if (parsedRoot == NULL) {
- return 1;
- }
-#ifdef PRINT_STATISTICS
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
- parseTime = diff(end, start);
- totalTime = add(totalTime, parseTime);
-#endif
-#ifdef PRINT_COMPILE_TREE
- parserNodePrint(parsedRoot, 0);
-#endif
-#ifdef PRINT_STATISTICS
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
-#endif
-
- AstTreeRoot *astTree = makeAstTree(parsedRoot);
- parserNodeDelete(parsedRoot);
- if (astTree == NULL) {
+ AstTreeRoots astTrees = makeAstTree(filePath);
+ if (astTrees.size == AST_TREE_ROOTS_ERROR.size) {
return 1;
}
#ifdef PRINT_STATISTICS
@@ -95,12 +60,12 @@ static int runWithoutRead(char *code) {
#endif
int ret;
- if (runAstTree(astTree)) {
+ if (runAstTree(astTrees)) {
ret = 0;
} else {
ret = 1;
}
- astTreeRootDelete(astTree);
+ astTreeRootsDestroy(astTrees);
#ifdef PRINT_STATISTICS
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
runTime = diff(end, start);
@@ -108,10 +73,6 @@ static int runWithoutRead(char *code) {
#endif
#ifdef PRINT_STATISTICS
- printf("----\nlexTime: ");
- printTime(lexTime);
- printf("\nparseTime: ");
- printTime(parseTime);
printf("\nastTime: ");
printTime(astTime);
printf("\nrunTime: ");
@@ -124,16 +85,6 @@ static int runWithoutRead(char *code) {
return ret;
}
-static int run(const char *filePath) {
- char *code = readWholeFile(filePath);
-
- if (code == NULL) {
- return 1;
- }
-
- return runWithoutRead(code);
-}
-
int main(int argc, char *argv[]) {
fileInit();
diff --git a/src/runner/runner.c b/src/runner/runner.c
index 7d1879d..b96f1a8 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -40,27 +40,30 @@ void runnerVariableSetValueWihtoutConstCheck(AstTreeVariable *variable,
variable->value = value;
}
-bool runAstTree(AstTreeRoot *root) {
+bool runAstTree(AstTreeRoots roots) {
static const char MAIN_STR[] = "main";
static const size_t MAIN_STR_SIZE =
(sizeof(MAIN_STR) / sizeof(*MAIN_STR)) - sizeof(*MAIN_STR);
AstTreeVariable *mainVariable = NULL;
- 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->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) {
- if (mainVariable != NULL) {
- printLog("Too many main variables");
- return false;
+ for (size_t i = 0; i < roots.size; ++i) {
+ AstTreeRoot *root = roots.data[i];
+ 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->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) {
+ if (mainVariable != NULL) {
+ printLog("Too many main variables");
+ return false;
+ }
+ mainVariable = variable;
+ }
+ if (!variable->isConst) {
+ runnerVariableSetValueWihtoutConstCheck(variable, variable->initValue);
}
- mainVariable = variable;
- }
- if (!variable->isConst) {
- runnerVariableSetValueWihtoutConstCheck(variable, variable->initValue);
}
}
diff --git a/src/runner/runner.h b/src/runner/runner.h
index eef0d40..12ee241 100644
--- a/src/runner/runner.h
+++ b/src/runner/runner.h
@@ -7,7 +7,7 @@ void runnerVariableSetValue(AstTreeVariable *variable, AstTree *value);
void runnerVariableSetValueWihtoutConstCheck(AstTreeVariable *variable,
AstTree *value);
-bool runAstTree(AstTreeRoot *root);
+bool runAstTree(AstTreeRoots roots);
AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments,
size_t arguments_size);