summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/ast-tree.c212
-rw-r--r--src/compiler/ast-tree.h20
-rw-r--r--src/compiler/code-generator.c20
3 files changed, 212 insertions, 40 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 34147b1..de17a82 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -123,7 +123,7 @@ void astTreePrint(const AstTree *tree, int indent) {
printf("]");
}
goto RETURN_SUCCESS;
- case AST_TREE_TOKEN_CONSTANT: {
+ case AST_TREE_TOKEN_VARIABLE: {
AstTreeVariable *metadata = tree->metadata;
printf(",variable.name=%.*s",
(int)(metadata->name_end - metadata->name_begin),
@@ -201,7 +201,7 @@ void astTreeDestroy(AstTree tree) {
free(metadata);
}
return;
- case AST_TREE_TOKEN_CONSTANT: {
+ case AST_TREE_TOKEN_VARIABLE: {
// AstTreeIdentifier *metadata = tree.metadata; // not needed
}
return;
@@ -243,6 +243,7 @@ AstTree *newAstTree(AstTreeToken token, void *metadata) {
AstTree *result = a404m_malloc(sizeof(*result));
result->token = token;
result->metadata = metadata;
+ result->typeChecked = false;
return result;
}
@@ -255,8 +256,8 @@ AstTree *copyAstTree(AstTree *tree) {
case AST_TREE_TOKEN_VALUE_U64:
return newAstTree(AST_TREE_TOKEN_VALUE_U64,
(void *)(AstTreeU64)tree->metadata);
- case AST_TREE_TOKEN_CONSTANT:
- return newAstTree(AST_TREE_TOKEN_CONSTANT, tree->metadata);
+ case AST_TREE_TOKEN_VARIABLE:
+ return newAstTree(AST_TREE_TOKEN_VARIABLE, tree->metadata);
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
case AST_TREE_TOKEN_TYPE_FUNCTION:
@@ -297,8 +298,6 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
variable->name_begin = node_metadata->name->str_begin;
variable->name_end = node_metadata->name->str_end;
- // TODO: set type some how
-
if (!pushVariable(&root->variables, variable)) {
astTreeVariableDelete(variable);
goto RETURN_ERROR;
@@ -357,8 +356,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
AstTree *type;
if (node_metadata->type != NULL) {
- AstTreeVariables *variables = &root->variables;
- type = astTreeParse(node_metadata->type, &variables, 1);
+ type = astTreeParse(node_metadata->type, &variables, variables_size);
if (type == NULL) {
goto RETURN_ERROR;
}
@@ -368,13 +366,17 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
goto RETURN_ERROR;
}
} else {
- type = makeTypeOf(value);
+ type = NULL;
}
root->variables.data[i]->type = type;
root->variables.data[i]->value = value;
}
+ if (!setAllTypesRoot(root)) {
+ goto RETURN_ERROR;
+ }
+
return root;
RETURN_ERROR:
@@ -411,7 +413,7 @@ bool pushVariable(AstTreeVariables *variables, AstTreeVariable *variable) {
AstTreeVariable *getVariable(AstTreeVariables **variables,
size_t variables_size, char *name_begin,
char *name_end) {
- for (size_t i = 0; i < variables_size; ++i) {
+ for (size_t i = variables_size - 1; i != (size_t)-1ULL; --i) {
AstTreeVariables vars = *variables[i];
for (size_t j = 0; j < vars.size; ++j) {
char *var_begin = vars.data[j]->name_begin;
@@ -488,6 +490,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode,
for (size_t i = 0; i < p_variables_size; ++i) {
variables[i] = p_variables[i];
}
+ printLog("%p", function->arguments);
variables[variables_size - 2] = &function->arguments;
variables[variables_size - 1] = &scope.variables;
@@ -625,11 +628,10 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
if (function == NULL) {
return NULL;
}
- if (function->token != AST_TREE_TOKEN_CONSTANT) {
+ if (function->token != AST_TREE_TOKEN_VARIABLE) {
printLog("Not yet supported");
return NULL;
}
- // TODO: check types here
AstTreeFunctionCall *metadata = a404m_malloc(sizeof(*metadata));
metadata->function = function;
@@ -667,7 +669,7 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode,
printLog("Variable not found");
return NULL;
}
- return newAstTree(AST_TREE_TOKEN_CONSTANT, var);
+ return newAstTree(AST_TREE_TOKEN_VARIABLE, var);
}
AstTree *astTreeParsePrintU64(ParserNode *parserNode,
@@ -680,13 +682,6 @@ AstTree *astTreeParsePrintU64(ParserNode *parserNode,
return NULL;
}
- if (!hasTypeOf(operand, &AST_TREE_U64_TYPE)) {
- printLog("operand = %s", AST_TREE_TOKEN_STRINGS[operand->token]);
- printLog("Type mismatch");
- astTreeDelete(operand);
- return NULL;
- }
-
return newAstTree(AST_TREE_TOKEN_KEYWORD_PRINT_U64,
(AstTreeSingleChild *)operand);
}
@@ -709,7 +704,7 @@ bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
AstTree *type;
if (node_metadata->type == NULL) {
- type = makeTypeOf(value);
+ type = NULL;
} else {
type = astTreeParse(node_metadata->type, variables, variables_size);
if (type == NULL) {
@@ -734,7 +729,7 @@ RETURN_ERROR:
}
bool hasTypeOf(AstTree *value, const AstTree *type) {
- if (value->token == AST_TREE_TOKEN_CONSTANT) {
+ if (value->token == AST_TREE_TOKEN_VARIABLE) {
AstTreeVariable *variable = value->metadata;
return typeIsEqual(variable->type, type);
}
@@ -750,7 +745,7 @@ bool hasTypeOf(AstTree *value, const AstTree *type) {
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
case AST_TREE_TOKEN_FUNCTION_CALL:
- case AST_TREE_TOKEN_CONSTANT:
+ case AST_TREE_TOKEN_VARIABLE:
case AST_TREE_TOKEN_VALUE_U64:
case AST_TREE_TOKEN_NONE:
return false;
@@ -779,7 +774,7 @@ bool hasTypeOf(AstTree *value, const AstTree *type) {
case AST_TREE_TOKEN_TYPE_VOID:
case AST_TREE_TOKEN_TYPE_U64:
case AST_TREE_TOKEN_FUNCTION_CALL:
- case AST_TREE_TOKEN_CONSTANT:
+ case AST_TREE_TOKEN_VARIABLE:
return false;
case AST_TREE_TOKEN_NONE:
}
@@ -789,7 +784,7 @@ bool hasTypeOf(AstTree *value, const AstTree *type) {
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
case AST_TREE_TOKEN_FUNCTION_CALL:
- case AST_TREE_TOKEN_CONSTANT:
+ case AST_TREE_TOKEN_VARIABLE:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
case AST_TREE_TOKEN_VALUE_U64:
return false;
@@ -800,6 +795,32 @@ ERROR:
exit(1);
}
+bool isFunction(AstTree *value) {
+ switch (value->token) {
+ case AST_TREE_TOKEN_FUNCTION:
+ return true;
+ case AST_TREE_TOKEN_FUNCTION_CALL: {
+ AstTreeFunctionCall *metadata = value->metadata;
+ AstTreeFunction *function = metadata->function->metadata;
+ return isFunction(function->returnType);
+ }
+ case AST_TREE_TOKEN_VARIABLE: {
+ AstTreeVariable *metadata = value->metadata;
+ return metadata->type->token == AST_TREE_TOKEN_TYPE_FUNCTION;
+ }
+ case AST_TREE_TOKEN_KEYWORD_PRINT_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_VALUE_U64:
+ return false;
+ case AST_TREE_TOKEN_NONE:
+ }
+ printLog("Bad token '%d'", value->token);
+ exit(1);
+}
+
AstTree *makeTypeOf(AstTree *value) {
switch (value->token) {
case AST_TREE_TOKEN_TYPE_TYPE:
@@ -830,7 +851,7 @@ AstTree *makeTypeOf(AstTree *value) {
}
case AST_TREE_TOKEN_VALUE_U64:
return newAstTree(AST_TREE_TOKEN_TYPE_U64, NULL);
- case AST_TREE_TOKEN_CONSTANT:
+ case AST_TREE_TOKEN_VARIABLE:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
case AST_TREE_TOKEN_NONE:
}
@@ -857,8 +878,8 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_FUNCTION_CALL:
printLog("Not implemented yet");
exit(1);
- case AST_TREE_TOKEN_CONSTANT:
- return type1->token == AST_TREE_TOKEN_CONSTANT &&
+ case AST_TREE_TOKEN_VARIABLE:
+ return type1->token == AST_TREE_TOKEN_VARIABLE &&
type0->metadata == type1->metadata;
case AST_TREE_TOKEN_NONE:
break;
@@ -866,3 +887,138 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
printLog("Bad token '%d'", type0->token);
exit(1);
}
+
+bool setAllTypesRoot(AstTreeRoot *root) {
+ for (size_t i = 0; i < root->variables.size; ++i) {
+ AstTreeVariable *variable = root->variables.data[i];
+ if (!setTypesAstVariable(variable)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool setAllTypes(AstTree *tree) {
+ if (tree->typeChecked == true) {
+ return true;
+ }
+ tree->typeChecked = true;
+ switch (tree->token) {
+ case AST_TREE_TOKEN_TYPE_TYPE:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_U64:
+ case AST_TREE_TOKEN_VALUE_U64:
+ return true;
+ case AST_TREE_TOKEN_FUNCTION:
+ return setTypesFunction(tree);
+ case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ return setTypesPrintU64(tree);
+ case AST_TREE_TOKEN_TYPE_FUNCTION:
+ return setTypesTypeFunction(tree);
+ case AST_TREE_TOKEN_FUNCTION_CALL:
+ return setTypesFunctionCall(tree);
+ case AST_TREE_TOKEN_VARIABLE:
+ return setTypesVariable(tree);
+ case AST_TREE_TOKEN_NONE:
+ }
+ printLog("Bad token '%d'", tree->token);
+ exit(1);
+}
+
+bool setTypesFunction(AstTree *tree) {
+ AstTreeFunction *metadata = tree->metadata;
+
+ for (size_t i = 0; i < metadata->arguments.size; ++i) {
+ printLog("Type mismatch");
+ return false;
+ }
+
+ if (!setAllTypes(metadata->returnType)) {
+ return false;
+ }
+
+ for (size_t i = 0; i < metadata->scope.expressions_size; ++i) {
+ AstTree expression = metadata->scope.expressions[i];
+ if (!setAllTypes(&expression)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool setTypesPrintU64(AstTree *tree) {
+ AstTreeSingleChild *metadata = tree->metadata;
+ if (!setAllTypes(metadata)) {
+ return false;
+ }
+ if (!hasTypeOf(metadata, &AST_TREE_U64_TYPE)) {
+ printLog("Type mismatch");
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool setTypesTypeFunction(AstTree *tree) {
+ AstTreeTypeFunction *metadata = tree->metadata;
+
+ for (size_t i = 0; i < metadata->arguments_size; ++i) {
+ printLog("Not yet supported");
+ return false;
+ }
+
+ return setAllTypes(metadata->returnType);
+}
+
+bool setTypesFunctionCall(AstTree *tree) {
+ AstTreeFunctionCall *metadata = tree->metadata;
+
+ for (size_t i = 0; i < metadata->parameters_size; ++i) {
+ printLog("Not yet supported");
+ return false;
+ }
+
+ if (metadata->function->token != AST_TREE_TOKEN_VARIABLE) {
+ printLog("Not yet supported");
+ return false;
+ }
+
+ if (isFunction(metadata->function)) {
+ printLog("Type mismatch");
+ return false;
+ }
+
+ AstTreeFunction *function = metadata->function->metadata;
+ if (function->arguments.size != metadata->parameters_size) {
+ printLog("Not yet supported");
+ return false;
+ }
+
+ return true;
+}
+
+bool setTypesVariable(AstTree *tree) {
+ AstTreeVariable *metadata = tree->metadata;
+ return setTypesAstVariable(metadata);
+}
+
+bool setTypesAstVariable(AstTreeVariable *variable) {
+ if (variable->type == NULL) {
+ if ((variable->type = makeTypeOf(variable->value)) == NULL) {
+ return false;
+ }
+ }
+
+ if (!setAllTypes(variable->value)) {
+ return false;
+ }
+
+ if (!hasTypeOf(variable->value, variable->type)) {
+ printLog("Type mismatch");
+ return false;
+ } else {
+ return true;
+ }
+}
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 7590003..852441c 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -15,7 +15,7 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_TYPE_U64,
AST_TREE_TOKEN_FUNCTION_CALL,
- AST_TREE_TOKEN_CONSTANT,
+ AST_TREE_TOKEN_VARIABLE,
AST_TREE_TOKEN_VALUE_U64,
AST_TREE_TOKEN_NONE,
@@ -24,6 +24,7 @@ typedef enum AstTreeToken {
typedef struct AstTree {
AstTreeToken token;
void *metadata;
+ bool typeChecked;
} AstTree;
typedef struct AstTreeVariable {
@@ -114,10 +115,19 @@ AstTree *astTreeParsePrintU64(ParserNode *parserNode,
AstTreeVariables **variables,
size_t variables_size);
-bool astTreeParseConstant(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size);
+bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
+ size_t variables_size);
-bool hasTypeOf(AstTree *value,const AstTree *type);
+bool hasTypeOf(AstTree *value, const AstTree *type);
+bool isFunction(AstTree *value);
AstTree *makeTypeOf(AstTree *value);
bool typeIsEqual(const AstTree *type0, const AstTree *type1);
+
+bool setAllTypesRoot(AstTreeRoot *root);
+bool setAllTypes(AstTree *tree);
+bool setTypesFunction(AstTree *tree);
+bool setTypesPrintU64(AstTree *tree);
+bool setTypesTypeFunction(AstTree *tree);
+bool setTypesFunctionCall(AstTree *tree);
+bool setTypesVariable(AstTree *tree);
+bool setTypesAstVariable(AstTreeVariable *variable);
diff --git a/src/compiler/code-generator.c b/src/compiler/code-generator.c
index 27a0fdc..1969016 100644
--- a/src/compiler/code-generator.c
+++ b/src/compiler/code-generator.c
@@ -77,11 +77,18 @@ CodeGeneratorCodes *codeGenerator(AstTreeRoot *astTreeRoot) {
return NULL;
}
continue;
+ case AST_TREE_TOKEN_VALUE_U64: {
+ CodeGeneratorOperandU64 value = (AstTreeU64)variable->value->metadata;
+ generateCodePushCode(
+ codes, createGenerateCode(variable->name_begin, variable->name_end,
+ CODE_GENERATOR_INSTRUCTION_PRINT_U64,
+ (void *)value));
+ }
+ continue;
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
- case AST_TREE_TOKEN_VALUE_U64:
- case AST_TREE_TOKEN_CONSTANT:
+ case AST_TREE_TOKEN_VARIABLE:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
case AST_TREE_TOKEN_FUNCTION_CALL:
case AST_TREE_TOKEN_TYPE_U64:
@@ -110,7 +117,7 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end,
printLog("Not implemented");
exit(0);
}
- if (function->token != AST_TREE_TOKEN_CONSTANT) {
+ if (function->token != AST_TREE_TOKEN_VARIABLE) {
printLog("Not implemented");
exit(0);
}
@@ -132,7 +139,7 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end,
codes, createGenerateCode(label_begin, label_end,
CODE_GENERATOR_INSTRUCTION_PRINT_U64,
(void *)value));
- } else if (metadata->token == AST_TREE_TOKEN_CONSTANT) {
+ } else if (metadata->token == AST_TREE_TOKEN_VARIABLE) {
AstTreeVariable *variable = metadata->metadata;
CodeGeneratorOperandU64 value = (AstTreeU64)variable->value->metadata;
generateCodePushCode(
@@ -146,7 +153,7 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end,
}
goto OK;
case AST_TREE_TOKEN_VALUE_U64:
- case AST_TREE_TOKEN_CONSTANT:
+ case AST_TREE_TOKEN_VARIABLE:
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
@@ -168,8 +175,7 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end,
return true;
}
-static const char TEMPLATE[] =
- "include 'stdlib/main.asm'\n";
+static const char TEMPLATE[] = "include 'stdlib/main.asm'\n";
static const size_t TEMPLATE_LEN =
sizeof(TEMPLATE) / sizeof(*TEMPLATE) - sizeof(*TEMPLATE);