aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2024-09-25 19:47:29 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2024-09-25 19:47:29 +0330
commitc409b8aaf6b6f63bd68a3356e146ab80b2ec8c4b (patch)
tree65ea5801fd910fc6bcff3f2e8f06b5fd7d249c78
parentf79290084948f3cf140395c270c07cf29ca58e8d (diff)
fixed multiple variable definition bug
tried to implement import
-rw-r--r--README.md4
-rwxr-xr-xproject1
-rw-r--r--src/compiler/code_generator/code_generator.c6
-rw-r--r--src/compiler/code_generator/code_generator.h6
-rw-r--r--src/compiler/error_helper/error_helper.c22
-rw-r--r--src/compiler/error_helper/error_helper.h3
-rw-r--r--src/compiler/lexer/lexer.c18
-rw-r--r--src/compiler/lexer/lexer.h2
-rw-r--r--src/compiler/parser/parser.c102
-rw-r--r--src/compiler/parser/parser.h36
-rw-r--r--src/compiler/source_code/source_code.c57
-rw-r--r--src/compiler/source_code/source_code.h24
-rw-r--r--src/compiler/tree_parser/tree_parser.c211
-rw-r--r--src/compiler/tree_parser/tree_parser.h55
-rw-r--r--src/main.c75
-rw-r--r--src/utils/file.c14
-rw-r--r--src/utils/file.h5
-rw-r--r--src/utils/memory/memory.c13
-rw-r--r--src/utils/memory/memory.h3
-rw-r--r--src/utils/types.h3
-rw-r--r--src/vm/runner/runner.c13
-rw-r--r--src/vm/runner/runner.h2
-rw-r--r--std/builtins.felan (renamed from stdlib/builtins.felan)0
23 files changed, 440 insertions, 235 deletions
diff --git a/README.md b/README.md
index a624dcb..b07f660 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/project b/project
index 47da45b..0964681 100755
--- a/project
+++ b/project
@@ -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);
diff --git a/src/main.c b/src/main.c
index ea85110..0764388 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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