diff options
Diffstat (limited to 'src/compiler/parser/parser.c')
-rw-r--r-- | src/compiler/parser/parser.c | 148 |
1 files changed, 65 insertions, 83 deletions
diff --git a/src/compiler/parser/parser.c b/src/compiler/parser/parser.c index 2f5b89b..36b2574 100644 --- a/src/compiler/parser/parser.c +++ b/src/compiler/parser/parser.c @@ -7,7 +7,7 @@ const char *PARSED_TOKEN_STRINGS[] = { "PARSED_TOKEN_NONE", "PARSED_TOKEN_ROOT", - "PARSED_TOKEN_PRINT", "PARSED_TOKEN_PARENTHESIS", + "PARSED_TOKEN_PARENTHESIS", "PARSED_TOKEN_FUNCTION_CALL", "PARSED_TOKEN_VALUE_STRING", "PARSED_TOKEN_EOL", }; @@ -36,14 +36,6 @@ static const ParseOrder PARSE_ORDER[] = { .size = 1, .tokens = { - TOKEN_KEYWORD_PRINT, - }, - }, - { - .ltr = true, - .size = 1, - .tokens = - { TOKEN_STRING, }, }, @@ -88,11 +80,6 @@ void _printParsedNode(const ParsedNode *parsedNode, int indent) { printf("]\n"); --indent; } break; - case PARSED_TOKEN_PRINT: { - const PrintMetadata *metadata = parsedNode->metadata; - printf(",operand=\n"); - _printParsedNode(metadata, indent + 1); - } break; case PARSED_TOKEN_VALUE_STRING: printf("\n"); break; @@ -124,7 +111,8 @@ ParsedNode *getUntilCommonFather(ParsedNode *parsedNode, ParsedNode *parent) { void deleteParsedNode(ParsedNode *parsedNode) { switch (parsedNode->token) { case PARSED_TOKEN_NONE: - break; + case PARSED_TOKEN_VALUE_STRING: + goto FREE; case PARSED_TOKEN_PARENTHESIS: case PARSED_TOKEN_ROOT: { ScopeMetadata *metadata = parsedNode->metadata; @@ -133,23 +121,29 @@ void deleteParsedNode(ParsedNode *parsedNode) { } free(metadata->operands); free(metadata); - } break; - case PARSED_TOKEN_PRINT: { - PrintMetadata *metadata = parsedNode->metadata; - deleteParsedNode(metadata); - } break; - case PARSED_TOKEN_VALUE_STRING: - break; + goto FREE; + } case PARSED_TOKEN_EOL: { EOLMetadata *metadata = parsedNode->metadata; deleteParsedNode(metadata); - break; + goto FREE; + } + case PARSED_TOKEN_FUNCTION_CALL: { + FunctionCallMetadata *metadata = parsedNode->metadata; + ScopeMetadata *scope = metadata->scope; + for (size_t i = 0; i < scope->operands_size; ++i) { + deleteParsedNode(scope->operands[i]); + } + free(scope->operands); + free(scope); + free(metadata); + goto FREE; } - default: - fprintf(stderr, "bad parsed token %d at compiler line %d\n", - parsedNode->token, __LINE__); - exit(1); } + fprintf(stderr, "bad parsed token %d at compiler line %d\n", + parsedNode->token, __LINE__); + exit(1); +FREE: free(parsedNode); } @@ -168,22 +162,18 @@ ParsedNode *parser(Nodes lexedNodes) { ScopeMetadata *parserScope(Node *nodesBegin, Node *nodesEnd, ParsedNode *parent, bool (*isAllowed)(ParsedToken)) { - if (nodesBegin >= nodesEnd) { - return NULL; - } - size_t nodes_size = 0; ParsedNode **nodes = a404m_malloc(nodes_size * sizeof(ParsedNode *)); size_t nodes_inserted = 0; for (size_t order_index = 0; order_index < PARSE_ORDER_SIZE; ++order_index) { - const ParseOrder order = PARSE_ORDER[order_index]; + const ParseOrder *order = &PARSE_ORDER[order_index]; - for (Node *node = order.ltr ? nodesBegin : (nodesEnd - 1); - nodesBegin <= node && node < nodesEnd; order.ltr ? ++node : --node) { - for (size_t order_tokens_index = 0; order_tokens_index < order.size; + for (Node *node = order->ltr ? nodesBegin : (nodesEnd - 1); + nodesBegin <= node && node < nodesEnd; order->ltr ? ++node : --node) { + for (size_t order_tokens_index = 0; order_tokens_index < order->size; ++order_tokens_index) { - if (node->token == order.tokens[order_tokens_index]) { + if (node->token == order->tokens[order_tokens_index]) { ParsedNode *parsedNode = parseNode(nodesBegin, nodesEnd, node, parent); if (parsedNode == NULL) { @@ -246,9 +236,9 @@ static bool isAllowedCodeScope(ParsedToken token) { switch (token) { case PARSED_TOKEN_NONE: case PARSED_TOKEN_ROOT: - case PARSED_TOKEN_PRINT: case PARSED_TOKEN_PARENTHESIS: case PARSED_TOKEN_VALUE_STRING: + case PARSED_TOKEN_FUNCTION_CALL: return false; case PARSED_TOKEN_EOL: return true; @@ -261,10 +251,10 @@ static bool isAllowedParenthesisScope(ParsedToken token) { switch (token) { case PARSED_TOKEN_PARENTHESIS: case PARSED_TOKEN_VALUE_STRING: + case PARSED_TOKEN_FUNCTION_CALL: return true; case PARSED_TOKEN_NONE: case PARSED_TOKEN_ROOT: - case PARSED_TOKEN_PRINT: case PARSED_TOKEN_EOL: return false; } @@ -285,8 +275,6 @@ ScopeMetadata *parserScopeParenthesis(Node *nodesBegin, Node *nodesEnd, ParsedNode *parseNode(Node *nodesBegin, Node *nodesEnd, Node *node, ParsedNode *parent) { switch (node->token) { - case TOKEN_KEYWORD_PRINT: - return parserPrint(nodesBegin, nodesEnd, node, parent); case TOKEN_OPERATOR_PARENTHESES_CLOSE: return parseParenthesis(nodesBegin, nodesEnd, node, parent); case TOKEN_STRING: @@ -300,37 +288,9 @@ ParsedNode *parseNode(Node *nodesBegin, Node *nodesEnd, Node *node, } } -ParsedNode *parserPrint(Node *, Node *nodesEnd, Node *node, - ParsedNode *parent) { - Node *follow = node + 1; - - if (follow < nodesEnd && follow->token == TOKEN_PARSED) { - ParsedNode *root = a404m_malloc(sizeof(ParsedNode)); - root->strBegin = node->strBegin; - root->strEnd = node->strEnd; - root->token = PARSED_TOKEN_PRINT; - root->parent = parent; - - ParsedNode *operand = root->metadata = - getUntilCommonFather(follow->parsedNode, parent); - if (operand == NULL || operand->token != PARSED_TOKEN_PARENTHESIS) { - fprintf(stderr, "error in parsing token '%s' at compiler line %d\n", - TOKEN_STRINGS[node->token], __LINE__); - free(root); - return NULL; - } - operand->parent = root; - - node->parsedNode = root; - node->token = TOKEN_PARSED; - return root; - } - return NULL; -} - ParsedNode *parseParenthesis(Node *nodesBegin, Node *, Node *node, ParsedNode *parent) { - ParsedNode *parsedNode = a404m_malloc(sizeof(*parsedNode)); + ParsedNode *root = a404m_malloc(sizeof(*root)); Node *opening = NULL; Node *closing = node; for (Node *iter = closing - 1; iter >= nodesBegin; --iter) { @@ -345,26 +305,48 @@ ParsedNode *parseParenthesis(Node *nodesBegin, Node *, Node *node, goto RETURN_ERROR; } - parsedNode->strBegin = opening->strBegin; - parsedNode->strEnd = closing->strEnd; - parsedNode->token = PARSED_TOKEN_PARENTHESIS; - parsedNode->parent = parent; + Node *functionName = opening - 1; + if (functionName >= nodesBegin && functionName->token == TOKEN_IDENTIFIER) { + functionName->token = TOKEN_PARSED; + functionName->parsedNode = root; - const ScopeMetadata *metadata = parsedNode->metadata = - parserScopeParenthesis(opening + 1, closing, parsedNode); + root->token = PARSED_TOKEN_FUNCTION_CALL; + root->strBegin = (opening - 1)->strBegin; + root->strEnd = closing->strEnd; + root->parent = parent; - if (metadata == NULL) { - fprintf(stderr, "error in parsing token '%s' at compiler line %d\n", - TOKEN_STRINGS[node->token], __LINE__); - goto RETURN_ERROR; + FunctionCallMetadata *metadata = root->metadata = + a404m_malloc(sizeof(*metadata)); + metadata->functionNameBegin = functionName->strBegin; + metadata->functionNameEnd = functionName->strEnd; + + if ((metadata->scope = + parserScopeParenthesis(opening + 1, closing, root)) == NULL) { + fprintf(stderr, "error in parsing token '%s' at compiler line %d\n", + TOKEN_STRINGS[node->token], __LINE__); + free(metadata); + goto RETURN_ERROR; + } + } else { + root->token = PARSED_TOKEN_PARENTHESIS; + root->strBegin = opening->strBegin; + root->strEnd = closing->strEnd; + root->parent = parent; + + if ((root->metadata = parserScopeParenthesis(opening + 1, closing, root)) == + NULL) { + fprintf(stderr, "error in parsing token '%s' at compiler line %d\n", + TOKEN_STRINGS[node->token], __LINE__); + goto RETURN_ERROR; + } } - closing->parsedNode = opening->parsedNode = parsedNode; + closing->parsedNode = opening->parsedNode = root; opening->token = closing->token = TOKEN_PARSED; - return parsedNode; + return root; RETURN_ERROR: - free(parsedNode); + free(root); return NULL; } @@ -377,7 +359,7 @@ ParsedNode *parseString(Node *node, ParsedNode *parent) { ParsedNode *parseEOL(Node *nodesBegin, Node *, Node *node, ParsedNode *parent) { Node *before = node - 1; - if (before < nodesBegin && before->token != TOKEN_PARSED) { + if (before < nodesBegin || before->token != TOKEN_PARSED) { return NULL; } |