summaryrefslogtreecommitdiff
path: root/src/compiler/parser.c
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-01-25 20:53:59 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-01-25 20:53:59 +0330
commitb945815a225c3efdef5df03af52f921f98f9ed90 (patch)
treed70bc30bba6f0267596e9bac47be0882d7fe19b6 /src/compiler/parser.c
parent6a2b633d6fdc10ffb496f90912f57ec72daf25f6 (diff)
add function call
Diffstat (limited to 'src/compiler/parser.c')
-rw-r--r--src/compiler/parser.c109
1 files changed, 85 insertions, 24 deletions
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 7ec9e1c..14125cc 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -26,24 +26,26 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_FUNCTION_DEFINITION",
+ "PARSER_TOKEN_FUNCTION_CALL",
+
"PARSER_TOKEN_NONE",
};
static constexpr ParserOrder PARSER_ORDER[] = {
{
.ltr = true,
- .size = 2,
+ .size = 1,
.data =
{
- LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS,
LEXER_TOKEN_SYMBOL_CLOSE_CURLY_BRACKET,
},
},
{
.ltr = true,
- .size = 2,
+ .size = 3,
.data =
{
+ LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS,
LEXER_TOKEN_IDENTIFIER,
LEXER_TOKEN_KEYWORD_VOID,
},
@@ -183,6 +185,26 @@ void parserNodePrint(const ParserNode *node, int indent) {
printf(" ");
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_FUNCTION_CALL: {
+ const ParserNodeFunctionCall *metadata = node->metadata;
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("function=\n");
+ parserNodePrint(metadata->function, indent + 1);
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("params=[\n");
+ for (size_t i = 0; i < metadata->params->size; ++i) {
+ parserNodePrint(metadata->params->data[i], indent + 1);
+ printf(",\n");
+ }
+ printf("]\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_NONE:
}
printLog("Bad token '%d'", node->token);
@@ -241,6 +263,17 @@ void parserNodeDelete(ParserNode *node) {
free(metadata);
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_FUNCTION_CALL: {
+ ParserNodeFunctionCall *metadata = node->metadata;
+ parserNodeDelete(metadata->function);
+ for (size_t i = 0; i < metadata->params->size; ++i) {
+ parserNodeDelete(metadata->params->data[i]);
+ }
+ free(metadata->params->data);
+ free(metadata->params);
+ free(metadata);
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_NONE:
}
@@ -381,24 +414,21 @@ ParserNode *getUntilCommonParent(ParserNode *node, ParserNode *parent) {
}
ParserNode *parserIdentifier(LexerNode *node, ParserNode *parent) {
- ParserNode *parserNode = newParserNode(
- PARSER_TOKEN_IDENTIFIER, node->str_begin, node->str_end, NULL, parent);
- node->parserNode = parserNode;
- return parserNode;
+ return node->parserNode =
+ newParserNode(PARSER_TOKEN_IDENTIFIER, node->str_begin,
+ node->str_end, NULL, parent);
}
ParserNode *parserVoid(LexerNode *node, ParserNode *parent) {
- ParserNode *parserNode = newParserNode(
- PARSER_TOKEN_TYPE_VOID, node->str_begin, node->str_end, NULL, parent);
- node->parserNode = parserNode;
- return parserNode;
+ return node->parserNode =
+ newParserNode(PARSER_TOKEN_TYPE_VOID, node->str_begin,
+ node->str_end, NULL, parent);
}
ParserNode *parserPrint(LexerNode *node, ParserNode *parent) {
- ParserNode *parserNode = newParserNode(
- PARSER_TOKEN_KEYWORD_PRINT, node->str_begin, node->str_end, NULL, parent);
- node->parserNode = parserNode;
- return parserNode;
+ return node->parserNode =
+ newParserNode(PARSER_TOKEN_KEYWORD_PRINT, node->str_begin,
+ node->str_end, NULL, parent);
}
ParserNode *parserEol(LexerNode *node, LexerNode *begin, ParserNode *parent) {
@@ -461,17 +491,45 @@ ParserNode *parserParenthesis(LexerNode *closing, LexerNode *begin,
return NULL;
}
- ParserNode *parserNode =
- newParserNode(PARSER_TOKEN_SYMBOL_PARENTHESIS, opening->str_begin,
- closing->str_end, NULL, parent);
+ LexerNode *beforeNode = opening - 1;
+ ParserNode *before;
+ if (beforeNode < begin || beforeNode->parserNode == NULL ||
+ (before = getUntilCommonParent(beforeNode->parserNode, parent)) == NULL ||
+ !isExpression(before)) {
+ before = NULL;
+ }
- opening->parserNode = parserNode;
- closing->parserNode = parserNode;
- if (parserNodeArray(opening + 1, closing, parserNode)) {
- return parserNode;
+ if (before == NULL) {
+ ParserNode *parserNode =
+ newParserNode(PARSER_TOKEN_SYMBOL_PARENTHESIS, opening->str_begin,
+ closing->str_end, NULL, parent);
+
+ opening->parserNode = parserNode;
+ closing->parserNode = parserNode;
+ if (parserNodeArray(opening + 1, closing, parserNode)) {
+ return parserNode;
+ } else {
+ free(parserNode);
+ return NULL;
+ }
} else {
- free(parserNode);
- return NULL;
+ ParserNode *parserNode =
+ newParserNode(PARSER_TOKEN_FUNCTION_CALL, before->str_begin,
+ closing->str_end, NULL, parent);
+
+ before->parent = parserNode;
+ opening->parserNode = parserNode;
+ closing->parserNode = parserNode;
+ if (parserNodeArray(opening + 1, closing, parserNode)) {
+ ParserNodeFunctionCall *metadata = malloc(sizeof(*metadata));
+ metadata->function = before;
+ metadata->params = parserNode->metadata;
+ parserNode->metadata = metadata;
+ return parserNode;
+ } else {
+ free(parserNode);
+ return NULL;
+ }
}
}
@@ -683,6 +741,7 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
case PARSER_TOKEN_FUNCTION_DEFINITION:
case PARSER_TOKEN_KEYWORD_PRINT:
+ case PARSER_TOKEN_FUNCTION_CALL:
return true;
case PARSER_TOKEN_ROOT:
case PARSER_TOKEN_TYPE_FUNCTION:
@@ -711,6 +770,7 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_SYMBOL_EOL:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
case PARSER_TOKEN_SYMBOL_COMMA:
+ case PARSER_TOKEN_FUNCTION_CALL:
return false;
case PARSER_TOKEN_NONE:
}
@@ -721,6 +781,7 @@ bool isType(ParserNode *node) {
bool isValue(ParserNode *node) {
switch (node->token) {
case PARSER_TOKEN_FUNCTION_DEFINITION:
+ case PARSER_TOKEN_FUNCTION_CALL:
return true;
case PARSER_TOKEN_TYPE_VOID:
case PARSER_TOKEN_IDENTIFIER: