aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile12
-rw-r--r--code/basic.felan129
-rw-r--r--code/main.felan13
-rw-r--r--src/compiler/ast-tree.c191
-rw-r--r--src/compiler/ast-tree.h10
-rw-r--r--src/compiler/lexer.c34
-rw-r--r--src/compiler/lexer.h22
-rw-r--r--src/compiler/parser.c131
-rw-r--r--src/compiler/parser.h11
-rw-r--r--src/runner/runner.c177
10 files changed, 697 insertions, 33 deletions
diff --git a/Makefile b/Makefile
index c7b3eec..d713229 100644
--- a/Makefile
+++ b/Makefile
@@ -20,13 +20,15 @@ INC_DIRS := $(SRC_DIR)
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
# OP_FLAG := -Ofast
-OP_FLAG := -O3
+# OP_FLAG := -O3
# OP_FLAG := -Oz
-# OP_FLAG := -g
+OP_FLAG := -g
-# CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 -DPRINT_STATISTICS -DPRINT_COMPILE_TREE $(OP_FLAG)
-CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 -lffi -DPRINT_STATISTICS $(OP_FLAG)
-# CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 $(OP_FLAG)
+LINK_FLAGS := -lffi
+
+# CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 $(LINK_FLAGS) -DPRINT_STATISTICS -DPRINT_COMPILE_TREE $(OP_FLAG)
+CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 $(LINK_FLAGS) -DPRINT_STATISTICS $(OP_FLAG)
+# CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 $(LINK_FLAGS) $(OP_FLAG)
EXEC_FILE := $(BUILD_DIR)/$(PROJECT_NAME)
diff --git a/code/basic.felan b/code/basic.felan
index cec6032..fd2772d 100644
--- a/code/basic.felan
+++ b/code/basic.felan
@@ -597,3 +597,132 @@ __logical_or__ :: (left:bool,lazy right:bool) -> bool {
return false;
}
};
+
+__bitwise_not__ :: (value:u8) -> u8 {
+ return @bitwise_not(value);
+};
+
+__bitwise_not__ :: (value:i8) -> i8 {
+ return @bitwise_not(value);
+};
+
+__bitwise_not__ :: (value:u16) -> u16 {
+ return @bitwise_not(value);
+};
+
+__bitwise_not__ :: (value:i16) -> i16 {
+ return @bitwise_not(value);
+};
+
+__bitwise_not__ :: (value:u32) -> u32 {
+ return @bitwise_not(value);
+};
+
+__bitwise_not__ :: (value:i32) -> i32 {
+ return @bitwise_not(value);
+};
+
+__bitwise_not__ :: (value:u64) -> u64 {
+ return @bitwise_not(value);
+};
+
+__bitwise_not__ :: (value:i64) -> i64 {
+ return @bitwise_not(value);
+};
+
+__bitwise_and__ :: (left:u8,right:u8) -> u8 {
+ return @bitwise_and(left,right);
+};
+
+__bitwise_and__ :: (left:i8,right:i8) -> i8 {
+ return @bitwise_and(left,right);
+};
+
+__bitwise_and__ :: (left:u16,right:u16) -> u16 {
+ return @bitwise_and(left,right);
+};
+
+__bitwise_and__ :: (left:i16,right:i16) -> i16 {
+ return @bitwise_and(left,right);
+};
+
+__bitwise_and__ :: (left:u32,right:u32) -> u32 {
+ return @bitwise_and(left,right);
+};
+
+__bitwise_and__ :: (left:i32,right:i32) -> i32 {
+ return @bitwise_and(left,right);
+};
+
+__bitwise_and__ :: (left:u64,right:u64) -> u64 {
+ return @bitwise_and(left,right);
+};
+
+__bitwise_and__ :: (left:i64,right:i64) -> i64 {
+ return @bitwise_and(left,right);
+};
+
+__bitwise_xor__ :: (left:u8,right:u8) -> u8 {
+ return @bitwise_xor(left,right);
+};
+
+__bitwise_xor__ :: (left:i8,right:i8) -> i8 {
+ return @bitwise_xor(left,right);
+};
+
+__bitwise_xor__ :: (left:u16,right:u16) -> u16 {
+ return @bitwise_xor(left,right);
+};
+
+__bitwise_xor__ :: (left:i16,right:i16) -> i16 {
+ return @bitwise_xor(left,right);
+};
+
+__bitwise_xor__ :: (left:u32,right:u32) -> u32 {
+ return @bitwise_xor(left,right);
+};
+
+__bitwise_xor__ :: (left:i32,right:i32) -> i32 {
+ return @bitwise_xor(left,right);
+};
+
+__bitwise_xor__ :: (left:u64,right:u64) -> u64 {
+ return @bitwise_xor(left,right);
+};
+
+__bitwise_xor__ :: (left:i64,right:i64) -> i64 {
+ return @bitwise_xor(left,right);
+};
+
+__bitwise_or__ :: (left:u8,right:u8) -> u8 {
+ return @bitwise_or(left,right);
+};
+
+__bitwise_or__ :: (left:i8,right:i8) -> i8 {
+ return @bitwise_or(left,right);
+};
+
+__bitwise_or__ :: (left:u16,right:u16) -> u16 {
+ return @bitwise_or(left,right);
+};
+
+__bitwise_or__ :: (left:i16,right:i16) -> i16 {
+ return @bitwise_or(left,right);
+};
+
+__bitwise_or__ :: (left:u32,right:u32) -> u32 {
+ return @bitwise_or(left,right);
+};
+
+__bitwise_or__ :: (left:i32,right:i32) -> i32 {
+ return @bitwise_or(left,right);
+};
+
+__bitwise_or__ :: (left:u64,right:u64) -> u64 {
+ return @bitwise_or(left,right);
+};
+
+__bitwise_or__ :: (left:i64,right:i64) -> i64 {
+ return @bitwise_or(left,right);
+};
+
diff --git a/code/main.felan b/code/main.felan
index 0258e17..a415607 100644
--- a/code/main.felan
+++ b/code/main.felan
@@ -20,12 +20,19 @@ main :: ()->void{
str2 := &c[0];
screenWidth :i32: 800;
screenHeight :i32: 450;
+ white :u32: 4294967295;
+ black :u32: 4278190080;
InitWindow(screenWidth,screenHeight,str);
- while (!WindowShouldClose()) {
+ while !WindowShouldClose() {
BeginDrawing();
- ClearBackground(@cast(4294967295,u32));
- DrawText(str2,@cast(190,i32),@cast(200,i32),@cast(20,i32),@cast(4278190080,u32));
+ ClearBackground(@cast(white,u32));
+ DrawText(str2,@cast(190,i32),@cast(200,i32),@cast(20,i32),@cast(black,u32));
EndDrawing();
}
CloseWindow();
};
+
+color :: (a:u8,r:u8,g:u8,b:u8)->u32{
+ t :u8= 255;
+ c := t&a;
+};
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);
diff --git a/src/runner/runner.c b/src/runner/runner.c
index bedb2c6..926380a 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -932,6 +932,149 @@ AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope,
}
return ret;
}
+ case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT: {
+ AstTree *left = arguments[0];
+ AstTreeRawValue *ret = a404m_malloc(getSizeOfType(left->type));
+
+ switch (left->type->token) {
+ case AST_TREE_TOKEN_TYPE_I8:
+ *(i8 *)ret = *(i8 *)left->metadata;
+ break;
+ case AST_TREE_TOKEN_TYPE_U8:
+ *(u8 *)ret = *(u8 *)left->metadata;
+ break;
+ case AST_TREE_TOKEN_TYPE_I16:
+ *(i16 *)ret = *(i16 *)left->metadata;
+ break;
+ case AST_TREE_TOKEN_TYPE_U16:
+ *(u16 *)ret = *(u16 *)left->metadata;
+ break;
+ case AST_TREE_TOKEN_TYPE_I32:
+ *(i32 *)ret = *(i32 *)left->metadata;
+ break;
+ case AST_TREE_TOKEN_TYPE_U32:
+ *(u32 *)ret = *(u32 *)left->metadata;
+ break;
+ case AST_TREE_TOKEN_TYPE_I64:
+ *(i64 *)ret = *(i64 *)left->metadata;
+ break;
+ case AST_TREE_TOKEN_TYPE_U64:
+ *(u64 *)ret = *(u64 *)left->metadata;
+ break;
+ default:
+ UNREACHABLE;
+ }
+ return newAstTree(AST_TREE_TOKEN_RAW_VALUE, ret, copyAstTree(left->type),
+ NULL, NULL);
+ }
+ case AST_TREE_TOKEN_BUILTIN_BITWISE_AND: {
+ 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_BITWISE_XOR: {
+ 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_BITWISE_OR: {
+ 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);
@@ -1254,6 +1397,7 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
return ret;
}
case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT:
+ case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT:
case AST_TREE_TOKEN_OPERATOR_MINUS:
case AST_TREE_TOKEN_OPERATOR_PLUS: {
AstTreeUnary *metadata = expr->metadata;
@@ -1300,7 +1444,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
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 = expr->metadata;
AstTree *function =
runExpression(metadata->function->value, scope, shouldRet, false,
@@ -1390,6 +1537,10 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet,
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 copyAstTree(expr);
case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: {
AstTreeBool *metadata = a404m_malloc(sizeof(*metadata));
@@ -1875,6 +2026,10 @@ AstTree *toRawValue(AstTree *value) {
case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL:
case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL:
case AST_TREE_TOKEN_BUILTIN_PUTC:
+ 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:
@@ -1909,6 +2064,10 @@ AstTree *toRawValue(AstTree *value) {
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:
@@ -2042,6 +2201,10 @@ AstTree *castTo(AstTree *tree, AstTree *to) {
case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL:
case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL:
case AST_TREE_TOKEN_BUILTIN_PUTC:
+ 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:
@@ -2086,6 +2249,10 @@ AstTree *castTo(AstTree *tree, AstTree *to) {
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:
@@ -2160,6 +2327,10 @@ ffi_type *toFFIType(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:
@@ -2204,6 +2375,10 @@ ffi_type *toFFIType(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: