summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/ast-tree.c104
-rw-r--r--src/compiler/ast-tree.h11
-rw-r--r--src/compiler/parser.c54
-rw-r--r--src/compiler/parser.h6
4 files changed, 149 insertions, 26 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 7f955ff..c51e836 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -107,6 +107,18 @@ void astTreePrint(const AstTree *tree, int indent) {
astTreePrint(metadata, indent + 1);
}
goto RETURN_SUCCESS;
+ case AST_TREE_TOKEN_KEYWORD_RETURN: {
+ AstTreeReturn *metadata = tree->metadata;
+ if (metadata->value != NULL) {
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("value=\n");
+ astTreePrint(metadata->value, indent + 1);
+ }
+ }
+ goto RETURN_SUCCESS;
+
case AST_TREE_TOKEN_VALUE_U64: {
AstTreeU64 metadata = (AstTreeU64)tree->metadata;
printf(",value=%lu", metadata);
@@ -195,15 +207,6 @@ 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;
@@ -234,6 +237,14 @@ void astTreeDestroy(AstTree tree) {
astTreeDelete(metadata);
}
return;
+ case AST_TREE_TOKEN_KEYWORD_RETURN: {
+ AstTreeReturn *metadata = tree.metadata;
+ if (metadata->value != NULL) {
+ astTreeDelete(metadata->value);
+ }
+ free(metadata);
+ }
+ return;
case AST_TREE_TOKEN_TYPE_FUNCTION: {
AstTreeTypeFunction *metadata = tree.metadata;
for (size_t i = 0; i < metadata->arguments_size; ++i) {
@@ -287,6 +298,10 @@ void astTreeVariableDelete(AstTreeVariable *variable) {
}
void astTreeDelete(AstTree *tree) {
+ if (tree != &AST_TREE_TYPE_TYPE && tree != &AST_TREE_VOID_TYPE &&
+ tree != &AST_TREE_U64_TYPE) {
+ return;
+ }
astTreeDestroy(*tree);
free(tree);
}
@@ -334,6 +349,7 @@ AstTree *copyAstTree(AstTree *tree) {
case AST_TREE_TOKEN_OPERATOR_SUM:
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_FUNCTION_CALL:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_NONE:
@@ -410,6 +426,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
case PARSER_TOKEN_TYPE_VOID:
case PARSER_TOKEN_TYPE_U64:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
+ case PARSER_TOKEN_KEYWORD_RETURN:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_EOL:
@@ -419,9 +436,9 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
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;
+ case PARSER_TOKEN_NONE:
}
printLog("Bad token %d", node_metadata->value->token);
goto RETURN_ERROR;
@@ -528,6 +545,8 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables,
&AST_TREE_U64_TYPE);
case PARSER_TOKEN_KEYWORD_PRINT_U64:
return astTreeParsePrintU64(parserNode, variables, variables_size);
+ case PARSER_TOKEN_KEYWORD_RETURN:
+ return astTreeParseReturn(parserNode, variables, variables_size);
case PARSER_TOKEN_OPERATOR_ASSIGN:
return astTreeParseAssign(parserNode, variables, variables_size);
case PARSER_TOKEN_OPERATOR_SUM:
@@ -727,12 +746,6 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
}
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]);
- }
- free(metadata->parameters);
- return NULL;
}
AstTree *astTreeParseIdentifier(ParserNode *parserNode,
@@ -761,6 +774,27 @@ AstTree *astTreeParsePrintU64(ParserNode *parserNode,
(AstTreeSingleChild *)operand, NULL);
}
+AstTree *astTreeParseReturn(ParserNode *parserNode,
+ AstTreeVariables **variables,
+ size_t variables_size) {
+ ParserNodeReturnMetadata *node_metadata = parserNode->metadata;
+
+ AstTree *value;
+ if (node_metadata == NULL) {
+ value = NULL;
+ } else {
+ value = astTreeParse(node_metadata->value, variables, variables_size);
+ if (value == NULL) {
+ return NULL;
+ }
+ }
+
+ AstTreeReturn *metadata = a404m_malloc(sizeof(*metadata));
+ metadata->value = value;
+
+ return newAstTree(AST_TREE_TOKEN_KEYWORD_RETURN, metadata, NULL);
+}
+
AstTree *astTreeParseAssign(ParserNode *parserNode,
AstTreeVariables **variables,
size_t variables_size) {
@@ -917,6 +951,7 @@ AstTreeFunction *getFunction(AstTree *value) {
}
}
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -942,6 +977,7 @@ bool isConst(AstTree *value) {
case AST_TREE_TOKEN_VALUE_U64:
return true;
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_FUNCTION_CALL:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
@@ -1005,6 +1041,7 @@ AstTree *makeTypeOf(AstTree *value) {
}
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_NONE:
}
printLog("Bad token '%d'", value->token);
@@ -1015,6 +1052,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
switch (type0->token) {
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_VALUE_U64:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
@@ -1066,7 +1104,7 @@ bool setAllTypesRoot(AstTreeRoot *root) {
return true;
}
-bool setAllTypes(AstTree *tree) {
+bool setAllTypes(AstTree *tree, AstTreeFunction *function) {
if (tree->type != NULL) {
return true;
}
@@ -1081,6 +1119,8 @@ bool setAllTypes(AstTree *tree) {
return setTypesFunction(tree);
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
return setTypesPrintU64(tree);
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
+ return setTypesReturn(tree, function);
case AST_TREE_TOKEN_TYPE_FUNCTION:
return setTypesTypeFunction(tree);
case AST_TREE_TOKEN_FUNCTION_CALL:
@@ -1105,13 +1145,13 @@ bool setTypesFunction(AstTree *tree) {
return false;
}
- if (!setAllTypes(metadata->returnType)) {
+ if (!setAllTypes(metadata->returnType, NULL)) {
return false;
}
for (size_t i = 0; i < metadata->scope.expressions_size; ++i) {
AstTree *expression = &metadata->scope.expressions[i];
- if (!setAllTypes(expression)) {
+ if (!setAllTypes(expression, metadata)) {
return false;
}
}
@@ -1128,7 +1168,7 @@ bool setTypesFunction(AstTree *tree) {
bool setTypesPrintU64(AstTree *tree) {
AstTreeSingleChild *metadata = tree->metadata;
- if (!setAllTypes(metadata)) {
+ if (!setAllTypes(metadata, NULL)) {
return false;
} else if (!typeIsEqual(metadata->type, &AST_TREE_U64_TYPE)) {
printLog("Type mismatch");
@@ -1139,6 +1179,20 @@ bool setTypesPrintU64(AstTree *tree) {
}
}
+bool setTypesReturn(AstTree *tree, AstTreeFunction *function) {
+ AstTreeReturn *metadata = tree->metadata;
+ if (metadata->value != NULL) {
+ if (!setAllTypes(metadata->value, NULL)) {
+ return false;
+ } else if (!typeIsEqual(metadata->value->type, function->returnType)) {
+ printLog("Type mismatch");
+ return false;
+ }
+ }
+ tree->type = &AST_TREE_VOID_TYPE;
+ return true;
+}
+
bool setTypesTypeFunction(AstTree *tree) {
AstTreeTypeFunction *metadata = tree->metadata;
@@ -1147,7 +1201,7 @@ bool setTypesTypeFunction(AstTree *tree) {
return false;
}
- if (!setAllTypes(metadata->returnType)) {
+ if (!setAllTypes(metadata->returnType, NULL)) {
return false;
} else if (!typeIsEqual(metadata->returnType->type, &AST_TREE_TYPE_TYPE)) {
printLog("Type mismatch");
@@ -1169,7 +1223,7 @@ bool setTypesFunctionCall(AstTree *tree) {
if (metadata->function->token != AST_TREE_TOKEN_VARIABLE) {
printLog("Not yet supported");
return false;
- } else if (!setAllTypes(metadata->function)) {
+ } else if (!setAllTypes(metadata->function, NULL)) {
return false;
}
@@ -1222,7 +1276,7 @@ bool setTypesOperatorSum(AstTree *tree) {
}
bool setTypesAstVariable(AstTreeVariable *variable) {
- if (!setAllTypes(variable->value)) {
+ if (!setAllTypes(variable->value, NULL)) {
return false;
} else if (variable->type == NULL &&
(variable->type = makeTypeOf(variable->value)) == NULL) {
@@ -1236,7 +1290,7 @@ bool setTypesAstVariable(AstTreeVariable *variable) {
}
bool setTypesAstInfix(AstTreeInfix *infix) {
- return setAllTypes(&infix->left) && setAllTypes(&infix->right);
+ return setAllTypes(&infix->left, NULL) && setAllTypes(&infix->right, NULL);
}
bool astTreeCleanRoot(AstTreeRoot *root) {
@@ -1254,6 +1308,7 @@ bool astTreeClean(AstTree *tree) {
case AST_TREE_TOKEN_FUNCTION:
return astTreeCleanFunction(tree);
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -1335,6 +1390,7 @@ size_t astTreeTypeSize(AstTree tree) {
return 8;
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
case AST_TREE_TOKEN_TYPE_TYPE:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 28e74af..64068d3 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -8,6 +8,7 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_FUNCTION,
AST_TREE_TOKEN_KEYWORD_PRINT_U64,
+ AST_TREE_TOKEN_KEYWORD_RETURN,
AST_TREE_TOKEN_TYPE_TYPE,
AST_TREE_TOKEN_TYPE_FUNCTION,
@@ -88,6 +89,10 @@ typedef struct AstTreeInfix {
AstTree right;
} AstTreeInfix;
+typedef struct AstTreeReturn {
+ AstTree *value;
+} AstTreeReturn;
+
void astTreePrint(const AstTree *tree, int indent);
void astTreeRootPrint(const AstTreeRoot *root);
@@ -129,6 +134,9 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode,
AstTree *astTreeParsePrintU64(ParserNode *parserNode,
AstTreeVariables **variables,
size_t variables_size);
+AstTree *astTreeParseReturn(ParserNode *parserNode,
+ AstTreeVariables **variables,
+ size_t variables_size);
AstTree *astTreeParseAssign(ParserNode *parserNode,
AstTreeVariables **variables,
@@ -150,9 +158,10 @@ AstTree *makeTypeOf(AstTree *value);
bool typeIsEqual(const AstTree *type0, const AstTree *type1);
bool setAllTypesRoot(AstTreeRoot *root);
-bool setAllTypes(AstTree *tree);
+bool setAllTypes(AstTree *tree,AstTreeFunction *function);
bool setTypesFunction(AstTree *tree);
bool setTypesPrintU64(AstTree *tree);
+bool setTypesReturn(AstTree *tree,AstTreeFunction *function);
bool setTypesTypeFunction(AstTree *tree);
bool setTypesFunctionCall(AstTree *tree);
bool setTypesVariable(AstTree *tree);
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index c8ad924..1aa596c 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -21,6 +21,7 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_TYPE_U64",
"PARSER_TOKEN_KEYWORD_PRINT_U64",
+ "PARSER_TOKEN_KEYWORD_RETURN",
"PARSER_TOKEN_CONSTANT",
"PARSER_TOKEN_VARIABLE",
@@ -66,7 +67,7 @@ static constexpr ParserOrder PARSER_ORDER[] = {
},
{
.ltr = true,
- ORDER_ARRAY(LEXER_TOKEN_SYMBOL_COLON, LEXER_TOKEN_KEYWORD_PRINT_U64, ),
+ ORDER_ARRAY(LEXER_TOKEN_SYMBOL_COLON, ),
},
{
.ltr = false,
@@ -74,6 +75,11 @@ static constexpr ParserOrder PARSER_ORDER[] = {
},
{
.ltr = true,
+ ORDER_ARRAY(LEXER_TOKEN_KEYWORD_RETURN,
+ LEXER_TOKEN_KEYWORD_PRINT_U64, ),
+ },
+ {
+ .ltr = true,
ORDER_ARRAY(LEXER_TOKEN_SYMBOL_EOL, LEXER_TOKEN_SYMBOL_COMMA, ),
},
};
@@ -154,6 +160,18 @@ void parserNodePrint(const ParserNode *node, int indent) {
printf(" ");
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_KEYWORD_RETURN: {
+ const ParserNodeReturnMetadata *metadata = node->metadata;
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("value=\n");
+ parserNodePrint(metadata->value, indent + 1);
+ printf("\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_FUNCTION_DEFINITION: {
const ParserNodeFunctionDefnitionMetadata *metadata = node->metadata;
printf(",\n");
@@ -278,6 +296,14 @@ void parserNodeDelete(ParserNode *node) {
parserNodeDelete(metadata);
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_KEYWORD_RETURN: {
+ ParserNodeReturnMetadata *metadata = node->metadata;
+ if (metadata->value != NULL) {
+ parserNodeDelete(metadata->value);
+ }
+ free(metadata);
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_FUNCTION_DEFINITION: {
ParserNodeFunctionDefnitionMetadata *metadata = node->metadata;
parserNodeDelete(metadata->arguments);
@@ -425,6 +451,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
return parserU64(node, parent);
case LEXER_TOKEN_KEYWORD_PRINT_U64:
return parserPrintU64(node, end, parent);
+ case LEXER_TOKEN_KEYWORD_RETURN:
+ return parserReturn(node, end, parent);
case LEXER_TOKEN_SYMBOL_EOL:
return parserEol(node, begin, parent);
case LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS:
@@ -505,6 +533,27 @@ ParserNode *parserPrintU64(LexerNode *node, LexerNode *end,
(ParserNodeSingleChildMetadata *)operand, parent);
}
+ParserNode *parserReturn(LexerNode *node, LexerNode *end, ParserNode *parent) {
+ LexerNode *afterNode = node + 1;
+ ParserNode *operand;
+ if (afterNode >= end || afterNode->parserNode == NULL) {
+ operand = NULL;
+ } else {
+ operand = getUntilCommonParent(afterNode->parserNode, parent);
+ if (operand == NULL) {
+ printLog("No param");
+ return NULL;
+ }
+ }
+
+ ParserNodeReturnMetadata *metadata = a404m_malloc(sizeof(*metadata));
+ metadata->value = operand;
+
+ return operand->parent = node->parserNode =
+ newParserNode(PARSER_TOKEN_KEYWORD_RETURN, node->str_begin,
+ node->str_end, metadata, parent);
+}
+
ParserNode *parserNumber(LexerNode *node, ParserNode *parent) {
ParserNode *parserNode;
switch (*node->str_begin) {
@@ -902,6 +951,7 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_FUNCTION_DEFINITION:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
+ case PARSER_TOKEN_KEYWORD_RETURN:
case PARSER_TOKEN_OPERATOR_ASSIGN:
case PARSER_TOKEN_OPERATOR_SUM:
return true;
@@ -940,6 +990,7 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_VALUE_U64:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
+ case PARSER_TOKEN_KEYWORD_RETURN:
case PARSER_TOKEN_OPERATOR_ASSIGN:
case PARSER_TOKEN_OPERATOR_SUM:
return false;
@@ -970,6 +1021,7 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_KEYWORD_PRINT_U64:
+ case PARSER_TOKEN_KEYWORD_RETURN:
return false;
case PARSER_TOKEN_NONE:
}
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index abce8db..004f14f 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -17,6 +17,7 @@ typedef enum ParserToken {
PARSER_TOKEN_TYPE_U64,
PARSER_TOKEN_KEYWORD_PRINT_U64,
+ PARSER_TOKEN_KEYWORD_RETURN,
PARSER_TOKEN_CONSTANT,
PARSER_TOKEN_VARIABLE,
@@ -88,6 +89,10 @@ typedef struct ParserNodeInfixMetadata {
ParserNode *right;
} ParserNodeInfixMetadata;
+typedef struct ParserNodeReturnMetadata {
+ ParserNode *value;
+} ParserNodeReturnMetadata;
+
void parserNodePrint(const ParserNode *node, int indent);
void parserNodeDelete(ParserNode *node);
@@ -107,6 +112,7 @@ ParserNode *parserType(LexerNode *node, ParserNode *parent);
ParserNode *parserVoid(LexerNode *node, ParserNode *parent);
ParserNode *parserU64(LexerNode *node, ParserNode *parent);
ParserNode *parserPrintU64(LexerNode *node, LexerNode *end, ParserNode *parent);
+ParserNode *parserReturn(LexerNode *node, LexerNode *end, ParserNode *parent);
ParserNode *parserNumber(LexerNode *node, ParserNode *parent);
ParserNode *parserEol(LexerNode *node, LexerNode *begin, ParserNode *parent);
ParserNode *parserComma(LexerNode *node, LexerNode *begin, ParserNode *parent);