aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-07 14:32:53 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-07 14:32:53 +0330
commit20ff73d84b85db77aecb2171ce4d0e13253cccfd (patch)
tree2cc8b7f8816bc12ad97fe4a979ffccd29d347059 /src
parentd7c31e44861b4d98fbddc177002e0a311a6d26af (diff)
add lazy to variables
Diffstat (limited to 'src')
-rw-r--r--src/compiler/ast-tree.c17
-rw-r--r--src/compiler/ast-tree.h1
-rw-r--r--src/compiler/lexer.c12
-rw-r--r--src/compiler/lexer.h1
-rw-r--r--src/compiler/parser.c10
-rw-r--r--src/compiler/parser.h8
-rw-r--r--src/runner/runner.c19
-rw-r--r--src/runner/runner.h7
8 files changed, 53 insertions, 22 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 7c02209..f22786e 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -1331,6 +1331,7 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables,
result.data[i]->name_begin = variables.data[i]->name_begin;
result.data[i]->name_end = variables.data[i]->name_end;
result.data[i]->isConst = variables.data[i]->isConst;
+ result.data[i]->isLazy = variables.data[i]->isLazy;
result.data[i]->type =
copyAstTreeBack(variables.data[i]->type, new_oldVariables,
new_newVariables, new_variables_size);
@@ -1538,6 +1539,7 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) {
variable->name_begin = node_metadata->name->str_begin;
variable->name_end = node_metadata->name->str_end;
variable->isConst = node->token == PARSER_TOKEN_CONSTANT;
+ variable->isLazy = node_metadata->isLazy;
if (!pushVariable(&helper, &root->variables, variable)) {
astTreeVariableDelete(variable);
@@ -1959,11 +1961,11 @@ AstTree *astTreeParse(const ParserNode *parserNode, AstTreeHelper *helper) {
return astTreeParseUnaryOperator(parserNode, helper,
AST_TREE_TOKEN_OPERATOR_POINTER);
case PARSER_TOKEN_OPERATOR_ADDRESS:
- return astTreeParseUnaryOperatorSingleChild(parserNode, helper,
- AST_TREE_TOKEN_OPERATOR_ADDRESS);
+ return astTreeParseUnaryOperatorSingleChild(
+ parserNode, helper, AST_TREE_TOKEN_OPERATOR_ADDRESS);
case PARSER_TOKEN_OPERATOR_DEREFERENCE:
- return astTreeParseUnaryOperatorSingleChild(parserNode, helper,
- AST_TREE_TOKEN_OPERATOR_DEREFERENCE);
+ return astTreeParseUnaryOperatorSingleChild(
+ parserNode, helper, AST_TREE_TOKEN_OPERATOR_DEREFERENCE);
case PARSER_TOKEN_VARIABLE:
return astTreeParseVariable(parserNode, helper);
case PARSER_TOKEN_KEYWORD_IF:
@@ -2053,7 +2055,7 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode,
argument->type = type;
argument->name_begin = arg_metadata->name->str_begin;
argument->name_end = arg_metadata->name->str_end;
- argument->isConst = true; // all arguments are constants
+ argument->isLazy = true; // all arguments are constants
if (!pushVariable(&helper, &function->arguments, argument)) {
astTreeVariableDelete(argument);
@@ -2360,7 +2362,7 @@ AstTree *astTreeParseString(const ParserNode *parserNode,
metadata->variables.data[i] =
a404m_malloc(sizeof(*metadata->variables.data[i]));
- metadata->variables.data[i]->isConst = true;
+ metadata->variables.data[i]->isLazy = true;
metadata->variables.data[i]->name_begin = NULL;
metadata->variables.data[i]->name_end = NULL;
metadata->variables.data[i]->type = copyAstTree(&AST_TREE_U8_TYPE);
@@ -2546,6 +2548,7 @@ bool astTreeParseConstant(const ParserNode *parserNode, AstTreeHelper *helper) {
variable->name_begin = node_metadata->name->str_begin;
variable->name_end = node_metadata->name->str_end;
variable->isConst = true;
+ variable->isLazy = node_metadata->isLazy;
if (!pushVariable(helper, helper->variables[helper->variables_size - 1],
variable)) {
@@ -2593,6 +2596,7 @@ AstTree *astTreeParseVariable(const ParserNode *parserNode,
variable->name_begin = node_metadata->name->str_begin;
variable->name_end = node_metadata->name->str_end;
variable->isConst = false;
+ variable->isLazy = node_metadata->isLazy;
if (!pushVariable(helper, helper->variables[helper->variables_size - 1],
variable)) {
@@ -2898,6 +2902,7 @@ AstTree *astTreeParseStruct(const ParserNode *parserNode,
variable->initValue = NULL;
variable->isConst = false;
}
+ variable->isLazy = node_variable->isLazy;
variables.data[i] = variable;
}
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index e52d8c2..4d81616 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -131,6 +131,7 @@ typedef struct AstTreeVariable {
AstTree *value;
AstTree *initValue;
bool isConst;
+ bool isLazy;
} AstTreeVariable;
typedef struct AstTreeVariables {
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index a766ce7..f3a5d0e 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -110,6 +110,7 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS",
"LEXER_TOKEN_SYMBOL_OPEN_BRACKET",
"LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET",
+ "LEXER_TOKEN_KEYWORD_LAZY",
"LEXER_TOKEN_NONE",
};
@@ -158,13 +159,14 @@ static const size_t LEXER_SYMBOL_SIZE =
sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS);
static const char *LEXER_KEYWORD_STRINGS[] = {
- "type", "void", "i8", "u8", "i16", "u16", "i32", "u32",
- "i64", "u64",
+ "type", "void", "i8", "u8", "i16", "u16",
+ "i32", "u32", "i64", "u64",
#ifdef FLOAT_16_SUPPORT
"f16",
#endif
- "f32", "f64", "f128", "bool", "putc", "return", "true", "false",
- "if", "else", "while", "comptime", "null", "struct", "undefined", "code",
+ "f32", "f64", "f128", "bool", "putc", "return",
+ "true", "false", "if", "else", "while", "comptime",
+ "null", "struct", "undefined", "code", "lazy",
};
static const LexerToken LEXER_KEYWORD_TOKENS[] = {
LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID,
@@ -183,6 +185,7 @@ static const LexerToken LEXER_KEYWORD_TOKENS[] = {
LEXER_TOKEN_KEYWORD_WHILE, LEXER_TOKEN_KEYWORD_COMPTIME,
LEXER_TOKEN_KEYWORD_NULL, LEXER_TOKEN_KEYWORD_STRUCT,
LEXER_TOKEN_KEYWORD_UNDEFINED, LEXER_TOKEN_KEYWORD_CODE,
+ LEXER_TOKEN_KEYWORD_LAZY,
};
static const size_t LEXER_KEYWORD_SIZE =
sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS);
@@ -436,6 +439,7 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char const *iter,
case LEXER_TOKEN_KEYWORD_STRUCT:
case LEXER_TOKEN_KEYWORD_UNDEFINED:
case LEXER_TOKEN_KEYWORD_CODE:
+ case LEXER_TOKEN_KEYWORD_LAZY:
case LEXER_TOKEN_NUMBER:
case LEXER_TOKEN_CHAR:
case LEXER_TOKEN_STRING:
diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h
index 921b76a..0634e3e 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -126,6 +126,7 @@ typedef enum LexerToken {
LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS,
LEXER_TOKEN_SYMBOL_OPEN_BRACKET,
LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET,
+ LEXER_TOKEN_KEYWORD_LAZY,
LEXER_TOKEN_NONE,
} LexerToken;
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 0d41a25..4781122 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -306,7 +306,7 @@ void parserNodePrint(const ParserNode *node, int indent) {
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE: {
const ParserNodeVariableMetadata *metadata = node->metadata;
- printf(",\n");
+ printf("isLazy=%b,\n", metadata->isLazy);
for (int i = 0; i < indent; ++i)
printf(" ");
printf("name=\n");
@@ -1829,6 +1829,14 @@ ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end,
metadata->name = name;
metadata->type = type;
+ LexerNode *flagNode = nameNode - 1;
+ if (flagNode >= begin && flagNode->parserNode == NULL && flagNode->token == LEXER_TOKEN_KEYWORD_LAZY) {
+ metadata->isLazy = true;
+ flagNode->parserNode = variableNode;
+ } else {
+ metadata->isLazy = false;
+ }
+
variableNode->metadata = metadata;
if (value != NULL) {
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index 1237991..dadfd81 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -132,6 +132,7 @@ typedef struct ParserNodeVariableMetadata {
ParserNode *name;
ParserNode *type;
ParserNode *value;
+ bool isLazy;
} ParserNodeVariableMetadata;
typedef struct ParserNodeFunctionDefnitionMetadata {
@@ -204,8 +205,9 @@ ParserNode *parserFromPath(const char *filePath
ParserNode *parser(LexerNodeArray lexed);
bool parserNodeArray(LexerNode *begin, LexerNode *end, ParserNode *parent);
-ParserNode *newParserNode(ParserToken token, char const*str_begin, char const *str_end,
- void *metadata, ParserNode *parent);
+ParserNode *newParserNode(ParserToken token, char const *str_begin,
+ char const *str_end, void *metadata,
+ ParserNode *parent);
ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
ParserNode *parent, bool *conti);
@@ -262,4 +264,4 @@ bool isExpression(ParserNode *node);
bool isType(ParserNode *node);
bool isValue(ParserNode *node);
-char escapeChar(char const*begin, char const*end, bool *success);
+char escapeChar(char const *begin, char const *end, bool *success);
diff --git a/src/runner/runner.c b/src/runner/runner.c
index abbd05c..6199244 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -3,7 +3,6 @@
#include "utils/log.h"
#include "utils/memory.h"
#include "utils/string.h"
-#include <math.h>
#include <stdatomic.h>
#include <stdio.h>
@@ -1186,9 +1185,14 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
}
case AST_TREE_TOKEN_VARIABLE_DEFINE: {
AstTreeVariable *variable = expr->metadata;
- runnerVariableSetValue(variable,
- runExpression(variable->initValue, scope, shouldRet,
- false, isComptime));
+ AstTree *value;
+ if (variable->isLazy) {
+ value = copyAstTree(variable->initValue);
+ } else {
+ value = runExpression(variable->initValue, scope, shouldRet, false,
+ isComptime);
+ }
+ runnerVariableSetValue(variable, value);
return &AST_TREE_VOID_VALUE;
}
case AST_TREE_TOKEN_KEYWORD_IF: {
@@ -1378,7 +1382,12 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
if (variable->value == NULL) {
UNREACHABLE;
}
- return copyAstTree(variable->value);
+ if (variable->isLazy) {
+ return runExpression(variable->value, scope, shouldRet, false,
+ isComptime);
+ } else {
+ return copyAstTree(variable->value);
+ }
}
}
case AST_TREE_TOKEN_OPERATOR_ACCESS: {
diff --git a/src/runner/runner.h b/src/runner/runner.h
index 93b250a..343f6c2 100644
--- a/src/runner/runner.h
+++ b/src/runner/runner.h
@@ -5,15 +5,16 @@
void runnerVariableSetValue(AstTreeVariable *variable, AstTree *value);
void runnerVariableSetValueWihtoutConstCheck(AstTreeVariable *variable,
AstTree *value);
+AstTree *runnerVariableGetValue(AstTreeVariable *variable);
bool runAstTree(AstTreeRoots roots);
AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments,
- size_t arguments_size,bool isComptime);
+ size_t arguments_size, bool isComptime);
AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope,
AstTreeFunctionCallParam *arguments,
- size_t arguments_size,bool isComptime);
+ size_t arguments_size, bool isComptime);
AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
- bool isLeft,bool isComptime);
+ bool isLeft, bool isComptime);