summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-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
4 files changed, 174 insertions, 6 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);