summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/ast-tree.c124
-rw-r--r--src/compiler/ast-tree.h6
-rw-r--r--src/compiler/lexer.c31
-rw-r--r--src/compiler/lexer.h1
-rw-r--r--src/compiler/parser.c34
-rw-r--r--src/compiler/parser.h2
-rw-r--r--src/runner/runner.c5
-rw-r--r--test/main.felan2
8 files changed, 121 insertions, 84 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 8cb1fce..22b1103 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -112,6 +112,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
"AST_TREE_TOKEN_KEYWORD_RETURN",
"AST_TREE_TOKEN_KEYWORD_IF",
"AST_TREE_TOKEN_KEYWORD_WHILE",
+ "AST_TREE_TOKEN_KEYWORD_COMPTIME",
"AST_TREE_TOKEN_TYPE_FUNCTION",
"AST_TREE_TOKEN_TYPE_TYPE",
@@ -220,7 +221,8 @@ void astTreePrint(const AstTree *tree, int indent) {
goto RETURN_SUCCESS;
case AST_TREE_TOKEN_OPERATOR_PLUS:
case AST_TREE_TOKEN_OPERATOR_MINUS:
- case AST_TREE_TOKEN_KEYWORD_PRINT_U64: {
+ case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME: {
AstTreeSingleChild *metadata = tree->metadata;
printf(",\n");
for (int i = 0; i < indent; ++i)
@@ -450,7 +452,8 @@ void astTreeDestroy(AstTree tree) {
}
case AST_TREE_TOKEN_OPERATOR_PLUS:
case AST_TREE_TOKEN_OPERATOR_MINUS:
- case AST_TREE_TOKEN_KEYWORD_PRINT_U64: {
+ case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME: {
AstTreeSingleChild *metadata = tree.metadata;
astTreeDelete(metadata);
}
@@ -557,13 +560,18 @@ void astTreeVariableDelete(AstTreeVariable *variable) {
}
void astTreeDelete(AstTree *tree) {
- if (AST_TREE_TOKEN_STATIC_VARS_BEGIN > tree->token ||
- tree->token > AST_TREE_TOKEN_STATIC_VARS_END) {
+ if (astTreeShouldDelete(tree)) {
astTreeDestroy(*tree);
free(tree);
}
}
+bool astTreeShouldDelete(AstTree *tree) {
+ return (AST_TREE_TOKEN_STATIC_VARS_BEGIN > tree->token ||
+ tree->token > AST_TREE_TOKEN_STATIC_VARS_END) &&
+ tree != &AST_TREE_VOID_VALUE;
+}
+
void astTreeRootDelete(AstTreeRoot *root) {
for (size_t i = 0; i < root->variables.size; ++i) {
astTreeVariableDelete(root->variables.data[i]);
@@ -677,7 +685,8 @@ AstTree *copyAstTree(AstTree *tree) {
}
case AST_TREE_TOKEN_OPERATOR_PLUS:
case AST_TREE_TOKEN_OPERATOR_MINUS:
- case AST_TREE_TOKEN_KEYWORD_PRINT_U64: {
+ case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME: {
AstTreeSingleChild *metadata = tree->metadata;
AstTreeSingleChild *new_metadata = copyAstTree(metadata);
@@ -846,6 +855,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
case PARSER_TOKEN_KEYWORD_IF:
case PARSER_TOKEN_KEYWORD_WHILE:
+ case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_TYPE_VOID:
@@ -1104,6 +1114,8 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) {
return astTreeParseIf(parserNode, helper);
case PARSER_TOKEN_KEYWORD_WHILE:
return astTreeParseWhile(parserNode, helper);
+ case PARSER_TOKEN_KEYWORD_COMPTIME:
+ return astTreeParseComptime(parserNode, helper);
case PARSER_TOKEN_SYMBOL_EOL:
return astTreeParse((ParserNodeSingleChildMetadata *)parserNode->metadata,
helper);
@@ -1223,6 +1235,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) {
case PARSER_TOKEN_TYPE_BOOL:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
case PARSER_TOKEN_KEYWORD_RETURN:
+ case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
@@ -1650,6 +1663,16 @@ AstTree *astTreeParseWhile(ParserNode *parserNode, AstTreeHelper *helper) {
parserNode->str_begin, parserNode->str_end);
}
+AstTree *astTreeParseComptime(ParserNode *parserNode, AstTreeHelper *helper) {
+ ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata;
+
+ AstTreeSingleChild *metadata =
+ (AstTreeSingleChild *)astTreeParse((ParserNode *)node_metadata, helper);
+
+ return newAstTree(AST_TREE_TOKEN_KEYWORD_COMPTIME, metadata, NULL,
+ parserNode->str_begin, parserNode->str_end);
+}
+
AstTree *astTreeParseCurlyBracket(ParserNode *parserNode,
AstTreeHelper *p_helper) {
ParserNodeArray *body = parserNode->metadata;
@@ -1708,6 +1731,7 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode,
case PARSER_TOKEN_TYPE_BOOL:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
case PARSER_TOKEN_KEYWORD_RETURN:
+ case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
@@ -1807,6 +1831,7 @@ AstTreeFunction *getFunction(AstTree *value) {
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_KEYWORD_IF:
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -1872,6 +1897,7 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) {
case AST_TREE_TOKEN_VALUE_INT:
case AST_TREE_TOKEN_VALUE_FLOAT:
case AST_TREE_TOKEN_VALUE_BOOL:
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME:
return true;
case AST_TREE_TOKEN_KEYWORD_IF: {
AstTreeIf *metadata = tree->metadata;
@@ -1973,6 +1999,7 @@ AstTree *makeTypeOf(AstTree *value) {
AstTreeVariable *variable = value->metadata;
return copyAstTree(variable->type);
}
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME:
case AST_TREE_TOKEN_OPERATOR_PLUS:
case AST_TREE_TOKEN_OPERATOR_MINUS: {
AstTreeSingleChild *metadata = value->metadata;
@@ -2013,6 +2040,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_KEYWORD_IF:
case AST_TREE_TOKEN_KEYWORD_WHILE:
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME:
case AST_TREE_TOKEN_VALUE_VOID:
case AST_TREE_TOKEN_VALUE_INT:
case AST_TREE_TOKEN_VALUE_FLOAT:
@@ -2124,7 +2152,11 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) {
case AST_TREE_TOKEN_OPERATOR_GREATER:
case AST_TREE_TOKEN_OPERATOR_SMALLER:
case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
- case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: {
+ case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
+ case AST_TREE_TOKEN_KEYWORD_IF:
+ case AST_TREE_TOKEN_KEYWORD_WHILE:
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME:
+ case AST_TREE_TOKEN_SCOPE: {
AstTree *value = runExpression(tree, helper.pages);
if (value == NULL) {
printError(tree->str_begin, tree->str_end, "Unknown error");
@@ -2136,10 +2168,7 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) {
}
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
case AST_TREE_TOKEN_KEYWORD_RETURN:
- case AST_TREE_TOKEN_KEYWORD_IF:
- case AST_TREE_TOKEN_KEYWORD_WHILE:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
- case AST_TREE_TOKEN_SCOPE:
case AST_TREE_TOKEN_NONE:
}
UNREACHABLE;
@@ -2170,6 +2199,7 @@ bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable,
case AST_TREE_TOKEN_VALUE_FLOAT:
case AST_TREE_TOKEN_VALUE_BOOL:
return false;
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME:
case AST_TREE_TOKEN_OPERATOR_PLUS:
case AST_TREE_TOKEN_OPERATOR_MINUS: {
AstTreeSingleChild *metadata = tree->metadata;
@@ -2323,6 +2353,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
return setTypesWhile(tree, helper, function);
case AST_TREE_TOKEN_SCOPE:
return setTypesScope(tree, helper, function);
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME:
+ return setTypesComptime(tree, helper);
case AST_TREE_TOKEN_NONE:
break;
}
@@ -2791,6 +2823,25 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper helper,
return true;
}
+bool setTypesComptime(AstTree *tree, AstTreeSetTypesHelper helper) {
+ AstTreeSingleChild *operand = tree->metadata;
+
+ if (!setAllTypes(operand, helper, NULL)) {
+ return false;
+ }
+
+ AstTree *newTree = getValue(operand, helper);
+
+ if (operand != newTree) {
+ astTreeDelete(operand);
+ operand = newTree;
+ }
+ tree->metadata = operand;
+ tree->type = copyAstTree(operand->type);
+
+ return true;
+}
+
bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper) {
if (!setAllTypes(&infix->left, helper, NULL)) {
return false;
@@ -2803,58 +2854,3 @@ bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper) {
return setAllTypes(&infix->right, newHelper, NULL);
}
-
-size_t astTreeTypeSize(AstTree tree) {
- switch (tree.token) {
- case AST_TREE_TOKEN_TYPE_BOOL:
- case AST_TREE_TOKEN_TYPE_I8:
- case AST_TREE_TOKEN_TYPE_U8:
- return 1;
- case AST_TREE_TOKEN_TYPE_I16:
- case AST_TREE_TOKEN_TYPE_U16:
- case AST_TREE_TOKEN_TYPE_F16:
- return 2;
- case AST_TREE_TOKEN_TYPE_I32:
- case AST_TREE_TOKEN_TYPE_U32:
- case AST_TREE_TOKEN_TYPE_F32:
- return 4;
- case AST_TREE_TOKEN_TYPE_I64:
- case AST_TREE_TOKEN_TYPE_U64:
- case AST_TREE_TOKEN_TYPE_F64:
- return 8;
- case AST_TREE_TOKEN_TYPE_F128:
- return 16;
- case AST_TREE_TOKEN_FUNCTION:
- case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
- case AST_TREE_TOKEN_KEYWORD_RETURN:
- case AST_TREE_TOKEN_TYPE_TYPE:
- case AST_TREE_TOKEN_TYPE_FUNCTION:
- case AST_TREE_TOKEN_TYPE_VOID:
- case AST_TREE_TOKEN_FUNCTION_CALL:
- case AST_TREE_TOKEN_VARIABLE:
- case AST_TREE_TOKEN_VARIABLE_DEFINE:
- case AST_TREE_TOKEN_VALUE_VOID:
- case AST_TREE_TOKEN_VALUE_INT:
- case AST_TREE_TOKEN_VALUE_FLOAT:
- case AST_TREE_TOKEN_VALUE_BOOL:
- case AST_TREE_TOKEN_OPERATOR_ASSIGN:
- case AST_TREE_TOKEN_OPERATOR_PLUS:
- case AST_TREE_TOKEN_OPERATOR_MINUS:
- case AST_TREE_TOKEN_OPERATOR_SUM:
- case AST_TREE_TOKEN_OPERATOR_SUB:
- case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
- case AST_TREE_TOKEN_OPERATOR_DIVIDE:
- case AST_TREE_TOKEN_OPERATOR_MODULO:
- case AST_TREE_TOKEN_OPERATOR_EQUAL:
- case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL:
- case AST_TREE_TOKEN_OPERATOR_GREATER:
- case AST_TREE_TOKEN_OPERATOR_SMALLER:
- case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
- case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
- case AST_TREE_TOKEN_KEYWORD_IF:
- case AST_TREE_TOKEN_KEYWORD_WHILE:
- case AST_TREE_TOKEN_SCOPE:
- case AST_TREE_TOKEN_NONE:
- }
- UNREACHABLE;
-}
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 0294956..cc66ede 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -11,6 +11,7 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_KEYWORD_RETURN,
AST_TREE_TOKEN_KEYWORD_IF,
AST_TREE_TOKEN_KEYWORD_WHILE,
+ AST_TREE_TOKEN_KEYWORD_COMPTIME,
AST_TREE_TOKEN_TYPE_FUNCTION,
AST_TREE_TOKEN_TYPE_TYPE,
@@ -177,6 +178,7 @@ void astTreeDestroy(AstTree tree);
void astTreeVariableDestroy(AstTreeVariable variable);
void astTreeVariableDelete(AstTreeVariable *variable);
void astTreeDelete(AstTree *tree);
+bool astTreeShouldDelete(AstTree *tree);
void astTreeRootDelete(AstTreeRoot *root);
AstTree *newAstTree(AstTreeToken token, void *metadata, AstTree *type,
@@ -211,6 +213,7 @@ bool astTreeParseConstant(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseVariable(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseIf(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseWhile(ParserNode *parserNode, AstTreeHelper *helper);
+AstTree *astTreeParseComptime(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseCurlyBracket(ParserNode *parserNode,
AstTreeHelper *helper);
AstTree *astTreeParseParenthesis(ParserNode *parserNode, AstTreeHelper *helper);
@@ -248,9 +251,8 @@ bool setTypesWhile(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunction *function);
bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunction *function);
+bool setTypesComptime(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesAstVariable(AstTreeVariable *variable,
AstTreeSetTypesHelper helper);
bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper);
-
-size_t astTreeTypeSize(AstTree tree);
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index 2b7a789..54b78ec 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -34,6 +34,7 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_KEYWORD_IF",
"LEXER_TOKEN_KEYWORD_ELSE",
"LEXER_TOKEN_KEYWORD_WHILE",
+ "LEXER_TOKEN_KEYWORD_COMPTIME",
"LEXER_TOKEN_NUMBER",
@@ -104,22 +105,23 @@ const size_t LEXER_SYMBOL_SIZE =
sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS);
const char *LEXER_KEYWORD_STRINGS[] = {
- "type", "void", "i8", "u8", "i16", "u16", "i32", "u32",
- "i64", "u64", "f16", "f32", "f64", "f128", "bool", "print_u64",
- "return", "true", "false", "if", "else", "while",
+ "type", "void", "i8", "u8", "i16", "u16", "i32", "u32",
+ "i64", "u64", "f16", "f32", "f64", "f128", "bool", "print_u64",
+ "return", "true", "false", "if", "else", "while", "comptime",
};
const LexerToken LEXER_KEYWORD_TOKENS[] = {
- LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID,
- LEXER_TOKEN_KEYWORD_I8, LEXER_TOKEN_KEYWORD_U8,
- LEXER_TOKEN_KEYWORD_I16, LEXER_TOKEN_KEYWORD_U16,
- LEXER_TOKEN_KEYWORD_I32, LEXER_TOKEN_KEYWORD_U32,
- LEXER_TOKEN_KEYWORD_I64, LEXER_TOKEN_KEYWORD_U64,
- LEXER_TOKEN_KEYWORD_F16, LEXER_TOKEN_KEYWORD_F32,
- LEXER_TOKEN_KEYWORD_F64, LEXER_TOKEN_KEYWORD_F128,
- LEXER_TOKEN_KEYWORD_BOOL, LEXER_TOKEN_KEYWORD_PRINT_U64,
- LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_TRUE,
- LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_KEYWORD_IF,
- LEXER_TOKEN_KEYWORD_ELSE, LEXER_TOKEN_KEYWORD_WHILE,
+ LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID,
+ LEXER_TOKEN_KEYWORD_I8, LEXER_TOKEN_KEYWORD_U8,
+ LEXER_TOKEN_KEYWORD_I16, LEXER_TOKEN_KEYWORD_U16,
+ LEXER_TOKEN_KEYWORD_I32, LEXER_TOKEN_KEYWORD_U32,
+ LEXER_TOKEN_KEYWORD_I64, LEXER_TOKEN_KEYWORD_U64,
+ LEXER_TOKEN_KEYWORD_F16, LEXER_TOKEN_KEYWORD_F32,
+ LEXER_TOKEN_KEYWORD_F64, LEXER_TOKEN_KEYWORD_F128,
+ LEXER_TOKEN_KEYWORD_BOOL, LEXER_TOKEN_KEYWORD_PRINT_U64,
+ LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_TRUE,
+ LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_KEYWORD_IF,
+ LEXER_TOKEN_KEYWORD_ELSE, LEXER_TOKEN_KEYWORD_WHILE,
+ LEXER_TOKEN_KEYWORD_COMPTIME,
};
const size_t LEXER_KEYWORD_SIZE =
sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS);
@@ -268,6 +270,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter,
case LEXER_TOKEN_KEYWORD_IF:
case LEXER_TOKEN_KEYWORD_ELSE:
case LEXER_TOKEN_KEYWORD_WHILE:
+ case LEXER_TOKEN_KEYWORD_COMPTIME:
case LEXER_TOKEN_NUMBER:
case LEXER_TOKEN_SYMBOL_EOL:
case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS:
diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h
index 570b472..7a6aa74 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -27,6 +27,7 @@ typedef enum LexerToken {
LEXER_TOKEN_KEYWORD_IF,
LEXER_TOKEN_KEYWORD_ELSE,
LEXER_TOKEN_KEYWORD_WHILE,
+ LEXER_TOKEN_KEYWORD_COMPTIME,
LEXER_TOKEN_NUMBER,
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 405c921..9d95c1d 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -39,6 +39,7 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_KEYWORD_RETURN",
"PARSER_TOKEN_KEYWORD_IF",
"PARSER_TOKEN_KEYWORD_WHILE",
+ "PARSER_TOKEN_KEYWORD_COMPTIME",
"PARSER_TOKEN_CONSTANT",
"PARSER_TOKEN_VARIABLE",
@@ -136,8 +137,8 @@ static constexpr ParserOrder PARSER_ORDER[] = {
},
{
.ltr = true,
- ORDER_ARRAY(LEXER_TOKEN_KEYWORD_RETURN,
- LEXER_TOKEN_KEYWORD_PRINT_U64, ),
+ ORDER_ARRAY(LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_PRINT_U64,
+ LEXER_TOKEN_KEYWORD_COMPTIME, ),
},
{
.ltr = true,
@@ -147,6 +148,7 @@ static constexpr ParserOrder PARSER_ORDER[] = {
.ltr = true,
ORDER_ARRAY(LEXER_TOKEN_KEYWORD_IF, LEXER_TOKEN_KEYWORD_WHILE, ),
},
+
};
static constexpr size_t PARSER_ORDER_SIZE =
@@ -236,6 +238,7 @@ void parserNodePrint(const ParserNode *node, int indent) {
case PARSER_TOKEN_OPERATOR_PLUS:
case PARSER_TOKEN_OPERATOR_MINUS:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
+ case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_SYMBOL_EOL: {
const ParserNodeSingleChildMetadata *metadata = node->metadata;
@@ -459,6 +462,7 @@ void parserNodeDelete(ParserNode *node) {
case PARSER_TOKEN_OPERATOR_PLUS:
case PARSER_TOKEN_OPERATOR_MINUS:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
+ case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_SYMBOL_EOL: {
ParserNodeSingleChildMetadata *metadata = node->metadata;
@@ -763,6 +767,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
return parserIf(node, end, parent);
case LEXER_TOKEN_KEYWORD_WHILE:
return parserWhile(node, end, parent);
+ case LEXER_TOKEN_KEYWORD_COMPTIME:
+ return parserComptime(node, end, parent);
case LEXER_TOKEN_KEYWORD_ELSE:
case LEXER_TOKEN_SYMBOL:
case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS:
@@ -1180,6 +1186,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
case PARSER_TOKEN_FUNCTION_DEFINITION:
case PARSER_TOKEN_FUNCTION_CALL:
+ case PARSER_TOKEN_KEYWORD_COMPTIME:
printError(bodyArray->data[i]->str_begin, bodyArray->data[i]->str_end,
"Maybe forgot a ; with %s",
PARSER_TOKEN_STRINGS[bodyArray->data[i]->token]);
@@ -1475,6 +1482,26 @@ ParserNode *parserWhile(LexerNode *node, LexerNode *end, ParserNode *parent) {
body->str_end, metadata, parent);
}
+ParserNode *parserComptime(LexerNode *node, LexerNode *end,
+ ParserNode *parent) {
+ LexerNode *next = node + 1;
+ if (next >= end) {
+ printError(node->str_begin, node->str_end, "Comptime has no operand");
+ return NULL;
+ }
+
+ ParserNode *operand = getUntilCommonParent(next->parserNode, parent);
+
+ if (operand == NULL) {
+ printError(node->str_begin, node->str_end, "Comptime has bad operand");
+ return NULL;
+ }
+
+ return operand->parent = node->parserNode = newParserNode(
+ PARSER_TOKEN_KEYWORD_COMPTIME, node->str_begin, operand->str_end,
+ (ParserNodeSingleChildMetadata *)operand, parent);
+}
+
bool isAllArguments(const ParserNodeArray *nodes) {
for (size_t i = 0; i < nodes->size; ++i) {
const ParserNode *node = nodes->data[i];
@@ -1519,6 +1546,7 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_VALUE_BOOL:
case PARSER_TOKEN_KEYWORD_IF:
case PARSER_TOKEN_KEYWORD_WHILE:
+ case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_TYPE_VOID:
@@ -1568,6 +1596,7 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_KEYWORD_IF:
+ case PARSER_TOKEN_KEYWORD_COMPTIME:
return true;
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
@@ -1651,6 +1680,7 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_TYPE_F64:
case PARSER_TOKEN_TYPE_F128:
case PARSER_TOKEN_KEYWORD_IF:
+ case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
return true;
case PARSER_TOKEN_CONSTANT:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index 2d0c828..bb54099 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -35,6 +35,7 @@ typedef enum ParserToken {
PARSER_TOKEN_KEYWORD_RETURN,
PARSER_TOKEN_KEYWORD_IF,
PARSER_TOKEN_KEYWORD_WHILE,
+ PARSER_TOKEN_KEYWORD_COMPTIME,
PARSER_TOKEN_CONSTANT,
PARSER_TOKEN_VARIABLE,
@@ -187,6 +188,7 @@ ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin,
LexerToken laterToken);
ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent);
ParserNode *parserWhile(LexerNode *node, LexerNode *end, ParserNode *parent);
+ParserNode *parserComptime(LexerNode *node, LexerNode *end, ParserNode *parent);
bool isAllArguments(const ParserNodeArray *nodes);
diff --git a/src/runner/runner.c b/src/runner/runner.c
index cb2dc8f..47c825d 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -296,6 +296,10 @@ AstTree *runExpression(AstTree *expr, RunnerVariablePages *pages) {
}
return ret;
}
+ case AST_TREE_TOKEN_KEYWORD_COMPTIME: {
+ AstTreeSingleChild *operand = expr->metadata;
+ return runExpression((AstTree *)operand, pages);
+ }
case AST_TREE_TOKEN_SCOPE: {
AstTreeScope *metadata = expr->metadata;
@@ -335,7 +339,6 @@ AstTree *runExpression(AstTree *expr, RunnerVariablePages *pages) {
free(newPages.data);
return ret;
}
- return NULL;
case AST_TREE_TOKEN_OPERATOR_PLUS: {
AstTreeSingleChild *operand = runExpression(expr->metadata, pages);
if (operand->type == &AST_TREE_U64_TYPE) {
diff --git a/test/main.felan b/test/main.felan
index b453f6b..f852c7e 100644
--- a/test/main.felan
+++ b/test/main.felan
@@ -1,5 +1,5 @@
main :: () -> void {
- test(u64,i64);
+ comptime test(u64,u64);
};
test :: (from:type, to:type) -> void {