summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/ast-tree.c97
-rw-r--r--src/compiler/ast-tree.h11
-rw-r--r--src/compiler/lexer.c16
-rw-r--r--src/compiler/lexer.h15
-rw-r--r--src/compiler/parser.c41
-rw-r--r--src/compiler/parser.h3
-rw-r--r--src/runner/runner.c31
7 files changed, 197 insertions, 17 deletions
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: