summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/ast-tree.c114
-rw-r--r--src/compiler/ast-tree.h13
-rw-r--r--src/compiler/lexer.c17
-rw-r--r--src/compiler/lexer.h4
-rw-r--r--src/compiler/parser.c94
-rw-r--r--src/compiler/parser.h13
-rw-r--r--src/main.c3
-rw-r--r--src/runner/runner.c48
8 files changed, 223 insertions, 83 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index ea5da0b..d7769bc 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -58,6 +58,10 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
"AST_TREE_TOKEN_OPERATOR_ASSIGN",
"AST_TREE_TOKEN_OPERATOR_SUM",
+ "AST_TREE_TOKEN_OPERATOR_SUB",
+ "AST_TREE_TOKEN_OPERATOR_MULTIPLY",
+ "AST_TREE_TOKEN_OPERATOR_DIVIDE",
+ "AST_TREE_TOKEN_OPERATOR_MODULO",
"AST_TREE_TOKEN_NONE",
};
@@ -184,6 +188,10 @@ void astTreePrint(const AstTree *tree, int indent) {
}
goto RETURN_SUCCESS;
case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
case AST_TREE_TOKEN_OPERATOR_ASSIGN: {
AstTreeInfix *metadata = tree->metadata;
printf(",\n");
@@ -290,6 +298,10 @@ void astTreeDestroy(AstTree tree) {
}
return;
case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
case AST_TREE_TOKEN_OPERATOR_ASSIGN: {
AstTreeInfix *metadata = tree.metadata;
astTreeDestroy(metadata->left);
@@ -374,7 +386,11 @@ AstTree *copyAstTree(AstTree *tree) {
tree->str_begin, tree->str_end);
}
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
- case AST_TREE_TOKEN_OPERATOR_SUM: {
+ case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO: {
AstTreeInfix *metadata = tree->metadata;
AstTreeInfix *new_metadata = a404m_malloc(sizeof(*new_metadata));
AstTree *left = copyAstTree(&metadata->left);
@@ -487,7 +503,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
for (size_t i = 0; i < nodes->size; ++i) {
ParserNode *eol = nodes->data[i];
if (eol->token != PARSER_TOKEN_SYMBOL_EOL) {
- printError(eol->str_begin, eol->str_end, "Unexpected %s",
+ printError(eol->str_begin, eol->str_end, "Did you forgot semicolon?",
PARSER_TOKEN_STRINGS[eol->token]);
goto RETURN_ERROR;
}
@@ -536,6 +552,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
case PARSER_TOKEN_VALUE_BOOL:
case PARSER_TOKEN_VALUE_U64:
case PARSER_TOKEN_FUNCTION_DEFINITION:
+ case PARSER_TOKEN_FUNCTION_CALL:
goto AFTER_SWITCH;
case PARSER_TOKEN_ROOT:
case PARSER_TOKEN_IDENTIFIER:
@@ -552,9 +569,12 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
case PARSER_TOKEN_SYMBOL_COMMA:
- case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_OPERATOR_ASSIGN:
case PARSER_TOKEN_OPERATOR_SUM:
+ case PARSER_TOKEN_OPERATOR_SUB:
+ case PARSER_TOKEN_OPERATOR_MULTIPLY:
+ case PARSER_TOKEN_OPERATOR_DIVIDE:
+ case PARSER_TOKEN_OPERATOR_MODULO:
printError(node->str_begin, node->str_end, "Should not be here");
goto RETURN_ERROR;
case PARSER_TOKEN_NONE:
@@ -675,9 +695,23 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables,
case PARSER_TOKEN_KEYWORD_RETURN:
return astTreeParseReturn(parserNode, variables, variables_size);
case PARSER_TOKEN_OPERATOR_ASSIGN:
- return astTreeParseAssign(parserNode, variables, variables_size);
+ return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ AST_TREE_TOKEN_OPERATOR_ASSIGN);
case PARSER_TOKEN_OPERATOR_SUM:
- return astTreeParseSum(parserNode, variables, variables_size);
+ return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ AST_TREE_TOKEN_OPERATOR_SUM);
+ case PARSER_TOKEN_OPERATOR_SUB:
+ return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ AST_TREE_TOKEN_OPERATOR_SUB);
+ case PARSER_TOKEN_OPERATOR_MULTIPLY:
+ return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ AST_TREE_TOKEN_OPERATOR_MULTIPLY);
+ case PARSER_TOKEN_OPERATOR_DIVIDE:
+ return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ AST_TREE_TOKEN_OPERATOR_DIVIDE);
+ case PARSER_TOKEN_OPERATOR_MODULO:
+ return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ AST_TREE_TOKEN_OPERATOR_MODULO);
case PARSER_TOKEN_VARIABLE:
return astTreeParseVariable(parserNode, variables, variables_size);
case PARSER_TOKEN_CONSTANT:
@@ -944,35 +978,9 @@ AstTree *astTreeParseReturn(ParserNode *parserNode,
parserNode->str_begin, parserNode->str_end);
}
-AstTree *astTreeParseAssign(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size) {
- ParserNodeInfixMetadata *node_metadata = parserNode->metadata;
-
- AstTree *left = astTreeParse(node_metadata->left, variables, variables_size);
- if (left == NULL) {
- return NULL;
- }
- AstTree *right =
- astTreeParse(node_metadata->right, variables, variables_size);
- if (right == NULL) {
- return NULL;
- }
-
- AstTreeInfix *metadata = a404m_malloc(sizeof(*metadata));
-
- metadata->left = *left;
- metadata->right = *right;
-
- free(left);
- free(right);
-
- return newAstTree(AST_TREE_TOKEN_OPERATOR_ASSIGN, metadata, NULL,
- parserNode->str_begin, parserNode->str_end);
-}
-
-AstTree *astTreeParseSum(ParserNode *parserNode, AstTreeVariables **variables,
- size_t variables_size) {
+AstTree *astTreeParseBinaryOperator(ParserNode *parserNode,
+ AstTreeVariables **variables,
+ size_t variables_size, AstTreeToken token) {
ParserNodeInfixMetadata *node_metadata = parserNode->metadata;
AstTree *left = astTreeParse(node_metadata->left, variables, variables_size);
@@ -993,8 +1001,8 @@ AstTree *astTreeParseSum(ParserNode *parserNode, AstTreeVariables **variables,
free(left);
free(right);
- return newAstTree(AST_TREE_TOKEN_OPERATOR_SUM, metadata, NULL,
- parserNode->str_begin, parserNode->str_end);
+ return newAstTree(token, metadata, NULL, parserNode->str_begin,
+ parserNode->str_end);
}
bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
@@ -1115,6 +1123,10 @@ AstTreeFunction *getFunction(AstTree *value) {
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
return NULL;
case AST_TREE_TOKEN_NONE:
}
@@ -1139,6 +1151,10 @@ bool isConst(AstTree *value) {
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
return false;
case AST_TREE_TOKEN_VARIABLE: {
AstTreeVariable *metadata = value->metadata;
@@ -1190,7 +1206,11 @@ AstTree *makeTypeOf(AstTree *value) {
return copyAstTree(variable->type);
}
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
- case AST_TREE_TOKEN_OPERATOR_SUM: {
+ case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO: {
AstTreeInfix *metadata = value->metadata;
return copyAstTree(metadata->left.type);
}
@@ -1213,6 +1233,10 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
return false;
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -1289,7 +1313,11 @@ bool setAllTypes(AstTree *tree, AstTreeFunction *function) {
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
return setTypesOperatorAssign(tree);
case AST_TREE_TOKEN_OPERATOR_SUM:
- return setTypesOperatorSum(tree);
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
+ return setTypesOperatorInfix(tree);
case AST_TREE_TOKEN_VARIABLE_DEFINE:
return setTypesVariableDefine(tree);
case AST_TREE_TOKEN_NONE:
@@ -1429,7 +1457,7 @@ bool setTypesOperatorAssign(AstTree *tree) {
}
}
-bool setTypesOperatorSum(AstTree *tree) {
+bool setTypesOperatorInfix(AstTree *tree) {
AstTreeInfix *infix = tree->metadata;
if (!setTypesAstInfix(infix)) {
return false;
@@ -1500,6 +1528,10 @@ bool astTreeClean(AstTree *tree) {
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
return true;
case AST_TREE_TOKEN_NONE:
}
@@ -1586,6 +1618,10 @@ size_t astTreeTypeSize(AstTree tree) {
case AST_TREE_TOKEN_VALUE_BOOL:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
case AST_TREE_TOKEN_NONE:
}
UNREACHABLE;
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index d67560f..9caef63 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -25,6 +25,10 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_OPERATOR_ASSIGN,
AST_TREE_TOKEN_OPERATOR_SUM,
+ AST_TREE_TOKEN_OPERATOR_SUB,
+ AST_TREE_TOKEN_OPERATOR_MULTIPLY,
+ AST_TREE_TOKEN_OPERATOR_DIVIDE,
+ AST_TREE_TOKEN_OPERATOR_MODULO,
AST_TREE_TOKEN_NONE,
} AstTreeToken;
@@ -146,12 +150,9 @@ AstTree *astTreeParseReturn(ParserNode *parserNode,
AstTreeVariables **variables,
size_t variables_size);
-AstTree *astTreeParseAssign(ParserNode *parserNode,
+AstTree *astTreeParseBinaryOperator(ParserNode *parserNode,
AstTreeVariables **variables,
- size_t variables_size);
-
-AstTree *astTreeParseSum(ParserNode *parserNode, AstTreeVariables **variables,
- size_t variables_size);
+ size_t variables_size,AstTreeToken token);
bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
size_t variables_size);
@@ -174,7 +175,7 @@ bool setTypesTypeFunction(AstTree *tree);
bool setTypesFunctionCall(AstTree *tree);
bool setTypesVariable(AstTree *tree);
bool setTypesOperatorAssign(AstTree *tree);
-bool setTypesOperatorSum(AstTree *tree);
+bool setTypesOperatorInfix(AstTree *tree);
bool setTypesVariableDefine(AstTree *tree);
bool setTypesAstVariable(AstTreeVariable *variable);
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index 52702ba..70cd1fb 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -33,12 +33,16 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_SYMBOL_ASSIGN",
"LEXER_TOKEN_SYMBOL_COMMA",
"LEXER_TOKEN_SYMBOL_PLUS",
+ "LEXER_TOKEN_SYMBOL_MINUS",
+ "LEXER_TOKEN_SYMBOL_MULTIPLY",
+ "LEXER_TOKEN_SYMBOL_DIVIDE",
+ "LEXER_TOKEN_SYMBOL_MODULO",
"LEXER_TOKEN_NONE",
};
const char *LEXER_SYMBOL_STRINGS[] = {
- ";", "(", ")", "{", "}", "->", ":", "=", ",", "+",
+ ";", "(", ")", "{", "}", "->", ":", "=", ",", "+", "-", "*", "/", "%",
};
const LexerToken LEXER_SYMBOL_TOKENS[] = {
LEXER_TOKEN_SYMBOL_EOL,
@@ -51,6 +55,10 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = {
LEXER_TOKEN_SYMBOL_ASSIGN,
LEXER_TOKEN_SYMBOL_COMMA,
LEXER_TOKEN_SYMBOL_PLUS,
+ LEXER_TOKEN_SYMBOL_MINUS,
+ LEXER_TOKEN_SYMBOL_MULTIPLY,
+ LEXER_TOKEN_SYMBOL_DIVIDE,
+ LEXER_TOKEN_SYMBOL_MODULO,
};
const size_t LEXER_SYMBOL_SIZE =
sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS);
@@ -119,6 +127,9 @@ LexerNodeArray lexer(char *str) {
goto RETURN_ERROR;
}
}
+ } else {
+ --iter;
+ c = *iter;
}
}
if (isSpace(c)) {
@@ -198,6 +209,10 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter,
case LEXER_TOKEN_SYMBOL_ASSIGN:
case LEXER_TOKEN_SYMBOL_COMMA:
case LEXER_TOKEN_SYMBOL_PLUS:
+ case LEXER_TOKEN_SYMBOL_MINUS:
+ case LEXER_TOKEN_SYMBOL_MULTIPLY:
+ case LEXER_TOKEN_SYMBOL_DIVIDE:
+ case LEXER_TOKEN_SYMBOL_MODULO:
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 6c0660f..6723cc9 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -27,6 +27,10 @@ typedef enum LexerToken {
LEXER_TOKEN_SYMBOL_ASSIGN,
LEXER_TOKEN_SYMBOL_COMMA,
LEXER_TOKEN_SYMBOL_PLUS,
+ LEXER_TOKEN_SYMBOL_MINUS,
+ LEXER_TOKEN_SYMBOL_MULTIPLY,
+ LEXER_TOKEN_SYMBOL_DIVIDE,
+ LEXER_TOKEN_SYMBOL_MODULO,
LEXER_TOKEN_NONE,
} LexerToken;
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index f61836e..4b736b7 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -36,6 +36,10 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_OPERATOR_ASSIGN",
"PARSER_TOKEN_OPERATOR_SUM",
+ "PARSER_TOKEN_OPERATOR_SUB",
+ "PARSER_TOKEN_OPERATOR_MULTIPLY",
+ "PARSER_TOKEN_OPERATOR_DIVIDE",
+ "PARSER_TOKEN_OPERATOR_MODULO",
"PARSER_TOKEN_FUNCTION_DEFINITION",
@@ -67,7 +71,12 @@ static constexpr ParserOrder PARSER_ORDER[] = {
},
{
.ltr = true,
- ORDER_ARRAY(LEXER_TOKEN_SYMBOL_PLUS, ),
+ ORDER_ARRAY(LEXER_TOKEN_SYMBOL_MULTIPLY, LEXER_TOKEN_SYMBOL_DIVIDE,
+ LEXER_TOKEN_SYMBOL_MODULO, ),
+ },
+ {
+ .ltr = true,
+ ORDER_ARRAY(LEXER_TOKEN_SYMBOL_PLUS, LEXER_TOKEN_SYMBOL_MINUS, ),
},
{
.ltr = true,
@@ -242,7 +251,11 @@ void parserNodePrint(const ParserNode *node, int indent) {
}
goto RETURN_SUCCESS;
case PARSER_TOKEN_OPERATOR_ASSIGN:
- case PARSER_TOKEN_OPERATOR_SUM: {
+ case PARSER_TOKEN_OPERATOR_SUM:
+ case PARSER_TOKEN_OPERATOR_SUB:
+ case PARSER_TOKEN_OPERATOR_MULTIPLY:
+ case PARSER_TOKEN_OPERATOR_DIVIDE:
+ case PARSER_TOKEN_OPERATOR_MODULO: {
const ParserNodeInfixMetadata *metadata = node->metadata;
printf(",\n");
for (int i = 0; i < indent; ++i)
@@ -342,14 +355,17 @@ void parserNodeDelete(ParserNode *node) {
}
goto RETURN_SUCCESS;
case PARSER_TOKEN_OPERATOR_ASSIGN:
- case PARSER_TOKEN_OPERATOR_SUM: {
+ case PARSER_TOKEN_OPERATOR_SUM:
+ case PARSER_TOKEN_OPERATOR_SUB:
+ case PARSER_TOKEN_OPERATOR_MULTIPLY:
+ case PARSER_TOKEN_OPERATOR_DIVIDE:
+ case PARSER_TOKEN_OPERATOR_MODULO: {
ParserNodeInfixMetadata *metadata = node->metadata;
parserNodeDelete(metadata->left);
parserNodeDelete(metadata->right);
free(metadata);
}
goto RETURN_SUCCESS;
-
case PARSER_TOKEN_NONE:
}
UNREACHABLE;
@@ -412,12 +428,13 @@ bool parserNodeArray(LexerNode *begin, LexerNode *end, ParserNode *parent) {
for (LexerNode *iter = begin; iter < end; ++iter) {
ParserNode *pNode = iter->parserNode;
- if (pNode->parent != parent) {
- continue;
- } else if (pNode == NULL) {
- printError(pNode->str_begin, pNode->str_end, "Bad child");
+ if (pNode == NULL) {
+ printError(iter->str_begin, iter->str_end, "Bad child");
goto RETURN_ERROR;
+ } else if (pNode->parent != parent) {
+ continue;
}
+
for (size_t i = 0; i < parsedNodes->size; ++i) {
if (parsedNodes->data[i] == pNode) {
goto CONTINUE;
@@ -484,13 +501,28 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
case LEXER_TOKEN_NUMBER:
return parserNumber(node, parent);
case LEXER_TOKEN_SYMBOL_ASSIGN:
- return parserAssign(node, begin, end, parent);
+ return parserBinaryOperator(node, begin, end, parent,
+ PARSER_TOKEN_OPERATOR_ASSIGN);
+ case LEXER_TOKEN_SYMBOL_MULTIPLY:
+ return parserBinaryOperator(node, begin, end, parent,
+ PARSER_TOKEN_OPERATOR_MULTIPLY);
+ case LEXER_TOKEN_SYMBOL_DIVIDE:
+ return parserBinaryOperator(node, begin, end, parent,
+ PARSER_TOKEN_OPERATOR_DIVIDE);
+ case LEXER_TOKEN_SYMBOL_MODULO:
+ return parserBinaryOperator(node, begin, end, parent,
+ PARSER_TOKEN_OPERATOR_MODULO);
case LEXER_TOKEN_SYMBOL_PLUS:
- return parserPlus(node, begin, end, parent);
+ return parserBinaryOrLeftOperator(node, begin, end, parent,
+ PARSER_TOKEN_OPERATOR_SUM);
+ case LEXER_TOKEN_SYMBOL_MINUS:
+ return parserBinaryOrLeftOperator(node, begin, end, parent,
+ PARSER_TOKEN_OPERATOR_SUB);
case LEXER_TOKEN_SYMBOL:
case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS:
case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET:
case LEXER_TOKEN_NONE:
+ break;
}
UNREACHABLE;
}
@@ -915,7 +947,7 @@ ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end,
} else {
value = getUntilCommonParent(valueNode->parserNode, parent);
if (!isValue(value)) {
- printError(name->str_begin, name->str_end, "No value");
+ printError(name->str_begin, name->str_end, "Bad value");
return NULL;
}
value->parent = variableNode;
@@ -943,13 +975,14 @@ RETURN_ERROR:
return NULL;
}
-ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end,
- ParserNode *parent) {
+ParserNode *parserBinaryOperator(LexerNode *node, LexerNode *begin,
+ LexerNode *end, ParserNode *parent,
+ ParserToken token) {
LexerNode *leftNode = node - 1;
LexerNode *rightNode = node + 1;
if (leftNode < begin || rightNode >= end) {
- printError(node->str_begin, node->str_end, "Bad assign");
+ printError(node->str_begin, node->str_end, "Bad binary operator");
return NULL;
}
@@ -957,7 +990,7 @@ ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end,
ParserNode *right = getUntilCommonParent(rightNode->parserNode, parent);
if (left == NULL || right == NULL) {
- printError(node->str_begin, node->str_end, "Bad assign");
+ printError(node->str_begin, node->str_end, "Bad binary operator");
return NULL;
}
@@ -965,13 +998,13 @@ ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end,
metadata->left = left;
metadata->right = right;
- return left->parent = right->parent = node->parserNode =
- newParserNode(PARSER_TOKEN_OPERATOR_ASSIGN, left->str_begin,
- right->str_end, metadata, parent);
+ return left->parent = right->parent = node->parserNode = newParserNode(
+ token, left->str_begin, right->str_end, metadata, parent);
}
-ParserNode *parserPlus(LexerNode *node, LexerNode *begin, LexerNode *end,
- ParserNode *parent) {
+ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin,
+ LexerNode *end, ParserNode *parent,
+ ParserToken token) {
LexerNode *leftNode = node - 1;
LexerNode *rightNode = node + 1;
@@ -992,9 +1025,8 @@ ParserNode *parserPlus(LexerNode *node, LexerNode *begin, LexerNode *end,
metadata->left = left;
metadata->right = right;
- return left->parent = right->parent = node->parserNode =
- newParserNode(PARSER_TOKEN_OPERATOR_SUM, left->str_begin,
- right->str_end, metadata, parent);
+ return left->parent = right->parent = node->parserNode = newParserNode(
+ token, left->str_begin, right->str_end, metadata, parent);
}
bool isAllArguments(const ParserNodeArray *nodes) {
@@ -1019,6 +1051,10 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_KEYWORD_RETURN:
case PARSER_TOKEN_OPERATOR_ASSIGN:
case PARSER_TOKEN_OPERATOR_SUM:
+ case PARSER_TOKEN_OPERATOR_SUB:
+ case PARSER_TOKEN_OPERATOR_MULTIPLY:
+ case PARSER_TOKEN_OPERATOR_DIVIDE:
+ case PARSER_TOKEN_OPERATOR_MODULO:
case PARSER_TOKEN_VALUE_U64:
case PARSER_TOKEN_VALUE_BOOL:
return true;
@@ -1061,6 +1097,10 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_KEYWORD_RETURN:
case PARSER_TOKEN_OPERATOR_ASSIGN:
case PARSER_TOKEN_OPERATOR_SUM:
+ case PARSER_TOKEN_OPERATOR_SUB:
+ case PARSER_TOKEN_OPERATOR_MULTIPLY:
+ case PARSER_TOKEN_OPERATOR_DIVIDE:
+ case PARSER_TOKEN_OPERATOR_MODULO:
return false;
case PARSER_TOKEN_NONE:
}
@@ -1076,12 +1116,16 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_OPERATOR_ASSIGN:
case PARSER_TOKEN_OPERATOR_SUM:
- return true;
- case PARSER_TOKEN_TYPE_FUNCTION:
+ case PARSER_TOKEN_OPERATOR_SUB:
+ case PARSER_TOKEN_OPERATOR_MULTIPLY:
+ case PARSER_TOKEN_OPERATOR_DIVIDE:
+ case PARSER_TOKEN_OPERATOR_MODULO:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_VOID:
case PARSER_TOKEN_TYPE_U64:
case PARSER_TOKEN_TYPE_BOOL:
+ return true;
+ case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index 29a303c..0b92fe5 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -31,6 +31,10 @@ typedef enum ParserToken {
PARSER_TOKEN_OPERATOR_ASSIGN,
PARSER_TOKEN_OPERATOR_SUM,
+ PARSER_TOKEN_OPERATOR_SUB,
+ PARSER_TOKEN_OPERATOR_MULTIPLY,
+ PARSER_TOKEN_OPERATOR_DIVIDE,
+ PARSER_TOKEN_OPERATOR_MODULO,
PARSER_TOKEN_FUNCTION_DEFINITION,
@@ -130,10 +134,11 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
ParserNode *parent);
ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end,
ParserNode *parent);
-ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end,
- ParserNode *parent);
-ParserNode *parserPlus(LexerNode *node, LexerNode *begin, LexerNode *end,
- ParserNode *parent);
+ParserNode *parserBinaryOperator(LexerNode *node, LexerNode *begin,
+ LexerNode *end, ParserNode *parent,
+ ParserToken token);
+ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin, LexerNode *end,
+ ParserNode *parent,ParserToken token);
bool isAllArguments(const ParserNodeArray *nodes);
diff --git a/src/main.c b/src/main.c
index b206235..6a6fbab 100644
--- a/src/main.c
+++ b/src/main.c
@@ -118,6 +118,7 @@ int main(int argc, char *argv[]) {
return 1;
}
- const int ret = run(argv[1], false);
+ const int ret = run(argv[1], true);
fileDelete();
+ return ret;
}
diff --git a/src/runner/runner.c b/src/runner/runner.c
index 2378387..9c3e7e2 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -41,8 +41,8 @@ void runnerVariableSetValue(RunnerVariablePages *pages,
}
for (size_t i = 0; i < pages->size; ++i) {
RunnerVariables *variables = pages->data[i];
- for (size_t i = 0; i < variables->size; ++i) {
- RunnerVariable *var = variables->data[i];
+ for (size_t j = 0; j < variables->size; ++j) {
+ RunnerVariable *var = variables->data[j];
if (var->variable == variable) {
if (var->value != NULL) {
astTreeDelete(var->value);
@@ -63,8 +63,8 @@ AstTree *runnerVariableGetValue(RunnerVariablePages *pages,
}
for (size_t i = 0; i < pages->size; ++i) {
RunnerVariables *variables = pages->data[i];
- for (size_t i = 0; i < variables->size; ++i) {
- RunnerVariable *var = variables->data[i];
+ for (size_t j = 0; j < variables->size; ++j) {
+ RunnerVariable *var = variables->data[j];
if (var->variable == variable) {
if (var->value != NULL) {
return var->value;
@@ -205,6 +205,10 @@ AstTree *runAstTreeFunction(AstTree *tree, AstTree **arguments,
}
continue;
case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
@@ -249,7 +253,11 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) {
UNREACHABLE;
}
}
- case AST_TREE_TOKEN_OPERATOR_SUM: {
+ case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO: {
AstTreeInfix *metadata = tree->metadata;
AstTree *left = calcAstTreeValue(&metadata->left, pages);
AstTree *right = calcAstTreeValue(&metadata->right, pages);
@@ -257,8 +265,30 @@ AstTree *calcAstTreeValue(AstTree *tree, RunnerVariablePages *pages) {
if (left->type == &AST_TREE_U64_TYPE && right->type == &AST_TREE_U64_TYPE) {
if (left->token == AST_TREE_TOKEN_VALUE_U64 &&
right->token == AST_TREE_TOKEN_VALUE_U64) {
- left->metadata =
- (void *)((AstTreeU64)left->metadata + (AstTreeU64)right->metadata);
+ switch (tree->token) {
+ case AST_TREE_TOKEN_OPERATOR_SUM:
+ left->metadata = (void *)((AstTreeU64)left->metadata +
+ (AstTreeU64)right->metadata);
+ break;
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ left->metadata = (void *)((AstTreeU64)left->metadata -
+ (AstTreeU64)right->metadata);
+ break;
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ left->metadata = (void *)((AstTreeU64)left->metadata *
+ (AstTreeU64)right->metadata);
+ break;
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ left->metadata = (void *)((AstTreeU64)left->metadata /
+ (AstTreeU64)right->metadata);
+ break;
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
+ left->metadata = (void *)((AstTreeU64)left->metadata %
+ (AstTreeU64)right->metadata);
+ break;
+ default:
+ UNREACHABLE;
+ }
astTreeDelete(right);
return left;
} else {
@@ -301,6 +331,10 @@ AstTree *deepCopyAstTree(AstTree *tree) {
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
case AST_TREE_TOKEN_NONE:
}
UNREACHABLE;