summaryrefslogtreecommitdiff
path: root/src/compiler/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/parser.c')
-rw-r--r--src/compiler/parser.c54
1 files changed, 53 insertions, 1 deletions
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:
}