summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-04 18:31:59 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-04 18:31:59 +0330
commit6bfad51dbde77267368811737d4ecbd557eac2e9 (patch)
tree3bb12aa2ba13926bd03591dd7560b38bfb58f222
parent2a03e1e42906605be5ea093bcaca212c41acb62f (diff)
first stuff to have a struct
-rw-r--r--code/main.felan14
-rw-r--r--src/compiler/ast-tree.c142
-rw-r--r--src/compiler/ast-tree.h10
-rw-r--r--src/compiler/lexer.c10
-rw-r--r--src/compiler/lexer.h1
-rw-r--r--src/compiler/parser.c33
-rw-r--r--src/compiler/parser.h2
7 files changed, 192 insertions, 20 deletions
diff --git a/code/main.felan b/code/main.felan
index 532afaa..f755d37 100644
--- a/code/main.felan
+++ b/code/main.felan
@@ -5,14 +5,12 @@ long :: i64;
float :: f32;
double :: f64;
-main :: () -> void {
- f := foo();
- f(3);
+st :: struct {
+ a : int;
+ b : double;
};
-foo :: ()->((u64)->void){
- f :: (a:u64)->void{
- print_u64 a;
- };
- return f;
+main :: () -> void {
+ print_u64 1234;
};
+
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 4c6d36d..261e13b 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_IF",
"AST_TREE_TOKEN_KEYWORD_WHILE",
"AST_TREE_TOKEN_KEYWORD_COMPTIME",
+ "AST_TREE_TOKEN_KEYWORD_STRUCT",
"AST_TREE_TOKEN_TYPE_FUNCTION",
"AST_TREE_TOKEN_TYPE_TYPE",
@@ -341,7 +342,6 @@ void astTreePrint(const AstTree *tree, int indent) {
case AST_TREE_TOKEN_OPERATOR_SMALLER:
case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: {
-
AstTreeInfix *metadata = tree->metadata;
printf(",\n");
for (int i = 0; i < indent; ++i)
@@ -412,6 +412,23 @@ void astTreePrint(const AstTree *tree, int indent) {
printf("]");
}
goto RETURN_SUCCESS;
+ case AST_TREE_TOKEN_KEYWORD_STRUCT: {
+ AstTreeStruct *metadata = tree->metadata;
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("variables=[\n");
+ for (size_t i = 0; i < metadata->variables.size; ++i) {
+ astTreeVariablePrint(metadata->variables.data[i], indent + 1);
+ printf(",\n");
+ }
+ for (int i = 0; i < indent; ++i) {
+ printf(" ");
+ }
+ printf("]");
+
+ goto RETURN_SUCCESS;
+ }
case AST_TREE_TOKEN_NONE:
}
@@ -421,14 +438,21 @@ RETURN_SUCCESS:
printf("}");
}
+void astTreeVariablePrint(const AstTreeVariable *variable, int indent) {
+ for (int i = 0; i < indent; ++i) {
+ printf(" ");
+ }
+ printf("{\nname=\"%.*s\",\nvalue=\n",
+ (int)(variable->name_end - variable->name_begin),
+ variable->name_begin);
+ astTreePrint(variable->value, indent);
+ printf("\n}");
+}
+
void astTreeRootPrint(const AstTreeRoot *root) {
for (size_t i = 0; i < root->variables.size; ++i) {
- const AstTreeVariable *variable = root->variables.data[i];
- printf("{\nname=\"%.*s\",\nvalue=\n",
- (int)(variable->name_end - variable->name_begin),
- variable->name_begin);
- astTreePrint(variable->value, 1);
- printf("\n}\n");
+ astTreeVariablePrint(root->variables.data[i], 0);
+ printf("\n");
}
}
@@ -581,6 +605,15 @@ void astTreeDestroy(AstTree tree) {
free(metadata);
}
return;
+ case AST_TREE_TOKEN_KEYWORD_STRUCT: {
+ AstTreeStruct *metadata = tree.metadata;
+ for (size_t i = 0; i < metadata->variables.size; ++i) {
+ astTreeVariableDelete(metadata->variables.data[i]);
+ }
+ free(metadata->variables.data);
+ free(metadata);
+ }
+ return;
case AST_TREE_TOKEN_NONE:
}
printLog("token = %d", tree.token);
@@ -908,6 +941,18 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[],
new_newVariables, new_variables_size),
tree->str_begin, tree->str_end);
}
+ case AST_TREE_TOKEN_KEYWORD_STRUCT: {
+ AstTreeStruct *metadata = tree->metadata;
+ AstTreeStruct *new_metadata = a404m_malloc(sizeof(*new_metadata));
+
+ new_metadata->variables = copyAstTreeVariables(
+ metadata->variables, oldVariables, newVariables, variables_size);
+
+ return newAstTree(
+ tree->token, new_metadata,
+ copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size),
+ tree->str_begin, tree->str_end);
+ }
case AST_TREE_TOKEN_NONE:
}
printLog("Bad token %d", tree->token);
@@ -1078,6 +1123,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
case PARSER_TOKEN_OPERATOR_POINTER:
case PARSER_TOKEN_OPERATOR_ADDRESS:
case PARSER_TOKEN_OPERATOR_DEREFERENCE:
+ case PARSER_TOKEN_KEYWORD_STRUCT:
goto AFTER_SWITCH;
case PARSER_TOKEN_ROOT:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
@@ -1337,6 +1383,8 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) {
return astTreeParseCurlyBracket(parserNode, helper);
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
return astTreeParseParenthesis(parserNode, helper);
+ case PARSER_TOKEN_KEYWORD_STRUCT:
+ return astTreeParseStruct(parserNode, helper);
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_NONE:
@@ -1450,6 +1498,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) {
case PARSER_TOKEN_KEYWORD_PRINT_U64:
case PARSER_TOKEN_KEYWORD_RETURN:
case PARSER_TOKEN_KEYWORD_COMPTIME:
+ case PARSER_TOKEN_KEYWORD_STRUCT:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
@@ -1991,6 +2040,7 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode,
case PARSER_TOKEN_KEYWORD_PRINT_U64:
case PARSER_TOKEN_KEYWORD_RETURN:
case PARSER_TOKEN_KEYWORD_COMPTIME:
+ case PARSER_TOKEN_KEYWORD_STRUCT:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
@@ -2078,6 +2128,56 @@ AstTree *astTreeParseParenthesis(ParserNode *parserNode,
}
}
+AstTree *astTreeParseStruct(ParserNode *parserNode, AstTreeHelper *helper) {
+ ParserNode *body = parserNode->metadata;
+ ParserNodeArray *body_metadata = body->metadata;
+ AstTreeVariables variables = {
+ .data = a404m_malloc(sizeof(*variables.data) * body_metadata->size),
+ .size = body_metadata->size,
+ };
+
+ for (size_t i = 0; i < body_metadata->size; ++i) {
+ ParserNode *node = body_metadata->data[i];
+ if (node->token != PARSER_TOKEN_SYMBOL_EOL) {
+ printError(node->str_begin, node->str_end,
+ "Semicolon is required, maybe forget a semicolon?");
+ return NULL;
+ }
+ node = (ParserNodeSingleChildMetadata *)node->metadata;
+
+ if (node->token != PARSER_TOKEN_VARIABLE) {
+ printError(node->str_begin, node->str_end,
+ "Only variable definitions are allowed here");
+ return NULL;
+ }
+ ParserNodeVariableMetadata *node_variable = node->metadata;
+
+ AstTreeVariable *variable = a404m_malloc(sizeof(*variable));
+ variable->name_begin = node_variable->name->str_begin;
+ variable->name_end = node_variable->name->str_end;
+ if (node_variable->type != NULL) {
+ variable->type = astTreeParse(node_variable->type, helper);
+ } else {
+ variable->type = NULL;
+ }
+ if (node_variable->value != NULL) {
+ printError(node->str_begin, node->str_end, "Can't have default values");
+ NOT_IMPLEMENTED;
+ }
+ variable->value = NULL;
+ variable->isConst = false;
+
+ variables.data[i] = variable;
+ }
+
+ AstTreeStruct *metadata = a404m_malloc(sizeof(*metadata));
+ metadata->variables = variables;
+ metadata->id = (size_t)metadata; // TODO: change it
+
+ return newAstTree(AST_TREE_TOKEN_KEYWORD_STRUCT, metadata, NULL,
+ parserNode->str_begin, parserNode->str_end);
+}
+
bool isFunction(AstTree *value) {
return value->type->token == AST_TREE_TOKEN_TYPE_FUNCTION;
}
@@ -2107,6 +2207,7 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) {
case AST_TREE_TOKEN_VALUE_BOOL:
case AST_TREE_TOKEN_KEYWORD_COMPTIME:
case AST_TREE_TOKEN_SCOPE:
+ case AST_TREE_TOKEN_KEYWORD_STRUCT:
return true;
case AST_TREE_TOKEN_KEYWORD_IF: {
AstTreeIf *metadata = tree->metadata;
@@ -2179,6 +2280,7 @@ AstTree *makeTypeOf(AstTree *value) {
case AST_TREE_TOKEN_TYPE_F128:
case AST_TREE_TOKEN_TYPE_BOOL:
case AST_TREE_TOKEN_OPERATOR_POINTER:
+ case AST_TREE_TOKEN_KEYWORD_STRUCT:
return &AST_TREE_TYPE_TYPE;
case AST_TREE_TOKEN_OPERATOR_ADDRESS: {
AstTreeSingleChild *metadata = value->metadata;
@@ -2348,6 +2450,14 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_VARIABLE:
return type1->token == AST_TREE_TOKEN_VARIABLE &&
type0->metadata == type1->metadata;
+ case AST_TREE_TOKEN_KEYWORD_STRUCT: {
+ if (type1->token != AST_TREE_TOKEN_KEYWORD_STRUCT)
+ return false;
+
+ AstTreeStruct *type0_metadata = type0->metadata;
+ AstTreeStruct *type1_metadata = type1->metadata;
+ return type0_metadata->id == type1_metadata->id;
+ }
case AST_TREE_TOKEN_NONE:
}
UNREACHABLE;
@@ -2411,6 +2521,7 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) {
}
return value;
}
+ case AST_TREE_TOKEN_KEYWORD_STRUCT:
case AST_TREE_TOKEN_FUNCTION: {
return tree;
}
@@ -2437,7 +2548,6 @@ bool isCircularDependenciesBack(AstTreeHelper *helper,
AstTreeVariable *variable, AstTree *tree,
AstTreeVariables *checkedVariables) {
switch (tree->token) {
- case AST_TREE_TOKEN_SCOPE:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -2517,9 +2627,11 @@ bool isCircularDependenciesBack(AstTreeHelper *helper,
}
return false;
}
+ case AST_TREE_TOKEN_KEYWORD_STRUCT:
case AST_TREE_TOKEN_FUNCTION: {
return false;
}
+ case AST_TREE_TOKEN_SCOPE:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
@@ -2668,6 +2780,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
return setTypesScope(tree, helper, function);
case AST_TREE_TOKEN_KEYWORD_COMPTIME:
return setTypesComptime(tree, helper);
+ case AST_TREE_TOKEN_KEYWORD_STRUCT:
+ return setTypesStruct(tree, helper);
case AST_TREE_TOKEN_NONE:
break;
}
@@ -3302,6 +3416,18 @@ bool setTypesComptime(AstTree *tree, AstTreeSetTypesHelper helper) {
return true;
}
+bool setTypesStruct(AstTree *tree, AstTreeSetTypesHelper helper) {
+ AstTreeStruct *metadata = tree->metadata;
+
+ for (size_t i = 0; i < metadata->variables.size; ++i) {
+ if (!setAllTypes(metadata->variables.data[i]->type, helper, NULL)) {
+ return false;
+ }
+ }
+ tree->type = &AST_TREE_TYPE_TYPE;
+ return true;
+}
+
bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper) {
if (!setAllTypes(&infix->left, helper, NULL)) {
return false;
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 1513284..a62e195 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -3,6 +3,7 @@
#include "compiler/parser.h"
#include <stddef.h>
#include <stdint.h>
+#include <sys/types.h>
typedef enum AstTreeToken {
AST_TREE_TOKEN_FUNCTION,
@@ -12,6 +13,7 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_KEYWORD_IF,
AST_TREE_TOKEN_KEYWORD_WHILE,
AST_TREE_TOKEN_KEYWORD_COMPTIME,
+ AST_TREE_TOKEN_KEYWORD_STRUCT,
AST_TREE_TOKEN_TYPE_FUNCTION,
AST_TREE_TOKEN_TYPE_TYPE,
@@ -186,7 +188,13 @@ typedef struct AstTreeSetTypesHelper {
AstTreeHelper *treeHelper;
} AstTreeSetTypesHelper;
+typedef struct AstTreeStruct {
+ size_t id;
+ AstTreeVariables variables;
+} AstTreeStruct;
+
void astTreePrint(const AstTree *tree, int indent);
+void astTreeVariablePrint(const AstTreeVariable *variable, int indent);
void astTreeRootPrint(const AstTreeRoot *root);
void astTreeDestroy(AstTree tree);
@@ -241,6 +249,7 @@ AstTree *astTreeParseComptime(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseCurlyBracket(ParserNode *parserNode,
AstTreeHelper *helper);
AstTree *astTreeParseParenthesis(ParserNode *parserNode, AstTreeHelper *helper);
+AstTree *astTreeParseStruct(ParserNode *parserNode, AstTreeHelper *helper);
bool isFunction(AstTree *value);
bool isConst(AstTree *tree, AstTreeHelper *helper);
@@ -287,6 +296,7 @@ bool setTypesWhile(AstTree *tree, AstTreeSetTypesHelper helper,
bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunction *function);
bool setTypesComptime(AstTree *tree, AstTreeSetTypesHelper helper);
+bool setTypesStruct(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesAstVariable(AstTreeVariable *variable,
AstTreeSetTypesHelper helper);
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index 75fb04b..618851d 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -36,6 +36,7 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_KEYWORD_WHILE",
"LEXER_TOKEN_KEYWORD_COMPTIME",
"LEXER_TOKEN_KEYWORD_NULL",
+ "LEXER_TOKEN_KEYWORD_STRUCT",
"LEXER_TOKEN_NUMBER",
@@ -111,9 +112,10 @@ 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", "comptime", "null",
+ "type", "void", "i8", "u8", "i16", "u16", "i32",
+ "u32", "i64", "u64", "f16", "f32", "f64", "f128",
+ "bool", "print_u64", "return", "true", "false", "if", "else",
+ "while", "comptime", "null", "struct",
};
const LexerToken LEXER_KEYWORD_TOKENS[] = {
LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID,
@@ -128,6 +130,7 @@ const LexerToken LEXER_KEYWORD_TOKENS[] = {
LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_KEYWORD_IF,
LEXER_TOKEN_KEYWORD_ELSE, LEXER_TOKEN_KEYWORD_WHILE,
LEXER_TOKEN_KEYWORD_COMPTIME, LEXER_TOKEN_KEYWORD_NULL,
+ LEXER_TOKEN_KEYWORD_STRUCT,
};
const size_t LEXER_KEYWORD_SIZE =
sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS);
@@ -281,6 +284,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter,
case LEXER_TOKEN_KEYWORD_WHILE:
case LEXER_TOKEN_KEYWORD_COMPTIME:
case LEXER_TOKEN_KEYWORD_NULL:
+ case LEXER_TOKEN_KEYWORD_STRUCT:
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 5e2496b..6daa893 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -29,6 +29,7 @@ typedef enum LexerToken {
LEXER_TOKEN_KEYWORD_WHILE,
LEXER_TOKEN_KEYWORD_COMPTIME,
LEXER_TOKEN_KEYWORD_NULL,
+ LEXER_TOKEN_KEYWORD_STRUCT,
LEXER_TOKEN_NUMBER,
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 69a9c8a..d7fbade 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -41,6 +41,7 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_KEYWORD_WHILE",
"PARSER_TOKEN_KEYWORD_COMPTIME",
"PARSER_TOKEN_KEYWORD_NULL",
+ "PARSER_TOKEN_KEYWORD_STRUCT",
"PARSER_TOKEN_CONSTANT",
"PARSER_TOKEN_VARIABLE",
@@ -106,7 +107,7 @@ static constexpr ParserOrder PARSER_ORDER[] = {
{
.ltr = false,
ORDER_ARRAY(LEXER_TOKEN_SYMBOL_FUNCTION_ARROW,
- LEXER_TOKEN_SYMBOL_POINTER, ),
+ LEXER_TOKEN_SYMBOL_POINTER, LEXER_TOKEN_KEYWORD_STRUCT, ),
},
{
.ltr = true,
@@ -245,6 +246,7 @@ void parserNodePrint(const ParserNode *node, int indent) {
printf(" ");
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_KEYWORD_STRUCT:
case PARSER_TOKEN_OPERATOR_POINTER:
case PARSER_TOKEN_OPERATOR_ADDRESS:
case PARSER_TOKEN_OPERATOR_DEREFERENCE:
@@ -482,6 +484,7 @@ void parserNodeDelete(ParserNode *node) {
free(metadata);
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_KEYWORD_STRUCT:
case PARSER_TOKEN_OPERATOR_POINTER:
case PARSER_TOKEN_OPERATOR_ADDRESS:
case PARSER_TOKEN_OPERATOR_DEREFERENCE:
@@ -816,6 +819,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
return parserWhile(node, end, parent);
case LEXER_TOKEN_KEYWORD_COMPTIME:
return parserComptime(node, end, parent);
+ case LEXER_TOKEN_KEYWORD_STRUCT:
+ return parserStruct(node, end, parent);
case LEXER_TOKEN_KEYWORD_ELSE:
case LEXER_TOKEN_SYMBOL:
case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS:
@@ -1209,6 +1214,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
case PARSER_TOKEN_KEYWORD_NULL:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
case PARSER_TOKEN_KEYWORD_RETURN:
+ case PARSER_TOKEN_KEYWORD_STRUCT:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
@@ -1599,6 +1605,28 @@ ParserNode *parserComptime(LexerNode *node, LexerNode *end,
(ParserNodeSingleChildMetadata *)operand, parent);
}
+ParserNode *parserStruct(LexerNode *node, LexerNode *end, ParserNode *parent) {
+ LexerNode *next = node + 1;
+ if (next >= end) {
+ printError(node->str_begin, node->str_end, "Bad struct without a body");
+ return NULL;
+ }
+
+ ParserNode *operand = getUntilCommonParent(next->parserNode, parent);
+
+ if (operand == NULL) {
+ printError(node->str_begin, node->str_end, "Bad struct without a body");
+ return NULL;
+ } else if (operand->token != PARSER_TOKEN_SYMBOL_CURLY_BRACKET) {
+ printError(node->str_begin, node->str_end, "Bad body");
+ return NULL;
+ }
+
+ return operand->parent = node->parserNode = newParserNode(
+ PARSER_TOKEN_KEYWORD_STRUCT, 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];
@@ -1664,6 +1692,7 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_TYPE_F64:
case PARSER_TOKEN_TYPE_F128:
case PARSER_TOKEN_KEYWORD_NULL:
+ case PARSER_TOKEN_KEYWORD_STRUCT:
return true;
case PARSER_TOKEN_ROOT:
case PARSER_TOKEN_SYMBOL_EOL:
@@ -1700,6 +1729,7 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_OPERATOR_POINTER:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
+ case PARSER_TOKEN_KEYWORD_STRUCT:
return true;
case PARSER_TOKEN_OPERATOR_ADDRESS:
case PARSER_TOKEN_KEYWORD_NULL:
@@ -1791,6 +1821,7 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_KEYWORD_IF:
case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
+ case PARSER_TOKEN_KEYWORD_STRUCT:
return true;
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index e566696..317e913 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -37,6 +37,7 @@ typedef enum ParserToken {
PARSER_TOKEN_KEYWORD_WHILE,
PARSER_TOKEN_KEYWORD_COMPTIME,
PARSER_TOKEN_KEYWORD_NULL,
+ PARSER_TOKEN_KEYWORD_STRUCT,
PARSER_TOKEN_CONSTANT,
PARSER_TOKEN_VARIABLE,
@@ -197,6 +198,7 @@ ParserNode *parserRightOperator(LexerNode *node, LexerNode *begin,
ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent);
ParserNode *parserWhile(LexerNode *node, LexerNode *end, ParserNode *parent);
ParserNode *parserComptime(LexerNode *node, LexerNode *end, ParserNode *parent);
+ParserNode *parserStruct(LexerNode *node, LexerNode *end, ParserNode *parent);
bool isAllArguments(const ParserNodeArray *nodes);