summaryrefslogtreecommitdiff
path: root/src/compiler/parser.c
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-14 12:55:08 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-14 12:55:08 +0330
commit038bbfc95cf79e1be48b1926e9893e2a12a3b92a (patch)
tree7cfcf33b7f431acbb2edb4201dfc30f7e08acf3d /src/compiler/parser.c
parentf6a2a2ed20376f6ba677248b0dcf5d0ddceaeef7 (diff)
add arrays
Diffstat (limited to 'src/compiler/parser.c')
-rw-r--r--src/compiler/parser.c178
1 files changed, 177 insertions, 1 deletions
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index ba8f20a..ae2db33 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -53,6 +53,8 @@ const char *PARSER_TOKEN_STRINGS[] = {
"PARSER_TOKEN_SYMBOL_EOL",
"PARSER_TOKEN_SYMBOL_CURLY_BRACKET",
+ "PARSER_TOKEN_SYMBOL_BRACKET_LEFT",
+ "PARSER_TOKEN_SYMBOL_BRACKET_RIGHT",
"PARSER_TOKEN_SYMBOL_PARENTHESIS",
"PARSER_TOKEN_SYMBOL_COMMA",
@@ -182,7 +184,10 @@ void parserNodePrint(const ParserNode *node, int indent) {
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
case PARSER_TOKEN_SYMBOL_PARENTHESIS: {
const ParserNodeArray *metadata = node->metadata;
- printf(",children=[\n");
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("children=[\n");
for (size_t i = 0; i < metadata->size; ++i) {
parserNodePrint(metadata->data[i], indent + 1);
printf(",\n");
@@ -192,6 +197,27 @@ void parserNodePrint(const ParserNode *node, int indent) {
printf("]");
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: {
+ const ParserNodeBracketMetadata *metadata = node->metadata;
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("operand=\n");
+ parserNodePrint(metadata->operand, 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");
+ }
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("]");
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_BUILTIN:
case PARSER_TOKEN_TYPE_TYPE:
@@ -456,6 +482,18 @@ void parserNodeDelete(ParserNode *node) {
free(metadata);
}
goto RETURN_SUCCESS;
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: {
+ ParserNodeBracketMetadata *metadata = node->metadata;
+ parserNodeDelete(metadata->operand);
+ 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_IDENTIFIER:
case PARSER_TOKEN_BUILTIN:
case PARSER_TOKEN_TYPE_TYPE:
@@ -747,6 +785,10 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
return parserParenthesis(node, begin, parent);
case LEXER_TOKEN_SYMBOL_CLOSE_CURLY_BRACKET:
return parserCurlyBrackets(node, begin, parent);
+ case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET:
+ return parserBracketsRight(node, begin, parent, conti);
+ case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET_LEFT:
+ return parserBracketsLeft(node, begin, end, parent);
case LEXER_TOKEN_SYMBOL_FUNCTION_ARROW:
return parserFunction(node, begin, end, parent);
case LEXER_TOKEN_SYMBOL_COLON:
@@ -865,6 +907,7 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
case LEXER_TOKEN_SYMBOL:
case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS:
case LEXER_TOKEN_SYMBOL_OPEN_CURLY_BRACKET:
+ case LEXER_TOKEN_SYMBOL_OPEN_BRACKET:
case LEXER_TOKEN_NONE:
break;
}
@@ -1213,6 +1256,131 @@ ParserNode *parserParenthesis(LexerNode *closing, LexerNode *begin,
}
}
+ParserNode *parserBracketsRight(LexerNode *closing, LexerNode *begin,
+ ParserNode *parent, bool *conti) {
+ LexerNode *opening = NULL;
+
+ for (LexerNode *iter = closing - 1; iter >= begin; --iter) {
+ if (iter->parserNode == NULL &&
+ iter->token == LEXER_TOKEN_SYMBOL_OPEN_BRACKET) {
+ opening = iter;
+ break;
+ }
+ }
+
+ if (opening == NULL) {
+ printError(closing->str_begin, closing->str_end, "No opening for bracket");
+ return NULL;
+ }
+
+ LexerNode *beforeNode = opening - 1;
+ ParserNode *before;
+ if (beforeNode < begin || beforeNode->parserNode == NULL ||
+ (before = getUntilCommonParent(beforeNode->parserNode, parent)) == NULL ||
+ !isExpression(before)) {
+ closing->token = LEXER_TOKEN_SYMBOL_CLOSE_BRACKET_LEFT;
+ *conti = true;
+ return NULL;
+ }
+
+ ParserNode *parserNode = a404m_malloc(sizeof(*parserNode));
+ parserNode->parent = parent;
+
+ before->parent = parserNode;
+
+ for (LexerNode *iter = closing - 1; iter >= begin; --iter) {
+ if (iter->parserNode != NULL) {
+ ParserNode *pNode =
+ getUntilCommonParents(iter->parserNode, parent, parserNode);
+ if (pNode == NULL) {
+ printLog(pNode->str_begin, pNode->str_end, "Bad node");
+ return NULL;
+ } else {
+ pNode->parent = parserNode;
+ }
+ } else if (iter == opening) {
+ break;
+ }
+ }
+
+ opening->parserNode = parserNode;
+ closing->parserNode = parserNode;
+
+ parserNode->token = PARSER_TOKEN_SYMBOL_BRACKET_RIGHT;
+ parserNode->str_begin = before->str_begin;
+ parserNode->str_end = closing->str_end;
+
+ if (parserNodeArray(opening + 1, closing, parserNode)) {
+ ParserNodeBracketMetadata *metadata = malloc(sizeof(*metadata));
+ metadata->operand = before;
+ metadata->params = parserNode->metadata;
+ parserNode->metadata = metadata;
+ return parserNode;
+ } else {
+ free(parserNode);
+ return NULL;
+ }
+}
+
+ParserNode *parserBracketsLeft(LexerNode *closing, LexerNode *begin,
+ LexerNode *end, ParserNode *parent) {
+ LexerNode *afterNode = closing + 1;
+ ParserNode *after;
+ if (afterNode >= end || afterNode->parserNode == NULL ||
+ (after = getUntilCommonParent(afterNode->parserNode, parent)) == NULL ||
+ !isExpression(after)) {
+ printLog(closing->str_begin, closing->str_end,
+ "Bad bracket can't be parsed");
+ return NULL;
+ }
+
+ ParserNode *parserNode = a404m_malloc(sizeof(*parserNode));
+ parserNode->parent = parent;
+
+ after->parent = parserNode;
+
+ LexerNode *opening = NULL;
+
+ for (LexerNode *iter = closing - 1; iter >= begin; --iter) {
+
+ if (iter->parserNode != NULL) {
+ ParserNode *pNode =
+ getUntilCommonParents(iter->parserNode, parent, parserNode);
+ if (pNode == NULL) {
+ printLog(pNode->str_begin, pNode->str_end, "Bad node");
+ return NULL;
+ } else {
+ pNode->parent = parserNode;
+ }
+ } else if (iter->token == LEXER_TOKEN_SYMBOL_OPEN_BRACKET) {
+ opening = iter;
+ break;
+ }
+ }
+
+ if (opening == NULL) {
+ printError(closing->str_begin, closing->str_end, "No opening for bracket");
+ return NULL;
+ }
+ opening->parserNode = parserNode;
+ closing->parserNode = parserNode;
+
+ parserNode->token = PARSER_TOKEN_SYMBOL_BRACKET_LEFT;
+ parserNode->str_begin = opening->str_begin;
+ parserNode->str_end = after->str_end;
+
+ if (parserNodeArray(opening + 1, closing, parserNode)) {
+ ParserNodeBracketMetadata *metadata = malloc(sizeof(*metadata));
+ metadata->operand = after;
+ metadata->params = parserNode->metadata;
+ parserNode->metadata = metadata;
+ return parserNode;
+ } else {
+ free(parserNode);
+ return NULL;
+ }
+}
+
ParserNode *parserCurlyBrackets(LexerNode *closing, LexerNode *begin,
ParserNode *parent) {
ParserNode *parserNode = a404m_malloc(sizeof(*parserNode));
@@ -1323,6 +1491,8 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_OPERATOR_ACCESS:
case PARSER_TOKEN_OPERATOR_ASSIGN:
@@ -1752,6 +1922,8 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
case PARSER_TOKEN_FUNCTION_DEFINITION:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_KEYWORD_PUTC:
@@ -1844,6 +2016,8 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_BUILTIN:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
case PARSER_TOKEN_FUNCTION_CALL:
case PARSER_TOKEN_KEYWORD_IF:
case PARSER_TOKEN_KEYWORD_COMPTIME:
@@ -1956,6 +2130,8 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_KEYWORD_IF:
case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
+ case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
+ case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
case PARSER_TOKEN_KEYWORD_STRUCT:
return true;
case PARSER_TOKEN_CONSTANT: