diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/ast-tree.c | 219 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 19 | ||||
-rw-r--r-- | src/compiler/lexer.c | 21 | ||||
-rw-r--r-- | src/compiler/lexer.h | 4 | ||||
-rw-r--r-- | src/compiler/parser.c | 86 | ||||
-rw-r--r-- | src/compiler/parser.h | 31 |
6 files changed, 338 insertions, 42 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index df00517..9347303 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -74,6 +74,30 @@ AstTree AST_TREE_U64_TYPE = { .type = &AST_TREE_TYPE_TYPE, }; +AstTree AST_TREE_F16_TYPE = { + .token = AST_TREE_TOKEN_TYPE_F16, + .metadata = NULL, + .type = &AST_TREE_TYPE_TYPE, +}; + +AstTree AST_TREE_F32_TYPE = { + .token = AST_TREE_TOKEN_TYPE_F32, + .metadata = NULL, + .type = &AST_TREE_TYPE_TYPE, +}; + +AstTree AST_TREE_F64_TYPE = { + .token = AST_TREE_TOKEN_TYPE_F64, + .metadata = NULL, + .type = &AST_TREE_TYPE_TYPE, +}; + +AstTree AST_TREE_F128_TYPE = { + .token = AST_TREE_TOKEN_TYPE_F128, + .metadata = NULL, + .type = &AST_TREE_TYPE_TYPE, +}; + AstTree AST_TREE_VOID_VALUE = { .token = AST_TREE_TOKEN_VALUE_VOID, .metadata = NULL, @@ -85,6 +109,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_KEYWORD_PRINT_U64", "AST_TREE_TOKEN_KEYWORD_RETURN", + "AST_TREE_TOKEN_KEYWORD_IF", "AST_TREE_TOKEN_TYPE_FUNCTION", "AST_TREE_TOKEN_TYPE_TYPE", @@ -97,21 +122,36 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_TYPE_U32", "AST_TREE_TOKEN_TYPE_I64", "AST_TREE_TOKEN_TYPE_U64", + "AST_TREE_TOKEN_TYPE_F16", + "AST_TREE_TOKEN_TYPE_F32", + "AST_TREE_TOKEN_TYPE_F64", + "AST_TREE_TOKEN_TYPE_F128", "AST_TREE_TOKEN_TYPE_BOOL", "AST_TREE_TOKEN_FUNCTION_CALL", "AST_TREE_TOKEN_VARIABLE", "AST_TREE_TOKEN_VARIABLE_DEFINE", + "AST_TREE_TOKEN_VALUE_VOID", "AST_TREE_TOKEN_VALUE_INT", + "AST_TREE_TOKEN_VALUE_FLOAT", "AST_TREE_TOKEN_VALUE_BOOL", - "AST_TREE_TOKEN_VALUE_VOID", "AST_TREE_TOKEN_OPERATOR_ASSIGN", + "AST_TREE_TOKEN_OPERATOR_PLUS", + "AST_TREE_TOKEN_OPERATOR_MINUS", "AST_TREE_TOKEN_OPERATOR_SUM", "AST_TREE_TOKEN_OPERATOR_SUB", "AST_TREE_TOKEN_OPERATOR_MULTIPLY", "AST_TREE_TOKEN_OPERATOR_DIVIDE", "AST_TREE_TOKEN_OPERATOR_MODULO", + "AST_TREE_TOKEN_OPERATOR_EQUAL", + "AST_TREE_TOKEN_OPERATOR_NOT_EQUAL", + "AST_TREE_TOKEN_OPERATOR_GREATER", + "AST_TREE_TOKEN_OPERATOR_SMALLER", + "AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL", + "AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL", + + "AST_TREE_TOKEN_SCOPE", "AST_TREE_TOKEN_NONE", }; @@ -365,12 +405,20 @@ void astTreeDestroy(AstTree tree) { case AST_TREE_TOKEN_TYPE_U32: case AST_TREE_TOKEN_TYPE_I64: case AST_TREE_TOKEN_TYPE_U64: + case AST_TREE_TOKEN_TYPE_F16: + case AST_TREE_TOKEN_TYPE_F32: + case AST_TREE_TOKEN_TYPE_F64: + case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_BOOL: case AST_TREE_TOKEN_VARIABLE_DEFINE: return; + case AST_TREE_TOKEN_VALUE_FLOAT: { + free(tree.metadata); + return; + } case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: { @@ -502,6 +550,7 @@ AstTree *copyAstTree(AstTree *tree) { switch (tree->token) { case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: + case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_TYPE_I8: case AST_TREE_TOKEN_TYPE_U8: case AST_TREE_TOKEN_TYPE_I16: @@ -510,13 +559,23 @@ AstTree *copyAstTree(AstTree *tree) { case AST_TREE_TOKEN_TYPE_U32: case AST_TREE_TOKEN_TYPE_I64: case AST_TREE_TOKEN_TYPE_U64: - case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_TYPE_F16: + case AST_TREE_TOKEN_TYPE_F32: + case AST_TREE_TOKEN_TYPE_F64: + case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_VALUE_VOID: return tree; case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_BOOL: return newAstTree(tree->token, tree->metadata, tree->type, tree->str_begin, tree->str_end); + case AST_TREE_TOKEN_VALUE_FLOAT: { + AstTreeFloat *metadata = tree->metadata; + AstTreeFloat *newMetadata = a404m_malloc(sizeof(*newMetadata)); + *newMetadata = *metadata; + return newAstTree(tree->token, newMetadata, tree->type, tree->str_begin, + tree->str_end); + } case AST_TREE_TOKEN_VARIABLE: case AST_TREE_TOKEN_VARIABLE_DEFINE: return newAstTree(tree->token, tree->metadata, copyAstTree(tree->type), @@ -900,6 +959,14 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { return &AST_TREE_I64_TYPE; case PARSER_TOKEN_TYPE_U64: return &AST_TREE_U64_TYPE; + case PARSER_TOKEN_TYPE_F16: + return &AST_TREE_F16_TYPE; + case PARSER_TOKEN_TYPE_F32: + return &AST_TREE_F32_TYPE; + case PARSER_TOKEN_TYPE_F64: + return &AST_TREE_F64_TYPE; + case PARSER_TOKEN_TYPE_F128: + return &AST_TREE_F128_TYPE; case PARSER_TOKEN_TYPE_BOOL: return &AST_TREE_BOOL_TYPE; case PARSER_TOKEN_FUNCTION_CALL: @@ -911,6 +978,8 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { AST_TREE_TOKEN_VALUE_INT, (void *)(AstTreeInt)(ParserNodeIntMetadata)parserNode->metadata, NULL, parserNode->str_begin, parserNode->str_end); + case PARSER_TOKEN_VALUE_FLOAT: + return astTreeParseFloat(parserNode); case PARSER_TOKEN_VALUE_BOOL: return newAstTree( AST_TREE_TOKEN_VALUE_BOOL, @@ -1243,6 +1312,17 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper) { parserNode->str_end); } +AstTree *astTreeParseFloat(ParserNode *parserNode) { + AstTreeFloat *metadata = a404m_malloc(sizeof(*metadata)); + + ParserNodeFloatMetadata *node_metadata = parserNode->metadata; + + *metadata = *node_metadata; + + return newAstTree(AST_TREE_TOKEN_VALUE_FLOAT, metadata, NULL, + parserNode->str_begin, parserNode->str_end); +} + AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper) { ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata; @@ -1750,6 +1830,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_KEYWORD_IF: 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_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: @@ -1779,6 +1860,10 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_TYPE_I64: case AST_TREE_TOKEN_TYPE_U64: case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_TYPE_F16: + case AST_TREE_TOKEN_TYPE_F32: + case AST_TREE_TOKEN_TYPE_F64: + case AST_TREE_TOKEN_TYPE_F128: return type1->token == type0->token; case AST_TREE_TOKEN_TYPE_FUNCTION: if (type1->token != AST_TREE_TOKEN_TYPE_FUNCTION) { @@ -1914,6 +1999,7 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, switch (tree->token) { case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: + case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_TYPE_I8: case AST_TREE_TOKEN_TYPE_U8: case AST_TREE_TOKEN_TYPE_I16: @@ -1922,12 +2008,17 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_TYPE_U32: case AST_TREE_TOKEN_TYPE_I64: case AST_TREE_TOKEN_TYPE_U64: - case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_TYPE_F16: + case AST_TREE_TOKEN_TYPE_F32: + case AST_TREE_TOKEN_TYPE_F64: + case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_BOOL: return true; case AST_TREE_TOKEN_VALUE_INT: return setTypesValueInt(tree, helper); + case AST_TREE_TOKEN_VALUE_FLOAT: + return setTypesValueFloat(tree, helper); case AST_TREE_TOKEN_FUNCTION: return setTypesFunction(tree, helper); case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -1977,46 +2068,146 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { tree->type = &AST_TREE_U64_TYPE; } else if (helper.lookingType == &AST_TREE_I32_TYPE) { AstTreeInt value = (AstTreeInt)tree->metadata; - if (value & 0xffffffff00000000) { + i32 newValue = value; + tree->metadata = (void *)(u64)newValue; + if (value - newValue != 0) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_I32_TYPE; } else if (helper.lookingType == &AST_TREE_U32_TYPE) { AstTreeInt value = (AstTreeInt)tree->metadata; - if (value & 0xffffffff00000000) { + u32 newValue = value; + tree->metadata = (void *)(u64)newValue; + if (value - newValue != 0) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_U32_TYPE; } else if (helper.lookingType == &AST_TREE_I16_TYPE) { AstTreeInt value = (AstTreeInt)tree->metadata; - if (value & 0xffffffffffff0000) { + i16 newValue = value; + tree->metadata = (void *)(u64)newValue; + if (value - newValue != 0) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_I16_TYPE; } else if (helper.lookingType == &AST_TREE_U16_TYPE) { AstTreeInt value = (AstTreeInt)tree->metadata; - if (value & 0xffffffffffff0000) { + u16 newValue = value; + tree->metadata = (void *)(u64)newValue; + if (value - newValue != 0) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_U16_TYPE; } else if (helper.lookingType == &AST_TREE_I8_TYPE) { AstTreeInt value = (AstTreeInt)tree->metadata; - if (value & 0xffffffffffffff00) { + i8 newValue = value; + tree->metadata = (void *)(u64)newValue; + if (value - newValue != 0) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_I8_TYPE; } else if (helper.lookingType == &AST_TREE_U8_TYPE) { AstTreeInt value = (AstTreeInt)tree->metadata; - if (value & 0xffffffffffffff00) { + u8 newValue = value; + tree->metadata = (void *)(u64)newValue; + if (value - newValue != 0) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_U8_TYPE; + } else if (helper.lookingType == &AST_TREE_F16_TYPE) { + tree->token = AST_TREE_TOKEN_VALUE_FLOAT; + AstTreeInt value = (AstTreeInt)tree->metadata; + f16 newValue = value; + tree->metadata = a404m_malloc(sizeof(f128)); + *(f128 *)tree->metadata = value; + if (value - newValue != 0) { + printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); + } + tree->type = &AST_TREE_F16_TYPE; + } else if (helper.lookingType == &AST_TREE_F32_TYPE) { + tree->token = AST_TREE_TOKEN_VALUE_FLOAT; + AstTreeInt value = (AstTreeInt)tree->metadata; + f32 newValue = value; + tree->metadata = a404m_malloc(sizeof(f128)); + *(f128 *)tree->metadata = value; + if (value - newValue != 0) { + printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); + } + tree->type = &AST_TREE_F32_TYPE; + } else if (helper.lookingType == &AST_TREE_F64_TYPE) { + tree->token = AST_TREE_TOKEN_VALUE_FLOAT; + AstTreeInt value = (AstTreeInt)tree->metadata; + f64 newValue = value; + tree->metadata = a404m_malloc(sizeof(f128)); + *(f128 *)tree->metadata = value; + if (value - newValue != 0) { + printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); + } + tree->type = &AST_TREE_F64_TYPE; + } else if (helper.lookingType == &AST_TREE_F128_TYPE) { + tree->token = AST_TREE_TOKEN_VALUE_FLOAT; + AstTreeInt value = (AstTreeInt)tree->metadata; + f128 newValue = value; + tree->metadata = a404m_malloc(sizeof(f128)); + *(f128 *)tree->metadata = value; + if (value - newValue != 0) { + printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); + } + tree->type = &AST_TREE_F128_TYPE; } else { UNREACHABLE; } return true; } +bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) { + if (helper.lookingType == &AST_TREE_F16_TYPE) { + tree->token = AST_TREE_TOKEN_VALUE_FLOAT; + AstTreeFloat value = *(AstTreeFloat *)tree->metadata; + f16 newValue = value; + tree->metadata = a404m_malloc(sizeof(f128)); + *(f128 *)tree->metadata = value; + if (value - newValue != 0) { + printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); + } + tree->type = &AST_TREE_F16_TYPE; + } else if (helper.lookingType == &AST_TREE_F32_TYPE) { + tree->token = AST_TREE_TOKEN_VALUE_FLOAT; + AstTreeFloat value = *(AstTreeFloat *)tree->metadata; + f32 newValue = value; + tree->metadata = a404m_malloc(sizeof(f128)); + *(f128 *)tree->metadata = value; + if (value - newValue != 0) { + printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); + } + tree->type = &AST_TREE_F32_TYPE; + } else if (helper.lookingType == &AST_TREE_F64_TYPE) { + tree->token = AST_TREE_TOKEN_VALUE_FLOAT; + AstTreeFloat value = *(AstTreeFloat *)tree->metadata; + f64 newValue = value; + tree->metadata = a404m_malloc(sizeof(f128)); + *(f128 *)tree->metadata = value; + if (value - newValue != 0) { + printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); + } + tree->type = &AST_TREE_F64_TYPE; + } else if (helper.lookingType == &AST_TREE_F128_TYPE) { + tree->token = AST_TREE_TOKEN_VALUE_FLOAT; + AstTreeFloat value = *(AstTreeFloat *)tree->metadata; + f128 newValue = value; + tree->metadata = a404m_malloc(sizeof(f128)); + *(f128 *)tree->metadata = value; + if (value - newValue != 0) { + printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); + } + tree->type = &AST_TREE_F128_TYPE; + } else { + UNREACHABLE; + } + + return true; +} + bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeFunction *metadata = tree->metadata; @@ -2225,7 +2416,8 @@ bool setTypesAstVariable(AstTreeVariable *variable, return false; } else if (variable->value != NULL && !typeIsEqual(variable->value->type, variable->type)) { - printError(variable->name_begin, variable->name_end, "Type mismatch"); + printError(variable->name_begin, variable->name_end, "Type mismatch %s", + AST_TREE_TOKEN_STRINGS[variable->value->token]); return false; } @@ -2311,6 +2503,7 @@ bool astTreeClean(AstTree *tree) { case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: + case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_TYPE_I8: case AST_TREE_TOKEN_TYPE_U8: case AST_TREE_TOKEN_TYPE_I16: @@ -2319,11 +2512,15 @@ bool astTreeClean(AstTree *tree) { case AST_TREE_TOKEN_TYPE_U32: case AST_TREE_TOKEN_TYPE_I64: case AST_TREE_TOKEN_TYPE_U64: - case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_TYPE_F16: + case AST_TREE_TOKEN_TYPE_F32: + case AST_TREE_TOKEN_TYPE_F64: + case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_BOOL: + case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_PLUS: diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index c7253a0..eaf8b07 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -23,6 +23,10 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_TYPE_U32, AST_TREE_TOKEN_TYPE_I64, AST_TREE_TOKEN_TYPE_U64, + AST_TREE_TOKEN_TYPE_F16, + AST_TREE_TOKEN_TYPE_F32, + AST_TREE_TOKEN_TYPE_F64, + AST_TREE_TOKEN_TYPE_F128, AST_TREE_TOKEN_TYPE_BOOL, AST_TREE_TOKEN_STATIC_VARS_END = AST_TREE_TOKEN_TYPE_BOOL, @@ -31,6 +35,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_VARIABLE_DEFINE, AST_TREE_TOKEN_VALUE_VOID, AST_TREE_TOKEN_VALUE_INT, + AST_TREE_TOKEN_VALUE_FLOAT, AST_TREE_TOKEN_VALUE_BOOL, AST_TREE_TOKEN_OPERATOR_ASSIGN, @@ -74,6 +79,10 @@ extern AstTree AST_TREE_I32_TYPE; extern AstTree AST_TREE_U32_TYPE; extern AstTree AST_TREE_I64_TYPE; extern AstTree AST_TREE_U64_TYPE; +extern AstTree AST_TREE_F16_TYPE; +extern AstTree AST_TREE_F32_TYPE; +extern AstTree AST_TREE_F64_TYPE; +extern AstTree AST_TREE_F128_TYPE; extern AstTree AST_TREE_VOID_VALUE; typedef struct AstTreeVariable { @@ -117,7 +126,9 @@ typedef struct AstTreeFunctionCall { size_t parameters_size; } AstTreeFunctionCall; -typedef uint64_t AstTreeInt; +typedef u64 AstTreeInt; + +typedef f128 AstTreeFloat; typedef bool AstTreeBool; @@ -177,6 +188,7 @@ AstTree *astTreeParseTypeFunction(ParserNode *parserNode, AstTree *astTreeParseFunctionCall(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper); +AstTree *astTreeParseFloat(ParserNode *parserNode); AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseBinaryOperator(ParserNode *parserNode, @@ -188,9 +200,7 @@ AstTree *astTreeParseVariable(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseIf(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, AstTreeHelper *helper); -AstTree *astTreeParseParenthesis(ParserNode *parserNode, - AstTreeHelper *helper); - +AstTree *astTreeParseParenthesis(ParserNode *parserNode, AstTreeHelper *helper); AstTreeFunction *getFunction(AstTree *value); bool isConst(AstTree *value); @@ -204,6 +214,7 @@ bool setAllTypesRoot(AstTreeRoot *root, AstTreeHelper *helper); bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunction *function); bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper); +bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesPrintU64(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper helper, diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index c740dd3..7fef9be 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -22,6 +22,10 @@ const char *LEXER_TOKEN_STRINGS[] = { "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", @@ -89,9 +93,9 @@ 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", "bool", "print_u64", - "return", "true", "false", "if", "else", + "type", "void", "i8", "u8", "i16", "u16", "i32", + "u32", "i64", "u64", "f16", "f32", "f64", "f128", + "bool", "print_u64", "return", "true", "false", "if", "else", }; const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID, @@ -99,6 +103,8 @@ const LexerToken LEXER_KEYWORD_TOKENS[] = { 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, @@ -172,7 +178,8 @@ LexerNodeArray lexer(char *str) { lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token, LEXER_TOKEN_NONE); } else if (isIdentifier(c)) { - if (node_token != LEXER_TOKEN_IDENTIFIER) { + if (node_token != LEXER_TOKEN_IDENTIFIER && + node_token != LEXER_TOKEN_NUMBER) { lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token, LEXER_TOKEN_IDENTIFIER); } @@ -237,6 +244,10 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_KEYWORD_U32: case LEXER_TOKEN_KEYWORD_I64: case LEXER_TOKEN_KEYWORD_U64: + case LEXER_TOKEN_KEYWORD_F16: + case LEXER_TOKEN_KEYWORD_F32: + case LEXER_TOKEN_KEYWORD_F64: + case LEXER_TOKEN_KEYWORD_F128: case LEXER_TOKEN_KEYWORD_BOOL: case LEXER_TOKEN_KEYWORD_PRINT_U64: case LEXER_TOKEN_KEYWORD_RETURN: @@ -295,7 +306,7 @@ bool isIdentifier(char c) { return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || c == '_'; } -bool isNumber(char c) { return '0' <= c && c <= '9'; } +bool isNumber(char c) { return ('0' <= c && c <= '9') || c == '.'; } bool isSymbol(char c) { switch (c) { diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index af2e7a3..0a6da3a 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -15,6 +15,10 @@ typedef enum LexerToken { 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, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 367c490..84dca1c 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -15,11 +15,13 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_IDENTIFIER", "PARSER_TOKEN_VALUE_INT", + "PARSER_TOKEN_VALUE_FLOAT", "PARSER_TOKEN_VALUE_BOOL", "PARSER_TOKEN_TYPE_TYPE", "PARSER_TOKEN_TYPE_FUNCTION", "PARSER_TOKEN_TYPE_VOID", + "PARSER_TOKEN_TYPE_BOOL", "PARSER_TOKEN_TYPE_I8", "PARSER_TOKEN_TYPE_U8", "PARSER_TOKEN_TYPE_I16", @@ -28,7 +30,10 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_TYPE_U32", "PARSER_TOKEN_TYPE_I64", "PARSER_TOKEN_TYPE_U64", - "PARSER_TOKEN_TYPE_BOOL", + "PARSER_TOKEN_TYPE_F16", + "PARSER_TOKEN_TYPE_F32", + "PARSER_TOKEN_TYPE_F64", + "PARSER_TOKEN_TYPE_F128", "PARSER_TOKEN_KEYWORD_PRINT_U64", "PARSER_TOKEN_KEYWORD_RETURN", @@ -75,6 +80,8 @@ static constexpr ParserOrder PARSER_ORDER[] = { 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_F16, LEXER_TOKEN_KEYWORD_F32, + LEXER_TOKEN_KEYWORD_F64, LEXER_TOKEN_KEYWORD_F128, LEXER_TOKEN_KEYWORD_U64, LEXER_TOKEN_KEYWORD_BOOL, LEXER_TOKEN_KEYWORD_TRUE, LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_NUMBER, ), @@ -158,6 +165,7 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: + case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_TYPE_I8: case PARSER_TOKEN_TYPE_U8: case PARSER_TOKEN_TYPE_I16: @@ -166,13 +174,21 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_TYPE_U32: case PARSER_TOKEN_TYPE_I64: case PARSER_TOKEN_TYPE_U64: - case PARSER_TOKEN_TYPE_BOOL: + case PARSER_TOKEN_TYPE_F16: + case PARSER_TOKEN_TYPE_F32: + case PARSER_TOKEN_TYPE_F64: + case PARSER_TOKEN_TYPE_F128: goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_INT: { ParserNodeIntMetadata metadata = (ParserNodeIntMetadata)node->metadata; printf(",operand=%ld", metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_VALUE_FLOAT: { + ParserNodeFloatMetadata *metadata = node->metadata; + printf(",operand=%Lf", *metadata); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_BOOL: { ParserNodeIntMetadata metadata = (ParserNodeIntMetadata)node->metadata; printf(",value=%b", (ParserNodeBoolMetadata)metadata); @@ -368,6 +384,7 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: + case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_TYPE_I8: case PARSER_TOKEN_TYPE_U8: case PARSER_TOKEN_TYPE_I16: @@ -376,10 +393,18 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_TYPE_U32: case PARSER_TOKEN_TYPE_I64: case PARSER_TOKEN_TYPE_U64: - case PARSER_TOKEN_TYPE_BOOL: + case PARSER_TOKEN_TYPE_F16: + case PARSER_TOKEN_TYPE_F32: + case PARSER_TOKEN_TYPE_F64: + case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_BOOL: goto RETURN_SUCCESS; + case PARSER_TOKEN_VALUE_FLOAT: { + ParserNodeFloatMetadata *metadata = node->metadata; + free(metadata); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: { ParserNodeVariableMetadata *metadata = node->metadata; @@ -586,6 +611,14 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_U64); case LEXER_TOKEN_KEYWORD_BOOL: return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_BOOL); + case LEXER_TOKEN_KEYWORD_F16: + return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F16); + case LEXER_TOKEN_KEYWORD_F32: + return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F32); + case LEXER_TOKEN_KEYWORD_F64: + return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F64); + case LEXER_TOKEN_KEYWORD_F128: + return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F128); case LEXER_TOKEN_KEYWORD_PRINT_U64: return parserPrintU64(node, end, parent); case LEXER_TOKEN_KEYWORD_RETURN: @@ -804,13 +837,22 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) { default: { bool success; uint64_t value = decimalToU64(node->str_begin, node->str_end, &success); - if (!success) { - printError(node->str_begin, node->str_end, "Error in parsing number"); - return NULL; + if (success) { + parserNode = + newParserNode(PARSER_TOKEN_VALUE_INT, node->str_begin, node->str_end, + (void *)(ParserNodeIntMetadata)value, parent); + } else { + ParserNodeFloatMetadata *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = numberToFloat(node->str_begin, node->str_end, &success); + + if (success) { + parserNode = newParserNode(PARSER_TOKEN_VALUE_FLOAT, node->str_begin, + node->str_end, metadata, parent); + } else { + printError(node->str_begin, node->str_end, "Error in parsing number"); + return NULL; + } } - parserNode = - newParserNode(PARSER_TOKEN_VALUE_INT, node->str_begin, node->str_end, - (void *)(ParserNodeIntMetadata)value, parent); } } return node->parserNode = parserNode; @@ -1020,10 +1062,12 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_ROOT: case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_VALUE_INT: + case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_TYPE_VOID: + case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_TYPE_I8: case PARSER_TOKEN_TYPE_U8: case PARSER_TOKEN_TYPE_I16: @@ -1032,7 +1076,10 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_TYPE_U32: case PARSER_TOKEN_TYPE_I64: case PARSER_TOKEN_TYPE_U64: - case PARSER_TOKEN_TYPE_BOOL: + case PARSER_TOKEN_TYPE_F16: + case PARSER_TOKEN_TYPE_F32: + case PARSER_TOKEN_TYPE_F64: + case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_KEYWORD_RETURN: case PARSER_TOKEN_CONSTANT: @@ -1352,6 +1399,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_VALUE_INT: + case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: case PARSER_TOKEN_KEYWORD_IF: return true; @@ -1359,6 +1407,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_TYPE_VOID: + case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_TYPE_I8: case PARSER_TOKEN_TYPE_U8: case PARSER_TOKEN_TYPE_I16: @@ -1367,7 +1416,10 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_TYPE_U32: case PARSER_TOKEN_TYPE_I64: case PARSER_TOKEN_TYPE_U64: - case PARSER_TOKEN_TYPE_BOOL: + case PARSER_TOKEN_TYPE_F16: + case PARSER_TOKEN_TYPE_F32: + case PARSER_TOKEN_TYPE_F64: + case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_SYMBOL_EOL: case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: case PARSER_TOKEN_SYMBOL_COMMA: @@ -1390,6 +1442,10 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_TYPE_U32: case PARSER_TOKEN_TYPE_I64: case PARSER_TOKEN_TYPE_U64: + case PARSER_TOKEN_TYPE_F16: + case PARSER_TOKEN_TYPE_F32: + case PARSER_TOKEN_TYPE_F64: + case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_BOOL: return true; case PARSER_TOKEN_IDENTIFIER: @@ -1403,6 +1459,7 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_SYMBOL_COMMA: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_VALUE_INT: + case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_KEYWORD_RETURN: @@ -1432,6 +1489,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_VALUE_INT: + case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_OPERATOR_ASSIGN: @@ -1450,6 +1508,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: + case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_TYPE_I8: case PARSER_TOKEN_TYPE_U8: case PARSER_TOKEN_TYPE_I16: @@ -1458,7 +1517,10 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_TYPE_U32: case PARSER_TOKEN_TYPE_I64: case PARSER_TOKEN_TYPE_U64: - case PARSER_TOKEN_TYPE_BOOL: + case PARSER_TOKEN_TYPE_F16: + case PARSER_TOKEN_TYPE_F32: + case PARSER_TOKEN_TYPE_F64: + case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_KEYWORD_IF: return true; case PARSER_TOKEN_TYPE_FUNCTION: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 4e8c298..3af47e7 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -1,6 +1,7 @@ #pragma once #include "compiler/lexer.h" +#include "utils/type.h" #include <stddef.h> #include <stdint.h> @@ -10,11 +11,13 @@ typedef enum ParserToken { PARSER_TOKEN_IDENTIFIER, PARSER_TOKEN_VALUE_INT, + PARSER_TOKEN_VALUE_FLOAT, PARSER_TOKEN_VALUE_BOOL, PARSER_TOKEN_TYPE_TYPE, PARSER_TOKEN_TYPE_FUNCTION, PARSER_TOKEN_TYPE_VOID, + PARSER_TOKEN_TYPE_BOOL, PARSER_TOKEN_TYPE_I8, PARSER_TOKEN_TYPE_U8, PARSER_TOKEN_TYPE_I16, @@ -23,7 +26,10 @@ typedef enum ParserToken { PARSER_TOKEN_TYPE_U32, PARSER_TOKEN_TYPE_I64, PARSER_TOKEN_TYPE_U64, - PARSER_TOKEN_TYPE_BOOL, + PARSER_TOKEN_TYPE_F16, + PARSER_TOKEN_TYPE_F32, + PARSER_TOKEN_TYPE_F64, + PARSER_TOKEN_TYPE_F128, PARSER_TOKEN_KEYWORD_PRINT_U64, PARSER_TOKEN_KEYWORD_RETURN, @@ -104,7 +110,9 @@ typedef struct ParserNodeFunctionCall { typedef ParserNode ParserNodeSingleChildMetadata; -typedef uint64_t ParserNodeIntMetadata; +typedef u64 ParserNodeIntMetadata; + +typedef f128 ParserNodeFloatMetadata; typedef struct ParserNodeInfixMetadata { ParserNode *left; @@ -121,7 +129,7 @@ typedef struct ParserNodeIfMetadata { ParserNode *condition; ParserNode *ifBody; ParserNode *elseBody; -}ParserNodeIfMetadata; +} ParserNodeIfMetadata; void parserNodePrint(const ParserNode *node, int indent); void parserNodeDelete(ParserNode *node); @@ -136,11 +144,15 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent, bool *conti); ParserNode *getUntilCommonParent(ParserNode *node, ParserNode *parent); -ParserNode *getUntilCommonParents(ParserNode *node, ParserNode *parent,ParserNode *parent2); -ParserNode *getNextUsingCommonParent(LexerNode *node,LexerNode *end, ParserNode *parent); -LexerNode *getNextLexerNodeUsingCommonParent(LexerNode *node,LexerNode *end, ParserNode *parent); - -ParserNode *parserNoMetadata(LexerNode *node, ParserNode *parent,ParserToken token); +ParserNode *getUntilCommonParents(ParserNode *node, ParserNode *parent, + ParserNode *parent2); +ParserNode *getNextUsingCommonParent(LexerNode *node, LexerNode *end, + ParserNode *parent); +LexerNode *getNextLexerNodeUsingCommonParent(LexerNode *node, LexerNode *end, + ParserNode *parent); + +ParserNode *parserNoMetadata(LexerNode *node, ParserNode *parent, + ParserToken token); ParserNode *parserPrintU64(LexerNode *node, LexerNode *end, ParserNode *parent); ParserNode *parserReturn(LexerNode *node, LexerNode *end, ParserNode *parent); ParserNode *parserNumber(LexerNode *node, ParserNode *parent); @@ -162,8 +174,7 @@ ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin, LexerNode *end, ParserNode *parent, ParserToken token, LexerToken laterToken); -ParserNode *parserIf(LexerNode *node, LexerNode *end, - ParserNode *parent); +ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent); bool isAllArguments(const ParserNodeArray *nodes); |