diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/ast-tree.c | 66 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 11 | ||||
-rw-r--r-- | src/compiler/code-generator.c | 43 | ||||
-rw-r--r-- | src/compiler/code-generator.h | 6 | ||||
-rw-r--r-- | src/compiler/lexer.c | 4 | ||||
-rw-r--r-- | src/compiler/lexer.h | 1 | ||||
-rw-r--r-- | src/compiler/parser.c | 80 | ||||
-rw-r--r-- | src/compiler/parser.h | 10 |
8 files changed, 196 insertions, 25 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 729aa18..22ce146 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -7,9 +7,14 @@ #include <string.h> const char *AST_TREE_TOKEN_STRINGS[] = { - "AST_TREE_TOKEN_FUNCTION", "AST_TREE_TOKEN_KEYWORD_PRINT", - "AST_TREE_TOKEN_NONE", "AST_TREE_TOKEN_TYPE_FUNCTION", - "AST_TREE_TOKEN_TYPE_VOID", "AST_TREE_TOKEN_FUNCTION_CALL", + "AST_TREE_TOKEN_FUNCTION", + "AST_TREE_TOKEN_KEYWORD_PRINT", + "AST_TREE_TOKEN_KEYWORD_PRINT_U64", + + "AST_TREE_TOKEN_NONE", + "AST_TREE_TOKEN_TYPE_FUNCTION", + "AST_TREE_TOKEN_TYPE_VOID", + "AST_TREE_TOKEN_FUNCTION_CALL", "AST_TREE_TOKEN_IDENTIFIER", }; @@ -58,6 +63,20 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_KEYWORD_PRINT: case AST_TREE_TOKEN_TYPE_VOID: goto RETURN_SUCCESS; + case AST_TREE_TOKEN_KEYWORD_PRINT_U64: { + AstTreeSingleChild *metadata = tree->metadata; + printf(",\n"); + for (int i = 0; i < indent; ++i) + printf(" "); + printf("child=\n"); + astTreePrint(metadata, indent + 1); + } + goto RETURN_SUCCESS; + case AST_TREE_TOKEN_VALUE_U64: { + AstTreeU64 metadata = (AstTreeU64)tree->metadata; + printf(",value=%lu", metadata); + } + goto RETURN_SUCCESS; case AST_TREE_TOKEN_TYPE_FUNCTION: { AstTreeTypeFunction *metadata = tree->metadata; printf(",\n"); @@ -143,6 +162,12 @@ void astTreeDestroy(AstTree tree) { return; case AST_TREE_TOKEN_KEYWORD_PRINT: case AST_TREE_TOKEN_TYPE_VOID: + case AST_TREE_TOKEN_VALUE_U64: + return; + case AST_TREE_TOKEN_KEYWORD_PRINT_U64: { + AstTreeSingleChild *metadata = tree.metadata; + astTreeDelete(metadata); + } return; case AST_TREE_TOKEN_TYPE_FUNCTION: { AstTreeTypeFunction *metadata = tree.metadata; @@ -224,7 +249,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { printLog("Unexpected %s", PARSER_TOKEN_STRINGS[eol->token]); goto RETURN_ERROR; } - ParserNode *node = (ParserNodeEOLMetadata *)eol->metadata; + ParserNode *node = (ParserNodeSingleChildMetadata *)eol->metadata; if (node->token != PARSER_TOKEN_CONSTANT) { printLog("Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -239,7 +264,8 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { } for (size_t i = 0; i < nodes->size; ++i) { - ParserNode *node = (ParserNodeEOLMetadata *)nodes->data[i]->metadata; + ParserNode *node = + (ParserNodeSingleChildMetadata *)nodes->data[i]->metadata; ParserNodeVariableMetadata *node_metadata = node->metadata; AstTree *type; @@ -319,6 +345,12 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables *variables, return astTreeParseFunctionCall(parserNode, variables, variables_size); case PARSER_TOKEN_IDENTIFIER: return astTreeParseIdentifier(parserNode, variables, variables_size); + case PARSER_TOKEN_VALUE_U64: + return newAstTree( + AST_TREE_TOKEN_VALUE_U64, + (void *)(AstTreeU64)(ParserNodeU64Metadata)parserNode->metadata); + case PARSER_TOKEN_KEYWORD_PRINT_U64: + return astTreeParsePrintU64(parserNode, variables, variables_size); case PARSER_TOKEN_SYMBOL_EOL: case PARSER_TOKEN_SYMBOL_PARENTHESIS: case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: @@ -393,7 +425,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, printLog("Unexpected %s", PARSER_TOKEN_STRINGS[eol->token]); goto RETURN_ERROR; } - ParserNode *node = (ParserNodeEOLMetadata *)eol->metadata; + ParserNode *node = (ParserNodeSingleChildMetadata *)eol->metadata; AstTree *tree = astTreeParse(node, variables, variables_size); if (tree == NULL) { @@ -528,6 +560,22 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode, return newAstTree(AST_TREE_TOKEN_IDENTIFIER, (AstTreeIdentifier *)var); } +AstTree *astTreeParsePrintU64(ParserNode *parserNode, + AstTreeVariables *variables, + size_t variables_size) { + ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata; + + AstTree *operand = astTreeParse(node_metadata, variables, variables_size); + if (operand == NULL) { + return NULL; + } + + // TODO: check type to be u64 + + return newAstTree(AST_TREE_TOKEN_KEYWORD_PRINT_U64, + (AstTreeSingleChild *)operand); +} + bool hasTypeOf(AstTree *value, AstTree *type) { switch (type->token) { case AST_TREE_TOKEN_TYPE_FUNCTION: @@ -576,9 +624,9 @@ bool typeIsEqual(AstTree *type0, AstTree *type1) { case AST_TREE_TOKEN_TYPE_VOID: return type1->token == AST_TREE_TOKEN_TYPE_VOID; case AST_TREE_TOKEN_TYPE_FUNCTION: - if(type1->token != AST_TREE_TOKEN_TYPE_FUNCTION){ - return false; - } + if (type1->token != AST_TREE_TOKEN_TYPE_FUNCTION) { + return false; + } printLog("Not implemented yet"); exit(1); case AST_TREE_TOKEN_FUNCTION_CALL: diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index e92cb08..8a7617d 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -2,14 +2,17 @@ #include "compiler/parser.h" #include <stddef.h> +#include <stdint.h> typedef enum AstTreeToken { AST_TREE_TOKEN_FUNCTION, AST_TREE_TOKEN_KEYWORD_PRINT, + AST_TREE_TOKEN_KEYWORD_PRINT_U64, AST_TREE_TOKEN_TYPE_FUNCTION, AST_TREE_TOKEN_TYPE_VOID, AST_TREE_TOKEN_FUNCTION_CALL, AST_TREE_TOKEN_IDENTIFIER, + AST_TREE_TOKEN_VALUE_U64, AST_TREE_TOKEN_NONE, } AstTreeToken; @@ -62,6 +65,10 @@ typedef struct AstTreeFunctionCall { typedef AstTreeVariable AstTreeIdentifier; +typedef uint64_t AstTreeU64; + +typedef AstTree AstTreeSingleChild; + extern const char *AST_TREE_TOKEN_STRINGS[]; void astTreePrint(const AstTree *tree, int indent); @@ -100,5 +107,9 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeVariables *variables, size_t variables_size); +AstTree *astTreeParsePrintU64(ParserNode *parserNode, + AstTreeVariables *variables, + size_t variables_size); + bool hasTypeOf(AstTree *value, AstTree *type); bool typeIsEqual(AstTree *type0, AstTree *type1); diff --git a/src/compiler/code-generator.c b/src/compiler/code-generator.c index d9fc05d..fb843d0 100644 --- a/src/compiler/code-generator.c +++ b/src/compiler/code-generator.c @@ -3,6 +3,7 @@ #include "utils/log.h" #include "utils/memory.h" #include <assert.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -12,6 +13,7 @@ void codeGeneratorDelete(CodeGeneratorCodes *code) { CodeGeneratorCode current = code->codes[i]; switch (current.instruction) { case CODE_GENERATOR_INSTRUCTION_PRINT: + case CODE_GENERATOR_INSTRUCTION_PRINT_U64: case CODE_GENERATOR_INSTRUCTION_RET: continue; case CODE_GENERATOR_INSTRUCTION_CALL: { @@ -122,6 +124,21 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end, callMetadata)); } goto OK; + case AST_TREE_TOKEN_KEYWORD_PRINT_U64: { + AstTreeSingleChild *metadata = tree.metadata; + if (metadata->token == AST_TREE_TOKEN_VALUE_U64) { + CodeGeneratorOperandU64 value = (AstTreeU64)metadata->metadata; + generateCodePushCode( + codes, createGenerateCode(label_begin, label_end, + CODE_GENERATOR_INSTRUCTION_PRINT_U64, + (void *)value)); + } else { + printLog("Not implemented yet"); + exit(1); + } + } + goto OK; + case AST_TREE_TOKEN_VALUE_U64: case AST_TREE_TOKEN_IDENTIFIER: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_TYPE_FUNCTION: @@ -143,13 +160,16 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end, } static const char TEMPLATE[] = - "format ELF64 executable 3\nSYS_exit = 60\nSYS_write = 1\nSTDOUT = " - "1\nsegment readable writable\nhello: db \"Hello, " - "World!\",0xa\nhello_len = $-hello\nsegment readable executable\nentry " - "_start\nprint:\nmov rax, SYS_write\nmov rdi, STDOUT\nmov rsi, " - "hello\nmov rdx, hello_len\nsyscall\nret\n_start:\ncall main\nmov rax, " - "SYS_exit\nxor " - "rdi,rdi\nsyscall\n"; + "format ELF64 executable 3\n\nSYS_exit = 60\nSYS_write = 1\nSTDOUT = " + "1\n\nsegment readable writable\nhello: db \"Hello, " + "World!\",0xa\nhello_len = $-hello\n\nsegment readable executable\nentry " + "_start\n\nprint:\nmov rax, SYS_write\nmov rdi, STDOUT\nmov rsi, " + "hello\nmov rdx, hello_len\nsyscall\nret\n\n; rdi = the " + "number\nprint_u64:\nmov rcx, rsp\nmov rax, rdi\nmov rbx, 10\n\n.L:\nxor " + "rdx, rdx\ndiv rbx\nadd dl, '0'\ndec rcx\nmov [rcx],dl\ncmp rax, 0\njnz " + ".L\n\nmov rax, SYS_write\nmov rdi, STDOUT\nmov rsi, rcx\n\nmov rdx, " + "rsp\nsub rdx, rcx\n\nsyscall\nret\n\n_start:\ncall main\nmov rax, " + "SYS_exit\nxor rdi,rdi\nsyscall\n"; static const size_t TEMPLATE_LEN = sizeof(TEMPLATE) / sizeof(*TEMPLATE) - sizeof(*TEMPLATE); @@ -191,6 +211,15 @@ char *codeGeneratorToFlatASM(const CodeGeneratorCodes *codes) { strlen(INST)); } continue; + case CODE_GENERATOR_INSTRUCTION_PRINT_U64: { + CodeGeneratorOperandU64 metadata = (CodeGeneratorOperandU64)code.metadata; + char *inst; + asprintf(&inst, "mov rdi,%lu\ncall print_u64\n", (uint64_t)metadata); + codeGeneratorAppendFlatASMCommand(&fasm, &fasm_size, &fasm_inserted, inst, + strlen(inst)); + free(inst); + } + continue; case CODE_GENERATOR_INSTRUCTION_CALL: { CodeGeneratorCall *metadata = code.metadata; constexpr char CALL_INST[] = "call "; diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h index 94552ed..ace6e97 100644 --- a/src/compiler/code-generator.h +++ b/src/compiler/code-generator.h @@ -6,6 +6,7 @@ typedef enum CodeGeneratorInstruction : uint8_t { CODE_GENERATOR_INSTRUCTION_PRINT, + CODE_GENERATOR_INSTRUCTION_PRINT_U64, CODE_GENERATOR_INSTRUCTION_CALL, CODE_GENERATOR_INSTRUCTION_RET, } CodeGeneratorInstruction; @@ -22,6 +23,8 @@ typedef struct CodeGeneratorCall { char *label_end; } CodeGeneratorCall; +typedef uint64_t CodeGeneratorOperandU64; + typedef struct CodeGeneratorCodes { CodeGeneratorCode *codes; size_t codes_size; @@ -30,7 +33,8 @@ typedef struct CodeGeneratorCodes { void codeGeneratorDelete(CodeGeneratorCodes *code); CodeGeneratorCode createGenerateCode(char *label_begin, char *label_end, - CodeGeneratorInstruction instruction,void *metadata); + CodeGeneratorInstruction instruction, + void *metadata); CodeGeneratorCode *newGenerateCode(char *label_begin, char *label_end, CodeGeneratorInstruction instruction); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 8994bce..8b8b6bb 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -12,6 +12,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_IDENTIFIER", "LEXER_TOKEN_KEYWORD_VOID", "LEXER_TOKEN_KEYWORD_PRINT", + "LEXER_TOKEN_KEYWORD_PRINT_U64", "LEXER_TOKEN_NUMBER", @@ -47,10 +48,12 @@ const size_t LEXER_SYMBOL_SIZE = const char *LEXER_KEYWORD_STRINGS[] = { "void", "print", + "print_u64", }; const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_VOID, LEXER_TOKEN_KEYWORD_PRINT, + LEXER_TOKEN_KEYWORD_PRINT_U64, }; const size_t LEXER_KEYWORD_SIZE = sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS); @@ -169,6 +172,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, PUSH: case LEXER_TOKEN_KEYWORD_VOID: case LEXER_TOKEN_KEYWORD_PRINT: + case LEXER_TOKEN_KEYWORD_PRINT_U64: 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 f77522d..c3871e0 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -6,6 +6,7 @@ typedef enum LexerToken { LEXER_TOKEN_IDENTIFIER, LEXER_TOKEN_KEYWORD_VOID, LEXER_TOKEN_KEYWORD_PRINT, + LEXER_TOKEN_KEYWORD_PRINT_U64, LEXER_TOKEN_NUMBER, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 14125cc..333d755 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -2,6 +2,7 @@ #include "compiler/lexer.h" #include "utils/log.h" #include "utils/memory.h" +#include "utils/string.h" #include <stddef.h> #include <stdint.h> #include <stdio.h> @@ -12,10 +13,13 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_IDENTIFIER", + "PARSER_TOKEN_VALUE_U64", + "PARSER_TOKEN_TYPE_FUNCTION", "PARSER_TOKEN_TYPE_VOID", "PARSER_TOKEN_KEYWORD_PRINT", + "PARSER_TOKEN_KEYWORD_PRINT_U64", "PARSER_TOKEN_CONSTANT", @@ -42,12 +46,13 @@ static constexpr ParserOrder PARSER_ORDER[] = { }, { .ltr = true, - .size = 3, + .size = 4, .data = { LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS, LEXER_TOKEN_IDENTIFIER, LEXER_TOKEN_KEYWORD_VOID, + LEXER_TOKEN_NUMBER, }, }, { @@ -60,11 +65,12 @@ static constexpr ParserOrder PARSER_ORDER[] = { }, { .ltr = true, - .size = 2, + .size = 3, .data = { LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_KEYWORD_PRINT, + LEXER_TOKEN_KEYWORD_PRINT_U64, }, }, { @@ -111,6 +117,11 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_KEYWORD_PRINT: goto RETURN_SUCCESS; + case PARSER_TOKEN_VALUE_U64: { + ParserNodeU64Metadata metadata = (ParserNodeU64Metadata)node->metadata; + printf(",operand=%lu", metadata); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_CONSTANT: { const ParserNodeVariableMetadata *metadata = node->metadata; printf(",\n"); @@ -133,9 +144,10 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(" "); } goto RETURN_SUCCESS; + case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_SYMBOL_COMMA: case PARSER_TOKEN_SYMBOL_EOL: { - const ParserNodeEOLMetadata *metadata = node->metadata; + const ParserNodeSingleChildMetadata *metadata = node->metadata; printf(",\n"); for (int i = 0; i < indent; ++i) printf(" "); @@ -233,6 +245,7 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_KEYWORD_PRINT: + case PARSER_TOKEN_VALUE_U64: goto RETURN_SUCCESS; case PARSER_TOKEN_CONSTANT: { ParserNodeVariableMetadata *metadata = node->metadata; @@ -242,9 +255,10 @@ void parserNodeDelete(ParserNode *node) { free(metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_SYMBOL_COMMA: case PARSER_TOKEN_SYMBOL_EOL: { - ParserNodeEOLMetadata *metadata = node->metadata; + ParserNodeSingleChildMetadata *metadata = node->metadata; parserNodeDelete(metadata); } goto RETURN_SUCCESS; @@ -384,6 +398,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserVoid(node, parent); case LEXER_TOKEN_KEYWORD_PRINT: return parserPrint(node, parent); + case LEXER_TOKEN_KEYWORD_PRINT_U64: + return parserPrintU64(node, end, parent); case LEXER_TOKEN_SYMBOL_EOL: return parserEol(node, begin, parent); case LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS: @@ -396,8 +412,9 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserVariable(node, begin, end, parent); case LEXER_TOKEN_SYMBOL_COMMA: return parserComma(node, begin, parent); - case LEXER_TOKEN_NONE: case LEXER_TOKEN_NUMBER: + return parserNumber(node, parent); + case LEXER_TOKEN_NONE: case LEXER_TOKEN_SYMBOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET: @@ -431,6 +448,49 @@ ParserNode *parserPrint(LexerNode *node, ParserNode *parent) { node->str_end, NULL, parent); } +ParserNode *parserPrintU64(LexerNode *node, LexerNode *end, + ParserNode *parent) { + LexerNode *afterNode = node + 1; + if (afterNode >= end) { + printLog("No param"); + return NULL; + } else if (afterNode->parserNode == NULL) { + printLog("Bad param"); + return NULL; + } + + ParserNode *operand = getUntilCommonParent(afterNode->parserNode, parent); + if (operand == NULL) { + printLog("No param"); + return NULL; + } + + return operand->parent = node->parserNode = newParserNode( + PARSER_TOKEN_KEYWORD_PRINT_U64, node->str_begin, node->str_end, + (ParserNodeSingleChildMetadata *)operand, parent); +} + +ParserNode *parserNumber(LexerNode *node, ParserNode *parent) { + ParserNode *parserNode; + switch (*node->str_begin) { + case '0': + printLog("Not implemented"); + return NULL; + default: { + bool success; + uint64_t value = decimalToU64(node->str_begin, node->str_end, &success); + if (!success) { + printLog("Error in parsing number"); + return NULL; + } + parserNode = + newParserNode(PARSER_TOKEN_VALUE_U64, node->str_begin, node->str_end, + (void *)(ParserNodeU64Metadata)value, parent); + } + } + return node->parserNode = parserNode; +} + ParserNode *parserEol(LexerNode *node, LexerNode *begin, ParserNode *parent) { LexerNode *nodeBeore = node - 1; ParserNode *parserNodeBefore; @@ -448,7 +508,7 @@ ParserNode *parserEol(LexerNode *node, LexerNode *begin, ParserNode *parent) { } ParserNode *parserNode = newParserNode(PARSER_TOKEN_SYMBOL_EOL, node->str_begin, node->str_end, - (ParserNodeEOLMetadata *)parserNodeBefore, parent); + (ParserNodeSingleChildMetadata *)parserNodeBefore, parent); node->parserNode = parserNode; if (parserNodeBefore != NULL) { parserNodeBefore->parent = parserNode; @@ -471,7 +531,7 @@ ParserNode *parserComma(LexerNode *node, LexerNode *begin, ParserNode *parent) { } return node->parserNode = parserNodeBefore->parent = newParserNode( PARSER_TOKEN_SYMBOL_COMMA, node->str_begin, node->str_end, - (ParserNodeEOLMetadata *)parserNodeBefore, parent); + (ParserNodeSingleChildMetadata *)parserNodeBefore, parent); } ParserNode *parserParenthesis(LexerNode *closing, LexerNode *begin, @@ -742,6 +802,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_KEYWORD_PRINT: case PARSER_TOKEN_FUNCTION_CALL: + case PARSER_TOKEN_KEYWORD_PRINT_U64: return true; case PARSER_TOKEN_ROOT: case PARSER_TOKEN_TYPE_FUNCTION: @@ -749,6 +810,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_SYMBOL_EOL: case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: case PARSER_TOKEN_SYMBOL_COMMA: + case PARSER_TOKEN_VALUE_U64: return false; case PARSER_TOKEN_NONE: } @@ -771,6 +833,8 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: case PARSER_TOKEN_SYMBOL_COMMA: case PARSER_TOKEN_FUNCTION_CALL: + case PARSER_TOKEN_VALUE_U64: + case PARSER_TOKEN_KEYWORD_PRINT_U64: return false; case PARSER_TOKEN_NONE: } @@ -782,6 +846,7 @@ bool isValue(ParserNode *node) { switch (node->token) { case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: + case PARSER_TOKEN_VALUE_U64: return true; case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_IDENTIFIER: @@ -793,6 +858,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_SYMBOL_EOL: case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: case PARSER_TOKEN_SYMBOL_COMMA: + case PARSER_TOKEN_KEYWORD_PRINT_U64: return false; case PARSER_TOKEN_NONE: } diff --git a/src/compiler/parser.h b/src/compiler/parser.h index fb65358..974fdd5 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -2,16 +2,20 @@ #include "compiler/lexer.h" #include <stddef.h> +#include <stdint.h> typedef enum ParserToken { PARSER_TOKEN_ROOT, PARSER_TOKEN_IDENTIFIER, + PARSER_TOKEN_VALUE_U64, + PARSER_TOKEN_TYPE_FUNCTION, PARSER_TOKEN_TYPE_VOID, PARSER_TOKEN_KEYWORD_PRINT, + PARSER_TOKEN_KEYWORD_PRINT_U64, PARSER_TOKEN_CONSTANT, @@ -70,7 +74,9 @@ typedef struct ParserNodeFunctionCall { ParserNodeArray *params; } ParserNodeFunctionCall; -typedef ParserNode ParserNodeEOLMetadata; +typedef ParserNode ParserNodeSingleChildMetadata; + +typedef uint64_t ParserNodeU64Metadata; void parserNodePrint(const ParserNode *node, int indent); void parserNodeDelete(ParserNode *node); @@ -89,6 +95,8 @@ ParserNode *getUntilCommonParent(ParserNode *node, ParserNode *parent); ParserNode *parserIdentifier(LexerNode *node, ParserNode *parent); ParserNode *parserVoid(LexerNode *node, ParserNode *parent); ParserNode *parserPrint(LexerNode *node, ParserNode *parent); +ParserNode *parserPrintU64(LexerNode *node, LexerNode *end, ParserNode *parent); +ParserNode *parserNumber(LexerNode *node, ParserNode *parent); ParserNode *parserEol(LexerNode *node, LexerNode *begin, ParserNode *parent); ParserNode *parserComma(LexerNode *node, LexerNode *begin, ParserNode *parent); ParserNode *parserParenthesis(LexerNode *closing, LexerNode *begin, |