diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-05-26 01:24:56 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-05-26 01:24:56 +0330 |
commit | afa78451df1e9fb2810d4ae8cb697b1b2071ff9c (patch) | |
tree | 9b0ad12b58522cc0f99832253b1948fdebc1158c | |
parent | e55d45bac0bbd3039118bffa7e6aaf01c04b991a (diff) |
add shift
-rw-r--r-- | code/basic.felan | 64 | ||||
-rw-r--r-- | code/main.felan | 9 | ||||
-rw-r--r-- | src/compiler/ast-tree.c | 91 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 6 | ||||
-rw-r--r-- | src/compiler/lexer.c | 21 | ||||
-rw-r--r-- | src/compiler/lexer.h | 22 | ||||
-rw-r--r-- | src/compiler/parser.c | 83 | ||||
-rw-r--r-- | src/compiler/parser.h | 4 | ||||
-rw-r--r-- | src/runner/runner.c | 90 | ||||
-rw-r--r-- | src/utils/string.c | 27 | ||||
-rw-r--r-- | src/utils/string.h | 1 |
11 files changed, 389 insertions, 29 deletions
diff --git a/code/basic.felan b/code/basic.felan index fd2772d..d8121c2 100644 --- a/code/basic.felan +++ b/code/basic.felan @@ -726,3 +726,67 @@ __bitwise_or__ :: (left:i64,right:i64) -> i64 { return @bitwise_or(left,right); }; +__shift_left__ :: (left:u8,right:u8) -> u8 { + return @shift_left(left,right); +}; + +__shift_left__ :: (left:i8,right:i8) -> i8 { + return @shift_left(left,right); +}; + +__shift_left__ :: (left:u16,right:u16) -> u16 { + return @shift_left(left,right); +}; + +__shift_left__ :: (left:i16,right:i16) -> i16 { + return @shift_left(left,right); +}; + +__shift_left__ :: (left:u32,right:u32) -> u32 { + return @shift_left(left,right); +}; + +__shift_left__ :: (left:i32,right:i32) -> i32 { + return @shift_left(left,right); +}; + +__shift_left__ :: (left:u64,right:u64) -> u64 { + return @shift_left(left,right); +}; + +__shift_left__ :: (left:i64,right:i64) -> i64 { + return @shift_left(left,right); +}; + +__shift_right__ :: (left:u8,right:u8) -> u8 { + return @shift_right(left,right); +}; + +__shift_right__ :: (left:i8,right:i8) -> i8 { + return @shift_right(left,right); +}; + +__shift_right__ :: (left:u16,right:u16) -> u16 { + return @shift_right(left,right); +}; + +__shift_right__ :: (left:i16,right:i16) -> i16 { + return @shift_right(left,right); +}; + +__shift_right__ :: (left:u32,right:u32) -> u32 { + return @shift_right(left,right); +}; + +__shift_right__ :: (left:i32,right:i32) -> i32 { + return @shift_right(left,right); +}; + +__shift_right__ :: (left:u64,right:u64) -> u64 { + return @shift_right(left,right); +}; + +__shift_right__ :: (left:i64,right:i64) -> i64 { + return @shift_right(left,right); +}; + diff --git a/code/main.felan b/code/main.felan index a415607..1dff7fb 100644 --- a/code/main.felan +++ b/code/main.felan @@ -20,8 +20,10 @@ main :: ()->void{ str2 := &c[0]; screenWidth :i32: 800; screenHeight :i32: 450; - white :u32: 4294967295; - black :u32: 4278190080; + a : u8 : 255; + b : u8 : 0; + white :u32: color(a,a,a,a); + black :u32: 0xff000000; InitWindow(screenWidth,screenHeight,str); while !WindowShouldClose() { BeginDrawing(); @@ -33,6 +35,5 @@ main :: ()->void{ }; color :: (a:u8,r:u8,g:u8,b:u8)->u32{ - t :u8= 255; - c := t&a; + return @cast(a,u32)<<@cast(6*4,u32) | @cast(r,u32)<<@cast(0*4,u32) | @cast(g,u32)<<@cast(2*4,u32) | @cast(b,u32)<<@cast(4*4,u32); }; diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index de863c8..93c69ae 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -202,6 +202,8 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_BUILTIN_BITWISE_AND", "AST_TREE_TOKEN_BUILTIN_BITWISE_XOR", "AST_TREE_TOKEN_BUILTIN_BITWISE_OR", + "AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT", + "AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT", "AST_TREE_TOKEN_KEYWORD_RETURN", "AST_TREE_TOKEN_KEYWORD_BREAK", @@ -281,6 +283,8 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_OPERATOR_BITWISE_AND", "AST_TREE_TOKEN_OPERATOR_BITWISE_XOR", "AST_TREE_TOKEN_OPERATOR_BITWISE_OR", + "AST_TREE_TOKEN_OPERATOR_SHIFT_LEFT", + "AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT", "AST_TREE_TOKEN_SCOPE", @@ -361,6 +365,8 @@ void astTreePrint(const AstTree *tree, int indent) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: case AST_TREE_TOKEN_TYPE_I8: @@ -544,6 +550,8 @@ void astTreePrint(const AstTree *tree, int indent) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: case AST_TREE_TOKEN_OPERATOR_MULTIPLY: @@ -809,6 +817,8 @@ void astTreeDestroy(AstTree tree) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: case AST_TREE_TOKEN_TYPE_I8: @@ -945,6 +955,8 @@ void astTreeDestroy(AstTree tree) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: case AST_TREE_TOKEN_OPERATOR_MULTIPLY: @@ -1195,6 +1207,8 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: return newAstTree(tree->token, NULL, copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size, safetyCheck), @@ -1343,6 +1357,8 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: @@ -2168,6 +2184,8 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) { case PARSER_TOKEN_OPERATOR_BITWISE_AND: case PARSER_TOKEN_OPERATOR_BITWISE_XOR: case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: case PARSER_TOKEN_SYMBOL_PARENTHESIS: case PARSER_TOKEN_KEYWORD_IF: case PARSER_TOKEN_KEYWORD_WHILE: @@ -2225,6 +2243,8 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) { case PARSER_TOKEN_BUILTIN_BITWISE_AND: case PARSER_TOKEN_BUILTIN_BITWISE_XOR: case PARSER_TOKEN_BUILTIN_BITWISE_OR: + case PARSER_TOKEN_BUILTIN_SHIFT_LEFT: + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: goto AFTER_SWITCH; @@ -2362,6 +2382,10 @@ AstTree *astTreeParse(const ParserNode *parserNode) { 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_BUILTIN_SHIFT_LEFT: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT); + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT); case PARSER_TOKEN_TYPE_TYPE: return &AST_TREE_TYPE_TYPE; case PARSER_TOKEN_TYPE_FUNCTION: @@ -2507,6 +2531,12 @@ AstTree *astTreeParse(const ParserNode *parserNode) { case PARSER_TOKEN_OPERATOR_BITWISE_NOT: return astTreeParseUnaryOperator(parserNode, AST_TREE_TOKEN_OPERATOR_BITWISE_NOT); + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + return astTreeParseBinaryOperator(parserNode, + AST_TREE_TOKEN_OPERATOR_SHIFT_LEFT); + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: + return astTreeParseBinaryOperator(parserNode, + AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT); case PARSER_TOKEN_OPERATOR_PLUS: return astTreeParseUnaryOperator(parserNode, AST_TREE_TOKEN_OPERATOR_PLUS); case PARSER_TOKEN_OPERATOR_MINUS: @@ -2690,6 +2720,8 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode) { case PARSER_TOKEN_OPERATOR_BITWISE_AND: case PARSER_TOKEN_OPERATOR_BITWISE_XOR: case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: case PARSER_TOKEN_BUILTIN_SIZE_OF: @@ -2716,6 +2748,8 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode) { case PARSER_TOKEN_BUILTIN_BITWISE_AND: case PARSER_TOKEN_BUILTIN_BITWISE_XOR: case PARSER_TOKEN_BUILTIN_BITWISE_OR: + case PARSER_TOKEN_BUILTIN_SHIFT_LEFT: + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: printError(node->str_begin, node->str_end, "Unexpected %s", @@ -3300,6 +3334,8 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode) { case PARSER_TOKEN_OPERATOR_BITWISE_AND: case PARSER_TOKEN_OPERATOR_BITWISE_XOR: case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: case PARSER_TOKEN_BUILTIN_SIZE_OF: @@ -3326,6 +3362,8 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode) { case PARSER_TOKEN_BUILTIN_BITWISE_AND: case PARSER_TOKEN_BUILTIN_BITWISE_XOR: case PARSER_TOKEN_BUILTIN_BITWISE_OR: + case PARSER_TOKEN_BUILTIN_SHIFT_LEFT: + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: printError(node->str_begin, node->str_end, "Unexpected %s", @@ -3555,6 +3593,8 @@ bool isConst(AstTree *tree) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: @@ -3658,7 +3698,9 @@ bool isConst(AstTree *tree) { 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_BITWISE_OR: + case AST_TREE_TOKEN_OPERATOR_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: { AstTreeInfix *metadata = tree->metadata; return metadata->function->isConst && isConst(metadata->left) && isConst(metadata->right); @@ -3804,6 +3846,8 @@ AstTree *makeTypeOf(AstTree *value) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_EQUAL: case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: case AST_TREE_TOKEN_OPERATOR_GREATER: @@ -3878,6 +3922,8 @@ AstTree *makeTypeOf(AstTree *value) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_VALUE_OBJECT: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_KEYWORD_RETURN: @@ -3968,6 +4014,8 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: @@ -4010,6 +4058,8 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_ADDRESS: @@ -4161,6 +4211,8 @@ AstTree *getValue(AstTree *tree, bool copy) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: @@ -4221,6 +4273,8 @@ AstTree *getValue(AstTree *tree, bool copy) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_KEYWORD_IF: case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_KEYWORD_COMPTIME: @@ -4317,6 +4371,8 @@ bool isIntType(AstTree *type) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -4381,6 +4437,8 @@ bool isIntType(AstTree *type) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: @@ -4434,6 +4492,8 @@ bool isFloatType(AstTree *type) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -4492,6 +4552,8 @@ bool isFloatType(AstTree *type) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: @@ -4586,6 +4648,8 @@ bool isEqual(AstTree *left, AstTree *right) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -4628,6 +4692,8 @@ bool isEqual(AstTree *left, AstTree *right) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: @@ -4784,6 +4850,13 @@ static const size_t STR_BITWISE_XOR_SIZE = 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_SHIFT_LEFT[] = "__shift_left__"; +static const size_t STR_SHIFT_LEFT_SIZE = + sizeof(STR_SHIFT_LEFT) / sizeof(*STR_SHIFT_LEFT) - sizeof(*STR_SHIFT_LEFT); +static const char STR_SHIFT_RIGHT[] = "__shift_right__"; +static const size_t STR_SHIFT_RIGHT_SIZE = + sizeof(STR_SHIFT_RIGHT) / sizeof(*STR_SHIFT_RIGHT) - + sizeof(*STR_SHIFT_RIGHT); static const char STR_EQUAL[] = "__equal__"; static const size_t STR_EQUAL_SIZE = sizeof(STR_EQUAL) / sizeof(*STR_EQUAL) - sizeof(*STR_EQUAL); @@ -4916,6 +4989,12 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_OPERATOR_BITWISE_OR: return setTypesOperatorInfix(tree, helper, STR_BITWISE_OR, STR_BITWISE_OR_SIZE); + case AST_TREE_TOKEN_OPERATOR_SHIFT_LEFT: + return setTypesOperatorInfix(tree, helper, STR_SHIFT_LEFT, + STR_SHIFT_LEFT_SIZE); + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: + return setTypesOperatorInfix(tree, helper, STR_SHIFT_RIGHT, + STR_SHIFT_RIGHT_SIZE); case AST_TREE_TOKEN_OPERATOR_POINTER: return setTypesOperatorPointer(tree, helper); case AST_TREE_TOKEN_OPERATOR_ADDRESS: @@ -4961,6 +5040,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: return setTypesBuiltinBinary(tree, helper, functionCall); case AST_TREE_TOKEN_BUILTIN_EQUAL: case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL: @@ -6695,6 +6776,8 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -6750,6 +6833,8 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: @@ -7776,6 +7861,8 @@ size_t getSizeOfType(AstTree *type) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -7823,6 +7910,8 @@ size_t getSizeOfType(AstTree *type) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: 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 6891e29..63e24b0 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -33,7 +33,9 @@ typedef enum AstTreeToken { 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_BUILTIN_SHIFT_LEFT, + AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT, + AST_TREE_TOKEN_BUILTIN_END = AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT, AST_TREE_TOKEN_KEYWORD_RETURN, AST_TREE_TOKEN_KEYWORD_BREAK, @@ -115,6 +117,8 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_OPERATOR_BITWISE_AND, AST_TREE_TOKEN_OPERATOR_BITWISE_XOR, AST_TREE_TOKEN_OPERATOR_BITWISE_OR, + AST_TREE_TOKEN_OPERATOR_SHIFT_LEFT, + AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT, AST_TREE_TOKEN_SCOPE, diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index db1ba64..f79868a 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -37,6 +37,8 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_BUILTIN_BITWISE_AND", "LEXER_TOKEN_BUILTIN_BITWISE_XOR", "LEXER_TOKEN_BUILTIN_BITWISE_OR", + "LEXER_TOKEN_BUILTIN_SHIFT_LEFT", + "LEXER_TOKEN_BUILTIN_SHIFT_RIGHT", "LEXER_TOKEN_KEYWORD_TYPE", "LEXER_TOKEN_KEYWORD_VOID", "LEXER_TOKEN_KEYWORD_I8", @@ -89,6 +91,9 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_SUM", "LEXER_TOKEN_SYMBOL_SUB", + "LEXER_TOKEN_SYMBOL_LEFT_SHIFT", + "LEXER_TOKEN_SYMBOL_RIGHT_SHIFT", + "LEXER_TOKEN_SYMBOL_EQUAL", "LEXER_TOKEN_SYMBOL_NOT_EQUAL", "LEXER_TOKEN_SYMBOL_GREATER", @@ -135,9 +140,9 @@ const char *LEXER_TOKEN_STRINGS[] = { }; static const char *LEXER_SYMBOL_STRINGS[] = { - ";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=", "/=", - "%=", ",", "+", "-", "*", "/", "%", "==", "!=", ">", ">=", "<", - "<=", "&", ".*", ".", "!", "&&", "||", "[", "]", "^", "|", "~", + ";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=", "/=", "%=", + ",", "+", "-", "*", "/", "%", "==", "!=", ">", ">=", "<", "<=", "&", + ".*", ".", "!", "&&", "||", "[", "]", "^", "|", "~", "<<", ">>", }; static const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_EOL, @@ -176,6 +181,8 @@ static const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_BITWISE_XOR, LEXER_TOKEN_SYMBOL_BITWISE_OR, LEXER_TOKEN_SYMBOL_BITWISE_NOT, + LEXER_TOKEN_SYMBOL_LEFT_SHIFT, + LEXER_TOKEN_SYMBOL_RIGHT_SHIFT, }; static const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); @@ -245,6 +252,8 @@ static const char *LEXER_BUILTIN_STRINGS[] = { "bitwise_and", "bitwise_xor", "bitwise_or", + "shift_left", + "shift_right", }; static const LexerToken LEXER_BUILTIN_TOKENS[] = { LEXER_TOKEN_BUILTIN_CAST, @@ -273,6 +282,8 @@ static const LexerToken LEXER_BUILTIN_TOKENS[] = { LEXER_TOKEN_BUILTIN_BITWISE_AND, LEXER_TOKEN_BUILTIN_BITWISE_XOR, LEXER_TOKEN_BUILTIN_BITWISE_OR, + LEXER_TOKEN_BUILTIN_SHIFT_LEFT, + LEXER_TOKEN_BUILTIN_SHIFT_RIGHT, }; static const size_t LEXER_BUILTIN_SIZE = sizeof(LEXER_BUILTIN_TOKENS) / sizeof(*LEXER_BUILTIN_TOKENS); @@ -521,6 +532,8 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char const *iter, case LEXER_TOKEN_SYMBOL_LOGICAL_NOT: case LEXER_TOKEN_SYMBOL_LOGICAL_AND: case LEXER_TOKEN_SYMBOL_LOGICAL_OR: + case LEXER_TOKEN_SYMBOL_LEFT_SHIFT: + case LEXER_TOKEN_SYMBOL_RIGHT_SHIFT: case LEXER_TOKEN_BUILTIN_CAST: case LEXER_TOKEN_BUILTIN_TYPE_OF: case LEXER_TOKEN_BUILTIN_IMPORT: @@ -547,6 +560,8 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char const *iter, case LEXER_TOKEN_BUILTIN_BITWISE_AND: case LEXER_TOKEN_BUILTIN_BITWISE_XOR: case LEXER_TOKEN_BUILTIN_BITWISE_OR: + case LEXER_TOKEN_BUILTIN_SHIFT_LEFT: + case LEXER_TOKEN_BUILTIN_SHIFT_RIGHT: case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET: case LEXER_TOKEN_SYMBOL_OPEN_BRACKET: case LEXER_TOKEN_KEYWORD_SHAPE_SHIFTER: diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 045bf6e..8c2806d 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -39,6 +39,8 @@ typedef enum LexerToken { LEXER_TOKEN_BUILTIN_BITWISE_AND, LEXER_TOKEN_BUILTIN_BITWISE_XOR, LEXER_TOKEN_BUILTIN_BITWISE_OR, + LEXER_TOKEN_BUILTIN_SHIFT_LEFT, + LEXER_TOKEN_BUILTIN_SHIFT_RIGHT, LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID, LEXER_TOKEN_KEYWORD_I8, @@ -96,8 +98,12 @@ typedef enum LexerToken { LEXER_TOKEN_ORDER6 = LEXER_TOKEN_SYMBOL_SUM, LEXER_TOKEN_SYMBOL_SUB, + LEXER_TOKEN_SYMBOL_LEFT_SHIFT, + LEXER_TOKEN_ORDER7 = LEXER_TOKEN_SYMBOL_LEFT_SHIFT, + LEXER_TOKEN_SYMBOL_RIGHT_SHIFT, + LEXER_TOKEN_SYMBOL_EQUAL, - LEXER_TOKEN_ORDER7 = LEXER_TOKEN_SYMBOL_EQUAL, + LEXER_TOKEN_ORDER8 = LEXER_TOKEN_SYMBOL_EQUAL, LEXER_TOKEN_SYMBOL_NOT_EQUAL, LEXER_TOKEN_SYMBOL_GREATER, LEXER_TOKEN_SYMBOL_SMALLER, @@ -105,19 +111,19 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, LEXER_TOKEN_SYMBOL_BITWISE_AND, - LEXER_TOKEN_ORDER8 = LEXER_TOKEN_SYMBOL_BITWISE_AND, + LEXER_TOKEN_ORDER9 = LEXER_TOKEN_SYMBOL_BITWISE_AND, LEXER_TOKEN_SYMBOL_BITWISE_XOR, LEXER_TOKEN_SYMBOL_BITWISE_OR, LEXER_TOKEN_SYMBOL_LOGICAL_AND, - LEXER_TOKEN_ORDER9 = LEXER_TOKEN_SYMBOL_LOGICAL_AND, + LEXER_TOKEN_ORDER10 = LEXER_TOKEN_SYMBOL_LOGICAL_AND, LEXER_TOKEN_SYMBOL_LOGICAL_OR, LEXER_TOKEN_SYMBOL_COLON, - LEXER_TOKEN_ORDER10 = LEXER_TOKEN_SYMBOL_COLON, + LEXER_TOKEN_ORDER11 = LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_SYMBOL_ASSIGN, - LEXER_TOKEN_ORDER11 = LEXER_TOKEN_SYMBOL_ASSIGN, + LEXER_TOKEN_ORDER12 = LEXER_TOKEN_SYMBOL_ASSIGN, LEXER_TOKEN_SYMBOL_SUM_ASSIGN, LEXER_TOKEN_SYMBOL_SUB_ASSIGN, LEXER_TOKEN_SYMBOL_MULTIPLY_ASSIGN, @@ -125,17 +131,17 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_MODULO_ASSIGN, LEXER_TOKEN_KEYWORD_RETURN, - LEXER_TOKEN_ORDER12 = LEXER_TOKEN_KEYWORD_RETURN, + LEXER_TOKEN_ORDER13 = LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_BREAK, LEXER_TOKEN_KEYWORD_CONTINUE, LEXER_TOKEN_KEYWORD_COMPTIME, LEXER_TOKEN_SYMBOL_EOL, - LEXER_TOKEN_ORDER13 = LEXER_TOKEN_SYMBOL_EOL, + LEXER_TOKEN_ORDER14 = LEXER_TOKEN_SYMBOL_EOL, LEXER_TOKEN_SYMBOL_COMMA, LEXER_TOKEN_KEYWORD_IF, - LEXER_TOKEN_ORDER14 = LEXER_TOKEN_KEYWORD_IF, + LEXER_TOKEN_ORDER15 = 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 299ee42..b2258b2 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -38,6 +38,8 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_BUILTIN_BITWISE_AND", "PARSER_TOKEN_BUILTIN_BITWISE_XOR", "PARSER_TOKEN_BUILTIN_BITWISE_OR", + "PARSER_TOKEN_BUILTIN_SHIFT_LEFT", + "PARSER_TOKEN_BUILTIN_SHIFT_RIGHT", "PARSER_TOKEN_VALUE_INT", "PARSER_TOKEN_VALUE_FLOAT", @@ -119,6 +121,8 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_OPERATOR_BITWISE_AND", "PARSER_TOKEN_OPERATOR_BITWISE_XOR", "PARSER_TOKEN_OPERATOR_BITWISE_OR", + "PARSER_TOKEN_OPERATOR_SHIFT_LEFT", + "PARSER_TOKEN_OPERATOR_SHIFT_RIGHT", "PARSER_TOKEN_FUNCTION_DEFINITION", @@ -184,7 +188,7 @@ static const ParserOrder PARSER_ORDER[] = { .end = LEXER_TOKEN_ORDER11, }, { - .ltr = false, + .ltr = true, .begin = LEXER_TOKEN_ORDER11, .end = LEXER_TOKEN_ORDER12, }, @@ -194,13 +198,18 @@ static const ParserOrder PARSER_ORDER[] = { .end = LEXER_TOKEN_ORDER13, }, { - .ltr = true, + .ltr = false, .begin = LEXER_TOKEN_ORDER13, .end = LEXER_TOKEN_ORDER14, }, { - .ltr = false, + .ltr = true, .begin = LEXER_TOKEN_ORDER14, + .end = LEXER_TOKEN_ORDER15, + }, + { + .ltr = false, + .begin = LEXER_TOKEN_ORDER15, .end = LEXER_TOKEN_END_ORDERS, }, }; @@ -286,6 +295,8 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_BUILTIN_BITWISE_AND: case PARSER_TOKEN_BUILTIN_BITWISE_XOR: case PARSER_TOKEN_BUILTIN_BITWISE_OR: + case PARSER_TOKEN_BUILTIN_SHIFT_LEFT: + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_BOOL: @@ -462,6 +473,8 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_OPERATOR_BITWISE_AND: case PARSER_TOKEN_OPERATOR_BITWISE_XOR: case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: @@ -604,6 +617,8 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_BUILTIN_BITWISE_AND: case PARSER_TOKEN_BUILTIN_BITWISE_XOR: case PARSER_TOKEN_BUILTIN_BITWISE_OR: + case PARSER_TOKEN_BUILTIN_SHIFT_LEFT: + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_BOOL: @@ -719,6 +734,8 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_OPERATOR_BITWISE_AND: case PARSER_TOKEN_OPERATOR_BITWISE_XOR: case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: case PARSER_TOKEN_KEYWORD_STRUCT: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: @@ -948,6 +965,10 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, 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_BUILTIN_SHIFT_LEFT: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_SHIFT_LEFT); + case LEXER_TOKEN_BUILTIN_SHIFT_RIGHT: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_SHIFT_RIGHT); case LEXER_TOKEN_KEYWORD_TYPE: return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_TYPE); case LEXER_TOKEN_KEYWORD_VOID: @@ -1058,6 +1079,12 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, case LEXER_TOKEN_SYMBOL_MODULO: return parserBinaryOperator(node, begin, end, parent, PARSER_TOKEN_OPERATOR_MODULO); + case LEXER_TOKEN_SYMBOL_LEFT_SHIFT: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_SHIFT_LEFT); + case LEXER_TOKEN_SYMBOL_RIGHT_SHIFT: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_SHIFT_RIGHT); case LEXER_TOKEN_SYMBOL_EQUAL: return parserBinaryOperator(node, begin, end, parent, PARSER_TOKEN_OPERATOR_EQUAL); @@ -1148,7 +1175,6 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET: case LEXER_TOKEN_SYMBOL_OPEN_BRACKET: case LEXER_TOKEN_NONE: - break; } UNREACHABLE; } @@ -1256,15 +1282,30 @@ ParserNode *parserReturn(LexerNode *node, LexerNode *end, ParserNode *parent) { ParserNode *parserNumber(LexerNode *node, ParserNode *parent) { ParserNode *parserNode; + bool success; switch (*node->str_begin) { case '0': if (node->str_end - node->str_begin > 1) { - printError(node->str_begin, node->str_end, "Not implemented"); - return NULL; + switch (*(node->str_begin + 1)) { + case 'x': + case 'X': + u64 value = hexToU64(node->str_begin + 2, node->str_end, &success); + if (!success) { + printError(node->str_begin, node->str_end, "Error in parsing number"); + return NULL; + } + ParserNodeIntMetadata *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = value; + parserNode = newParserNode(PARSER_TOKEN_VALUE_INT, node->str_begin, + node->str_end, metadata, parent); + break; + default: + NOT_IMPLEMENTED; + } + break; } // fall through default: { - bool success; u64 value = decimalToU64(node->str_begin, node->str_end, &success); if (success) { ParserNodeIntMetadata *metadata = a404m_malloc(sizeof(*metadata)); @@ -1757,10 +1798,12 @@ 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_BUILTIN_BITWISE_NOT: + case PARSER_TOKEN_BUILTIN_BITWISE_AND: + case PARSER_TOKEN_BUILTIN_BITWISE_XOR: + case PARSER_TOKEN_BUILTIN_BITWISE_OR: + case PARSER_TOKEN_BUILTIN_SHIFT_LEFT: + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: @@ -1833,6 +1876,8 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_OPERATOR_BITWISE_AND: case PARSER_TOKEN_OPERATOR_BITWISE_XOR: case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_COMPTIME: printError(bodyArray->data[i]->str_begin, bodyArray->data[i]->str_end, @@ -2300,6 +2345,8 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_BUILTIN_BITWISE_AND: case PARSER_TOKEN_BUILTIN_BITWISE_XOR: case PARSER_TOKEN_BUILTIN_BITWISE_OR: + case PARSER_TOKEN_BUILTIN_SHIFT_LEFT: + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: case PARSER_TOKEN_SYMBOL_PARENTHESIS: @@ -2338,6 +2385,8 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_OPERATOR_BITWISE_AND: case PARSER_TOKEN_OPERATOR_BITWISE_XOR: case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: @@ -2414,6 +2463,8 @@ bool parserIsFunction(ParserNode *node) { case PARSER_TOKEN_BUILTIN_BITWISE_AND: case PARSER_TOKEN_BUILTIN_BITWISE_XOR: case PARSER_TOKEN_BUILTIN_BITWISE_OR: + case PARSER_TOKEN_BUILTIN_SHIFT_LEFT: + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_SYMBOL_CURLY_BRACKET: @@ -2454,6 +2505,8 @@ bool parserIsFunction(ParserNode *node) { case PARSER_TOKEN_OPERATOR_BITWISE_AND: case PARSER_TOKEN_OPERATOR_BITWISE_XOR: case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: @@ -2562,6 +2615,8 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_BUILTIN_BITWISE_AND: case PARSER_TOKEN_BUILTIN_BITWISE_XOR: case PARSER_TOKEN_BUILTIN_BITWISE_OR: + case PARSER_TOKEN_BUILTIN_SHIFT_LEFT: + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_UNDEFINED: @@ -2606,6 +2661,8 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_OPERATOR_BITWISE_AND: case PARSER_TOKEN_OPERATOR_BITWISE_XOR: case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: case PARSER_TOKEN_KEYWORD_WHILE: return false; case PARSER_TOKEN_NONE: @@ -2649,6 +2706,8 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_BUILTIN_BITWISE_AND: case PARSER_TOKEN_BUILTIN_BITWISE_XOR: case PARSER_TOKEN_BUILTIN_BITWISE_OR: + case PARSER_TOKEN_BUILTIN_SHIFT_LEFT: + case PARSER_TOKEN_BUILTIN_SHIFT_RIGHT: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: @@ -2679,6 +2738,8 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_OPERATOR_BITWISE_AND: case PARSER_TOKEN_OPERATOR_BITWISE_XOR: case PARSER_TOKEN_OPERATOR_BITWISE_OR: + case PARSER_TOKEN_OPERATOR_SHIFT_LEFT: + case PARSER_TOKEN_OPERATOR_SHIFT_RIGHT: 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 45804f7..dc48511 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -35,6 +35,8 @@ typedef enum ParserToken { PARSER_TOKEN_BUILTIN_BITWISE_AND, PARSER_TOKEN_BUILTIN_BITWISE_XOR, PARSER_TOKEN_BUILTIN_BITWISE_OR, + PARSER_TOKEN_BUILTIN_SHIFT_LEFT, + PARSER_TOKEN_BUILTIN_SHIFT_RIGHT, PARSER_TOKEN_VALUE_INT, PARSER_TOKEN_VALUE_FLOAT, @@ -116,6 +118,8 @@ typedef enum ParserToken { PARSER_TOKEN_OPERATOR_BITWISE_AND, PARSER_TOKEN_OPERATOR_BITWISE_XOR, PARSER_TOKEN_OPERATOR_BITWISE_OR, + PARSER_TOKEN_OPERATOR_SHIFT_LEFT, + PARSER_TOKEN_OPERATOR_SHIFT_RIGHT, PARSER_TOKEN_FUNCTION_DEFINITION, diff --git a/src/runner/runner.c b/src/runner/runner.c index 926380a..923f9af 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -1075,6 +1075,78 @@ AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope, return newAstTree(AST_TREE_TOKEN_RAW_VALUE, ret, copyAstTree(left->type), NULL, NULL); } + case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT: { + AstTree *left = arguments[0]; + AstTree *right = arguments[1]; + AstTreeRawValue *ret = a404m_malloc(getSizeOfType(left->type)); + + switch (left->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(i8 *)ret = *(i8 *)left->metadata << *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(u8 *)ret = *(u8 *)left->metadata << *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(i16 *)ret = *(i16 *)left->metadata << *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(u16 *)ret = *(u16 *)left->metadata << *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(i32 *)ret = *(i32 *)left->metadata << *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(u32 *)ret = *(u32 *)left->metadata << *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(i64 *)ret = *(i64 *)left->metadata << *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(u64 *)ret = *(u64 *)left->metadata << *(u64 *)right->metadata; + break; + default: + UNREACHABLE; + } + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, ret, copyAstTree(left->type), + NULL, NULL); + } + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: { + AstTree *left = arguments[0]; + AstTree *right = arguments[1]; + AstTreeRawValue *ret = a404m_malloc(getSizeOfType(left->type)); + + switch (left->type->token) { + case AST_TREE_TOKEN_TYPE_I8: + *(i8 *)ret = *(i8 *)left->metadata >> *(i8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U8: + *(u8 *)ret = *(u8 *)left->metadata >> *(u8 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I16: + *(i16 *)ret = *(i16 *)left->metadata >> *(i16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U16: + *(u16 *)ret = *(u16 *)left->metadata >> *(u16 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I32: + *(i32 *)ret = *(i32 *)left->metadata >> *(i32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U32: + *(u32 *)ret = *(u32 *)left->metadata >> *(u32 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_I64: + *(i64 *)ret = *(i64 *)left->metadata >> *(i64 *)right->metadata; + break; + case AST_TREE_TOKEN_TYPE_U64: + *(u64 *)ret = *(u64 *)left->metadata >> *(u64 *)right->metadata; + break; + default: + UNREACHABLE; + } + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, ret, copyAstTree(left->type), + NULL, NULL); + } case AST_TREE_TOKEN_BUILTIN_PUTC: { putchar(*(u8 *)arguments[0]->metadata); return copyAstTree(&AST_TREE_VOID_VALUE); @@ -1447,7 +1519,9 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet, 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_BITWISE_OR: + case AST_TREE_TOKEN_OPERATOR_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: { AstTreeInfix *metadata = expr->metadata; AstTree *function = runExpression(metadata->function->value, scope, shouldRet, false, @@ -1541,6 +1615,8 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet, 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: return copyAstTree(expr); case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: { AstTreeBool *metadata = a404m_malloc(sizeof(*metadata)); @@ -2030,6 +2106,8 @@ AstTree *toRawValue(AstTree *value) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -2068,6 +2146,8 @@ AstTree *toRawValue(AstTree *value) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: @@ -2205,6 +2285,8 @@ AstTree *castTo(AstTree *tree, AstTree *to) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -2253,6 +2335,8 @@ AstTree *castTo(AstTree *tree, AstTree *to) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: @@ -2331,6 +2415,8 @@ ffi_type *toFFIType(AstTree *type) { 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_BUILTIN_SHIFT_LEFT: + case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -2379,6 +2465,8 @@ ffi_type *toFFIType(AstTree *type) { 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_SHIFT_LEFT: + case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT: case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_NONE: diff --git a/src/utils/string.c b/src/utils/string.c index d05f0ec..1932d89 100644 --- a/src/utils/string.c +++ b/src/utils/string.c @@ -56,6 +56,33 @@ u64 decimalToU64(char const *str_begin, char const *str_end, bool *success) { return result; } +u64 hexToU64(char const *str_begin, char const *str_end, bool *success) { + u64 result = 0; + + if (str_end - str_begin > 16) { + *success = false; + return 0; + } + + while (str_begin < str_end) { + result *= 16; + if ('0' <= *str_begin && *str_begin <= '9') { + result += *str_begin - '0'; + } else if ('A' <= *str_begin && *str_begin <= 'F') { + result += *str_begin - 'A' + 10; + } else if ('a' <= *str_begin && *str_begin <= 'f') { + result += *str_begin - 'a' + 10; + } else { + *success = false; + return 0; + } + str_begin += 1; + } + + *success = true; + return result; +} + f128 numberToFloat(char const *str_begin, char const *str_end, bool *success) { f128 left = 0; f128 right = 0; diff --git a/src/utils/string.h b/src/utils/string.h index 878311f..dd2209c 100644 --- a/src/utils/string.h +++ b/src/utils/string.h @@ -13,6 +13,7 @@ size_t searchInStringArray(const char *array[], size_t array_size, const char *str, size_t str_size); u64 decimalToU64(char const*str_begin, char const*str_end, bool *success); +u64 hexToU64(char const*str_begin, char const*str_end, bool *success); f128 numberToFloat(char const*str_begin, char const*str_end, bool *success); char *u64ToString(u64 value); |