aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-26 01:24:56 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-26 01:24:56 +0330
commitafa78451df1e9fb2810d4ae8cb697b1b2071ff9c (patch)
tree9b0ad12b58522cc0f99832253b1948fdebc1158c
parente55d45bac0bbd3039118bffa7e6aaf01c04b991a (diff)
add shift
-rw-r--r--code/basic.felan64
-rw-r--r--code/main.felan9
-rw-r--r--src/compiler/ast-tree.c91
-rw-r--r--src/compiler/ast-tree.h6
-rw-r--r--src/compiler/lexer.c21
-rw-r--r--src/compiler/lexer.h22
-rw-r--r--src/compiler/parser.c83
-rw-r--r--src/compiler/parser.h4
-rw-r--r--src/runner/runner.c90
-rw-r--r--src/utils/string.c27
-rw-r--r--src/utils/string.h1
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);