summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/ast-tree.c337
-rw-r--r--src/compiler/ast-tree.h19
-rw-r--r--src/compiler/code-generator.c30
-rw-r--r--src/compiler/code-generator.h1
-rw-r--r--src/compiler/lexer.c7
-rw-r--r--src/compiler/lexer.h2
-rw-r--r--src/compiler/parser.c44
-rw-r--r--src/compiler/parser.h3
8 files changed, 268 insertions, 175 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 7bb9f8f..7f955ff 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -6,9 +6,28 @@
#include <stdlib.h>
#include <string.h>
-const AstTree AST_TREE_U64_TYPE = {
+AstTree AST_TREE_TYPE_TYPE = {
+ .token = AST_TREE_TOKEN_TYPE_TYPE,
+ .metadata = NULL,
+ .type = &AST_TREE_TYPE_TYPE,
+};
+
+AstTree AST_TREE_VOID_TYPE = {
+ .token = AST_TREE_TOKEN_TYPE_VOID,
+ .metadata = NULL,
+ .type = &AST_TREE_TYPE_TYPE,
+};
+
+AstTree AST_TREE_U64_TYPE = {
.token = AST_TREE_TOKEN_TYPE_U64,
.metadata = NULL,
+ .type = &AST_TREE_TYPE_TYPE,
+};
+
+AstTree AST_TREE_VOID_VALUE = {
+ .token = AST_TREE_TOKEN_NONE,
+ .metadata = NULL,
+ .type = &AST_TREE_VOID_TYPE,
};
const char *AST_TREE_TOKEN_STRINGS[] = {
@@ -27,6 +46,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
"AST_TREE_TOKEN_VALUE_U64",
"AST_TREE_TOKEN_OPERATOR_ASSIGN",
+ "AST_TREE_TOKEN_OPERATOR_SUM",
"AST_TREE_TOKEN_NONE",
};
@@ -134,6 +154,7 @@ void astTreePrint(const AstTree *tree, int indent) {
metadata->name_begin);
}
goto RETURN_SUCCESS;
+ case AST_TREE_TOKEN_OPERATOR_SUM:
case AST_TREE_TOKEN_OPERATOR_ASSIGN: {
AstTreeInfix *metadata = tree->metadata;
printf(",\n");
@@ -146,16 +167,6 @@ void astTreePrint(const AstTree *tree, int indent) {
printf(" ");
printf("right=\n");
astTreePrint(&metadata->right, indent + 1);
- printf(",\n");
- for (int i = 0; i < indent; ++i)
- printf(" ");
- printf("leftType=\n");
- astTreePrint(&metadata->leftType, indent + 1);
- printf(",\n");
- for (int i = 0; i < indent; ++i)
- printf(" ");
- printf("rightType=\n");
- astTreePrint(&metadata->rightType, indent + 1);
printf("\n");
for (int i = 0; i < indent; ++i)
printf(" ");
@@ -184,6 +195,15 @@ void astTreeRootPrint(const AstTreeRoot *root) {
}
void astTreeDestroy(AstTree tree) {
+ if (tree.type != &AST_TREE_TYPE_TYPE && tree.type != &AST_TREE_VOID_TYPE &&
+ tree.type != &AST_TREE_U64_TYPE) {
+ if (tree.type == NULL) {
+ printLog("token = %s %p %p", AST_TREE_TOKEN_STRINGS[tree.token],
+ tree.metadata, tree.type);
+ return;
+ }
+ astTreeDelete(tree.type);
+ }
switch (tree.token) {
case AST_TREE_TOKEN_FUNCTION: {
AstTreeFunction *metadata = tree.metadata;
@@ -238,12 +258,11 @@ void astTreeDestroy(AstTree tree) {
// AstTreeIdentifier *metadata = tree.metadata; // not needed
}
return;
+ case AST_TREE_TOKEN_OPERATOR_SUM:
case AST_TREE_TOKEN_OPERATOR_ASSIGN: {
AstTreeInfix *metadata = tree.metadata;
astTreeDestroy(metadata->left);
astTreeDestroy(metadata->right);
- astTreeDestroy(metadata->leftType);
- astTreeDestroy(metadata->rightType);
free(metadata);
}
return;
@@ -281,28 +300,40 @@ void astTreeRootDelete(AstTreeRoot *root) {
free(root);
}
-AstTree *newAstTree(AstTreeToken token, void *metadata) {
+AstTree *newAstTree(AstTreeToken token, void *metadata, AstTree *type) {
AstTree *result = a404m_malloc(sizeof(*result));
result->token = token;
result->metadata = metadata;
- result->typeChecked = false;
+ result->type = type;
return result;
}
AstTree *copyAstTree(AstTree *tree) {
switch (tree->token) {
case AST_TREE_TOKEN_TYPE_TYPE:
+ return &AST_TREE_TYPE_TYPE;
case AST_TREE_TOKEN_TYPE_VOID:
+ return &AST_TREE_VOID_TYPE;
case AST_TREE_TOKEN_TYPE_U64:
- return newAstTree(tree->token, NULL);
+ return &AST_TREE_U64_TYPE;
case AST_TREE_TOKEN_VALUE_U64:
- return newAstTree(tree->token, (void *)(AstTreeU64)tree->metadata);
+ return newAstTree(tree->token, (void *)(AstTreeU64)tree->metadata,
+ &AST_TREE_U64_TYPE);
case AST_TREE_TOKEN_VARIABLE:
- return newAstTree(tree->token, tree->metadata);
+ return newAstTree(tree->token, tree->metadata, copyAstTree(tree->type));
+ case AST_TREE_TOKEN_TYPE_FUNCTION: {
+ AstTreeTypeFunction *metadata = tree->metadata;
+ AstTreeTypeFunction *new_metadata = a404m_malloc(sizeof(*new_metadata));
+ new_metadata->returnType = copyAstTree(metadata->returnType);
+ if (metadata->arguments_size != 0) {
+ UNREACHABLE;
+ }
+ return newAstTree(tree->token, new_metadata, copyAstTree(tree->type));
+ }
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
- case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_FUNCTION_CALL:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_NONE:
@@ -387,6 +418,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_OPERATOR_ASSIGN:
+ case PARSER_TOKEN_OPERATOR_SUM:
case PARSER_TOKEN_NONE:
printLog("Should not be here");
goto RETURN_ERROR;
@@ -408,11 +440,6 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
if (type == NULL) {
goto RETURN_ERROR;
}
-
- if (!hasTypeOf(value, type)) {
- printLog("Type mismatch");
- goto RETURN_ERROR;
- }
} else {
type = NULL;
}
@@ -483,13 +510,13 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables,
case PARSER_TOKEN_FUNCTION_DEFINITION:
return astTreeParseFunction(parserNode, variables, variables_size);
case PARSER_TOKEN_TYPE_TYPE:
- return newAstTree(AST_TREE_TOKEN_TYPE_TYPE, NULL);
+ return &AST_TREE_TYPE_TYPE;
case PARSER_TOKEN_TYPE_FUNCTION:
return astTreeParseTypeFunction(parserNode, variables, variables_size);
case PARSER_TOKEN_TYPE_VOID:
- return newAstTree(AST_TREE_TOKEN_TYPE_VOID, NULL);
+ return &AST_TREE_VOID_TYPE;
case PARSER_TOKEN_TYPE_U64:
- return newAstTree(AST_TREE_TOKEN_TYPE_U64, NULL);
+ return &AST_TREE_U64_TYPE;
case PARSER_TOKEN_FUNCTION_CALL:
return astTreeParseFunctionCall(parserNode, variables, variables_size);
case PARSER_TOKEN_IDENTIFIER:
@@ -497,11 +524,14 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables,
case PARSER_TOKEN_VALUE_U64:
return newAstTree(
AST_TREE_TOKEN_VALUE_U64,
- (void *)(AstTreeU64)(ParserNodeU64Metadata)parserNode->metadata);
+ (void *)(AstTreeU64)(ParserNodeU64Metadata)parserNode->metadata,
+ &AST_TREE_U64_TYPE);
case PARSER_TOKEN_KEYWORD_PRINT_U64:
return astTreeParsePrintU64(parserNode, variables, variables_size);
case PARSER_TOKEN_OPERATOR_ASSIGN:
return astTreeParseAssign(parserNode, variables, variables_size);
+ case PARSER_TOKEN_OPERATOR_SUM:
+ return astTreeParseSum(parserNode, variables, variables_size);
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_SYMBOL_EOL:
@@ -611,7 +641,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode,
function->scope = scope;
- AstTree *result = newAstTree(AST_TREE_TOKEN_FUNCTION, function);
+ AstTree *result = newAstTree(AST_TREE_TOKEN_FUNCTION, function, NULL);
return result;
@@ -663,7 +693,8 @@ AstTree *astTreeParseTypeFunction(ParserNode *parserNode,
goto RETURN_ERROR;
}
- return newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, typeFunction);
+ return newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, typeFunction,
+ &AST_TREE_TYPE_TYPE);
RETURN_ERROR:
return NULL;
@@ -693,15 +724,9 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
for (size_t i = 0; i < metadata->parameters_size; ++i) {
printLog("Not impelemented yet");
exit(1);
- if ((metadata->parameters[i] = astTreeParse(node_metadata->params->data[i],
- variables, variables_size)) ==
- NULL ||
- hasTypeOf(metadata->parameters[i], function->metadata)) {
- goto RETURN_ERROR;
- }
}
- return newAstTree(AST_TREE_TOKEN_FUNCTION_CALL, metadata);
+ return newAstTree(AST_TREE_TOKEN_FUNCTION_CALL, metadata, NULL);
RETURN_ERROR:
for (size_t i = 0; i < metadata->parameters_size; ++i) {
astTreeDelete(metadata->parameters[i]);
@@ -719,7 +744,7 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode,
printLog("Variable not found");
return NULL;
}
- return newAstTree(AST_TREE_TOKEN_VARIABLE, var);
+ return newAstTree(AST_TREE_TOKEN_VARIABLE, var, NULL);
}
AstTree *astTreeParsePrintU64(ParserNode *parserNode,
@@ -733,7 +758,7 @@ AstTree *astTreeParsePrintU64(ParserNode *parserNode,
}
return newAstTree(AST_TREE_TOKEN_KEYWORD_PRINT_U64,
- (AstTreeSingleChild *)operand);
+ (AstTreeSingleChild *)operand, NULL);
}
AstTree *astTreeParseAssign(ParserNode *parserNode,
@@ -759,7 +784,32 @@ AstTree *astTreeParseAssign(ParserNode *parserNode,
free(left);
free(right);
- return newAstTree(AST_TREE_TOKEN_OPERATOR_ASSIGN, metadata);
+ return newAstTree(AST_TREE_TOKEN_OPERATOR_ASSIGN, metadata, NULL);
+}
+
+AstTree *astTreeParseSum(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_SUM, metadata, NULL);
}
bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
@@ -844,84 +894,11 @@ AstTree *astTreeParseVariable(ParserNode *parserNode,
goto RETURN_ERROR;
}
- return newAstTree(AST_TREE_TOKEN_VARIABLE_DEFINE, variable);
+ return newAstTree(AST_TREE_TOKEN_VARIABLE_DEFINE, variable, NULL);
RETURN_ERROR:
return NULL;
}
-bool hasTypeOf(AstTree *value, const AstTree *type) {
- if (value->token == AST_TREE_TOKEN_VARIABLE) {
- AstTreeVariable *variable = value->metadata;
- return typeIsEqual(variable->type, type);
- }
-
- switch (type->token) {
- case AST_TREE_TOKEN_TYPE_TYPE:
- switch (value->token) {
- case AST_TREE_TOKEN_TYPE_TYPE:
- case AST_TREE_TOKEN_TYPE_FUNCTION:
- case AST_TREE_TOKEN_TYPE_VOID:
- case AST_TREE_TOKEN_TYPE_U64:
- return true;
- case AST_TREE_TOKEN_FUNCTION:
- case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
- case AST_TREE_TOKEN_FUNCTION_CALL:
- case AST_TREE_TOKEN_VARIABLE:
- case AST_TREE_TOKEN_VALUE_U64:
- case AST_TREE_TOKEN_VARIABLE_DEFINE:
- case AST_TREE_TOKEN_OPERATOR_ASSIGN:
- return false;
- case AST_TREE_TOKEN_NONE:
- }
- goto ERROR;
- case AST_TREE_TOKEN_TYPE_FUNCTION:
- AstTreeTypeFunction *typeMetadata = type->metadata;
- switch (value->token) {
- case AST_TREE_TOKEN_FUNCTION: {
- AstTreeFunction *valueMetadata = value->metadata;
- if (typeMetadata->arguments_size != valueMetadata->arguments.size) {
- return false;
- }
- for (size_t i = 0; i < typeMetadata->arguments_size; ++i) {
- if (!typeIsEqual(typeMetadata->arguments[i],
- valueMetadata->arguments.data[i]->type)) {
- return false;
- }
- }
- return typeIsEqual(typeMetadata->returnType, valueMetadata->returnType);
- }
- case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
- case AST_TREE_TOKEN_VALUE_U64:
- case AST_TREE_TOKEN_TYPE_TYPE:
- case AST_TREE_TOKEN_TYPE_FUNCTION:
- case AST_TREE_TOKEN_TYPE_VOID:
- case AST_TREE_TOKEN_TYPE_U64:
- case AST_TREE_TOKEN_FUNCTION_CALL:
- case AST_TREE_TOKEN_VARIABLE:
- case AST_TREE_TOKEN_VARIABLE_DEFINE:
- case AST_TREE_TOKEN_OPERATOR_ASSIGN:
- return false;
- case AST_TREE_TOKEN_NONE:
- }
- goto ERROR;
- case AST_TREE_TOKEN_TYPE_U64:
- return value->token == AST_TREE_TOKEN_VALUE_U64;
- case AST_TREE_TOKEN_FUNCTION:
- case AST_TREE_TOKEN_TYPE_VOID:
- case AST_TREE_TOKEN_FUNCTION_CALL:
- case AST_TREE_TOKEN_VARIABLE:
- case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
- case AST_TREE_TOKEN_VALUE_U64:
- case AST_TREE_TOKEN_VARIABLE_DEFINE:
- case AST_TREE_TOKEN_OPERATOR_ASSIGN:
- return false;
- case AST_TREE_TOKEN_NONE:
- }
-ERROR:
- printLog("Bad token '%d'", type->token);
- exit(1);
-}
-
AstTreeFunction *getFunction(AstTree *value) {
switch (value->token) {
case AST_TREE_TOKEN_FUNCTION:
@@ -933,7 +910,7 @@ AstTreeFunction *getFunction(AstTree *value) {
}
case AST_TREE_TOKEN_VARIABLE: {
AstTreeVariable *metadata = value->metadata;
- if (metadata->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) {
+ if (metadata->value->token == AST_TREE_TOKEN_FUNCTION) {
return metadata->value->metadata;
} else {
return NULL;
@@ -947,6 +924,7 @@ AstTreeFunction *getFunction(AstTree *value) {
case AST_TREE_TOKEN_VALUE_U64:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
return NULL;
case AST_TREE_TOKEN_NONE:
}
@@ -967,6 +945,7 @@ bool isConst(AstTree *value) {
case AST_TREE_TOKEN_FUNCTION_CALL:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
return false;
case AST_TREE_TOKEN_VARIABLE: {
AstTreeVariable *metadata = value->metadata;
@@ -984,7 +963,7 @@ AstTree *makeTypeOf(AstTree *value) {
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
case AST_TREE_TOKEN_TYPE_U64:
- return newAstTree(AST_TREE_TOKEN_TYPE_TYPE, NULL);
+ return &AST_TREE_TYPE_TYPE;
case AST_TREE_TOKEN_FUNCTION_CALL: {
AstTreeFunctionCall *metadata = value->metadata;
AstTreeFunction *function = metadata->function->metadata;
@@ -1004,17 +983,28 @@ AstTree *makeTypeOf(AstTree *value) {
copyAstTree(function->arguments.data[i]->type);
}
- return newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata);
+ return newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata,
+ &AST_TREE_TYPE_TYPE);
}
case AST_TREE_TOKEN_VALUE_U64:
- return newAstTree(AST_TREE_TOKEN_TYPE_U64, NULL);
+ return &AST_TREE_U64_TYPE;
case AST_TREE_TOKEN_VARIABLE: {
AstTreeVariable *variable = value->metadata;
return copyAstTree(variable->type);
}
+ case AST_TREE_TOKEN_OPERATOR_ASSIGN: {
+ AstTreeInfix *metadata = value->metadata;
+ return makeTypeOf(&metadata->left);
+ }
+ case AST_TREE_TOKEN_OPERATOR_SUM: {
+ AstTreeInfix *metadata = value->metadata;
+
+ // TODO: find a better way
+
+ return makeTypeOf(&metadata->left);
+ }
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
- case AST_TREE_TOKEN_OPERATOR_ASSIGN:
case AST_TREE_TOKEN_NONE:
}
printLog("Bad token '%d'", value->token);
@@ -1028,6 +1018,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_VALUE_U64:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
return false;
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -1037,8 +1028,20 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
if (type1->token != AST_TREE_TOKEN_TYPE_FUNCTION) {
return false;
}
- printLog("Not implemented yet");
- exit(1);
+ AstTreeTypeFunction *type0_metadata = type0->metadata;
+ AstTreeTypeFunction *type1_metadata = type1->metadata;
+ if (!typeIsEqual(type0_metadata->returnType->type,
+ type1_metadata->returnType->type)) {
+ return false;
+ }
+ if (type0_metadata->arguments_size != type1_metadata->arguments_size) {
+ return false;
+ }
+ for (size_t i = 0; i < type0_metadata->arguments_size; ++i) {
+ printLog("Not implemented yet");
+ exit(1);
+ }
+ return true;
case AST_TREE_TOKEN_FUNCTION_CALL:
printLog("Not implemented yet");
exit(1);
@@ -1064,10 +1067,9 @@ bool setAllTypesRoot(AstTreeRoot *root) {
}
bool setAllTypes(AstTree *tree) {
- if (tree->typeChecked == true) {
+ if (tree->type != NULL) {
return true;
}
- tree->typeChecked = true;
switch (tree->token) {
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -1087,6 +1089,8 @@ bool setAllTypes(AstTree *tree) {
return setTypesVariable(tree);
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
return setTypesOperatorAssign(tree);
+ case AST_TREE_TOKEN_OPERATOR_SUM:
+ return setTypesOperatorSum(tree);
case AST_TREE_TOKEN_NONE:
}
printLog("Bad token '%d'", tree->token);
@@ -1106,8 +1110,8 @@ bool setTypesFunction(AstTree *tree) {
}
for (size_t i = 0; i < metadata->scope.expressions_size; ++i) {
- AstTree expression = metadata->scope.expressions[i];
- if (!setAllTypes(&expression)) {
+ AstTree *expression = &metadata->scope.expressions[i];
+ if (!setAllTypes(expression)) {
return false;
}
}
@@ -1118,18 +1122,19 @@ bool setTypesFunction(AstTree *tree) {
}
}
- return true;
+ tree->type = makeTypeOf(tree);
+ return tree->type != NULL;
}
bool setTypesPrintU64(AstTree *tree) {
AstTreeSingleChild *metadata = tree->metadata;
if (!setAllTypes(metadata)) {
return false;
- }
- if (!hasTypeOf(metadata, &AST_TREE_U64_TYPE)) {
+ } else if (!typeIsEqual(metadata->type, &AST_TREE_U64_TYPE)) {
printLog("Type mismatch");
return false;
} else {
+ tree->type = &AST_TREE_VOID_TYPE;
return true;
}
}
@@ -1142,7 +1147,15 @@ bool setTypesTypeFunction(AstTree *tree) {
return false;
}
- return setAllTypes(metadata->returnType);
+ if (!setAllTypes(metadata->returnType)) {
+ return false;
+ } else if (!typeIsEqual(metadata->returnType->type, &AST_TREE_TYPE_TYPE)) {
+ printLog("Type mismatch");
+ return false;
+ }
+
+ tree->type = &AST_TREE_TYPE_TYPE;
+ return true;
}
bool setTypesFunctionCall(AstTree *tree) {
@@ -1156,10 +1169,7 @@ bool setTypesFunctionCall(AstTree *tree) {
if (metadata->function->token != AST_TREE_TOKEN_VARIABLE) {
printLog("Not yet supported");
return false;
- }
-
- if (!setAllTypes(metadata->function)) {
- printLog("Type mismatch");
+ } else if (!setAllTypes(metadata->function)) {
return false;
}
@@ -1168,64 +1178,65 @@ bool setTypesFunctionCall(AstTree *tree) {
function->arguments.size != metadata->parameters_size) {
printLog("Arguments doesn't match %ld != %ld", function->arguments.size,
metadata->parameters_size);
- return false;
+ return NULL;
}
+ tree->type = copyAstTree(function->returnType);
return true;
}
bool setTypesVariable(AstTree *tree) {
AstTreeVariable *metadata = tree->metadata;
- return setTypesAstVariable(metadata);
+ if (setTypesAstVariable(metadata)) {
+ tree->type = copyAstTree(metadata->type);
+ return true;
+ } else {
+ return false;
+ }
}
bool setTypesOperatorAssign(AstTree *tree) {
AstTreeInfix *infix = tree->metadata;
if (!setTypesAstInfix(infix)) {
- return true;
- } else if (!typeIsEqual(&infix->leftType, &infix->rightType)) {
+ return false;
+ } else if (!typeIsEqual(infix->left.type, infix->right.type)) {
printLog("Type mismatch");
return false;
} else {
+ tree->type = copyAstTree(infix->left.type);
return true;
}
}
-bool setTypesAstVariable(AstTreeVariable *variable) {
- if (!setAllTypes(variable->value)) {
+bool setTypesOperatorSum(AstTree *tree) {
+ AstTreeInfix *infix = tree->metadata;
+ if (!setTypesAstInfix(infix)) {
return false;
- }
-
- if (variable->type == NULL) {
- if ((variable->type = makeTypeOf(variable->value)) == NULL) {
- return false;
- }
- }
-
- if (!hasTypeOf(variable->value, variable->type)) {
+ } else if (!typeIsEqual(infix->left.type, infix->right.type)) {
printLog("Type mismatch");
return false;
} else {
+ tree->type = copyAstTree(infix->left.type);
return true;
}
}
-bool setTypesAstInfix(AstTreeInfix *infix) {
- if (!setAllTypes(&infix->left) || !setAllTypes(&infix->right)) {
+bool setTypesAstVariable(AstTreeVariable *variable) {
+ if (!setAllTypes(variable->value)) {
+ return false;
+ } else if (variable->type == NULL &&
+ (variable->type = makeTypeOf(variable->value)) == NULL) {
+ return false;
+ } else if (!typeIsEqual(variable->value->type, variable->type)) {
printLog("Type mismatch");
return false;
+ } else {
+ return true;
}
+}
- AstTree *lType = makeTypeOf(&infix->left);
- AstTree *rType = makeTypeOf(&infix->right);
-
- infix->leftType = *lType;
- infix->rightType = *rType;
-
- free(lType);
- free(rType);
-
- return true;
+bool setTypesAstInfix(AstTreeInfix *infix) {
+ return setAllTypes(&infix->left) && setAllTypes(&infix->right);
}
bool astTreeCleanRoot(AstTreeRoot *root) {
@@ -1251,6 +1262,7 @@ bool astTreeClean(AstTree *tree) {
case AST_TREE_TOKEN_VALUE_U64:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
return true;
case AST_TREE_TOKEN_NONE:
}
@@ -1271,8 +1283,8 @@ bool astTreeCleanFunction(AstTree *tree) {
}
for (size_t i = 0; i < metadata->scope.expressions_size; ++i) {
- AstTree expression = metadata->scope.expressions[i];
- if (!astTreeClean(&expression)) {
+ AstTree *expression = &metadata->scope.expressions[i];
+ if (!astTreeClean(expression)) {
return false;
}
}
@@ -1331,6 +1343,7 @@ size_t astTreeTypeSize(AstTree tree) {
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_VALUE_U64:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
case AST_TREE_TOKEN_NONE:
}
UNREACHABLE;
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 1aada03..28e74af 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -20,6 +20,7 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_VALUE_U64,
AST_TREE_TOKEN_OPERATOR_ASSIGN,
+ AST_TREE_TOKEN_OPERATOR_SUM,
AST_TREE_TOKEN_NONE,
} AstTreeToken;
@@ -28,11 +29,14 @@ extern const char *AST_TREE_TOKEN_STRINGS[];
typedef struct AstTree {
AstTreeToken token;
- bool typeChecked;
void *metadata;
+ struct AstTree *type;
} AstTree;
-extern const AstTree AST_TREE_U64_TYPE;
+extern AstTree AST_TREE_TYPE_TYPE;
+extern AstTree AST_TREE_VOID_TYPE;
+extern AstTree AST_TREE_U64_TYPE;
+extern AstTree AST_TREE_VOID_VALUE;
typedef struct AstTreeVariable {
char *name_begin;
@@ -82,8 +86,6 @@ typedef AstTree AstTreeSingleChild;
typedef struct AstTreeInfix {
AstTree left;
AstTree right;
- AstTree leftType;
- AstTree rightType;
} AstTreeInfix;
void astTreePrint(const AstTree *tree, int indent);
@@ -95,7 +97,7 @@ void astTreeVariableDelete(AstTreeVariable *variable);
void astTreeDelete(AstTree *tree);
void astTreeRootDelete(AstTreeRoot *root);
-AstTree *newAstTree(AstTreeToken token, void *metadata);
+AstTree *newAstTree(AstTreeToken token, void *metadata, AstTree *type);
AstTree *copyAstTree(AstTree *tree);
AstTreeRoot *makeAstTree(ParserNode *parsedRoot);
@@ -132,6 +134,9 @@ AstTree *astTreeParseAssign(ParserNode *parserNode,
AstTreeVariables **variables,
size_t variables_size);
+AstTree *astTreeParseSum(ParserNode *parserNode, AstTreeVariables **variables,
+ size_t variables_size);
+
bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
size_t variables_size);
@@ -139,8 +144,7 @@ AstTree *astTreeParseVariable(ParserNode *parserNode,
AstTreeVariables **variables,
size_t variables_size);
-bool hasTypeOf(AstTree *value, const AstTree *type);
-AstTreeFunction* getFunction(AstTree *value);
+AstTreeFunction *getFunction(AstTree *value);
bool isConst(AstTree *value);
AstTree *makeTypeOf(AstTree *value);
bool typeIsEqual(const AstTree *type0, const AstTree *type1);
@@ -153,6 +157,7 @@ bool setTypesTypeFunction(AstTree *tree);
bool setTypesFunctionCall(AstTree *tree);
bool setTypesVariable(AstTree *tree);
bool setTypesOperatorAssign(AstTree *tree);
+bool setTypesOperatorSum(AstTree *tree);
bool setTypesAstVariable(AstTreeVariable *variable);
bool setTypesAstInfix(AstTreeInfix *infix);
diff --git a/src/compiler/code-generator.c b/src/compiler/code-generator.c
index 6ef6807..ab7583e 100644
--- a/src/compiler/code-generator.c
+++ b/src/compiler/code-generator.c
@@ -132,6 +132,7 @@ CodeGeneratorOperand *newCodeGeneratorOperandFromAstTree(AstTree tree) {
case AST_TREE_TOKEN_FUNCTION_CALL:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
case AST_TREE_TOKEN_NONE:
}
UNREACHABLE;
@@ -232,6 +233,7 @@ CodeGeneratorCodes *codeGenerator(AstTreeRoot *astTreeRoot) {
case AST_TREE_TOKEN_TYPE_U64:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
case AST_TREE_TOKEN_NONE:
break;
}
@@ -325,7 +327,7 @@ bool codeGeneratorAstTreeFunction(char *name_begin, char *name_end,
newCodeGeneratorOperandFromAstTree(infix->right);
operands->op0 = *op0;
operands->op1 = *op1;
- operands->bytes = astTreeTypeSize(infix->leftType);
+ operands->bytes = astTreeTypeSize(*infix->left.type);
free(op0);
free(op1);
@@ -334,6 +336,30 @@ bool codeGeneratorAstTreeFunction(char *name_begin, char *name_end,
operands));
}
goto OK;
+ case AST_TREE_TOKEN_OPERATOR_SUM: {
+ AstTreeInfix *infix = tree.metadata;
+
+ if (infix->left.token != AST_TREE_TOKEN_VARIABLE) {
+ printLog("Not implemented yet");
+ exit(1);
+ }
+
+ CodeGeneratorMov *operands = a404m_malloc(sizeof(*operands));
+ CodeGeneratorOperand *op0 =
+ newCodeGeneratorOperandFromAstTree(infix->left);
+ CodeGeneratorOperand *op1 =
+ newCodeGeneratorOperandFromAstTree(infix->right);
+ operands->op0 = *op0;
+ operands->op1 = *op1;
+ operands->bytes = astTreeTypeSize(*infix->left.type);
+ free(op0);
+ free(op1);
+
+ generateCodePushCode(
+ codes, createGenerateCode(NULL, NULL, CODE_GENERATOR_INSTRUCTION_ADD,
+ operands));
+ }
+ goto OK;
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_VALUE_U64:
case AST_TREE_TOKEN_VARIABLE:
@@ -488,6 +514,8 @@ char *codeGeneratorToFlatASM(const CodeGeneratorCodes *codes) {
free(inst);
}
continue;
+ case CODE_GENERATOR_INSTRUCTION_ADD: {
+ }
}
UNREACHABLE;
}
diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h
index e4d9cac..3c3222a 100644
--- a/src/compiler/code-generator.h
+++ b/src/compiler/code-generator.h
@@ -9,6 +9,7 @@ typedef enum CodeGeneratorInstruction : uint8_t {
CODE_GENERATOR_INSTRUCTION_CALL,
CODE_GENERATOR_INSTRUCTION_RET,
CODE_GENERATOR_INSTRUCTION_MOV,
+ CODE_GENERATOR_INSTRUCTION_ADD,
CODE_GENERATOR_INSTRUCTION_FUNCTION_BEGIN,
CODE_GENERATOR_INSTRUCTION_FUNCTION_END,
} CodeGeneratorInstruction;
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index 071a2f8..fc7307f 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -15,6 +15,7 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_KEYWORD_VOID",
"LEXER_TOKEN_KEYWORD_U64",
"LEXER_TOKEN_KEYWORD_PRINT_U64",
+ "LEXER_TOKEN_KEYWORD_RETURN",
"LEXER_TOKEN_NUMBER",
@@ -28,12 +29,13 @@ const char *LEXER_TOKEN_STRINGS[] = {
"LEXER_TOKEN_SYMBOL_COLON",
"LEXER_TOKEN_SYMBOL_ASSIGN",
"LEXER_TOKEN_SYMBOL_COMMA",
+ "LEXER_TOKEN_SYMBOL_PLUS",
"LEXER_TOKEN_NONE",
};
const char *LEXER_SYMBOL_STRINGS[] = {
- ";", "(", ")", "{", "}", "->", ":", "=", ",",
+ ";", "(", ")", "{", "}", "->", ":", "=", ",", "+",
};
const LexerToken LEXER_SYMBOL_TOKENS[] = {
LEXER_TOKEN_SYMBOL_EOL,
@@ -45,6 +47,7 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = {
LEXER_TOKEN_SYMBOL_COLON,
LEXER_TOKEN_SYMBOL_ASSIGN,
LEXER_TOKEN_SYMBOL_COMMA,
+ LEXER_TOKEN_SYMBOL_PLUS,
};
const size_t LEXER_SYMBOL_SIZE =
sizeof(LEXER_SYMBOL_TOKENS) / sizeof(*LEXER_SYMBOL_TOKENS);
@@ -54,12 +57,14 @@ const char *LEXER_KEYWORD_STRINGS[] = {
"void",
"u64",
"print_u64",
+ "return",
};
const LexerToken LEXER_KEYWORD_TOKENS[] = {
LEXER_TOKEN_KEYWORD_TYPE,
LEXER_TOKEN_KEYWORD_VOID,
LEXER_TOKEN_KEYWORD_U64,
LEXER_TOKEN_KEYWORD_PRINT_U64,
+ LEXER_TOKEN_KEYWORD_RETURN,
};
const size_t LEXER_KEYWORD_SIZE =
sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS);
diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h
index 41c1ab7..81d6fd5 100644
--- a/src/compiler/lexer.h
+++ b/src/compiler/lexer.h
@@ -9,6 +9,7 @@ typedef enum LexerToken {
LEXER_TOKEN_KEYWORD_VOID,
LEXER_TOKEN_KEYWORD_U64,
LEXER_TOKEN_KEYWORD_PRINT_U64,
+ LEXER_TOKEN_KEYWORD_RETURN,
LEXER_TOKEN_NUMBER,
@@ -22,6 +23,7 @@ typedef enum LexerToken {
LEXER_TOKEN_SYMBOL_COLON,
LEXER_TOKEN_SYMBOL_ASSIGN,
LEXER_TOKEN_SYMBOL_COMMA,
+ LEXER_TOKEN_SYMBOL_PLUS,
LEXER_TOKEN_NONE,
} LexerToken;
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 7a9e0e3..c8ad924 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -31,6 +31,7 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_SYMBOL_COMMA",
"PARSER_TOKEN_OPERATOR_ASSIGN",
+ "PARSER_TOKEN_OPERATOR_SUM",
"PARSER_TOKEN_FUNCTION_DEFINITION",
@@ -61,6 +62,10 @@ static constexpr ParserOrder PARSER_ORDER[] = {
},
{
.ltr = true,
+ ORDER_ARRAY(LEXER_TOKEN_SYMBOL_PLUS, ),
+ },
+ {
+ .ltr = true,
ORDER_ARRAY(LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_KEYWORD_PRINT_U64, ),
},
{
@@ -208,7 +213,8 @@ void parserNodePrint(const ParserNode *node, int indent) {
printf(" ");
}
goto RETURN_SUCCESS;
- case PARSER_TOKEN_OPERATOR_ASSIGN: {
+ case PARSER_TOKEN_OPERATOR_ASSIGN:
+ case PARSER_TOKEN_OPERATOR_SUM: {
const ParserNodeInfixMetadata *metadata = node->metadata;
printf(",\n");
for (int i = 0; i < indent; ++i)
@@ -298,7 +304,8 @@ void parserNodeDelete(ParserNode *node) {
free(metadata);
}
goto RETURN_SUCCESS;
- case PARSER_TOKEN_OPERATOR_ASSIGN: {
+ case PARSER_TOKEN_OPERATOR_ASSIGN:
+ case PARSER_TOKEN_OPERATOR_SUM: {
ParserNodeInfixMetadata *metadata = node->metadata;
parserNodeDelete(metadata->left);
parserNodeDelete(metadata->right);
@@ -434,6 +441,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
return parserNumber(node, parent);
case LEXER_TOKEN_SYMBOL_ASSIGN:
return parserAssign(node, begin, end, parent);
+ case LEXER_TOKEN_SYMBOL_PLUS:
+ return parserPlus(node, begin, end, parent);
case LEXER_TOKEN_SYMBOL:
case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS:
case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET:
@@ -845,9 +854,33 @@ ParserNode *parserAssign(LexerNode *node, LexerNode *begin, LexerNode *end,
return left->parent = right->parent = node->parserNode =
newParserNode(PARSER_TOKEN_OPERATOR_ASSIGN, left->str_begin,
right->str_end, metadata, parent);
+}
- printLog("Not implemented");
- return NULL;
+ParserNode *parserPlus(LexerNode *node, LexerNode *begin, LexerNode *end,
+ ParserNode *parent) {
+ LexerNode *leftNode = node - 1;
+ LexerNode *rightNode = node + 1;
+
+ if (leftNode < begin || rightNode >= end) {
+ printLog("Bad plus");
+ return NULL;
+ }
+
+ ParserNode *left = getUntilCommonParent(leftNode->parserNode, parent);
+ ParserNode *right = getUntilCommonParent(rightNode->parserNode, parent);
+
+ if (left == NULL || right == NULL) {
+ printLog("Bad plus");
+ return NULL;
+ }
+
+ ParserNodeInfixMetadata *metadata = a404m_malloc(sizeof(*metadata));
+ 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);
}
bool isAllArguments(const ParserNodeArray *nodes) {
@@ -870,6 +903,7 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
case PARSER_TOKEN_OPERATOR_ASSIGN:
+ case PARSER_TOKEN_OPERATOR_SUM:
return true;
case PARSER_TOKEN_ROOT:
case PARSER_TOKEN_TYPE_TYPE:
@@ -907,6 +941,7 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_VALUE_U64:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
case PARSER_TOKEN_OPERATOR_ASSIGN:
+ case PARSER_TOKEN_OPERATOR_SUM:
return false;
case PARSER_TOKEN_NONE:
}
@@ -921,6 +956,7 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_VALUE_U64:
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_OPERATOR_ASSIGN:
+ case PARSER_TOKEN_OPERATOR_SUM:
return true;
case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_TYPE_TYPE:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index ea53042..abce8db 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -27,6 +27,7 @@ typedef enum ParserToken {
PARSER_TOKEN_SYMBOL_COMMA,
PARSER_TOKEN_OPERATOR_ASSIGN,
+ PARSER_TOKEN_OPERATOR_SUM,
PARSER_TOKEN_FUNCTION_DEFINITION,
@@ -119,6 +120,8 @@ 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);
bool isAllArguments(const ParserNodeArray *nodes);