From c85ce38fbb02342d8ef00030d203ab6bcc690f73 Mon Sep 17 00:00:00 2001
From: A404M <ahmadmahmoudiprogrammer@gmail.com>
Date: Sat, 26 Apr 2025 15:14:45 +0330
Subject: add @isComptime to determine if code is running in comptime or not

---
 src/compiler/ast-tree.c |  34 +++++++--
 src/compiler/ast-tree.h |   3 +
 src/compiler/lexer.c    |  16 +++--
 src/compiler/lexer.h    |   1 +
 src/compiler/parser.c   |   9 +++
 src/compiler/parser.h   |   1 +
 src/runner/runner.c     | 184 ++++++++++++++++++++++++++++++------------------
 src/runner/runner.h     |   6 +-
 8 files changed, 173 insertions(+), 81 deletions(-)

(limited to 'src')

diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 17c2630..6b68a75 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -119,6 +119,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
     "AST_TREE_TOKEN_BUILTIN_CAST",
     "AST_TREE_TOKEN_BUILTIN_TYPE_OF",
     "AST_TREE_TOKEN_BUILTIN_IMPORT",
+    "AST_TREE_TOKEN_BUILTIN_IS_COMPTIME",
 
     "AST_TREE_TOKEN_KEYWORD_PUTC",
     "AST_TREE_TOKEN_KEYWORD_RETURN",
@@ -232,11 +233,10 @@ void astTreePrint(const AstTree *tree, int indent) {
     printf("]");
   }
     goto RETURN_SUCCESS;
-  case AST_TREE_TOKEN_BUILTIN: {
-    AstTreeBuiltin *metadata = tree->metadata;
-    printf(",token = %s", AST_TREE_BUILTIN_TOKEN_STRINGS[metadata->token]);
-  }
-    goto RETURN_SUCCESS;
+  case AST_TREE_TOKEN_BUILTIN_CAST:
+  case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
+  case AST_TREE_TOKEN_BUILTIN_IMPORT:
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
   case AST_TREE_TOKEN_TYPE_TYPE:
   case AST_TREE_TOKEN_TYPE_VOID:
   case AST_TREE_TOKEN_TYPE_I8:
@@ -623,6 +623,7 @@ void astTreeDestroy(AstTree tree) {
   case AST_TREE_TOKEN_BUILTIN_CAST:
   case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
   case AST_TREE_TOKEN_TYPE_TYPE:
   case AST_TREE_TOKEN_TYPE_VOID:
   case AST_TREE_TOKEN_TYPE_I8:
@@ -894,6 +895,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[],
   case AST_TREE_TOKEN_BUILTIN_CAST:
   case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
     return newAstTree(
         tree->token, NULL,
         copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size),
@@ -1584,6 +1586,7 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) {
       case PARSER_TOKEN_BUILTIN_CAST:
       case PARSER_TOKEN_BUILTIN_TYPE_OF:
       case PARSER_TOKEN_BUILTIN_IMPORT:
+      case PARSER_TOKEN_BUILTIN_IS_COMPTIME:
       case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
       case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
         goto AFTER_SWITCH;
@@ -1687,6 +1690,8 @@ AstTree *astTreeParse(const ParserNode *parserNode, AstTreeHelper *helper) {
     return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_TYPE_OF);
   case PARSER_TOKEN_BUILTIN_IMPORT:
     return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_IMPORT);
+  case PARSER_TOKEN_BUILTIN_IS_COMPTIME:
+    return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_IS_COMPTIME);
   case PARSER_TOKEN_TYPE_TYPE:
     return &AST_TREE_TYPE_TYPE;
   case PARSER_TOKEN_TYPE_FUNCTION:
@@ -2006,6 +2011,7 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode,
     case PARSER_TOKEN_BUILTIN_CAST:
     case PARSER_TOKEN_BUILTIN_TYPE_OF:
     case PARSER_TOKEN_BUILTIN_IMPORT:
+    case PARSER_TOKEN_BUILTIN_IS_COMPTIME:
     case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
     case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
       printError(node->str_begin, node->str_end, "Unexpected %s",
@@ -2600,6 +2606,7 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode,
     case PARSER_TOKEN_BUILTIN_CAST:
     case PARSER_TOKEN_BUILTIN_TYPE_OF:
     case PARSER_TOKEN_BUILTIN_IMPORT:
+    case PARSER_TOKEN_BUILTIN_IS_COMPTIME:
     case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
     case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
       printError(node->str_begin, node->str_end, "Unexpected %s",
@@ -2788,6 +2795,7 @@ bool isConst(AstTree *tree) {
   case AST_TREE_TOKEN_BUILTIN_CAST:
   case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
   case AST_TREE_TOKEN_TYPE_TYPE:
   case AST_TREE_TOKEN_TYPE_FUNCTION:
   case AST_TREE_TOKEN_TYPE_VOID:
@@ -2905,6 +2913,7 @@ bool isConstByValue(AstTree *tree) {
   case AST_TREE_TOKEN_BUILTIN_CAST:
   case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
   case AST_TREE_TOKEN_TYPE_TYPE:
   case AST_TREE_TOKEN_TYPE_FUNCTION:
   case AST_TREE_TOKEN_TYPE_VOID:
@@ -3141,6 +3150,7 @@ AstTree *makeTypeOf(AstTree *value) {
   case AST_TREE_TOKEN_BUILTIN_CAST:
   case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
   case AST_TREE_TOKEN_VALUE_OBJECT:
   case AST_TREE_TOKEN_VARIABLE_DEFINE:
   case AST_TREE_TOKEN_KEYWORD_PUTC:
@@ -3180,6 +3190,7 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) {
   case AST_TREE_TOKEN_BUILTIN_CAST:
   case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
   case AST_TREE_TOKEN_FUNCTION:
   case AST_TREE_TOKEN_KEYWORD_PUTC:
   case AST_TREE_TOKEN_KEYWORD_RETURN:
@@ -3326,6 +3337,7 @@ AstTree *getValue(AstTree *tree) {
   case AST_TREE_TOKEN_BUILTIN_CAST:
   case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
   case AST_TREE_TOKEN_TYPE_FUNCTION:
   case AST_TREE_TOKEN_TYPE_TYPE:
   case AST_TREE_TOKEN_TYPE_VOID:
@@ -3396,7 +3408,7 @@ AstTree *getValue(AstTree *tree) {
         .str_end = NULL,
     };
 
-    AstTree *value = runExpression(tree, scope, &shouldRet, false);
+    AstTree *value = runExpression(tree, scope, &shouldRet, false, true);
 
     astTreeDestroy(scopeTree);
 
@@ -3432,6 +3444,7 @@ bool isIntType(AstTree *type) {
   case AST_TREE_TOKEN_BUILTIN_CAST:
   case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
   case AST_TREE_TOKEN_KEYWORD_PUTC:
   case AST_TREE_TOKEN_KEYWORD_RETURN:
   case AST_TREE_TOKEN_KEYWORD_IF:
@@ -3531,6 +3544,7 @@ bool isEqual(AstTree *left, AstTree *right) {
   case AST_TREE_TOKEN_BUILTIN_CAST:
   case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
   case AST_TREE_TOKEN_KEYWORD_PUTC:
   case AST_TREE_TOKEN_KEYWORD_RETURN:
   case AST_TREE_TOKEN_KEYWORD_IF:
@@ -3768,6 +3782,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
     return setTypesBuiltinTypeOf(tree, helper, functionCall);
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
     return setTypesBuiltinImport(tree, helper, functionCall);
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
+    return setTypesBuiltinIsComptime(tree, helper);
   case AST_TREE_TOKEN_TYPE_ARRAY:
     return setTypesTypeArray(tree, helper);
   case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS:
@@ -4938,6 +4954,12 @@ bool setTypesBuiltinImport(AstTree *tree, AstTreeSetTypesHelper helper,
   return false;
 }
 
+bool setTypesBuiltinIsComptime(AstTree *tree, AstTreeSetTypesHelper helper) {
+  (void)helper;
+  tree->type = copyAstTree(&AST_TREE_BOOL_TYPE);
+  return true;
+}
+
 bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper) {
   AstTreeBracket *metadata = tree->metadata;
 
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index aaf614e..39df36d 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -5,9 +5,11 @@
 
 typedef enum AstTreeToken {
   AST_TREE_TOKEN_FUNCTION,
+
   AST_TREE_TOKEN_BUILTIN_CAST,
   AST_TREE_TOKEN_BUILTIN_TYPE_OF,
   AST_TREE_TOKEN_BUILTIN_IMPORT,
+  AST_TREE_TOKEN_BUILTIN_IS_COMPTIME,
 
   AST_TREE_TOKEN_KEYWORD_PUTC,
   AST_TREE_TOKEN_KEYWORD_RETURN,
@@ -382,6 +384,7 @@ bool setTypesBuiltinTypeOf(AstTree *tree, AstTreeSetTypesHelper helper,
                      AstTreeFunctionCall *functionCall);
 bool setTypesBuiltinImport(AstTree *tree, AstTreeSetTypesHelper helper,
                      AstTreeFunctionCall *functionCall);
+bool setTypesBuiltinIsComptime(AstTree *tree, AstTreeSetTypesHelper helper);
 bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper);
 bool setTypesArrayAccess(AstTree *tree, AstTreeSetTypesHelper helper);
 
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index ffc3976..378e480 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -10,7 +10,10 @@ const char *LEXER_TOKEN_STRINGS[] = {
     "LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS",
     "LEXER_TOKEN_SYMBOL_CLOSE_BRACKET",
     "LEXER_TOKEN_IDENTIFIER",
-    "LEXER_TOKEN_BUILTIN",
+    "LEXER_TOKEN_BUILTIN_CAST",
+    "LEXER_TOKEN_BUILTIN_TYPE_OF",
+    "LEXER_TOKEN_BUILTIN_IMPORT",
+    "LEXER_TOKEN_BUILTIN_IS_COMPTIME",
     "LEXER_TOKEN_KEYWORD_TYPE",
     "LEXER_TOKEN_KEYWORD_VOID",
     "LEXER_TOKEN_KEYWORD_I8",
@@ -170,14 +173,16 @@ static const size_t LEXER_KEYWORD_SIZE =
     sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS);
 
 static const char *LEXER_BUILTIN_STRINGS[] = {
-    "@cast",
-    "@typeOf",
-    "@import",
+    "cast",
+    "typeOf",
+    "import",
+    "isComptime",
 };
 static const LexerToken LEXER_BUILTIN_TOKENS[] = {
     LEXER_TOKEN_BUILTIN_CAST,
     LEXER_TOKEN_BUILTIN_TYPE_OF,
     LEXER_TOKEN_BUILTIN_IMPORT,
+    LEXER_TOKEN_BUILTIN_IS_COMPTIME,
 };
 static const size_t LEXER_BUILTIN_SIZE =
     sizeof(LEXER_BUILTIN_TOKENS) / sizeof(*LEXER_BUILTIN_TOKENS);
@@ -344,7 +349,7 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter,
   case LEXER_TOKEN_BUILTIN: {
     const size_t index =
         searchInStringArray(LEXER_BUILTIN_STRINGS, LEXER_BUILTIN_SIZE,
-                            *node_str_begin, iter - *node_str_begin);
+                            *node_str_begin + 1, iter - *node_str_begin - 1);
     if (index == LEXER_BUILTIN_SIZE) {
       printError(*node_str_begin, iter, "Bad builtin");
       UNREACHABLE;
@@ -423,6 +428,7 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter,
   case LEXER_TOKEN_BUILTIN_CAST:
   case LEXER_TOKEN_BUILTIN_TYPE_OF:
   case LEXER_TOKEN_BUILTIN_IMPORT:
+  case LEXER_TOKEN_BUILTIN_IS_COMPTIME:
   case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET:
   case LEXER_TOKEN_SYMBOL_OPEN_BRACKET:
     if (*array_size == array->size) {
diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h
index 98da7b5..7cceae7 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -16,6 +16,7 @@ typedef enum LexerToken {
   LEXER_TOKEN_BUILTIN_CAST,
   LEXER_TOKEN_BUILTIN_TYPE_OF,
   LEXER_TOKEN_BUILTIN_IMPORT,
+  LEXER_TOKEN_BUILTIN_IS_COMPTIME,
   LEXER_TOKEN_KEYWORD_TYPE,
   LEXER_TOKEN_KEYWORD_VOID,
   LEXER_TOKEN_KEYWORD_I8,
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 0f4a880..c4cbfee 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -15,6 +15,7 @@ const char *PARSER_TOKEN_STRINGS[] = {
     "PARSER_TOKEN_BUILTIN_CAST",
     "PARSER_TOKEN_BUILTIN_TYPE_OF",
     "PARSER_TOKEN_BUILTIN_IMPORT",
+    "PARSER_TOKEN_BUILTIN_IS_COMPTIME",
 
     "PARSER_TOKEN_VALUE_INT",
     "PARSER_TOKEN_VALUE_FLOAT",
@@ -226,6 +227,7 @@ void parserNodePrint(const ParserNode *node, int indent) {
   case PARSER_TOKEN_BUILTIN_CAST:
   case PARSER_TOKEN_BUILTIN_TYPE_OF:
   case PARSER_TOKEN_BUILTIN_IMPORT:
+  case PARSER_TOKEN_BUILTIN_IS_COMPTIME:
   case PARSER_TOKEN_TYPE_TYPE:
   case PARSER_TOKEN_TYPE_VOID:
   case PARSER_TOKEN_TYPE_BOOL:
@@ -512,6 +514,7 @@ void parserNodeDelete(ParserNode *node) {
   case PARSER_TOKEN_BUILTIN_CAST:
   case PARSER_TOKEN_BUILTIN_TYPE_OF:
   case PARSER_TOKEN_BUILTIN_IMPORT:
+  case PARSER_TOKEN_BUILTIN_IS_COMPTIME:
   case PARSER_TOKEN_TYPE_TYPE:
   case PARSER_TOKEN_TYPE_VOID:
   case PARSER_TOKEN_TYPE_BOOL:
@@ -796,6 +799,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
     return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_TYPE_OF);
   case LEXER_TOKEN_BUILTIN_IMPORT:
     return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_IMPORT);
+  case LEXER_TOKEN_BUILTIN_IS_COMPTIME:
+    return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_IS_COMPTIME);
   case LEXER_TOKEN_KEYWORD_TYPE:
     return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_TYPE);
   case LEXER_TOKEN_KEYWORD_VOID:
@@ -1531,6 +1536,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
       case PARSER_TOKEN_BUILTIN_CAST:
       case PARSER_TOKEN_BUILTIN_TYPE_OF:
       case PARSER_TOKEN_BUILTIN_IMPORT:
+      case PARSER_TOKEN_BUILTIN_IS_COMPTIME:
       case PARSER_TOKEN_VALUE_INT:
       case PARSER_TOKEN_VALUE_FLOAT:
       case PARSER_TOKEN_VALUE_BOOL:
@@ -1994,6 +2000,7 @@ bool isExpression(ParserNode *node) {
   case PARSER_TOKEN_BUILTIN_CAST:
   case PARSER_TOKEN_BUILTIN_TYPE_OF:
   case PARSER_TOKEN_BUILTIN_IMPORT:
+  case PARSER_TOKEN_BUILTIN_IS_COMPTIME:
   case PARSER_TOKEN_CONSTANT:
   case PARSER_TOKEN_VARIABLE:
   case PARSER_TOKEN_SYMBOL_PARENTHESIS:
@@ -2106,6 +2113,7 @@ bool isType(ParserNode *node) {
   case PARSER_TOKEN_BUILTIN_CAST:
   case PARSER_TOKEN_BUILTIN_TYPE_OF:
   case PARSER_TOKEN_BUILTIN_IMPORT:
+  case PARSER_TOKEN_BUILTIN_IS_COMPTIME:
   case PARSER_TOKEN_OPERATOR_ADDRESS:
   case PARSER_TOKEN_KEYWORD_NULL:
   case PARSER_TOKEN_KEYWORD_UNDEFINED:
@@ -2165,6 +2173,7 @@ bool isValue(ParserNode *node) {
   case PARSER_TOKEN_BUILTIN_CAST:
   case PARSER_TOKEN_BUILTIN_TYPE_OF:
   case PARSER_TOKEN_BUILTIN_IMPORT:
+  case PARSER_TOKEN_BUILTIN_IS_COMPTIME:
   case PARSER_TOKEN_OPERATOR_ACCESS:
   case PARSER_TOKEN_OPERATOR_ASSIGN:
   case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index f0d8372..271cc13 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -12,6 +12,7 @@ typedef enum ParserToken {
   PARSER_TOKEN_BUILTIN_CAST,
   PARSER_TOKEN_BUILTIN_TYPE_OF,
   PARSER_TOKEN_BUILTIN_IMPORT,
+  PARSER_TOKEN_BUILTIN_IS_COMPTIME,
 
   PARSER_TOKEN_VALUE_INT,
   PARSER_TOKEN_VALUE_FLOAT,
diff --git a/src/runner/runner.c b/src/runner/runner.c
index 8d3251d..4f788e7 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -3,6 +3,7 @@
 #include "utils/log.h"
 #include "utils/memory.h"
 #include "utils/string.h"
+#include <stdatomic.h>
 #include <stdio.h>
 
 #define doOperation(op0, op1, operator, originalType, type)                    \
@@ -81,7 +82,7 @@ bool runAstTree(AstTreeRoots roots) {
     return false;
   }
 
-  AstTree *res = runAstTreeFunction(main, NULL, 0);
+  AstTree *res = runAstTreeFunction(main, NULL, 0, false);
   const bool ret = res == &AST_TREE_VOID_VALUE;
   astTreeDelete(res);
   astTreeDelete(main);
@@ -89,7 +90,7 @@ bool runAstTree(AstTreeRoots roots) {
 }
 
 AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments,
-                            size_t arguments_size) {
+                            size_t arguments_size, bool isComptime) {
   AstTreeFunction *function = tree->metadata;
 
   bool shouldRet = false;
@@ -97,16 +98,17 @@ AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments,
   for (size_t i = 0; i < arguments_size; ++i) {
     AstTreeFunctionCallParam param = arguments[i];
     AstTreeVariable *arg = function->arguments.data[i];
-    AstTree *value =
-        runExpression(param.value, &function->scope, &shouldRet, false);
+    AstTree *value = runExpression(param.value, &function->scope, &shouldRet,
+                                   false, isComptime);
     runnerVariableSetValueWihtoutConstCheck(arg, value);
   }
 
   shouldRet = false;
 
   for (size_t i = 0; i < function->scope.expressions_size; ++i) {
-    AstTree *ret = runExpression(function->scope.expressions[i],
-                                 &function->scope, &shouldRet, false);
+    AstTree *ret =
+        runExpression(function->scope.expressions[i], &function->scope,
+                      &shouldRet, false, isComptime);
     if (shouldRet) {
       return ret;
     } else {
@@ -119,7 +121,7 @@ AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments,
 
 AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope,
                            AstTreeFunctionCallParam *arguments,
-                           size_t arguments_size) {
+                           size_t arguments_size, bool isComptime) {
   AstTrees args = {
       .data = a404m_malloc(arguments_size * sizeof(*args.data)),
       .size = arguments_size,
@@ -129,7 +131,8 @@ AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope,
 
   for (size_t i = 0; i < arguments_size; ++i) {
     AstTreeFunctionCallParam param = arguments[i];
-    args.data[i] = runExpression(param.value, scope, &shouldRet, false);
+    args.data[i] =
+        runExpression(param.value, scope, &shouldRet, false, isComptime);
   }
 
   if (shouldRet) {
@@ -394,11 +397,12 @@ RETURN:
 }
 
 AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
-                       bool isLeft) {
+                       bool isLeft, bool isComptime) {
   switch (expr->token) {
   case AST_TREE_TOKEN_KEYWORD_PUTC: {
     AstTreeSingleChild *metadata = expr->metadata;
-    AstTree *tree = runExpression(metadata, scope, shouldRet, false);
+    AstTree *tree =
+        runExpression(metadata, scope, shouldRet, false, isComptime);
     putchar((u8) * (AstTreeInt *)tree->metadata);
     astTreeDelete(tree);
     return &AST_TREE_VOID_VALUE;
@@ -406,16 +410,16 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   case AST_TREE_TOKEN_FUNCTION_CALL: {
     AstTreeFunctionCall *metadata = expr->metadata;
     AstTree *function =
-        runExpression(metadata->function, scope, shouldRet, false);
+        runExpression(metadata->function, scope, shouldRet, false, isComptime);
     AstTree *result;
     if (function->token == AST_TREE_TOKEN_FUNCTION) {
       result = runAstTreeFunction(function, metadata->parameters,
-                                  metadata->parameters_size);
+                                  metadata->parameters_size, isComptime);
     } else if (function->token == AST_TREE_TOKEN_BUILTIN_CAST ||
                function->token == AST_TREE_TOKEN_BUILTIN_TYPE_OF ||
                function->token == AST_TREE_TOKEN_BUILTIN_IMPORT) {
       result = runAstTreeBuiltin(function, scope, metadata->parameters,
-                                 metadata->parameters_size);
+                                 metadata->parameters_size, isComptime);
     } else {
       UNREACHABLE;
     }
@@ -424,13 +428,14 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_ASSIGN: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *l = runExpression(metadata->left, scope, shouldRet, true);
+    AstTree *l =
+        runExpression(metadata->left, scope, shouldRet, true, isComptime);
     if (l->token != AST_TREE_TOKEN_VARIABLE) {
       UNREACHABLE;
     }
     AstTreeVariable *left = l->metadata;
-    runnerVariableSetValue(
-        left, runExpression(metadata->right, scope, shouldRet, false));
+    runnerVariableSetValue(left, runExpression(metadata->right, scope,
+                                               shouldRet, false, isComptime));
     astTreeDelete(l);
     return copyAstTree(left->value);
   }
@@ -438,26 +443,30 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
     AstTreeReturn *metadata = expr->metadata;
     *shouldRet = true;
     if (metadata->value != NULL) {
-      return runExpression(metadata->value, scope, shouldRet, false);
+      return runExpression(metadata->value, scope, shouldRet, false,
+                           isComptime);
     } else {
       return &AST_TREE_VOID_VALUE;
     }
   }
   case AST_TREE_TOKEN_VARIABLE_DEFINE: {
     AstTreeVariable *variable = expr->metadata;
-    runnerVariableSetValue(
-        variable, runExpression(variable->initValue, scope, shouldRet, false));
+    runnerVariableSetValue(variable,
+                           runExpression(variable->initValue, scope, shouldRet,
+                                         false, isComptime));
     return &AST_TREE_VOID_VALUE;
   }
   case AST_TREE_TOKEN_KEYWORD_IF: {
     AstTreeIf *metadata = expr->metadata;
     AstTree *condition =
-        runExpression(metadata->condition, scope, shouldRet, false);
+        runExpression(metadata->condition, scope, shouldRet, false, isComptime);
     AstTree *ret;
     if (*(AstTreeBool *)condition->metadata) {
-      ret = runExpression(metadata->ifBody, scope, shouldRet, isLeft);
+      ret =
+          runExpression(metadata->ifBody, scope, shouldRet, isLeft, isComptime);
     } else if (metadata->elseBody != NULL) {
-      ret = runExpression(metadata->elseBody, scope, shouldRet, isLeft);
+      ret = runExpression(metadata->elseBody, scope, shouldRet, isLeft,
+                          isComptime);
     } else {
       ret = &AST_TREE_VOID_VALUE;
     }
@@ -468,21 +477,22 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
     AstTreeWhile *metadata = expr->metadata;
     AstTree *ret = &AST_TREE_VOID_VALUE;
     while (!*shouldRet) {
-      AstTree *tree =
-          runExpression(metadata->condition, scope, shouldRet, false);
+      AstTree *tree = runExpression(metadata->condition, scope, shouldRet,
+                                    false, isComptime);
       bool conti = *(AstTreeBool *)tree->metadata;
       astTreeDelete(tree);
       if (!conti) {
         break;
       }
       astTreeDelete(ret);
-      ret = runExpression(metadata->body, scope, shouldRet, isLeft);
+      ret = runExpression(metadata->body, scope, shouldRet, isLeft, isComptime);
     }
     return ret;
   }
   case AST_TREE_TOKEN_KEYWORD_COMPTIME: {
     AstTreeSingleChild *operand = expr->metadata;
-    return runExpression((AstTree *)operand, scope, shouldRet, isLeft);
+    return runExpression((AstTree *)operand, scope, shouldRet, isLeft,
+                         isComptime);
   }
   case AST_TREE_TOKEN_SCOPE: {
     AstTreeScope *metadata = expr->metadata;
@@ -491,13 +501,14 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
     for (size_t i = 0; i < metadata->expressions_size && !*shouldRet; ++i) {
       astTreeDelete(ret);
       ret = runExpression(metadata->expressions[i], scope, shouldRet,
-                          i == metadata->expressions_size - 1 && isLeft);
+                          i == metadata->expressions_size - 1 && isLeft,
+                          isComptime);
     }
     return ret;
   }
   case AST_TREE_TOKEN_OPERATOR_PLUS: {
     AstTreeSingleChild *operand =
-        runExpression(expr->metadata, scope, shouldRet, false);
+        runExpression(expr->metadata, scope, shouldRet, false, isComptime);
     if (operand->type == &AST_TREE_U64_TYPE) {
       doLeftOperation(operand, +, AstTreeInt, u64);
     } else if (operand->type == &AST_TREE_I64_TYPE) {
@@ -532,7 +543,7 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_MINUS: {
     AstTreeSingleChild *operand =
-        runExpression(expr->metadata, scope, shouldRet, false);
+        runExpression(expr->metadata, scope, shouldRet, false, isComptime);
     if (operand->type == &AST_TREE_U64_TYPE) {
       doLeftOperation(operand, -, AstTreeInt, u64);
     } else if (operand->type == &AST_TREE_I64_TYPE) {
@@ -567,15 +578,17 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: {
     AstTreeSingleChild *operand =
-        runExpression(expr->metadata, scope, shouldRet, false);
+        runExpression(expr->metadata, scope, shouldRet, false, isComptime);
 
     *(AstTreeBool *)operand->metadata = !*((AstTreeBool *)operand->metadata);
     return operand;
   }
   case AST_TREE_TOKEN_OPERATOR_SUM: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doOperation(left, right, +, AstTreeInt, u64);
@@ -623,8 +636,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_SUB: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doOperation(left, right, -, AstTreeInt, u64);
@@ -672,8 +687,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_MULTIPLY: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doOperation(left, right, *, AstTreeInt, u64);
@@ -721,8 +738,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_DIVIDE: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doOperation(left, right, /, AstTreeInt, u64);
@@ -770,8 +789,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_MODULO: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doOperation(left, right, %, AstTreeInt, u64);
@@ -806,8 +827,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_EQUAL: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doLogicalOperation(left, right, ==, AstTreeInt, u64);
@@ -861,8 +884,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doLogicalOperation(left, right, !=, AstTreeInt, u64);
@@ -916,8 +941,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_GREATER: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doLogicalOperation(left, right, >, AstTreeInt, u64);
@@ -965,8 +992,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_SMALLER: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doLogicalOperation(left, right, <, AstTreeInt, u64);
@@ -1014,8 +1043,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doLogicalOperation(left, right, >=, AstTreeInt, u64);
@@ -1063,8 +1094,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
       doLogicalOperation(left, right, <=, AstTreeInt, u64);
@@ -1112,8 +1145,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     *(AstTreeBool *)left->metadata =
         *(AstTreeBool *)left->metadata && *(AstTreeBool *)right->metadata;
@@ -1123,8 +1158,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: {
     AstTreeInfix *metadata = expr->metadata;
-    AstTree *left = runExpression(metadata->left, scope, shouldRet, false);
-    AstTree *right = runExpression(metadata->right, scope, shouldRet, false);
+    AstTree *left =
+        runExpression(metadata->left, scope, shouldRet, false, isComptime);
+    AstTree *right =
+        runExpression(metadata->right, scope, shouldRet, false, isComptime);
 
     *(AstTreeBool *)left->metadata =
         *(AstTreeBool *)left->metadata || *(AstTreeBool *)right->metadata;
@@ -1164,6 +1201,13 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
   case AST_TREE_TOKEN_BUILTIN_IMPORT:
     return copyAstTree(expr);
+  case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: {
+    AstTreeBool *metadata = a404m_malloc(sizeof(*metadata));
+    *metadata = isComptime;
+    return newAstTree(AST_TREE_TOKEN_VALUE_BOOL, metadata,
+                      copyAstTree(&AST_TREE_BOOL_TYPE), expr->str_begin,
+                      expr->str_end);
+  }
   case AST_TREE_TOKEN_OPERATOR_ADDRESS: {
     AstTreeSingleChild *metadata = expr->metadata;
     if (metadata->token != AST_TREE_TOKEN_VARIABLE) {
@@ -1173,7 +1217,8 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: {
     AstTreeSingleChild *metadata = expr->metadata;
-    AstTree *operand = runExpression(metadata, scope, shouldRet, false);
+    AstTree *operand =
+        runExpression(metadata, scope, shouldRet, false, isComptime);
     if (operand->token != AST_TREE_TOKEN_VARIABLE) {
       printLog("%s", AST_TREE_TOKEN_STRINGS[operand->token]);
       UNREACHABLE;
@@ -1201,7 +1246,8 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   }
   case AST_TREE_TOKEN_OPERATOR_ACCESS: {
     AstTreeAccess *metadata = expr->metadata;
-    AstTree *tree = runExpression(metadata->object, scope, shouldRet, true);
+    AstTree *tree =
+        runExpression(metadata->object, scope, shouldRet, true, isComptime);
     if (tree->token != AST_TREE_TOKEN_VARIABLE) {
       UNREACHABLE;
     }
@@ -1215,8 +1261,9 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
         if (array_metadata->parameters.size == 0) {
           UNREACHABLE;
         } else {
-          AstTree *sizeTree = runExpression(array_metadata->parameters.data[0],
-                                            scope, shouldRet, false);
+          AstTree *sizeTree =
+              runExpression(array_metadata->parameters.data[0], scope,
+                            shouldRet, false, isComptime);
           if (sizeTree->token != AST_TREE_TOKEN_VALUE_INT) {
             UNREACHABLE;
           } else {
@@ -1272,7 +1319,8 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
     for (size_t i = 0; i < metadata->variables.size; ++i) {
       AstTreeVariable *member = metadata->variables.data[i];
       AstTree *type = member->type;
-      member->type = runExpression(member->type, scope, shouldRet, isLeft);
+      member->type =
+          runExpression(member->type, scope, shouldRet, isLeft, isComptime);
       if (type != member->type) {
         astTreeDelete(type);
       }
@@ -1282,14 +1330,15 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
   case AST_TREE_TOKEN_OPERATOR_POINTER: {
     AstTreeSingleChild *metadata = expr->metadata;
     AstTreeSingleChild *newMetadata =
-        runExpression(metadata, scope, shouldRet, isLeft);
+        runExpression(metadata, scope, shouldRet, isLeft, isComptime);
 
     return newAstTree(AST_TREE_TOKEN_OPERATOR_POINTER, newMetadata,
                       copyAstTree(expr->type), expr->str_begin, expr->str_end);
   }
   case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: {
     AstTreeBracket *metadata = expr->metadata;
-    AstTree *operand = runExpression(metadata->operand, scope, shouldRet, true);
+    AstTree *operand =
+        runExpression(metadata->operand, scope, shouldRet, true, isComptime);
 
     if (operand->token != AST_TREE_TOKEN_VARIABLE) {
       UNREACHABLE;
@@ -1297,8 +1346,8 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
       UNREACHABLE;
     }
 
-    AstTree *array_indexNode =
-        runExpression(metadata->parameters.data[0], scope, shouldRet, false);
+    AstTree *array_indexNode = runExpression(
+        metadata->parameters.data[0], scope, shouldRet, false, isComptime);
 
     if (array_indexNode->token != AST_TREE_TOKEN_VALUE_INT) {
       UNREACHABLE;
@@ -1314,8 +1363,9 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
       if (array_type_metadata->parameters.size != 1) {
         UNREACHABLE;
       }
-      AstTree *arraySize_tree = runExpression(
-          array_type_metadata->parameters.data[0], scope, shouldRet, false);
+      AstTree *arraySize_tree =
+          runExpression(array_type_metadata->parameters.data[0], scope,
+                        shouldRet, false, isComptime);
       if (arraySize_tree->token != AST_TREE_TOKEN_VALUE_INT) {
         UNREACHABLE;
       }
diff --git a/src/runner/runner.h b/src/runner/runner.h
index 4de6fbe..93b250a 100644
--- a/src/runner/runner.h
+++ b/src/runner/runner.h
@@ -9,11 +9,11 @@ void runnerVariableSetValueWihtoutConstCheck(AstTreeVariable *variable,
 bool runAstTree(AstTreeRoots roots);
 
 AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments,
-                            size_t arguments_size);
+                            size_t arguments_size,bool isComptime);
 
 AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope,
                            AstTreeFunctionCallParam *arguments,
-                           size_t arguments_size);
+                           size_t arguments_size,bool isComptime);
 
 AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
-                       bool isLeft);
+                       bool isLeft,bool isComptime);
-- 
cgit v1.2.3