diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-09-25 19:47:29 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2024-09-25 19:47:29 +0330 |
commit | c409b8aaf6b6f63bd68a3356e146ab80b2ec8c4b (patch) | |
tree | 65ea5801fd910fc6bcff3f2e8f06b5fd7d249c78 | |
parent | f79290084948f3cf140395c270c07cf29ca58e8d (diff) |
fixed multiple variable definition bug
tried to implement import
-rw-r--r-- | README.md | 4 | ||||
-rwxr-xr-x | project | 1 | ||||
-rw-r--r-- | src/compiler/code_generator/code_generator.c | 6 | ||||
-rw-r--r-- | src/compiler/code_generator/code_generator.h | 6 | ||||
-rw-r--r-- | src/compiler/error_helper/error_helper.c | 22 | ||||
-rw-r--r-- | src/compiler/error_helper/error_helper.h | 3 | ||||
-rw-r--r-- | src/compiler/lexer/lexer.c | 18 | ||||
-rw-r--r-- | src/compiler/lexer/lexer.h | 2 | ||||
-rw-r--r-- | src/compiler/parser/parser.c | 102 | ||||
-rw-r--r-- | src/compiler/parser/parser.h | 36 | ||||
-rw-r--r-- | src/compiler/source_code/source_code.c | 57 | ||||
-rw-r--r-- | src/compiler/source_code/source_code.h | 24 | ||||
-rw-r--r-- | src/compiler/tree_parser/tree_parser.c | 211 | ||||
-rw-r--r-- | src/compiler/tree_parser/tree_parser.h | 55 | ||||
-rw-r--r-- | src/main.c | 75 | ||||
-rw-r--r-- | src/utils/file.c | 14 | ||||
-rw-r--r-- | src/utils/file.h | 5 | ||||
-rw-r--r-- | src/utils/memory/memory.c | 13 | ||||
-rw-r--r-- | src/utils/memory/memory.h | 3 | ||||
-rw-r--r-- | src/utils/types.h | 3 | ||||
-rw-r--r-- | src/vm/runner/runner.c | 13 | ||||
-rw-r--r-- | src/vm/runner/runner.h | 2 | ||||
-rw-r--r-- | std/builtins.felan (renamed from stdlib/builtins.felan) | 0 |
23 files changed, 440 insertions, 235 deletions
@@ -27,12 +27,12 @@ To run code just send your source file to the program like To print `Hello` with no new line ```felan -print("Hello") +print("Hello"); ``` To print `Hello` with a new line ```felan -print("Hello\n") +print("Hello\n"); ``` To comment one line you can use C++ style comments @@ -12,6 +12,7 @@ function compile(){ gcc -Wall -Wextra -std=gnu23 -I./src/ -O3 \ ./src/main.c \ + ./src/compiler/source_code/source_code.c \ ./src/compiler/error_helper/error_helper.c \ ./src/compiler/lexer/lexer.c \ ./src/compiler/parser/parser.c \ diff --git a/src/compiler/code_generator/code_generator.c b/src/compiler/code_generator/code_generator.c index 2b575d8..03901cd 100644 --- a/src/compiler/code_generator/code_generator.c +++ b/src/compiler/code_generator/code_generator.c @@ -61,7 +61,7 @@ void deleteInstructions(Instructions instructions) { free(instructions.instructions); } -Instructions codeGenerator(SourceCode code) { +Instructions codeGenerator(SourceCode *code) { ParsedTree *root = treeParser(code); if (root != NULL) { Instructions instructions = _codeGenerator(root, code); @@ -76,7 +76,7 @@ Instructions codeGenerator(SourceCode code) { return error; } -Instructions _codeGenerator(ParsedTree *root, SourceCode code) { +Instructions _codeGenerator(ParsedTree *root, SourceCode *code) { const TreeScopeMetadata *metadata = root->metadata; size_t instructions_size = 10; @@ -111,7 +111,7 @@ RETURN_ERROR: bool nodeToInstruction(ParsedTree *tree, Instruction **instructions, size_t *instructions_size, size_t *instructions_inserted, - SourceCode code) { + SourceCode *code) { switch (tree->token) { case TREE_TOKEN_FUNCTION_CALL: { const TreeFunctionCallMetadata *tree_metadata = tree->metadata; diff --git a/src/compiler/code_generator/code_generator.h b/src/compiler/code_generator/code_generator.h index 0f8b69d..0ae3219 100644 --- a/src/compiler/code_generator/code_generator.h +++ b/src/compiler/code_generator/code_generator.h @@ -36,12 +36,12 @@ extern void printInstructions(Instructions instructions); extern void deleteInstruction(Instruction instruction); extern void deleteInstructions(Instructions instructions); -extern Instructions codeGenerator(SourceCode code); -extern Instructions _codeGenerator(ParsedTree *root, SourceCode code); +extern Instructions codeGenerator(SourceCode *code); +extern Instructions _codeGenerator(ParsedTree *root, SourceCode *code); extern bool nodeToInstruction(ParsedTree *tree, Instruction **instructions, size_t *instructions_size, - size_t *instructions_inserted, SourceCode code); + size_t *instructions_inserted, SourceCode *code); extern void insertInstruction(const Instruction instruction, Instruction **restrict instructions, diff --git a/src/compiler/error_helper/error_helper.c b/src/compiler/error_helper/error_helper.c index fd648e4..2a9b209 100644 --- a/src/compiler/error_helper/error_helper.c +++ b/src/compiler/error_helper/error_helper.c @@ -3,18 +3,32 @@ #include <stdarg.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> -void printError(char const *error, SourceCode code, char const *begin, +void printError(char const *error, SourceCode *sourceCode, char const *begin, char const *end, ...) { va_list args; va_start(args, end); char *errorStr; vasprintf(&errorStr, error, args); - char const *lineBegin = code; + const Code *code = NULL; + + for (size_t i = 0; i < sourceCode->size; ++i) { + const Code *source = sourceCode->codes[i]; + if (source->code <= begin && strlen(source->code)+source->code >= end) { + code = source; + } + } + if (code == NULL) { + fprintf(stderr, "Bad Error: the error is in no source code"); + return; + } + + char const *lineBegin = code->code; int line = 1; - char const *iter = code; + char const *iter = code->code; for (; iter < begin; ++iter) { const char c = *iter; switch (c) { @@ -54,7 +68,7 @@ void printError(char const *error, SourceCode code, char const *begin, } AFTER_LOOP: - fprintf(stderr, "Error: %s at line %d\n", errorStr, line); + fprintf(stderr, "Error: %s at %s:%d\n", errorStr, code->filePath, line); int printed = 0; for (iter = lineBegin; iter < lineEnd; ++iter) { diff --git a/src/compiler/error_helper/error_helper.h b/src/compiler/error_helper/error_helper.h index 3a78c7c..c118fa9 100644 --- a/src/compiler/error_helper/error_helper.h +++ b/src/compiler/error_helper/error_helper.h @@ -1,6 +1,7 @@ #pragma once +#include <compiler/source_code/source_code.h> #include <utils/types.h> -extern void printError(char const *error, SourceCode code, char const *begin, +extern void printError(char const *error, SourceCode *code, char const *begin, char const *end, ...); diff --git a/src/compiler/lexer/lexer.c b/src/compiler/lexer/lexer.c index ebcccc8..b6aeb2e 100644 --- a/src/compiler/lexer/lexer.c +++ b/src/compiler/lexer/lexer.c @@ -69,11 +69,13 @@ void printNodes(Nodes nodes) { void deleteNodes(Nodes nodes) { free(nodes.nodes); } -Nodes lexer(char const *const restrict code) { +Nodes lexer(SourceCode *sourceCode, size_t sourceIndex) { size_t nodes_size = 10; Node *nodes = a404m_malloc(nodes_size * sizeof(Node)); size_t nodes_inserted = 0; + const char *const code = sourceCode->codes[sourceIndex]->code; + Node node = { .strBegin = code, .strEnd = code, @@ -105,7 +107,7 @@ Nodes lexer(char const *const restrict code) { for (i += 2;; ++i) { switch (code[i]) { case '\0': - printError("Expected multi line comment to end", code, + printError("Expected multi line comment to end", sourceCode, node.strBegin, code + i); goto RETURN_ERROR; case '*': @@ -116,7 +118,7 @@ Nodes lexer(char const *const restrict code) { goto END_OF_BLOCK_COMMENT_LOOP; } } else if (code[i] == '\0') { - printError("Expected multi line comment to end", code, + printError("Expected multi line comment to end", sourceCode, node.strBegin, code + i); goto RETURN_ERROR; } @@ -126,7 +128,7 @@ Nodes lexer(char const *const restrict code) { if (code[i] == '*') { ++in; } else if (code[i] == '\0') { - printError("Expected multi line comment to end", code, + printError("Expected multi line comment to end", sourceCode, node.strBegin, code + i); goto RETURN_ERROR; } @@ -158,7 +160,7 @@ Nodes lexer(char const *const restrict code) { if (current == c) { break; } else if (current == '\0') { - printError("Expected %c to end", code, node.strBegin, code + i, c); + printError("Expected %c to end", sourceCode, node.strBegin, code + i, c); goto RETURN_ERROR; } } @@ -182,7 +184,7 @@ Nodes lexer(char const *const restrict code) { } else if (current == '\\') { ++i; } else if (current == '\0') { - printError("Expected %c to end", code, node.strBegin, code + i, c); + printError("Expected %c to end", sourceCode, node.strBegin, code + i, c); goto RETURN_ERROR; } } @@ -199,7 +201,7 @@ Nodes lexer(char const *const restrict code) { } else { node.token = getOperator(node.strBegin, code + i); if (node.token == TOKEN_NONE) { - printError("Unknown operator '%.*s'", code, node.strBegin, + printError("Unknown operator '%.*s'", sourceCode, node.strBegin, node.strEnd, (int)(code + i - node.strBegin), node.strBegin); goto RETURN_ERROR; @@ -217,7 +219,7 @@ Nodes lexer(char const *const restrict code) { TOKEN_SYMBOL); } } else { - printError("Unexpected char '%c'", code, code + i, code + i + 1, c); + printError("Unexpected char '%c'", sourceCode, code + i, code + i + 1, c); goto RETURN_ERROR; } } diff --git a/src/compiler/lexer/lexer.h b/src/compiler/lexer/lexer.h index 8d88a90..66db1cf 100644 --- a/src/compiler/lexer/lexer.h +++ b/src/compiler/lexer/lexer.h @@ -47,7 +47,7 @@ typedef struct Nodes { extern void printNodes(Nodes nodes); extern void deleteNodes(Nodes nodes); -extern Nodes lexer(char const *const restrict code); +extern Nodes lexer(SourceCode *sourceCode,size_t sourceIndex); extern void push_if_not_empty(Node **restrict nodes, size_t *restrict nodes_size, diff --git a/src/compiler/parser/parser.c b/src/compiler/parser/parser.c index 61a0cf9..2ffde16 100644 --- a/src/compiler/parser/parser.c +++ b/src/compiler/parser/parser.c @@ -22,6 +22,7 @@ const char *PARSED_TOKEN_STRINGS[] = { "PARSED_TOKEN_FUNCTION", "PARSED_TOKEN_FUNCTION_PARAMS", "PARSED_TOKEN_CODE_BODY", + "PARSED_TOKEN_IMPORT", }; static const ParseOrder PARSE_ORDER[] = { @@ -45,18 +46,12 @@ static const ParseOrder PARSE_ORDER[] = { }, { .ltr = true, - .size = 1, + .size = 3, .tokens = { TOKEN_OPERATOR_FUNCTION, - }, - }, - { - .ltr = true, - .size = 1, - .tokens = - { TOKEN_KEYWORD_STRUCT, + TOKEN_KEYWORD_IMPORT, }, }, { @@ -70,18 +65,11 @@ static const ParseOrder PARSE_ORDER[] = { }, }, { - .ltr = false, - .size = 1, - .tokens = - { - TOKEN_OPERATOR_COMMA, - }, - }, - { .ltr = true, - .size = 1, + .size = 2, .tokens = { + TOKEN_OPERATOR_COMMA, TOKEN_OPERATOR_EOL, }, }, @@ -187,6 +175,12 @@ void _printParsedNode(const ParsedNode *parsedNode, int indent) { _printParsedNode(metadata->body, indent + 1); goto END_SUCCESS; } + case PARSED_TOKEN_IMPORT: { + const ParserImportMetadata *metadata = parsedNode->metadata; + printf(",import=\n"); + _printParsedNode(metadata, indent + 1); + goto END_SUCCESS; + } case PARSED_TOKEN_NONE: } fprintf(stderr, "bad parsed token %d at compiler line %d\n", @@ -269,6 +263,11 @@ void deleteParsedNode(ParsedNode *parsedNode) { free(metadata); goto FREE; } + case PARSED_TOKEN_IMPORT: { + ParserImportMetadata *metadata = parsedNode->metadata; + deleteParsedNode(metadata); + goto FREE; + } } fprintf(stderr, "bad parsed token %d at compiler line %d\n", parsedNode->token, __LINE__); @@ -277,8 +276,8 @@ FREE: free(parsedNode); } -ParsedNode *parser(SourceCode code) { - Nodes nodes = lexer(code); +ParsedNode *parser(SourceCode *code, size_t sourceIndex) { + Nodes nodes = lexer(code,sourceIndex); if (nodes.size == ERROR_SIZE) { return NULL; } @@ -288,7 +287,7 @@ ParsedNode *parser(SourceCode code) { return root; } -ParsedNode *_parser(Nodes lexedNodes, SourceCode code) { +ParsedNode *_parser(Nodes lexedNodes, SourceCode *code) { ParsedNode *root = a404m_malloc(sizeof(*root)); root->token = PARSED_TOKEN_ROOT; root->parent = NULL; @@ -303,7 +302,7 @@ ParsedNode *_parser(Nodes lexedNodes, SourceCode code) { ParserScopeMetadata *parserScope( Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, - bool (*isAllowed)(ParsedToken token, bool isLast), SourceCode code) { + bool (*isAllowed)(ParsedToken token, bool isLast), SourceCode *code) { size_t nodes_size = 0; ParsedNode **nodes = a404m_malloc(nodes_size * sizeof(ParsedNode *)); size_t nodes_inserted = 0; @@ -385,6 +384,7 @@ static bool isAllowedCodeScope(ParsedToken token, bool) { case PARSED_TOKEN_STRUCT: case PARSED_TOKEN_FUNCTION: case PARSED_TOKEN_FUNCTION_PARAMS: + case PARSED_TOKEN_IMPORT: return false; case PARSED_TOKEN_EOL: case PARSED_TOKEN_CODE_BODY: @@ -411,6 +411,7 @@ static bool isAllowedParenthesisScope(ParsedToken token, bool) { case PARSED_TOKEN_FUNCTION: case PARSED_TOKEN_CODE_BODY: case PARSED_TOKEN_FUNCTION_PARAMS: + case PARSED_TOKEN_IMPORT: return false; } fprintf(stderr, "bad token '%d' at compiler line %d\n", token, __LINE__); @@ -435,6 +436,7 @@ static bool isAllowedFunctionCallScope(ParsedToken token, bool isLast) { case PARSED_TOKEN_FUNCTION: case PARSED_TOKEN_FUNCTION_PARAMS: case PARSED_TOKEN_CODE_BODY: + case PARSED_TOKEN_IMPORT: return false; } fprintf(stderr, "bad token '%d' at compiler line %d\n", token, __LINE__); @@ -459,6 +461,7 @@ static bool isAllowedFunctionParamScope(ParsedToken token, bool isLast) { case PARSED_TOKEN_FUNCTION: case PARSED_TOKEN_FUNCTION_PARAMS: case PARSED_TOKEN_CODE_BODY: + case PARSED_TOKEN_IMPORT: return false; } fprintf(stderr, "bad token '%d' at compiler line %d\n", token, __LINE__); @@ -481,6 +484,7 @@ static bool isAllowedStructScope(ParsedToken token, bool) { case PARSED_TOKEN_DEFINE_CONSTANT: case PARSED_TOKEN_FUNCTION_PARAMS: case PARSED_TOKEN_CODE_BODY: + case PARSED_TOKEN_IMPORT: return false; } fprintf(stderr, "bad token '%d' at compiler line %d\n", token, __LINE__); @@ -488,38 +492,38 @@ static bool isAllowedStructScope(ParsedToken token, bool) { } ParserScopeMetadata *parserScopeCode(Node *nodesBegin, Node *nodesEnd, - ParsedNode *parent, SourceCode code) { + ParsedNode *parent, SourceCode *code) { return parserScope(nodesBegin, nodesEnd, parent, isAllowedCodeScope, code); } ParserScopeMetadata *parserScopeParenthesis(Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, - SourceCode code) { + SourceCode *code) { return parserScope(nodesBegin, nodesEnd, parent, isAllowedParenthesisScope, code); } ParserScopeMetadata *parserScopeFunctionCall(Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, - SourceCode code) { + SourceCode *code) { return parserScope(nodesBegin, nodesEnd, parent, isAllowedFunctionCallScope, code); } ParserScopeMetadata *parserScopeFunctionParam(Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, - SourceCode code) { + SourceCode *code) { return parserScope(nodesBegin, nodesEnd, parent, isAllowedFunctionParamScope, code); } ParserScopeMetadata *parserScopeStruct(Node *nodesBegin, Node *nodesEnd, - ParsedNode *parent, SourceCode code) { + ParsedNode *parent, SourceCode *code) { return parserScope(nodesBegin, nodesEnd, parent, isAllowedStructScope, code); } ParsedNode *parseNode(Node *nodesBegin, Node *nodesEnd, Node *node, - ParsedNode *parent, SourceCode code) { + ParsedNode *parent, SourceCode *code) { switch (node->token) { case TOKEN_OPERATOR_PARENTHESES_CLOSE: return parseParenthesis(nodesBegin, nodesEnd, node, parent, code); @@ -559,7 +563,7 @@ ParsedNode *parseNode(Node *nodesBegin, Node *nodesEnd, Node *node, } ParsedNode *parseParenthesis(Node *nodesBegin, Node *nodesEnd, Node *closing, - ParsedNode *parent, SourceCode code) { + ParsedNode *parent, SourceCode *code) { ParsedNode *root = a404m_malloc(sizeof(*root)); Node *opening = NULL; for (Node *iter = closing - 1; iter >= nodesBegin; --iter) { @@ -635,7 +639,7 @@ RETURN_ERROR: } ParsedNode *parseCurly(Node *nodesBegin, Node *closing, ParsedNode *parent, - SourceCode code) { + SourceCode *code) { ParsedNode *root = a404m_malloc(sizeof(*root)); Node *opening = NULL; @@ -685,7 +689,7 @@ ParsedNode *parseIdentifier(Node *node, ParsedNode *parent) { } ParsedNode *parseEOL(Node *nodesBegin, Node *node, ParsedNode *parent, - SourceCode code) { + SourceCode *code) { Node *before = node - 1; if (before < nodesBegin) { RETURN_EMPTY: @@ -719,7 +723,7 @@ ParsedNode *parseEOL(Node *nodesBegin, Node *node, ParsedNode *parent, } ParsedNode *parseVariable(Node *nodesBegin, Node *nodesEnd, Node *node, - ParsedNode *parent, SourceCode code) { + ParsedNode *parent, SourceCode *code) { ParsedNode *root = a404m_malloc(sizeof(*root)); ParserVariableDefineMetadata *metadata = root->metadata = a404m_malloc(sizeof(*metadata)); @@ -832,7 +836,7 @@ RETURN_ERROR: } ParsedNode *parseComma(Node *nodesBegin, Node *, Node *node, ParsedNode *parent, - SourceCode code) { + SourceCode *code) { Node *before = node - 1; if (before < nodesBegin || before->token != TOKEN_PARSED) { UNEXPECTED: @@ -861,7 +865,7 @@ ParsedNode *parseComma(Node *nodesBegin, Node *, Node *node, ParsedNode *parent, } ParsedNode *parseStruct(Node *nodesEnd, Node *node, ParsedNode *parent, - SourceCode code) { + SourceCode *code) { ParsedNode *root = a404m_malloc(sizeof(*root)); ParserStructMetadata *metadata = root->metadata = a404m_malloc(sizeof(*metadata)); @@ -904,7 +908,7 @@ RETURN_ERROR: } ParsedNode *parseFunction(Node *nodesBegin, Node *nodesEnd, Node *node, - ParsedNode *parent, SourceCode code) { + ParsedNode *parent, SourceCode *code) { ParsedNode *root = a404m_malloc(sizeof(*root)); ParserFunctionMetadata *metadata = root->metadata = a404m_malloc(sizeof(*metadata)); @@ -965,10 +969,36 @@ RETURN_ERROR: } ParsedNode *parseImport(Node *nodesEnd, Node *node, ParsedNode *parent, - SourceCode code) { + SourceCode *code) { ParsedNode *root = a404m_malloc(sizeof(*root)); + root->parent = parent; + root->token = PARSED_TOKEN_IMPORT; + ParserImportMetadata *metadata; + + Node const *package = node + 1; - // TODO: do it + if (package == nodesEnd) { + NO_PATH: + printError("Import needs a path", code, node->strBegin, node->strEnd); + goto RETURN_ERROR; + } else if (package->token != TOKEN_PARSED) { + BAD_PATH: + printError("Import path should be an string", code, package->strBegin, + package->strEnd); + goto RETURN_ERROR; + } else if ((metadata = getUntilCommonFather(package->parsedNode, parent)) == + NULL) { + goto NO_PATH; + } else if (metadata->token != PARSED_TOKEN_VALUE_STRING) { + goto BAD_PATH; + } + metadata->parent = root; + root->metadata = metadata; + + node->token = TOKEN_PARSED; + node->parsedNode = root; + root->strBegin = node->strBegin; + root->strEnd = package->strEnd; return root; diff --git a/src/compiler/parser/parser.h b/src/compiler/parser/parser.h index 24c6c5d..234264b 100644 --- a/src/compiler/parser/parser.h +++ b/src/compiler/parser/parser.h @@ -17,6 +17,7 @@ typedef enum ParsedToken { PARSED_TOKEN_FUNCTION, PARSED_TOKEN_FUNCTION_PARAMS, PARSED_TOKEN_CODE_BODY, + PARSED_TOKEN_IMPORT, } ParsedToken; extern const char *PARSED_TOKEN_STRINGS[]; @@ -61,6 +62,7 @@ typedef struct ParserFunctionMetadata { ParsedNode *type; ParsedNode *body; } ParserFunctionMetadata; +typedef ParsedNode ParserImportMetadata; extern ParsedNode *newParsedNode(char const *strBegin, char const *strEnd, ParsedToken token, void *metadata, @@ -71,50 +73,50 @@ extern ParsedNode *getUntilCommonFather(ParsedNode *parsedNode, ParsedNode *parent); extern void deleteParsedNode(ParsedNode *parsedNode); -extern ParsedNode *parser(SourceCode code); -extern ParsedNode *_parser(Nodes lexedNodes, SourceCode code); +extern ParsedNode *parser(SourceCode *code,size_t sourceIndex); +extern ParsedNode *_parser(Nodes lexedNodes, SourceCode *code); extern ParserScopeMetadata *parserScope( Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, - bool (*isAllowed)(ParsedToken token, bool isLast), SourceCode code); + bool (*isAllowed)(ParsedToken token, bool isLast), SourceCode *code); extern ParserScopeMetadata *parserScopeCode(Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, - SourceCode code); + SourceCode *code); extern ParserScopeMetadata *parserScopeParenthesis(Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, - SourceCode code); + SourceCode *code); extern ParserScopeMetadata *parserScopeFunctionCall(Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, - SourceCode code); + SourceCode *code); extern ParserScopeMetadata *parserScopeFunctionParam(Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, - SourceCode code); + SourceCode *code); extern ParserScopeMetadata *parserScopeStruct(Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, - SourceCode code); + SourceCode *code); extern ParsedNode *parseNode(Node *nodesBegin, Node *nodesEnd, Node *node, - ParsedNode *parent, SourceCode code); + ParsedNode *parent, SourceCode *code); extern ParsedNode *parseParenthesis(Node *nodesBegin, Node *nodesEnd, Node *node, ParsedNode *parent, - SourceCode code); + SourceCode *code); extern ParsedNode *parseCurly(Node *nodesBegin, Node *node, ParsedNode *parent, - SourceCode code); + SourceCode *code); extern ParsedNode *parseString(Node *node, ParsedNode *parent); extern ParsedNode *parseIdentifier(Node *node, ParsedNode *parent); extern ParsedNode *parseEOL(Node *nodesBegin, Node *node, ParsedNode *parent, - SourceCode code); + SourceCode *code); extern ParsedNode *parseVariable(Node *nodesBegin, Node *nodesEnd, Node *node, - ParsedNode *parent, SourceCode code); + ParsedNode *parent, SourceCode *code); extern ParsedNode *parseComma(Node *nodesBegin, Node *nodesEnd, Node *node, - ParsedNode *parent, SourceCode code); + ParsedNode *parent, SourceCode *code); extern ParsedNode *parseStruct(Node *nodesEnd, Node *node, ParsedNode *parent, - SourceCode code); + SourceCode *code); extern ParsedNode *parseFunction(Node *nodesBegin, Node *nodesEnd, Node *node, - ParsedNode *parent, SourceCode code); + ParsedNode *parent, SourceCode *code); extern ParsedNode *parseImport(Node *nodesEnd, Node *node, ParsedNode *parent, - SourceCode code); + SourceCode *code); diff --git a/src/compiler/source_code/source_code.c b/src/compiler/source_code/source_code.c new file mode 100644 index 0000000..7f1c8fa --- /dev/null +++ b/src/compiler/source_code/source_code.c @@ -0,0 +1,57 @@ +#include "source_code.h" + +#include <stdlib.h> +#include <utils/memory/memory.h> + +Code makeCode(char *filePath, char *code) { + const Code result = { + .filePath = filePath, + .code = code, + }; + return result; +} + +SourceCode makeSourceCode() { + const SourceCode result = { + .codes = NULL, + .size = 0, + }; + return result; +} + +SourceCode *newSourceCode() { + SourceCode *result = a404m_malloc(sizeof(*result)); + result->codes = NULL; + result->size = 0; + return result; +} + +void pushToSourceCode(SourceCode *sourceCode, Code *code) { + size_t size = a404m_malloc_usable_size(sourceCode->codes) / sizeof(Code *); + if (sourceCode->size == size) { + size += size / 2 + 1; + sourceCode->codes = a404m_realloc(sourceCode->codes, size * sizeof(Code *)); + } + sourceCode->codes[sourceCode->size] = code; + sourceCode->size += 1; +} + +void deleteSourceCodeInners(SourceCode sourceCode) { + if (sourceCode.size != 0) { + for (size_t i = 0; i < sourceCode.size; ++i) { + deleteCode(sourceCode.codes[i]); + } + free(sourceCode.codes); + } +} + +void deleteSourceCode(SourceCode *sourceCode) { + deleteSourceCodeInners(*sourceCode); + free(sourceCode); +} + +void deleteCode(Code *code) { + free(code->filePath); + free(code->code); + free(code); +} diff --git a/src/compiler/source_code/source_code.h b/src/compiler/source_code/source_code.h new file mode 100644 index 0000000..7e5b42d --- /dev/null +++ b/src/compiler/source_code/source_code.h @@ -0,0 +1,24 @@ +#pragma once + +#include <stdio.h> + +typedef struct Code { + char *filePath; + char *code; +} Code; + +typedef struct SourceCode { + Code **codes; + size_t size; +} SourceCode; + +extern Code makeCode(char *filePath, char *code); + +extern SourceCode makeSourceCode(); +extern SourceCode *newSourceCode(); + +extern void pushToSourceCode(SourceCode *sourceCode,Code *code); + +extern void deleteSourceCodeInners(SourceCode sourceCode); +extern void deleteSourceCode(SourceCode *sourceCode); +extern void deleteCode(Code *code); diff --git a/src/compiler/tree_parser/tree_parser.c b/src/compiler/tree_parser/tree_parser.c index cb1ef4c..fd1dabb 100644 --- a/src/compiler/tree_parser/tree_parser.c +++ b/src/compiler/tree_parser/tree_parser.c @@ -6,12 +6,13 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <utils/file.h> #include <utils/memory/memory.h> - -#include "utils/types.h" +#include <utils/types.h> const char *TREE_TOKEN_STRINGS[] = { "TREE_TOKEN_NONE", + "TREE_TOKEN_ROOT", "TREE_TOKEN_GLOBAL_SCOPE", "TREE_TOKEN_LOCAL_SCOPE", "TREE_TOKEN_FUNCTION_CALL", @@ -32,6 +33,7 @@ void _printParsedTreeNode(const ParsedTree *parsedTree, int indent) { switch (parsedTree->token) { case TREE_TOKEN_NONE: goto RETURN_SUCCESS; + case TREE_TOKEN_ROOT: case TREE_TOKEN_GLOBAL_SCOPE: case TREE_TOKEN_LOCAL_SCOPE: case TREE_TOKEN_FUNCTION_CALL: @@ -60,6 +62,7 @@ void deleteParsedTree(ParsedTree *parsedTree) { switch (parsedTree->token) { case TREE_TOKEN_NONE: goto RETURN_SUCCESS; + case TREE_TOKEN_ROOT: case TREE_TOKEN_GLOBAL_SCOPE: case TREE_TOKEN_LOCAL_SCOPE: { TreeScopeMetadata *metadata = parsedTree->metadata; @@ -129,17 +132,41 @@ RETURN_SUCCESS: free(parsedTree); } -ParsedTree *treeParser(SourceCode code) { - ParsedNode *parsedNode = parser(code); +ParsedTree *treeParser(SourceCode *code) { + ParserScopeMetadata *scope = a404m_malloc(sizeof(*scope)); + scope->operands_size = 0; + scope->operands = a404m_malloc(scope->operands_size * sizeof(ParsedNode *)); + ParsedNode *const parsedNode = + newParsedNode(NULL, NULL, PARSED_TOKEN_ROOT, scope, NULL); + + for (size_t i = 0; i < code->size; ++i) { + ParsedNode *const nParsedNode = parser(code, i); + ParserScopeMetadata *const nscope = nParsedNode->metadata; + for (size_t j = 0; j < nscope->operands_size; ++j) { + size_t scopeSize = + a404m_malloc_usable_size(scope->operands) / sizeof(ParsedNode *); + if (scopeSize == scope->operands_size) { + scopeSize += scopeSize / 2 + 1; + scope->operands = + a404m_realloc(scope->operands, scopeSize * sizeof(ParsedNode *)); + } + scope->operands[scope->operands_size] = nscope->operands[j]; + scope->operands_size += 1; + } + free(nscope->operands); + nscope->operands = NULL; + nscope->operands_size = 0; + deleteParsedNode(nParsedNode); + } if (parsedNode == NULL) { return NULL; } - ParsedTree *tree= _treeParser(parsedNode, code); + ParsedTree *tree = _treeParser(parsedNode, code); deleteParsedNode(parsedNode); return tree; } -ParsedTree *_treeParser(const ParsedNode *node, SourceCode code) { +ParsedTree *_treeParser(const ParsedNode *node, SourceCode *code) { if (node->token == PARSED_TOKEN_ROOT) { return treeParseRoot(node, code); } else { @@ -147,9 +174,8 @@ ParsedTree *_treeParser(const ParsedNode *node, SourceCode code) { } } -ParsedTree *treeParseNode(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], - size_t scopes_size) { +ParsedTree *treeParseNode(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { switch (node->token) { case PARSED_TOKEN_ROOT: case PARSED_TOKEN_NONE: @@ -183,6 +209,8 @@ ParsedTree *treeParseNode(const ParsedNode *node, SourceCode code, return treeParseStruct(node, code, scopes, scopes_size); case PARSED_TOKEN_FUNCTION: return treeParseFunction(node, code, scopes, scopes_size); + case PARSED_TOKEN_IMPORT: + return treeParseImport(node, code, scopes, scopes_size); case PARSED_TOKEN_FUNCTION_PARAMS: } fprintf(stderr, "bad parsed token %d at %s:%d", node->token, __FILE_NAME__, @@ -190,9 +218,8 @@ ParsedTree *treeParseNode(const ParsedNode *node, SourceCode code, return NULL; } -ParsedTree *treeParseExpr(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], - size_t scopes_size) { +ParsedTree *treeParseExpr(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { switch (node->token) { case PARSED_TOKEN_ROOT: case PARSED_TOKEN_NONE: @@ -201,6 +228,7 @@ ParsedTree *treeParseExpr(const ParsedNode *node, SourceCode code, case PARSED_TOKEN_DEFINE_VARIABLE: case PARSED_TOKEN_DEFINE_CONSTANT: case PARSED_TOKEN_CODE_BODY: + case PARSED_TOKEN_IMPORT: printError("Parsed token %s is not an expression", code, node->strBegin, node->strEnd, PARSED_TOKEN_STRINGS[node->token]); return NULL; @@ -217,12 +245,12 @@ ParsedTree *treeParseExpr(const ParsedNode *node, SourceCode code, return NULL; } -ParsedTree *treeParseRoot(const ParsedNode *node, SourceCode code) { +ParsedTree *treeParseRoot(const ParsedNode *node, SourceCode *code) { return treeParseLocalScope(node, code, NULL, 0); } -ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { const ParserScopeMetadata *node_metadata = node->metadata; ParsedNode **const operands = node_metadata->operands; @@ -236,55 +264,41 @@ ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode code, TreeScopeMetadata *metadata = tree->metadata = a404m_malloc(sizeof(*metadata)); - size_t metadata_variables_size = 0; - metadata->variables = a404m_malloc(metadata_variables_size * - sizeof(TreeDefineVariableMetadata *)); + metadata->variables = a404m_malloc(0); metadata->variables_size = 0; - size_t metadata_lines_size = 0; - metadata->lines = a404m_malloc(metadata_lines_size * sizeof(ParsedTree *)); + metadata->lines = a404m_malloc(0); metadata->lines_size = 0; const size_t newScopes_size = scopes_size + 1; - const TreeScopeMetadata *newScopes[newScopes_size]; - - for (size_t i = 0; i < scopes_size; ++i) { - newScopes[i] = scopes[i]; - } + TreeScopeMetadata *newScopes[newScopes_size]; + memcpy(newScopes, scopes, scopes_size); newScopes[newScopes_size - 1] = metadata; for (size_t i = 0; i < operands_size; ++i) { - const ParsedNode *operand = operands[i]; + const ParsedNode *const operand = operands[i]; ParsedTree *const parsedTree = treeParseNode(operand, code, newScopes, newScopes_size); if (parsedTree == NULL) { goto RETURN_ERROR; } switch (parsedTree->token) { + case TREE_TOKEN_ROOT: + printError("It is not allowed here", code, operand->strBegin, + operand->strEnd); + goto RETURN_ERROR; case TREE_TOKEN_DEFINE_CONSTANT: case TREE_TOKEN_DEFINE_VARIABLE: { TreeDefineVariableMetadata *const variableDefine = parsedTree->metadata; if (variableDefine == NULL) { goto RETURN_ERROR; - } else if (metadata->variables_size == metadata_variables_size) { - metadata_variables_size += metadata_variables_size / 2 + 1; - metadata->variables = a404m_realloc( - metadata->variables, - metadata_variables_size * sizeof(TreeDefineVariableMetadata *)); } - metadata->variables[metadata->variables_size] = variableDefine; - metadata->variables_size += 1; + pushVariableToScope(metadata, variableDefine); } /* fall through */ default: - if (metadata->lines_size == metadata_lines_size) { - metadata_lines_size += metadata_lines_size / 2 + 1; - metadata->lines = a404m_realloc( - metadata->lines, metadata_lines_size * sizeof(ParsedTree *)); - } - metadata->lines[metadata->lines_size] = parsedTree; - metadata->lines_size += 1; + pushLineToScope(metadata, parsedTree); continue; } printError("'%s' Is not allowed here", code, operand->strBegin, @@ -303,9 +317,11 @@ RETURN_ERROR: return NULL; } -TreeDefineVariableMetadata *treeParseDefineVariable( - ParsedTree *tree, const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], size_t scopes_size) { +TreeDefineVariableMetadata *treeParseDefineVariable(ParsedTree *tree, + const ParsedNode *node, + SourceCode *code, + TreeScopeMetadata *scopes[], + size_t scopes_size) { TreeDefineVariableMetadata *define = a404m_malloc(sizeof(*define)); define->tree = tree; @@ -356,14 +372,14 @@ RETURN_ERROR: } TreeDefineVariableMetadata *getVariable(const char *strBegin, - const char *strEnd, SourceCode code, - const TreeScopeMetadata *scopes[], + const char *strEnd, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { const size_t size = strEnd - strBegin; const char *str = strBegin; for (size_t i = 0; i < scopes_size; ++i) { - const TreeScopeMetadata *scope = scopes[i]; + TreeScopeMetadata *scope = scopes[i]; for (size_t j = scope->variables_size - 1; j != (typeof(j))-1; --j) { TreeDefineVariableMetadata *variable = scope->variables[j]; const size_t variable_str_size = variable->nameEnd - variable->nameBegin; @@ -378,8 +394,8 @@ TreeDefineVariableMetadata *getVariable(const char *strBegin, return NULL; } -ParsedTree *treeParseIdentifier(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +ParsedTree *treeParseIdentifier(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { TreeDefineVariableMetadata *variable = getVariable(node->strBegin, node->strEnd, code, scopes, scopes_size); @@ -396,8 +412,8 @@ ParsedTree *treeParseIdentifier(const ParsedNode *node, SourceCode code, return NULL; } -ParsedTree *treeParseFunctionCall(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +ParsedTree *treeParseFunctionCall(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { ParserFunctionCallMetadata *node_metadata = node->metadata; @@ -449,7 +465,7 @@ RETURN_ERROR: return NULL; } -ParsedTree *treeParseValueString(const ParsedNode *node, SourceCode code) { +ParsedTree *treeParseValueString(const ParsedNode *node, SourceCode *code) { ParsedTree *const tree = a404m_malloc(sizeof(*tree)); tree->token = TREE_TOKEN_VALUE_STRING; tree->strBegin = node->strBegin; @@ -461,8 +477,9 @@ ParsedTree *treeParseValueString(const ParsedNode *node, SourceCode code) { return tree; } -ParsedTree *treeParseVariableDefinition(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +ParsedTree *treeParseVariableDefinition(const ParsedNode *node, + SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size, TreeToken token) { ParsedTree *const tree = a404m_malloc(sizeof(*tree)); tree->token = token; @@ -476,9 +493,8 @@ ParsedTree *treeParseVariableDefinition(const ParsedNode *node, SourceCode code, return tree; } -ParsedTree *treeParseStruct(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], - size_t scopes_size) { +ParsedTree *treeParseStruct(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { const ParserStructMetadata *node_metadata = node->metadata; ParsedTree *const tree = a404m_malloc(sizeof(*tree)); @@ -503,9 +519,8 @@ ParsedTree *treeParseStruct(const ParsedNode *node, SourceCode code, return tree; } -ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], - size_t scopes_size) { +ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { const ParserFunctionMetadata *node_metadata = node->metadata; ParsedTree *const tree = a404m_malloc(sizeof(*tree)); @@ -528,9 +543,7 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, const ParserScopeMetadata *params = node_metadata->params->metadata; - size_t metadata_params_size = 0; - metadata->params = - a404m_malloc(metadata_params_size * sizeof(TreeDefineVariableMetadata *)); + metadata->params = a404m_malloc(0); metadata->params_size = 0; for (size_t i = 0; i < params->operands_size; ++i) { @@ -540,6 +553,8 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, if (define == NULL) { goto RETURN_ERROR; } + size_t metadata_params_size = a404m_malloc_usable_size(metadata->params) / + sizeof(ParserScopeMetadata *); if (metadata->params_size == metadata_params_size) { metadata_params_size += metadata_params_size / 2 + 1; metadata->params = a404m_realloc( @@ -556,8 +571,7 @@ ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, if (node_metadata->body != NULL) { printError("Not implemented", code, node->strBegin, node->strEnd); - free(metadata); - free(tree); + goto RETURN_ERROR; return NULL; } else { metadata->scope = NULL; @@ -571,6 +585,32 @@ RETURN_ERROR: return NULL; } +ParsedTree *treeParseImport(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size) { + const ParserImportMetadata *node_metadata = node->metadata; + SizedString *path = nodeToString(node_metadata, code); + if (path == NULL) { + return NULL; + } + + Code *fileCode = read_whole_file(path->str); + if (fileCode == NULL) { + goto RETURN_ERROR; + } + pushToSourceCode(code, fileCode); + + ParsedNode *parsedNode = parser(code, code->size - 1); + + if (parsedNode == NULL) { + goto RETURN_ERROR; + } + return _treeParser(parsedNode, code); +RETURN_ERROR: + free(path->str); + free(path); + return NULL; +} + TypeId getTreeExpressionType(ParsedTree *tree) { switch (tree->token) { case TREE_TOKEN_FUNCTION_CALL: @@ -590,6 +630,7 @@ TypeId getTreeExpressionType(ParsedTree *tree) { case TREE_TOKEN_FUNCTION: // TODO: find a better way for function return tree; case TREE_TOKEN_NONE: + case TREE_TOKEN_ROOT: } fprintf(stderr, "bad parsed tree token %d at %d:%s", tree->token, __LINE__, __FILE_NAME__); @@ -613,20 +654,22 @@ bool isType(ParsedTree *const tree) { case TREE_TOKEN_VALUE_STRING: case TREE_TOKEN_GLOBAL_SCOPE: case TREE_TOKEN_LOCAL_SCOPE: + case TREE_TOKEN_ROOT: return false; case TREE_TOKEN_STRUCT: case TREE_TOKEN_FUNCTION: // TODO: find a better way for function return true; case TREE_TOKEN_NONE: + break; } fprintf(stderr, "bad parsed tree token %d at %d:%s", tree->token, __LINE__, __FILE_NAME__); exit(1); } -SizedString *nodeToString(ParsedNode const *tree, SourceCode code) { - const char *strBegin = tree->strBegin + 1; - const char *strEnd = tree->strEnd - 1; +SizedString *nodeToString(ParsedNode const *node, SourceCode *code) { + const char *strBegin = node->strBegin + 1; + const char *strEnd = node->strEnd - 1; char *str = a404m_malloc((strEnd - strBegin + 1) * sizeof(char)); size_t inserted = 0; @@ -670,13 +713,13 @@ SizedString *nodeToString(ParsedNode const *tree, SourceCode code) { /* c = '';*/ /* break;*/ default: - printError("Bad escape code '\\%s'", code, tree->strBegin, - tree->strEnd, *iter); + printError("Bad escape code '\\%s'", code, node->strBegin, + node->strEnd, *iter); goto RETURN_ERROR; } } else { - printError("Expected character after '\\'", code, tree->strBegin, - tree->strEnd); + printError("Expected character after '\\'", code, node->strBegin, + node->strEnd); goto RETURN_ERROR; } } @@ -693,3 +736,29 @@ RETURN_ERROR: free(str); return NULL; } + +void pushVariableToScope(TreeScopeMetadata *scope, + TreeDefineVariableMetadata *variable) { + size_t scope_variables_size = a404m_malloc_usable_size(scope->variables) / + sizeof(TreeDefineVariableMetadata *); + if (scope->variables_size == scope_variables_size) { + scope_variables_size += scope_variables_size / 2 + 1; + scope->variables = a404m_realloc( + scope->variables, + scope_variables_size * sizeof(TreeDefineVariableMetadata *)); + } + scope->variables[scope->variables_size] = variable; + scope->variables_size += 1; +} + +void pushLineToScope(TreeScopeMetadata *scope, ParsedTree *line) { + size_t scope_lines_size = + a404m_malloc_usable_size(scope->lines) / sizeof(ParsedTree *); + if (scope->lines_size == scope_lines_size) { + scope_lines_size += scope_lines_size / 2 + 1; + scope->lines = + a404m_realloc(scope->lines, scope_lines_size * sizeof(ParsedTree *)); + } + scope->lines[scope->lines_size] = line; + scope->lines_size += 1; +} diff --git a/src/compiler/tree_parser/tree_parser.h b/src/compiler/tree_parser/tree_parser.h index 0ee783f..1eeb63d 100644 --- a/src/compiler/tree_parser/tree_parser.h +++ b/src/compiler/tree_parser/tree_parser.h @@ -2,10 +2,9 @@ #include <compiler/parser/parser.h> -#include "utils/types.h" - typedef enum TreeToken { TREE_TOKEN_NONE = 0, + TREE_TOKEN_ROOT, TREE_TOKEN_GLOBAL_SCOPE, TREE_TOKEN_LOCAL_SCOPE, TREE_TOKEN_FUNCTION_CALL, @@ -65,49 +64,55 @@ typedef struct TreeFunctionMetadata { typedef SizedString TreeStringValueMetadata; -extern void _printParsedTreeNode(const ParsedTree *parsedTree,int indent); +extern void _printParsedTreeNode(const ParsedTree *parsedTree, int indent); extern void printParsedTreeNode(const ParsedTree *parsedTree); extern void deleteParsedTree(ParsedTree *parsedTree); -extern ParsedTree *treeParser(SourceCode code); -extern ParsedTree *_treeParser(const ParsedNode *node, SourceCode code); +extern ParsedTree *treeParser(SourceCode *code); +extern ParsedTree *_treeParser(const ParsedNode *node, SourceCode *code); -extern ParsedTree *treeParseNode(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +extern ParsedTree *treeParseNode(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size); -extern ParsedTree *treeParseRoot(const ParsedNode *root, SourceCode code); -extern ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +extern ParsedTree *treeParseRoot(const ParsedNode *root, SourceCode *code); +extern ParsedTree *treeParseLocalScope(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size); extern TreeDefineVariableMetadata *treeParseDefineVariable( - ParsedTree *tree, const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], size_t scopes_size); + ParsedTree *tree, const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size); extern TreeDefineVariableMetadata *getVariable( - const char *strBegin, const char *strEnd, SourceCode code, - const TreeScopeMetadata *scopes[], size_t scopes_size); -extern ParsedTree *treeParseIdentifier(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], + const char *strBegin, const char *strEnd, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size); +extern ParsedTree *treeParseIdentifier(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size); extern ParsedTree *treeParseFunctionCall(const ParsedNode *node, - SourceCode code, - const TreeScopeMetadata *scopes[], + SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size); extern ParsedTree *treeParseValueString(const ParsedNode *node, - SourceCode code); + SourceCode *code); extern ParsedTree *treeParseVariableDefinition( - const ParsedNode *node, SourceCode code, const TreeScopeMetadata *scopes[], + const ParsedNode *node, SourceCode *code, TreeScopeMetadata *scopes[], size_t scopes_size, TreeToken token); -extern ParsedTree *treeParseStruct(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +extern ParsedTree *treeParseStruct(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size); -extern ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode code, - const TreeScopeMetadata *scopes[], +extern ParsedTree *treeParseFunction(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], size_t scopes_size); +extern ParsedTree *treeParseImport(const ParsedNode *node, SourceCode *code, + TreeScopeMetadata *scopes[], + size_t scopes_size); extern TypeId getTreeExpressionType(ParsedTree *const tree); extern TypeId getType(const TreeDefineVariableMetadata *define); extern bool isType(ParsedTree *const tree); -extern SizedString *nodeToString(ParsedNode const *tree, SourceCode code); +extern SizedString *nodeToString(ParsedNode const *node, SourceCode *code); + +extern void pushVariableToScope(TreeScopeMetadata *scope,TreeDefineVariableMetadata *variable); +extern void pushLineToScope(TreeScopeMetadata *scope,ParsedTree *line); @@ -1,22 +1,19 @@ +#include <compiler/tree_parser/tree_parser.h> #include <stdlib.h> #include <string.h> #include <utils/file.h> #include <utils/time.h> +#include <utils/types.h> #include <vm/runner/runner.h> -#include "compiler/tree_parser/tree_parser.h" -#include "utils/types.h" +#include "compiler/source_code/source_code.h" -static const char *codes[] = { - "print(\"Hello\\n\");", -}; - -Clock runWithPrint(char const *restrict code) { +Clock runWithPrint(SourceCode *code) { Clock sum = 0; Clock diff = 0; - fprintf(stderr, "----code:\n%s\n----\n", code); + fprintf(stderr, "----code:\n%s\n----\n", code->codes[0]->code); Clock start = getTimeInNano(); - const Nodes nodes = lexer(code); + const Nodes nodes = lexer(code, 0); diff += getTimeInNano() - start; sum += diff; if (nodes.size != ERROR_SIZE) { @@ -70,53 +67,35 @@ Clock runWithPrint(char const *restrict code) { return sum; } -Clock process() { - Clock sumAll = 0; - for (size_t i = 0; i < sizeof(codes) / sizeof(char *); ++i) { - Clock start = getTimeInNano(); - runWithPrint(codes[i]); - sumAll += getTimeInNano() - start; - } - return sumAll; -} - -void runBenchmark() { - Clock sum = 0; - const int times = 100; - for (int i = 0; i < times; ++i) { - sum += process(); - } - printf("\n\navg = %fns", ((float)sum) / times); -} - int main(int argc, char *argv[]) { - /*runBenchmark();*/ if (argc < 2) { fprintf(stderr, "no file"); return 1; } - char *code = read_whole_file(argv[1]); + SourceCode sourceCode = makeSourceCode(); + const char *const filePath = argv[1]; + + Code *code; + code = read_whole_file("std/builtins.felan"); + if (code == NULL) { + goto RETURN_ERROR; + } + pushToSourceCode(&sourceCode, code); + + code = read_whole_file(filePath); if (code == NULL) { - return 1; + goto RETURN_ERROR; } - char *import = read_whole_file("stdlib/builtins.felan"); - if (import == NULL) { - return 1; + pushToSourceCode(&sourceCode, code); + + if (!runner(&sourceCode)) { + goto RETURN_ERROR; } - char *lastCode = code; - code = a404m_malloc(strlen(code) + strlen(import) + 2); - strcpy(code, import); - strcat(code, "\n"); - strcat(code, lastCode); - free(lastCode); - free(import); - bool ret = runner(code); + deleteSourceCodeInners(sourceCode); + return 0; - free(code); - if (ret) { - return 0; - } else { - return 1; - } +RETURN_ERROR: + deleteSourceCodeInners(sourceCode); + return 1; } diff --git a/src/utils/file.c b/src/utils/file.c index 410c218..cdb2dfe 100644 --- a/src/utils/file.c +++ b/src/utils/file.c @@ -1,8 +1,10 @@ #include "file.h" + #include <stdio.h> +#include <string.h> #include <utils/memory/memory.h> -char *read_whole_file(const char *path) { +Code *read_whole_file(const char *path) { FILE *file = fopen(path, "r"); if (!file) { fprintf(stderr, "could not open file at path '%s'\n", path); @@ -18,5 +20,13 @@ char *read_whole_file(const char *path) { str[file_size] = '\0'; fclose(file); - return str; + Code *code = a404m_malloc(sizeof(*code)); + + size_t pathLen = strlen(path); + code->code = str; + code->filePath = a404m_malloc(pathLen+1); + + memcpy(code->filePath, path, pathLen+1); + + return code; } diff --git a/src/utils/file.h b/src/utils/file.h index 541e69d..104aec2 100644 --- a/src/utils/file.h +++ b/src/utils/file.h @@ -1,3 +1,6 @@ #pragma once -extern char *read_whole_file(const char *path); +#include <utils/types.h> +#include <compiler/source_code/source_code.h> + +extern Code *read_whole_file(const char *path); diff --git a/src/utils/memory/memory.c b/src/utils/memory/memory.c index d793bc7..cde2995 100644 --- a/src/utils/memory/memory.c +++ b/src/utils/memory/memory.c @@ -1,6 +1,7 @@ #include "memory.h" #include <stdlib.h> +#include <malloc.h> void *a404m_malloc(size_t size) { if (size == 0) { @@ -14,9 +15,17 @@ void *a404m_realloc(void *restrict pointer, size_t size) { if (size == 0) { free(pointer); return NULL; - } else if(pointer != NULL) { + } else if (pointer != NULL) { return realloc(pointer, size); - }else{ + } else { return malloc(size); } } + +size_t a404m_malloc_usable_size(void *pointer) { + if (pointer == NULL) { + return 0; + } else { + return malloc_usable_size(pointer); + } +} diff --git a/src/utils/memory/memory.h b/src/utils/memory/memory.h index 1c5017f..29bd3db 100644 --- a/src/utils/memory/memory.h +++ b/src/utils/memory/memory.h @@ -3,4 +3,5 @@ #include <stddef.h> extern void *a404m_malloc(size_t size); -extern void *a404m_realloc(void *restrict pointer,size_t size); +extern void *a404m_realloc(void *restrict pointer, size_t size); +extern size_t a404m_malloc_usable_size(void *pointer); diff --git a/src/utils/types.h b/src/utils/types.h index e2d8053..b75d64d 100644 --- a/src/utils/types.h +++ b/src/utils/types.h @@ -5,13 +5,10 @@ #ifndef __cplusplus #if (__STDC_VERSION__ < 202000L) - #include <stdint.h> typedef enum bool : uint8_t { false = 0, true = 1 } bool; #endif #endif -typedef const char *const SourceCode; - typedef struct SizedString { char *str; size_t size; diff --git a/src/vm/runner/runner.c b/src/vm/runner/runner.c index 4fcea52..3dcab9b 100644 --- a/src/vm/runner/runner.c +++ b/src/vm/runner/runner.c @@ -16,8 +16,8 @@ const char *BUILTIN_FUNCTION_NAMES[] = { const size_t BUILTIN_FUNCTIONS_SIZE = sizeof(BUILTIN_FUNCTIONS) / sizeof(BuiltinFunction); -bool runner(SourceCode code) { - Instructions instructions = codeGenerator(code); +bool runner(SourceCode *sourceCode) { + Instructions instructions = codeGenerator(sourceCode); if (instructions.size != ERROR_SIZE) { bool ranSuccess = _runner(instructions); deleteInstructions(instructions); @@ -44,7 +44,7 @@ bool _runner(Instructions instructions) { } } - for(size_t i = 0;i < variables_size;++i){ + for (size_t i = 0; i < variables_inserted; ++i) { free(variables[i]); } @@ -88,8 +88,9 @@ bool runInstruction(Instruction instruction, void ***restrict stack, switch (instruction.command) { case COMMAND_PUSH_IDENTIFIER: { const CommandPushIdentifierOperand *operand = instruction.operand; - pushToStack(getRunnerVariable(operand, variables, variables_inserted)->value, - stack, stack_size, stack_inserted); + pushToStack( + getRunnerVariable(operand, variables, variables_inserted)->value, + stack, stack_size, stack_inserted); return true; } case COMMAND_PUSH_STRING: { @@ -123,7 +124,7 @@ bool runInstruction(Instruction instruction, void ***restrict stack, RunnerVariable *getRunnerVariable(const SizedString *varName, RunnerVariable ***restrict variables, size_t *restrict variables_inserted) { - for (size_t i = *variables_inserted - 1; i != (typeof(i))-1; ++i) { + for (size_t i = *variables_inserted - 1; i != (typeof(i))-1; --i) { RunnerVariable *variable = (*variables)[i]; if (variable->name->size == varName->size && strncmp(varName->str, variable->name->str, varName->size) == 0) { diff --git a/src/vm/runner/runner.h b/src/vm/runner/runner.h index d2df5d7..80ef571 100644 --- a/src/vm/runner/runner.h +++ b/src/vm/runner/runner.h @@ -14,7 +14,7 @@ extern const BuiltinFunction BUILTIN_FUNCTIONS[]; extern const char *BUILTIN_FUNCTION_NAMES[]; extern const size_t BUILTIN_FUNCTIONS_SIZE; -extern bool runner(SourceCode code); +extern bool runner(SourceCode *code); extern bool _runner(Instructions instructions); extern bool runInstruction(Instruction instruction, void ***restrict stack, diff --git a/stdlib/builtins.felan b/std/builtins.felan index 96f7335..96f7335 100644 --- a/stdlib/builtins.felan +++ b/std/builtins.felan |