From e55d45bac0bbd3039118bffa7e6aaf01c04b991a Mon Sep 17 00:00:00 2001 From: A404M Date: Sun, 25 May 2025 01:38:01 +0330 Subject: add bitwise not and xor or --- src/compiler/ast-tree.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++- src/compiler/ast-tree.h | 10 ++- src/compiler/lexer.c | 34 ++++++++- src/compiler/lexer.h | 22 ++++-- src/compiler/parser.c | 131 ++++++++++++++++++++++++++++++--- src/compiler/parser.h | 11 +++ 6 files changed, 375 insertions(+), 24 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 07ff036..de863c8 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -198,6 +198,10 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_BUILTIN_PUTC", "AST_TREE_TOKEN_BUILTIN_C_LIBRARY", "AST_TREE_TOKEN_BUILTIN_C_FUNCTION", + "AST_TREE_TOKEN_BUILTIN_BITWISE_NOT", + "AST_TREE_TOKEN_BUILTIN_BITWISE_AND", + "AST_TREE_TOKEN_BUILTIN_BITWISE_XOR", + "AST_TREE_TOKEN_BUILTIN_BITWISE_OR", "AST_TREE_TOKEN_KEYWORD_RETURN", "AST_TREE_TOKEN_KEYWORD_BREAK", @@ -273,6 +277,10 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_OPERATOR_LOGICAL_AND", "AST_TREE_TOKEN_OPERATOR_LOGICAL_OR", "AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS", + "AST_TREE_TOKEN_OPERATOR_BITWISE_NOT", + "AST_TREE_TOKEN_OPERATOR_BITWISE_AND", + "AST_TREE_TOKEN_OPERATOR_BITWISE_XOR", + "AST_TREE_TOKEN_OPERATOR_BITWISE_OR", "AST_TREE_TOKEN_SCOPE", @@ -349,6 +357,10 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: case AST_TREE_TOKEN_TYPE_I8: @@ -384,6 +396,7 @@ void astTreePrint(const AstTree *tree, int indent) { printf("count=%d", meatadata->count); } case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: { AstTreeUnary *metadata = tree->metadata; @@ -528,6 +541,9 @@ void astTreePrint(const AstTree *tree, int indent) { goto RETURN_SUCCESS; case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: case AST_TREE_TOKEN_OPERATOR_MULTIPLY: @@ -789,6 +805,10 @@ void astTreeDestroy(AstTree tree) { case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: case AST_TREE_TOKEN_TYPE_I8: @@ -871,6 +891,7 @@ void astTreeDestroy(AstTree tree) { return; } case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: { AstTreeUnary *metadata = tree.metadata; @@ -921,6 +942,9 @@ void astTreeDestroy(AstTree tree) { return; case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: case AST_TREE_TOKEN_OPERATOR_MULTIPLY: @@ -1167,6 +1191,10 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: return newAstTree(tree->token, NULL, copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size, safetyCheck), @@ -1312,6 +1340,9 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], } case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: @@ -1391,6 +1422,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], tree->str_begin, tree->str_end); } case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: { AstTreeUnary *metadata = tree->metadata; @@ -2132,6 +2164,10 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) { case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: case PARSER_TOKEN_OPERATOR_LOGICAL_AND: case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + case PARSER_TOKEN_OPERATOR_BITWISE_OR: case PARSER_TOKEN_SYMBOL_PARENTHESIS: case PARSER_TOKEN_KEYWORD_IF: case PARSER_TOKEN_KEYWORD_WHILE: @@ -2185,6 +2221,10 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) { case PARSER_TOKEN_BUILTIN_PUTC: case PARSER_TOKEN_BUILTIN_C_LIBRARY: case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: goto AFTER_SWITCH; @@ -2314,6 +2354,14 @@ AstTree *astTreeParse(const ParserNode *parserNode) { return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_C_LIBRARY); case PARSER_TOKEN_BUILTIN_C_FUNCTION: return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_C_FUNCTION); + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_BITWISE_NOT); + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_BITWISE_AND); + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_BITWISE_XOR); + case PARSER_TOKEN_BUILTIN_BITWISE_OR: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_BITWISE_OR); case PARSER_TOKEN_TYPE_TYPE: return &AST_TREE_TYPE_TYPE; case PARSER_TOKEN_TYPE_FUNCTION: @@ -2447,6 +2495,18 @@ AstTree *astTreeParse(const ParserNode *parserNode) { case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: return astTreeParseUnaryOperator(parserNode, AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT); + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + return astTreeParseBinaryOperator(parserNode, + AST_TREE_TOKEN_OPERATOR_BITWISE_AND); + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + return astTreeParseBinaryOperator(parserNode, + AST_TREE_TOKEN_OPERATOR_BITWISE_XOR); + case PARSER_TOKEN_OPERATOR_BITWISE_OR: + return astTreeParseBinaryOperator(parserNode, + AST_TREE_TOKEN_OPERATOR_BITWISE_OR); + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: + return astTreeParseUnaryOperator(parserNode, + AST_TREE_TOKEN_OPERATOR_BITWISE_NOT); case PARSER_TOKEN_OPERATOR_PLUS: return astTreeParseUnaryOperator(parserNode, AST_TREE_TOKEN_OPERATOR_PLUS); case PARSER_TOKEN_OPERATOR_MINUS: @@ -2626,6 +2686,10 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode) { case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: case PARSER_TOKEN_OPERATOR_LOGICAL_AND: case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + case PARSER_TOKEN_OPERATOR_BITWISE_OR: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: case PARSER_TOKEN_BUILTIN_SIZE_OF: @@ -2648,6 +2712,10 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode) { case PARSER_TOKEN_BUILTIN_PUTC: case PARSER_TOKEN_BUILTIN_C_LIBRARY: case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: printError(node->str_begin, node->str_end, "Unexpected %s", @@ -3228,6 +3296,10 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode) { case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: case PARSER_TOKEN_OPERATOR_LOGICAL_AND: case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + case PARSER_TOKEN_OPERATOR_BITWISE_OR: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: case PARSER_TOKEN_BUILTIN_SIZE_OF: @@ -3250,6 +3322,10 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode) { case PARSER_TOKEN_BUILTIN_PUTC: case PARSER_TOKEN_BUILTIN_C_LIBRARY: case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: printError(node->str_begin, node->str_end, "Unexpected %s", @@ -3475,6 +3551,10 @@ bool isConst(AstTree *tree) { case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: @@ -3558,7 +3638,8 @@ bool isConst(AstTree *tree) { return false; case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: - case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: { + case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: { AstTreeUnary *metadata = tree->metadata; return metadata->function->isConst && isConst(metadata->operand); } @@ -3574,7 +3655,10 @@ bool isConst(AstTree *tree) { case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: - case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: { + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: { AstTreeInfix *metadata = tree->metadata; return metadata->function->isConst && isConst(metadata->left) && isConst(metadata->right); @@ -3696,6 +3780,7 @@ AstTree *makeTypeOf(AstTree *value) { return copyAstTree(variable->type); } case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: { AstTreeUnary *metadata = value->metadata; @@ -3716,6 +3801,9 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_OPERATOR_MODULO: case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_OPERATOR_EQUAL: case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: case AST_TREE_TOKEN_OPERATOR_GREATER: @@ -3786,6 +3874,10 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_VALUE_OBJECT: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_KEYWORD_RETURN: @@ -3872,6 +3964,10 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: @@ -3910,6 +4006,10 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_ADDRESS: @@ -4057,6 +4157,10 @@ AstTree *getValue(AstTree *tree, bool copy) { case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: @@ -4113,6 +4217,10 @@ AstTree *getValue(AstTree *tree, bool copy) { case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_KEYWORD_IF: case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_KEYWORD_COMPTIME: @@ -4205,6 +4313,10 @@ bool isIntType(AstTree *type) { case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -4265,6 +4377,10 @@ bool isIntType(AstTree *type) { case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: @@ -4314,6 +4430,10 @@ bool isFloatType(AstTree *type) { case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -4368,6 +4488,10 @@ bool isFloatType(AstTree *type) { case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: @@ -4458,6 +4582,10 @@ bool isEqual(AstTree *left, AstTree *right) { case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -4496,6 +4624,10 @@ bool isEqual(AstTree *left, AstTree *right) { case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: @@ -4609,10 +4741,15 @@ static const size_t STR_PLUS_SIZE = sizeof(STR_PLUS) / sizeof(*STR_PLUS) - sizeof(*STR_PLUS); static const char STR_MINUS[] = "__minus__"; static const size_t STR_MINUS_SIZE = - sizeof(STR_MINUS) / sizeof(*STR_MINUS) - sizeof(*STR_PLUS); + sizeof(STR_MINUS) / sizeof(*STR_MINUS) - sizeof(*STR_MINUS); static const char STR_LOGICAL_NOT[] = "__logical_not__"; static const size_t STR_LOGICAL_NOT_SIZE = - sizeof(STR_LOGICAL_NOT) / sizeof(*STR_LOGICAL_NOT) - sizeof(*STR_PLUS); + sizeof(STR_LOGICAL_NOT) / sizeof(*STR_LOGICAL_NOT) - + sizeof(*STR_LOGICAL_NOT); +static const char STR_BITWISE_NOT[] = "__bitwise_not__"; +static const size_t STR_BITWISE_NOT_SIZE = + sizeof(STR_BITWISE_NOT) / sizeof(*STR_BITWISE_NOT) - + sizeof(*STR_BITWISE_NOT); static const char STR_SUM[] = "__sum__"; static const size_t STR_SUM_SIZE = @@ -4636,6 +4773,17 @@ static const size_t STR_LOGICAL_AND_SIZE = static const char STR_LOGICAL_OR[] = "__logical_or__"; static const size_t STR_LOGICAL_OR_SIZE = sizeof(STR_LOGICAL_OR) / sizeof(*STR_LOGICAL_OR) - sizeof(*STR_LOGICAL_OR); +static const char STR_BITWISE_AND[] = "__bitwise_and__"; +static const size_t STR_BITWISE_AND_SIZE = + sizeof(STR_BITWISE_AND) / sizeof(*STR_BITWISE_AND) - + sizeof(*STR_BITWISE_AND); +static const char STR_BITWISE_XOR[] = "__bitwise_xor__"; +static const size_t STR_BITWISE_XOR_SIZE = + sizeof(STR_BITWISE_XOR) / sizeof(*STR_BITWISE_XOR) - + sizeof(*STR_BITWISE_XOR); +static const char STR_BITWISE_OR[] = "__bitwise_or__"; +static const size_t STR_BITWISE_OR_SIZE = + sizeof(STR_BITWISE_OR) / sizeof(*STR_BITWISE_OR) - sizeof(*STR_BITWISE_OR); static const char STR_EQUAL[] = "__equal__"; static const size_t STR_EQUAL_SIZE = sizeof(STR_EQUAL) / sizeof(*STR_EQUAL) - sizeof(*STR_EQUAL); @@ -4725,6 +4873,9 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: return setTypesOperatorUnary(tree, helper, STR_LOGICAL_NOT, STR_LOGICAL_NOT_SIZE); + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: + return setTypesOperatorUnary(tree, helper, STR_BITWISE_NOT, + STR_BITWISE_NOT_SIZE); case AST_TREE_TOKEN_OPERATOR_SUM: return setTypesOperatorInfix(tree, helper, STR_SUM, STR_SUM_SIZE); case AST_TREE_TOKEN_OPERATOR_SUB: @@ -4756,6 +4907,15 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: return setTypesOperatorInfix(tree, helper, STR_LOGICAL_OR, STR_LOGICAL_OR_SIZE); + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + return setTypesOperatorInfix(tree, helper, STR_BITWISE_AND, + STR_BITWISE_AND_SIZE); + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + return setTypesOperatorInfix(tree, helper, STR_BITWISE_XOR, + STR_BITWISE_XOR_SIZE); + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: + return setTypesOperatorInfix(tree, helper, STR_BITWISE_OR, + STR_BITWISE_OR_SIZE); case AST_TREE_TOKEN_OPERATOR_POINTER: return setTypesOperatorPointer(tree, helper); case AST_TREE_TOKEN_OPERATOR_ADDRESS: @@ -4791,12 +4951,16 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: return setTypesBuiltinHeapAlloc(tree, helper, functionCall); case AST_TREE_TOKEN_BUILTIN_NEG: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: return setTypesBuiltinUnary(tree, helper, functionCall); case AST_TREE_TOKEN_BUILTIN_ADD: case AST_TREE_TOKEN_BUILTIN_SUB: case AST_TREE_TOKEN_BUILTIN_MUL: case AST_TREE_TOKEN_BUILTIN_DIV: case AST_TREE_TOKEN_BUILTIN_MOD: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: return setTypesBuiltinBinary(tree, helper, functionCall); case AST_TREE_TOKEN_BUILTIN_EQUAL: case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: @@ -6527,6 +6691,10 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -6578,6 +6746,10 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: @@ -6656,6 +6828,9 @@ bool setTypesBuiltinBinary(AstTree *tree, AstTreeSetTypesHelper helper, if (left == NULL || right == NULL) { return false; + } else if (!typeIsEqual(left->type, right->type)) { + printError(tree->str_begin, tree->str_end, "Type mismatch"); + return false; } AstTreeTypeFunction *type_metadata = a404m_malloc(sizeof(*type_metadata)); @@ -7597,6 +7772,10 @@ size_t getSizeOfType(AstTree *type) { case AST_TREE_TOKEN_BUILTIN_PUTC: case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: + case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: + case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR: + case AST_TREE_TOKEN_BUILTIN_BITWISE_OR: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -7640,6 +7819,10 @@ size_t getSizeOfType(AstTree *type) { case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: + case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: + case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: + case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index ff8529e..6891e29 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -29,7 +29,11 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_BUILTIN_PUTC, AST_TREE_TOKEN_BUILTIN_C_LIBRARY, AST_TREE_TOKEN_BUILTIN_C_FUNCTION, - AST_TREE_TOKEN_BUILTIN_END = AST_TREE_TOKEN_BUILTIN_C_FUNCTION, + AST_TREE_TOKEN_BUILTIN_BITWISE_NOT, + AST_TREE_TOKEN_BUILTIN_BITWISE_AND, + AST_TREE_TOKEN_BUILTIN_BITWISE_XOR, + AST_TREE_TOKEN_BUILTIN_BITWISE_OR, + AST_TREE_TOKEN_BUILTIN_END = AST_TREE_TOKEN_BUILTIN_BITWISE_OR, AST_TREE_TOKEN_KEYWORD_RETURN, AST_TREE_TOKEN_KEYWORD_BREAK, @@ -107,6 +111,10 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_OPERATOR_LOGICAL_AND, AST_TREE_TOKEN_OPERATOR_LOGICAL_OR, AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS, + AST_TREE_TOKEN_OPERATOR_BITWISE_NOT, + AST_TREE_TOKEN_OPERATOR_BITWISE_AND, + AST_TREE_TOKEN_OPERATOR_BITWISE_XOR, + AST_TREE_TOKEN_OPERATOR_BITWISE_OR, AST_TREE_TOKEN_SCOPE, diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 1fbba2f..db1ba64 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -33,6 +33,10 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_BUILTIN_PUTC", "LEXER_TOKEN_BUILTIN_C_LIBRARY", "LEXER_TOKEN_BUILTIN_C_FUNCTION", + "LEXER_TOKEN_BUILTIN_BITWISE_NOT", + "LEXER_TOKEN_BUILTIN_BITWISE_AND", + "LEXER_TOKEN_BUILTIN_BITWISE_XOR", + "LEXER_TOKEN_BUILTIN_BITWISE_OR", "LEXER_TOKEN_KEYWORD_TYPE", "LEXER_TOKEN_KEYWORD_VOID", "LEXER_TOKEN_KEYWORD_I8", @@ -76,6 +80,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_MINUS", "LEXER_TOKEN_SYMBOL_ADDRESS", "LEXER_TOKEN_SYMBOL_LOGICAL_NOT", + "LEXER_TOKEN_SYMBOL_BITWISE_NOT", "LEXER_TOKEN_SYMBOL_MULTIPLY", "LEXER_TOKEN_SYMBOL_DIVIDE", @@ -91,6 +96,10 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL", "LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL", + "LEXER_TOKEN_SYMBOL_BITWISE_AND", + "LEXER_TOKEN_SYMBOL_BITWISE_XOR", + "LEXER_TOKEN_SYMBOL_BITWISE_OR", + "LEXER_TOKEN_SYMBOL_LOGICAL_AND", "LEXER_TOKEN_SYMBOL_LOGICAL_OR", @@ -126,9 +135,9 @@ const char *LEXER_TOKEN_STRINGS[] = { }; static const char *LEXER_SYMBOL_STRINGS[] = { - ";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=", - "/=", "%=", ",", "+", "-", "*", "/", "%", "==", "!=", ">", - ">=", "<", "<=", "&", ".*", ".", "!", "&&", "||", "[", "]", + ";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=", "/=", + "%=", ",", "+", "-", "*", "/", "%", "==", "!=", ">", ">=", "<", + "<=", "&", ".*", ".", "!", "&&", "||", "[", "]", "^", "|", "~", }; static const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_EOL, @@ -164,6 +173,9 @@ static const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_LOGICAL_OR, LEXER_TOKEN_SYMBOL_OPEN_BRACKET, LEXER_TOKEN_SYMBOL_CLOSE_BRACKET, + LEXER_TOKEN_SYMBOL_BITWISE_XOR, + LEXER_TOKEN_SYMBOL_BITWISE_OR, + LEXER_TOKEN_SYMBOL_BITWISE_NOT, }; static const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); @@ -229,6 +241,10 @@ static const char *LEXER_BUILTIN_STRINGS[] = { "putc", "c_library", "c_function", + "bitwise_not", + "bitwise_and", + "bitwise_xor", + "bitwise_or", }; static const LexerToken LEXER_BUILTIN_TOKENS[] = { LEXER_TOKEN_BUILTIN_CAST, @@ -253,6 +269,10 @@ static const LexerToken LEXER_BUILTIN_TOKENS[] = { LEXER_TOKEN_BUILTIN_PUTC, LEXER_TOKEN_BUILTIN_C_LIBRARY, LEXER_TOKEN_BUILTIN_C_FUNCTION, + LEXER_TOKEN_BUILTIN_BITWISE_NOT, + LEXER_TOKEN_BUILTIN_BITWISE_AND, + LEXER_TOKEN_BUILTIN_BITWISE_XOR, + LEXER_TOKEN_BUILTIN_BITWISE_OR, }; static const size_t LEXER_BUILTIN_SIZE = sizeof(LEXER_BUILTIN_TOKENS) / sizeof(*LEXER_BUILTIN_TOKENS); @@ -523,6 +543,10 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char const *iter, case LEXER_TOKEN_BUILTIN_SIZE_OF: case LEXER_TOKEN_BUILTIN_C_LIBRARY: case LEXER_TOKEN_BUILTIN_C_FUNCTION: + case LEXER_TOKEN_BUILTIN_BITWISE_NOT: + case LEXER_TOKEN_BUILTIN_BITWISE_AND: + case LEXER_TOKEN_BUILTIN_BITWISE_XOR: + case LEXER_TOKEN_BUILTIN_BITWISE_OR: case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET: case LEXER_TOKEN_SYMBOL_OPEN_BRACKET: case LEXER_TOKEN_KEYWORD_SHAPE_SHIFTER: @@ -530,6 +554,10 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char const *iter, case LEXER_TOKEN_KEYWORD_CONTINUE: case LEXER_TOKEN_KEYWORD_C_LIBRARY: case LEXER_TOKEN_KEYWORD_C_FUNCTION: + case LEXER_TOKEN_SYMBOL_BITWISE_AND: + case LEXER_TOKEN_SYMBOL_BITWISE_XOR: + case LEXER_TOKEN_SYMBOL_BITWISE_OR: + case LEXER_TOKEN_SYMBOL_BITWISE_NOT: if (*array_size == array->size) { *array_size += 1 + *array_size / 2; array->data = diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index e56617f..045bf6e 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -35,6 +35,10 @@ typedef enum LexerToken { LEXER_TOKEN_BUILTIN_PUTC, LEXER_TOKEN_BUILTIN_C_LIBRARY, LEXER_TOKEN_BUILTIN_C_FUNCTION, + LEXER_TOKEN_BUILTIN_BITWISE_NOT, + LEXER_TOKEN_BUILTIN_BITWISE_AND, + LEXER_TOKEN_BUILTIN_BITWISE_XOR, + LEXER_TOKEN_BUILTIN_BITWISE_OR, LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID, LEXER_TOKEN_KEYWORD_I8, @@ -81,6 +85,7 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_MINUS, LEXER_TOKEN_SYMBOL_ADDRESS, LEXER_TOKEN_SYMBOL_LOGICAL_NOT, + LEXER_TOKEN_SYMBOL_BITWISE_NOT, LEXER_TOKEN_SYMBOL_MULTIPLY, LEXER_TOKEN_ORDER5 = LEXER_TOKEN_SYMBOL_MULTIPLY, @@ -99,15 +104,20 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL, LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, + LEXER_TOKEN_SYMBOL_BITWISE_AND, + LEXER_TOKEN_ORDER8 = LEXER_TOKEN_SYMBOL_BITWISE_AND, + LEXER_TOKEN_SYMBOL_BITWISE_XOR, + LEXER_TOKEN_SYMBOL_BITWISE_OR, + LEXER_TOKEN_SYMBOL_LOGICAL_AND, - LEXER_TOKEN_ORDER8 = LEXER_TOKEN_SYMBOL_LOGICAL_AND, + LEXER_TOKEN_ORDER9 = LEXER_TOKEN_SYMBOL_LOGICAL_AND, LEXER_TOKEN_SYMBOL_LOGICAL_OR, LEXER_TOKEN_SYMBOL_COLON, - LEXER_TOKEN_ORDER9 = LEXER_TOKEN_SYMBOL_COLON, + LEXER_TOKEN_ORDER10 = LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_SYMBOL_ASSIGN, - LEXER_TOKEN_ORDER10 = LEXER_TOKEN_SYMBOL_ASSIGN, + LEXER_TOKEN_ORDER11 = LEXER_TOKEN_SYMBOL_ASSIGN, LEXER_TOKEN_SYMBOL_SUM_ASSIGN, LEXER_TOKEN_SYMBOL_SUB_ASSIGN, LEXER_TOKEN_SYMBOL_MULTIPLY_ASSIGN, @@ -115,17 +125,17 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_MODULO_ASSIGN, LEXER_TOKEN_KEYWORD_RETURN, - LEXER_TOKEN_ORDER11 = LEXER_TOKEN_KEYWORD_RETURN, + LEXER_TOKEN_ORDER12 = LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_BREAK, LEXER_TOKEN_KEYWORD_CONTINUE, LEXER_TOKEN_KEYWORD_COMPTIME, LEXER_TOKEN_SYMBOL_EOL, - LEXER_TOKEN_ORDER12 = LEXER_TOKEN_SYMBOL_EOL, + LEXER_TOKEN_ORDER13 = LEXER_TOKEN_SYMBOL_EOL, LEXER_TOKEN_SYMBOL_COMMA, LEXER_TOKEN_KEYWORD_IF, - LEXER_TOKEN_ORDER13 = LEXER_TOKEN_KEYWORD_IF, + LEXER_TOKEN_ORDER14 = LEXER_TOKEN_KEYWORD_IF, LEXER_TOKEN_KEYWORD_WHILE, LEXER_TOKEN_KEYWORD_ELSE, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 3e4c8f6..299ee42 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -34,6 +34,10 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_BUILTIN_PUTC", "PARSER_TOKEN_BUILTIN_C_LIBRARY", "PARSER_TOKEN_BUILTIN_C_FUNCTION", + "PARSER_TOKEN_BUILTIN_BITWISE_NOT", + "PARSER_TOKEN_BUILTIN_BITWISE_AND", + "PARSER_TOKEN_BUILTIN_BITWISE_XOR", + "PARSER_TOKEN_BUILTIN_BITWISE_OR", "PARSER_TOKEN_VALUE_INT", "PARSER_TOKEN_VALUE_FLOAT", @@ -111,6 +115,10 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_OPERATOR_LOGICAL_NOT", "PARSER_TOKEN_OPERATOR_LOGICAL_AND", "PARSER_TOKEN_OPERATOR_LOGICAL_OR", + "PARSER_TOKEN_OPERATOR_BITWISE_NOT", + "PARSER_TOKEN_OPERATOR_BITWISE_AND", + "PARSER_TOKEN_OPERATOR_BITWISE_XOR", + "PARSER_TOKEN_OPERATOR_BITWISE_OR", "PARSER_TOKEN_FUNCTION_DEFINITION", @@ -171,7 +179,7 @@ static const ParserOrder PARSER_ORDER[] = { .end = LEXER_TOKEN_ORDER10, }, { - .ltr = false, + .ltr = true, .begin = LEXER_TOKEN_ORDER10, .end = LEXER_TOKEN_ORDER11, }, @@ -181,13 +189,18 @@ static const ParserOrder PARSER_ORDER[] = { .end = LEXER_TOKEN_ORDER12, }, { - .ltr = true, + .ltr = false, .begin = LEXER_TOKEN_ORDER12, .end = LEXER_TOKEN_ORDER13, }, { - .ltr = false, + .ltr = true, .begin = LEXER_TOKEN_ORDER13, + .end = LEXER_TOKEN_ORDER14, + }, + { + .ltr = false, + .begin = LEXER_TOKEN_ORDER14, .end = LEXER_TOKEN_END_ORDERS, }, }; @@ -269,6 +282,10 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_BUILTIN_PUTC: case PARSER_TOKEN_BUILTIN_C_LIBRARY: case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_BOOL: @@ -346,6 +363,7 @@ void parserNodePrint(const ParserNode *node, int indent) { } goto RETURN_SUCCESS; case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: case PARSER_TOKEN_KEYWORD_STRUCT: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: @@ -441,6 +459,9 @@ void parserNodePrint(const ParserNode *node, int indent) { goto RETURN_SUCCESS; case PARSER_TOKEN_OPERATOR_LOGICAL_AND: case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + case PARSER_TOKEN_OPERATOR_BITWISE_OR: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: @@ -579,6 +600,10 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_BUILTIN_PUTC: case PARSER_TOKEN_BUILTIN_C_LIBRARY: case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_BOOL: @@ -642,7 +667,7 @@ void parserNodeDelete(ParserNode *node) { } goto RETURN_SUCCESS; case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: - case PARSER_TOKEN_KEYWORD_STRUCT: + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_OPERATOR_DEREFERENCE: @@ -691,6 +716,10 @@ void parserNodeDelete(ParserNode *node) { goto RETURN_SUCCESS; case PARSER_TOKEN_OPERATOR_LOGICAL_AND: case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_KEYWORD_STRUCT: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: @@ -911,6 +940,14 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_C_LIBRARY); case LEXER_TOKEN_BUILTIN_C_FUNCTION: return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_C_FUNCTION); + case LEXER_TOKEN_BUILTIN_BITWISE_NOT: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_BITWISE_NOT); + case LEXER_TOKEN_BUILTIN_BITWISE_AND: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_BITWISE_AND); + case LEXER_TOKEN_BUILTIN_BITWISE_XOR: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_BITWISE_XOR); + case LEXER_TOKEN_BUILTIN_BITWISE_OR: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_BITWISE_OR); case LEXER_TOKEN_KEYWORD_TYPE: return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_TYPE); case LEXER_TOKEN_KEYWORD_VOID: @@ -1053,6 +1090,18 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, case LEXER_TOKEN_SYMBOL_LOGICAL_NOT: return parserLeftOperator(node, end, parent, PARSER_TOKEN_OPERATOR_LOGICAL_NOT); + case LEXER_TOKEN_SYMBOL_BITWISE_AND: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_BITWISE_AND); + case LEXER_TOKEN_SYMBOL_BITWISE_XOR: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_BITWISE_XOR); + case LEXER_TOKEN_SYMBOL_BITWISE_OR: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_BITWISE_OR); + case LEXER_TOKEN_SYMBOL_BITWISE_NOT: + return parserLeftOperator(node, end, parent, + PARSER_TOKEN_OPERATOR_BITWISE_NOT); case LEXER_TOKEN_SYMBOL_PLUS: { ParserNode *result = parserBinaryOrLeftOperator(node, begin, end, parent, PARSER_TOKEN_OPERATOR_PLUS, @@ -1074,12 +1123,9 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, *conti = result == NULL; return result; } - case LEXER_TOKEN_SYMBOL_ADDRESS: { - ParserNode *result = - parserLeftOperator(node, end, parent, PARSER_TOKEN_OPERATOR_ADDRESS); - *conti = result == NULL; - return result; - } + case LEXER_TOKEN_SYMBOL_ADDRESS: + return parserLeftOperatorWithConti(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_ADDRESS, conti); case LEXER_TOKEN_SYMBOL_DEREFERENCE: { ParserNode *result = parserRightOperator(node, begin, parent, PARSER_TOKEN_OPERATOR_DEREFERENCE); @@ -1711,6 +1757,10 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_BUILTIN_PUTC: case PARSER_TOKEN_BUILTIN_C_LIBRARY: case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: @@ -1779,6 +1829,10 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: case PARSER_TOKEN_OPERATOR_LOGICAL_AND: case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + case PARSER_TOKEN_OPERATOR_BITWISE_OR: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_COMPTIME: printError(bodyArray->data[i]->str_begin, bodyArray->data[i]->str_end, @@ -2025,6 +2079,31 @@ ParserNode *parserLeftOperator(LexerNode *node, LexerNode *end, (ParserNodeSingleChildMetadata *)right, parent); } +ParserNode *parserLeftOperatorWithConti(LexerNode *node, LexerNode *begin, + LexerNode *end, ParserNode *parent, + ParserToken token, bool *conti) { + LexerNode *leftNode = node - 1; + LexerNode *rightNode = node + 1; + + if ((leftNode >= begin && leftNode->parserNode != NULL) || + (rightNode >= end || rightNode->parserNode == NULL)) { + node->token = LEXER_TOKEN_SYMBOL_BITWISE_AND; + *conti = true; + return NULL; + } + + ParserNode *right = getUntilCommonParent(rightNode->parserNode, parent); + + if (right == NULL) { + printError(node->str_begin, node->str_end, "No operand found"); + return NULL; + } + + return right->parent = node->parserNode = + newParserNode(token, node->str_begin, right->str_end, + (ParserNodeSingleChildMetadata *)right, parent); +} + ParserNode *parserRightOperator(LexerNode *node, LexerNode *begin, ParserNode *parent, ParserToken token) { LexerNode *leftNode = node - 1; @@ -2217,6 +2296,10 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_BUILTIN_PUTC: case PARSER_TOKEN_BUILTIN_C_LIBRARY: case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: case PARSER_TOKEN_SYMBOL_PARENTHESIS: @@ -2251,6 +2334,10 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: case PARSER_TOKEN_OPERATOR_LOGICAL_AND: case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + case PARSER_TOKEN_OPERATOR_BITWISE_OR: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: @@ -2323,6 +2410,10 @@ bool parserIsFunction(ParserNode *node) { case PARSER_TOKEN_BUILTIN_PUTC: case PARSER_TOKEN_BUILTIN_C_LIBRARY: case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: @@ -2359,6 +2450,10 @@ bool parserIsFunction(ParserNode *node) { case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: case PARSER_TOKEN_OPERATOR_LOGICAL_AND: case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + case PARSER_TOKEN_OPERATOR_BITWISE_OR: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: @@ -2463,6 +2558,10 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_BUILTIN_PUTC: case PARSER_TOKEN_BUILTIN_C_LIBRARY: case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_UNDEFINED: @@ -2503,6 +2602,10 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: case PARSER_TOKEN_OPERATOR_LOGICAL_AND: case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + case PARSER_TOKEN_OPERATOR_BITWISE_OR: case PARSER_TOKEN_KEYWORD_WHILE: return false; case PARSER_TOKEN_NONE: @@ -2542,6 +2645,10 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_BUILTIN_PUTC: case PARSER_TOKEN_BUILTIN_C_LIBRARY: case PARSER_TOKEN_BUILTIN_C_FUNCTION: + case PARSER_TOKEN_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: @@ -2568,6 +2675,10 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: case PARSER_TOKEN_OPERATOR_LOGICAL_AND: case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + case PARSER_TOKEN_OPERATOR_BITWISE_NOT: + case PARSER_TOKEN_OPERATOR_BITWISE_AND: + case PARSER_TOKEN_OPERATOR_BITWISE_XOR: + case PARSER_TOKEN_OPERATOR_BITWISE_OR: case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 1b202c3..45804f7 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -31,6 +31,10 @@ typedef enum ParserToken { PARSER_TOKEN_BUILTIN_PUTC, PARSER_TOKEN_BUILTIN_C_LIBRARY, PARSER_TOKEN_BUILTIN_C_FUNCTION, + PARSER_TOKEN_BUILTIN_BITWISE_NOT, + PARSER_TOKEN_BUILTIN_BITWISE_AND, + PARSER_TOKEN_BUILTIN_BITWISE_XOR, + PARSER_TOKEN_BUILTIN_BITWISE_OR, PARSER_TOKEN_VALUE_INT, PARSER_TOKEN_VALUE_FLOAT, @@ -108,6 +112,10 @@ typedef enum ParserToken { PARSER_TOKEN_OPERATOR_LOGICAL_NOT, PARSER_TOKEN_OPERATOR_LOGICAL_AND, PARSER_TOKEN_OPERATOR_LOGICAL_OR, + PARSER_TOKEN_OPERATOR_BITWISE_NOT, + PARSER_TOKEN_OPERATOR_BITWISE_AND, + PARSER_TOKEN_OPERATOR_BITWISE_XOR, + PARSER_TOKEN_OPERATOR_BITWISE_OR, PARSER_TOKEN_FUNCTION_DEFINITION, @@ -262,6 +270,9 @@ ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin, LexerToken laterToken); ParserNode *parserLeftOperator(LexerNode *node, LexerNode *end, ParserNode *parent, ParserToken token); +ParserNode *parserLeftOperatorWithConti(LexerNode *node, LexerNode *begin, + LexerNode *end, ParserNode *parent, + ParserToken token, bool *conti); ParserNode *parserRightOperator(LexerNode *node, LexerNode *begin, ParserNode *parent, ParserToken token); ParserNode *parserIf(LexerNode *node, LexerNode *end, ParserNode *parent); -- cgit v1.2.3