diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | code/main.felan | 18 | ||||
-rw-r--r-- | src/compiler/ast-tree.c | 97 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 11 | ||||
-rw-r--r-- | src/compiler/lexer.c | 16 | ||||
-rw-r--r-- | src/compiler/lexer.h | 15 | ||||
-rw-r--r-- | src/compiler/parser.c | 41 | ||||
-rw-r--r-- | src/compiler/parser.h | 3 | ||||
-rw-r--r-- | src/runner/runner.c | 31 |
9 files changed, 214 insertions, 22 deletions
@@ -19,9 +19,9 @@ NC := \033[0m INC_DIRS := $(SRC_DIR) INC_FLAGS := $(addprefix -I,$(INC_DIRS)) -CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 -O3 +# CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 -O3 # CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 -Oz -# CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 -g +CFLAGS := $(INC_FLAGS) -Wall -Wextra -std=gnu23 -g EXEC_FILE := $(BUILD_DIR)/$(PROJECT_NAME) diff --git a/code/main.felan b/code/main.felan index 032cfc8..edca8f2 100644 --- a/code/main.felan +++ b/code/main.felan @@ -17,8 +17,20 @@ long_double :: f128; usize :: u64; + main :: () -> void { - a := 'a'; - putc a; - putc '\n'; + print_u64(1234); +}; + +print_u64 :: (value:u64) -> void { + value := value; + digit : u64 = undefined; + first_time := true; + while { + first_time = false; + digit = value % 10; + putc 'a'; + value /= 10; + value != 0; + } {} }; diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 6efdc6a..7f30116 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -234,6 +234,7 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VARIABLE_DEFINE: goto RETURN_SUCCESS; + case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: @@ -361,6 +362,8 @@ void astTreePrint(const AstTree *tree, int indent) { metadata->name_begin); } goto RETURN_SUCCESS; + case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: case AST_TREE_TOKEN_OPERATOR_MULTIPLY: @@ -602,6 +605,7 @@ void astTreeDestroy(AstTree tree) { free(metadata); return; } + case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: @@ -646,6 +650,8 @@ void astTreeDestroy(AstTree tree) { // AstTreeIdentifier *metadata = tree.metadata; // not needed } return; + case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: case AST_TREE_TOKEN_OPERATOR_MULTIPLY: @@ -867,6 +873,8 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], return newAstTree(tree->token, new_metadata, &AST_TREE_TYPE_TYPE, tree->str_begin, tree->str_end); } + case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: @@ -942,6 +950,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], new_newVariables, new_variables_size), tree->str_begin, tree->str_end); } + case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: @@ -1261,6 +1270,9 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_OPERATOR_SMALLER: case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + case PARSER_TOKEN_OPERATOR_LOGICAL_OR: case PARSER_TOKEN_SYMBOL_PARENTHESIS: case PARSER_TOKEN_KEYWORD_IF: case PARSER_TOKEN_KEYWORD_WHILE: @@ -1535,6 +1547,15 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { case PARSER_TOKEN_OPERATOR_ACCESS: return astTreeParseAccessOperator(parserNode, helper, AST_TREE_TOKEN_OPERATOR_ACCESS); + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + return astTreeParseBinaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_LOGICAL_AND); + case PARSER_TOKEN_OPERATOR_LOGICAL_OR: + return astTreeParseBinaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_LOGICAL_OR); + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: + return astTreeParseUnaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT); case PARSER_TOKEN_OPERATOR_PLUS: return astTreeParseUnaryOperator(parserNode, helper, AST_TREE_TOKEN_OPERATOR_PLUS); @@ -1661,7 +1682,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) { case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: - case PARSER_TOKEN_VALUE_CHAR: + case PARSER_TOKEN_VALUE_CHAR: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_TYPE_VOID: @@ -1716,6 +1737,9 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) { case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_OPERATOR_DEREFERENCE: case PARSER_TOKEN_OPERATOR_ACCESS: + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + case PARSER_TOKEN_OPERATOR_LOGICAL_OR: printError(node->str_begin, node->str_end, "Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -1919,9 +1943,8 @@ AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper) { return NULL; } - return newAstTree(AST_TREE_TOKEN_KEYWORD_PUTC, - (AstTreeSingleChild *)operand, NULL, parserNode->str_begin, - parserNode->str_end); + return newAstTree(AST_TREE_TOKEN_KEYWORD_PUTC, (AstTreeSingleChild *)operand, + NULL, parserNode->str_begin, parserNode->str_end); } AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeHelper *helper) { @@ -2208,7 +2231,7 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: - case PARSER_TOKEN_VALUE_CHAR: + case PARSER_TOKEN_VALUE_CHAR: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_TYPE_VOID: @@ -2263,6 +2286,9 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_OPERATOR_DEREFERENCE: case PARSER_TOKEN_OPERATOR_ACCESS: + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + case PARSER_TOKEN_OPERATOR_LOGICAL_OR: printError(node->str_begin, node->str_end, "Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -2479,6 +2505,9 @@ bool isConst(AstTree *tree) { case AST_TREE_TOKEN_OPERATOR_SMALLER: case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: return false; case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *metadata = tree->metadata; @@ -2496,6 +2525,7 @@ bool isConst(AstTree *tree) { } case AST_TREE_TOKEN_NONE: } + printLog("Unknown token '%d'", tree->token); UNREACHABLE; } @@ -2578,6 +2608,9 @@ bool isConstByValue(AstTree *tree) { case AST_TREE_TOKEN_OPERATOR_SMALLER: case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: return false; case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *metadata = tree->metadata; @@ -2688,6 +2721,9 @@ AstTree *makeTypeOf(AstTree *value) { AstTreeInfix *metadata = value->metadata; return copyAstTree(metadata->left.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_EQUAL: case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL: case AST_TREE_TOKEN_OPERATOR_GREATER: @@ -2776,6 +2812,9 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: 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_AND: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_ADDRESS: @@ -2906,6 +2945,9 @@ AstTree *getValue(AstTree *tree) { case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_ACCESS: + 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_KEYWORD_IF: case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_KEYWORD_COMPTIME: @@ -2970,6 +3012,7 @@ bool isCircularDependenciesBack(AstTreeHelper *helper, case AST_TREE_TOKEN_VALUE_BOOL: case AST_TREE_TOKEN_OPERATOR_ACCESS: return false; + case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_ADDRESS: case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: @@ -2980,6 +3023,8 @@ bool isCircularDependenciesBack(AstTreeHelper *helper, return isCircularDependenciesBack(helper, variable, metadata, checkedVariables); } + case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: @@ -3177,6 +3222,9 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: return setTypesOperatorUnary(tree, helper); + case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: + return setTypesOperatorUnaryWithRetAndLooking(tree, &AST_TREE_BOOL_TYPE, + &AST_TREE_BOOL_TYPE, helper); case AST_TREE_TOKEN_OPERATOR_SUM: case AST_TREE_TOKEN_OPERATOR_SUB: case AST_TREE_TOKEN_OPERATOR_MULTIPLY: @@ -3190,6 +3238,10 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: return setTypesOperatorInfixWithRet(tree, &AST_TREE_BOOL_TYPE, helper); + case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: + return setTypesOperatorInfixWithRetAndLooking(tree, &AST_TREE_BOOL_TYPE, + &AST_TREE_BOOL_TYPE, helper); case AST_TREE_TOKEN_OPERATOR_POINTER: return setTypesOperatorPointer(tree, helper); case AST_TREE_TOKEN_OPERATOR_ADDRESS: @@ -3654,6 +3706,25 @@ bool setTypesOperatorInfixWithRet(AstTree *tree, AstTree *retType, } } +bool setTypesOperatorInfixWithRetAndLooking(AstTree *tree, AstTree *lookingType, + AstTree *retType, + AstTreeSetTypesHelper _helper) { + AstTreeSetTypesHelper helper = { + .lookingType = lookingType, + .treeHelper = _helper.treeHelper, + }; + AstTreeInfix *infix = tree->metadata; + if (!setTypesAstInfix(infix, helper)) { + return false; + } else if (!typeIsEqual(infix->left.type, infix->right.type)) { + printError(tree->str_begin, tree->str_end, "Type mismatch"); + return false; + } else { + tree->type = retType; + return true; + } +} + bool setTypesOperatorUnary(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeSingleChild *operand = tree->metadata; if (!setAllTypes(operand, helper, NULL)) { @@ -3664,6 +3735,22 @@ bool setTypesOperatorUnary(AstTree *tree, AstTreeSetTypesHelper helper) { } } +bool setTypesOperatorUnaryWithRetAndLooking(AstTree *tree, AstTree *lookingType, + AstTree *retType, + AstTreeSetTypesHelper _helper) { + AstTreeSetTypesHelper helper = { + .lookingType = lookingType, + .treeHelper = _helper.treeHelper, + }; + AstTreeSingleChild *operand = tree->metadata; + if (!setAllTypes(operand, helper, NULL)) { + return false; + } else { + tree->type = retType; + return true; + } +} + bool setTypesOperatorPointer(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeSingleChild *metadata = tree->metadata; if (!setAllTypes(metadata, helper, NULL)) { diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 3ada2df..5170178 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -65,6 +65,9 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_OPERATOR_ADDRESS, AST_TREE_TOKEN_OPERATOR_DEREFERENCE, AST_TREE_TOKEN_OPERATOR_ACCESS, + AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT, + AST_TREE_TOKEN_OPERATOR_LOGICAL_AND, + AST_TREE_TOKEN_OPERATOR_LOGICAL_OR, AST_TREE_TOKEN_SCOPE, @@ -260,7 +263,7 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseValue(ParserNode *parserNode, AstTreeToken token, - size_t metadata_size,AstTree *type); + size_t metadata_size, AstTree *type); AstTree *astTreeParseKeyword(ParserNode *parserNode, AstTreeToken token); AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeHelper *helper); @@ -320,7 +323,13 @@ bool setTypesOperatorAssign(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesOperatorInfix(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesOperatorInfixWithRet(AstTree *tree, AstTree *retType, AstTreeSetTypesHelper helper); +bool setTypesOperatorInfixWithRetAndLooking(AstTree *tree, AstTree *lookingType, + AstTree *retType, + AstTreeSetTypesHelper helper); bool setTypesOperatorUnary(AstTree *tree, AstTreeSetTypesHelper helper); +bool setTypesOperatorUnaryWithRetAndLooking(AstTree *tree, AstTree *lookingType, + AstTree *retType, + AstTreeSetTypesHelper helper); bool setTypesOperatorPointer(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesOperatorAddress(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesOperatorDereference(AstTree *tree, AstTreeSetTypesHelper helper); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 71a8572..d53560e 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -47,6 +47,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_PLUS", "LEXER_TOKEN_SYMBOL_MINUS", "LEXER_TOKEN_SYMBOL_ADDRESS", + "LEXER_TOKEN_SYMBOL_LOGICAL_NOT", "LEXER_TOKEN_SYMBOL_MULTIPLY", "LEXER_TOKEN_SYMBOL_DIVIDE", @@ -62,6 +63,9 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL", "LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL", + "LEXER_TOKEN_SYMBOL_LOGICAL_AND", + "LEXER_TOKEN_SYMBOL_LOGICAL_OR", + "LEXER_TOKEN_SYMBOL_COLON", "LEXER_TOKEN_SYMBOL_ASSIGN", @@ -91,8 +95,9 @@ const char *LEXER_TOKEN_STRINGS[] = { }; const char *LEXER_SYMBOL_STRINGS[] = { - ";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=", "/=", "%=", ",", - "+", "-", "*", "/", "%", "==", "!=", ">", ">=", "<", "<=", "&", ".*", ".", + ";", "(", ")", "{", "}", "->", ":", "=", "+=", "-=", "*=", + "/=", "%=", ",", "+", "-", "*", "/", "%", "==", "!=", ">", + ">=", "<", "<=", "&", ".*", ".", "!", "&&", "||", }; const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_EOL, @@ -123,6 +128,9 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_ADDRESS, LEXER_TOKEN_SYMBOL_DEREFERENCE, LEXER_TOKEN_SYMBOL_ACCESS, + LEXER_TOKEN_SYMBOL_LOGICAL_NOT, + LEXER_TOKEN_SYMBOL_LOGICAL_AND, + LEXER_TOKEN_SYMBOL_LOGICAL_OR, }; const size_t LEXER_SYMBOL_SIZE = sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS); @@ -369,6 +377,9 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_SYMBOL_ADDRESS: case LEXER_TOKEN_SYMBOL_DEREFERENCE: case LEXER_TOKEN_SYMBOL_ACCESS: + case LEXER_TOKEN_SYMBOL_LOGICAL_NOT: + case LEXER_TOKEN_SYMBOL_LOGICAL_AND: + case LEXER_TOKEN_SYMBOL_LOGICAL_OR: if (*array_size == array->size) { *array_size += 1 + *array_size / 2; array->data = @@ -412,6 +423,7 @@ bool isSymbol(char c) { case '=': case '!': case '&': + case '|': case ';': case ':': case ',': diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 352e044..eff75c5 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -48,6 +48,7 @@ typedef enum LexerToken { LEXER_TOKEN_ORDER4 = LEXER_TOKEN_SYMBOL_PLUS, LEXER_TOKEN_SYMBOL_MINUS, LEXER_TOKEN_SYMBOL_ADDRESS, + LEXER_TOKEN_SYMBOL_LOGICAL_NOT, LEXER_TOKEN_SYMBOL_MULTIPLY, LEXER_TOKEN_ORDER5 = LEXER_TOKEN_SYMBOL_MULTIPLY, @@ -66,11 +67,15 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL, LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, + LEXER_TOKEN_SYMBOL_LOGICAL_AND, + LEXER_TOKEN_ORDER8 = LEXER_TOKEN_SYMBOL_LOGICAL_AND, + LEXER_TOKEN_SYMBOL_LOGICAL_OR, + LEXER_TOKEN_SYMBOL_COLON, - LEXER_TOKEN_ORDER8 = LEXER_TOKEN_SYMBOL_COLON, + LEXER_TOKEN_ORDER9 = LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_SYMBOL_ASSIGN, - LEXER_TOKEN_ORDER9 = LEXER_TOKEN_SYMBOL_ASSIGN, + LEXER_TOKEN_ORDER10 = LEXER_TOKEN_SYMBOL_ASSIGN, LEXER_TOKEN_SYMBOL_SUM_ASSIGN, LEXER_TOKEN_SYMBOL_SUB_ASSIGN, LEXER_TOKEN_SYMBOL_MULTIPLY_ASSIGN, @@ -78,16 +83,16 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_MODULO_ASSIGN, LEXER_TOKEN_KEYWORD_RETURN, - LEXER_TOKEN_ORDER10 = LEXER_TOKEN_KEYWORD_RETURN, + LEXER_TOKEN_ORDER11 = LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_PUTC, LEXER_TOKEN_KEYWORD_COMPTIME, LEXER_TOKEN_SYMBOL_EOL, - LEXER_TOKEN_ORDER11 = LEXER_TOKEN_SYMBOL_EOL, + LEXER_TOKEN_ORDER12 = LEXER_TOKEN_SYMBOL_EOL, LEXER_TOKEN_SYMBOL_COMMA, LEXER_TOKEN_KEYWORD_IF, - LEXER_TOKEN_ORDER12 = LEXER_TOKEN_KEYWORD_IF, + LEXER_TOKEN_ORDER13 = 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 5a0d00b..cd4a45b 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -78,6 +78,9 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_OPERATOR_ADDRESS", "PARSER_TOKEN_OPERATOR_DEREFERENCE", "PARSER_TOKEN_OPERATOR_ACCESS", + "PARSER_TOKEN_OPERATOR_LOGICAL_NOT", + "PARSER_TOKEN_OPERATOR_LOGICAL_AND", + "PARSER_TOKEN_OPERATOR_LOGICAL_OR", "PARSER_TOKEN_FUNCTION_DEFINITION", @@ -133,7 +136,7 @@ static const ParserOrder PARSER_ORDER[] = { .end = LEXER_TOKEN_ORDER9, }, { - .ltr = false, + .ltr = true, .begin = LEXER_TOKEN_ORDER9, .end = LEXER_TOKEN_ORDER10, }, @@ -143,13 +146,18 @@ static const ParserOrder PARSER_ORDER[] = { .end = LEXER_TOKEN_ORDER11, }, { - .ltr = true, + .ltr = false, .begin = LEXER_TOKEN_ORDER11, .end = LEXER_TOKEN_ORDER12, }, { - .ltr = false, + .ltr = true, .begin = LEXER_TOKEN_ORDER12, + .end = LEXER_TOKEN_ORDER13, + }, + { + .ltr = false, + .begin = LEXER_TOKEN_ORDER13, .end = LEXER_TOKEN_END_ORDERS, }, }; @@ -247,6 +255,7 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(" "); } goto RETURN_SUCCESS; + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: case PARSER_TOKEN_KEYWORD_STRUCT: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: @@ -341,6 +350,8 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(" "); } goto RETURN_SUCCESS; + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + case PARSER_TOKEN_OPERATOR_LOGICAL_OR: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: @@ -493,6 +504,7 @@ void parserNodeDelete(ParserNode *node) { free(metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: case PARSER_TOKEN_KEYWORD_STRUCT: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: @@ -541,6 +553,8 @@ void parserNodeDelete(ParserNode *node) { free(metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + case PARSER_TOKEN_OPERATOR_LOGICAL_OR: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: @@ -792,6 +806,15 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, case LEXER_TOKEN_SYMBOL_ACCESS: return parserBinaryOperator(node, begin, end, parent, PARSER_TOKEN_OPERATOR_ACCESS); + case LEXER_TOKEN_SYMBOL_LOGICAL_AND: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_LOGICAL_AND); + case LEXER_TOKEN_SYMBOL_LOGICAL_OR: + return parserBinaryOperator(node, begin, end, parent, + PARSER_TOKEN_OPERATOR_LOGICAL_OR); + case LEXER_TOKEN_SYMBOL_LOGICAL_NOT: + return parserLeftOperator(node, end, parent, + PARSER_TOKEN_OPERATOR_LOGICAL_NOT); case LEXER_TOKEN_SYMBOL_PLUS: { ParserNode *result = parserBinaryOrLeftOperator(node, begin, end, parent, PARSER_TOKEN_OPERATOR_PLUS, @@ -1319,6 +1342,9 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_FUNCTION_DEFINITION: + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + case PARSER_TOKEN_OPERATOR_LOGICAL_OR: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_COMPTIME: printError(bodyArray->data[i]->str_begin, bodyArray->data[i]->str_end, @@ -1746,6 +1772,9 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_OPERATOR_SMALLER: case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + case PARSER_TOKEN_OPERATOR_LOGICAL_OR: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: @@ -1850,6 +1879,9 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_OPERATOR_SMALLER: case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + case PARSER_TOKEN_OPERATOR_LOGICAL_OR: case PARSER_TOKEN_KEYWORD_WHILE: return false; case PARSER_TOKEN_NONE: @@ -1889,6 +1921,9 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_OPERATOR_SMALLER: case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL: case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + case PARSER_TOKEN_OPERATOR_LOGICAL_NOT: + case PARSER_TOKEN_OPERATOR_LOGICAL_AND: + case PARSER_TOKEN_OPERATOR_LOGICAL_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 91147ea..c3302f0 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -74,6 +74,9 @@ typedef enum ParserToken { PARSER_TOKEN_OPERATOR_ADDRESS, PARSER_TOKEN_OPERATOR_DEREFERENCE, PARSER_TOKEN_OPERATOR_ACCESS, + PARSER_TOKEN_OPERATOR_LOGICAL_NOT, + PARSER_TOKEN_OPERATOR_LOGICAL_AND, + PARSER_TOKEN_OPERATOR_LOGICAL_OR, PARSER_TOKEN_FUNCTION_DEFINITION, diff --git a/src/runner/runner.c b/src/runner/runner.c index 140e3f8..8746e7c 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -154,7 +154,7 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) { } case AST_TREE_TOKEN_KEYWORD_WHILE: { AstTreeWhile *metadata = expr->metadata; - AstTree *ret = NULL; + AstTree *ret = &AST_TREE_VOID_VALUE; while (!*shouldRet) { AstTree *tree = runExpression(metadata->condition, shouldRet, false); bool conti = *(AstTreeBool *)tree->metadata; @@ -251,6 +251,13 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) { } return operand; } + case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: { + AstTreeSingleChild *operand = + runExpression(expr->metadata, shouldRet, false); + + *(AstTreeBool *)operand->metadata = !*((AstTreeBool *)operand->metadata); + return operand; + } case AST_TREE_TOKEN_OPERATOR_SUM: { AstTreeInfix *metadata = expr->metadata; AstTree *left = runExpression(&metadata->left, shouldRet, false); @@ -788,6 +795,28 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) { astTreeDelete(right); return left; } + case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: { + AstTreeInfix *metadata = expr->metadata; + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); + + *(AstTreeBool *)left->metadata = + *(AstTreeBool *)left->metadata && *(AstTreeBool *)right->metadata; + + astTreeDelete(right); + return left; + } + case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: { + AstTreeInfix *metadata = expr->metadata; + AstTree *left = runExpression(&metadata->left, shouldRet, false); + AstTree *right = runExpression(&metadata->right, shouldRet, false); + + *(AstTreeBool *)left->metadata = + *(AstTreeBool *)left->metadata || *(AstTreeBool *)right->metadata; + + astTreeDelete(right); + return left; + } case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: |