summaryrefslogtreecommitdiff
path: root/src/compiler
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
parent6a2b633d6fdc10ffb496f90912f57ec72daf25f6 (diff)
add function call
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/ast-tree.c133
-rw-r--r--src/compiler/ast-tree.h20
-rw-r--r--src/compiler/code-generator.c59
-rw-r--r--src/compiler/code-generator.h14
-rw-r--r--src/compiler/parser.c109
-rw-r--r--src/compiler/parser.h9
6 files changed, 300 insertions, 44 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 0a8811c..8cbfaf5 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -4,6 +4,7 @@
#include "utils/memory.h"
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
const char *AST_TREE_TOKEN_STRINGS[] = {
"AST_TREE_TOKEN_FUNCTION", "AST_TREE_TOKEN_KEYWORD_PRINT",
@@ -71,6 +72,33 @@ void astTreePrint(const AstTree *tree, int indent) {
printf("]");
}
goto RETURN_SUCCESS;
+ case AST_TREE_TOKEN_FUNCTION_CALL: {
+ AstTreeFunctionCall *metadata = tree->metadata;
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("function=\n");
+ astTreePrint(metadata->function, indent + 1);
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("paramters=[\n");
+ for (size_t i = 0; i < metadata->parameters_size; ++i) {
+ astTreePrint(metadata->parameters[i], indent + 1);
+ printf(",\n");
+ }
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("]");
+ }
+ goto RETURN_SUCCESS;
+ case AST_TREE_TOKEN_IDENTIFIER: {
+ AstTreeIdentifier *metadata = tree->metadata;
+ printf(",variable.name=%.*s",
+ (int)(metadata->name_end - metadata->name_begin),
+ metadata->name_begin);
+ }
+ goto RETURN_SUCCESS;
case AST_TREE_TOKEN_NONE:
}
@@ -105,6 +133,7 @@ void astTreeDestroy(AstTree tree) {
return;
case AST_TREE_TOKEN_KEYWORD_PRINT:
case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_IDENTIFIER:
return;
case AST_TREE_TOKEN_TYPE_FUNCTION: {
AstTreeTypeFunction *metadata = tree.metadata;
@@ -116,6 +145,15 @@ void astTreeDestroy(AstTree tree) {
free(metadata);
}
return;
+ case AST_TREE_TOKEN_FUNCTION_CALL: {
+ AstTreeFunctionCall *metadata = tree.metadata;
+ for (size_t i = 0; i < metadata->parameters_size; ++i) {
+ astTreeDelete(metadata->parameters[i]);
+ }
+ free(metadata->parameters);
+ free(metadata);
+ }
+ return;
case AST_TREE_TOKEN_NONE:
break;
}
@@ -182,9 +220,14 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
ParserNode *node = (ParserNodeEOLMetadata *)nodes->data[i]->metadata;
ParserNodeVariableMetadata *node_metadata = node->metadata;
- AstTree *type = astTreeParse(node_metadata->type, &root->variables, 1);
- if (type == NULL) {
- goto RETURN_ERROR;
+ AstTree *type;
+ if (node_metadata->type != NULL) {
+ type = astTreeParse(node_metadata->type, &root->variables, 1);
+ if (type == NULL) {
+ goto RETURN_ERROR;
+ }
+ } else {
+ type = NULL; // TODO: change this to find type
}
AstTree *value = astTreeParse(node_metadata->value, &root->variables, 1);
@@ -192,7 +235,8 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
goto RETURN_ERROR;
}
- if (!hasTypeOf(value, type)) {
+ // TODO: then delete type != NULL
+ if (type != NULL && !hasTypeOf(value, type)) {
printLog("Type mismatch");
goto RETURN_ERROR;
}
@@ -220,6 +264,24 @@ void pushVariable(AstTreeVariables *variables, size_t *variables_size,
variables->size += 1;
}
+AstTreeVariable *getVariable(AstTreeVariables *variables, size_t variables_size,
+ char *name_begin, char *name_end) {
+ for (size_t i = 0; i < variables_size; ++i) {
+ AstTreeVariables vars = variables[i];
+ for (size_t j = 0; j < vars.size; ++j) {
+ char *var_begin = vars.data[j]->name_begin;
+ char *var_end = vars.data[j]->name_end;
+
+ if (name_end - name_begin == var_end - var_begin &&
+ strncmp(var_begin, name_begin, name_end - name_begin) == 0) {
+ return vars.data[j];
+ }
+ }
+ }
+
+ return NULL;
+}
+
AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables *variables,
size_t variables_size) {
switch (parserNode->token) {
@@ -231,12 +293,15 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables *variables,
return astTreeParseTypeFunction(parserNode, variables, variables_size);
case PARSER_TOKEN_TYPE_VOID:
return newAstTree(AST_TREE_TOKEN_TYPE_VOID, NULL);
+ case PARSER_TOKEN_FUNCTION_CALL:
+ return astTreeParseFunctionCall(parserNode, variables, variables_size);
+ case PARSER_TOKEN_IDENTIFIER:
+ return astTreeParseIdentifier(parserNode, variables, variables_size);
case PARSER_TOKEN_SYMBOL_EOL:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_CONSTANT:
- case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_NONE:
case PARSER_TOKEN_ROOT:
}
@@ -390,6 +455,60 @@ RETURN_ERROR:
return NULL;
}
+AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
+ AstTreeVariables *variables,
+ size_t variables_size) {
+ ParserNodeFunctionCall *node_metadata = parserNode->metadata;
+ AstTree *function =
+ astTreeParse(node_metadata->function, variables, variables_size);
+ if (function == NULL) {
+ return NULL;
+ }
+ if (function->token != AST_TREE_TOKEN_IDENTIFIER) {
+ printLog("Not yet supported");
+ return NULL;
+ }
+ // TODO: check types here
+
+ AstTreeFunctionCall *metadata = a404m_malloc(sizeof(*metadata));
+ metadata->function = function;
+
+ metadata->parameters =
+ a404m_malloc(sizeof(*metadata->parameters) * node_metadata->params->size);
+ metadata->parameters_size = node_metadata->params->size;
+
+ for (size_t i = 0; i < metadata->parameters_size; ++i) {
+ printLog("Not impelemented yet");
+ exit(1);
+ if ((metadata->parameters[i] = astTreeParse(node_metadata->params->data[i],
+ variables, variables_size)) ==
+ NULL ||
+ hasTypeOf(metadata->parameters[i], function->metadata)) {
+ goto RETURN_ERROR;
+ }
+ }
+
+ return newAstTree(AST_TREE_TOKEN_FUNCTION_CALL, metadata);
+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,
+ AstTreeVariables *variables,
+ size_t variables_size) {
+ AstTreeVariable *var = getVariable(
+ variables, variables_size, parserNode->str_begin, parserNode->str_end);
+ if (var == NULL) {
+ printLog("Variable not found");
+ return NULL;
+ }
+ return newAstTree(AST_TREE_TOKEN_IDENTIFIER, (AstTreeIdentifier *)var);
+}
+
bool hasTypeOf(AstTree *value, AstTree *type) {
switch (type->token) {
case AST_TREE_TOKEN_TYPE_FUNCTION:
@@ -411,6 +530,8 @@ bool hasTypeOf(AstTree *value, AstTree *type) {
case AST_TREE_TOKEN_KEYWORD_PRINT:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_FUNCTION_CALL:
+ case AST_TREE_TOKEN_IDENTIFIER:
return false;
case AST_TREE_TOKEN_NONE:
}
@@ -418,6 +539,8 @@ bool hasTypeOf(AstTree *value, AstTree *type) {
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_KEYWORD_PRINT:
case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_FUNCTION_CALL:
+ case AST_TREE_TOKEN_IDENTIFIER:
return false;
case AST_TREE_TOKEN_NONE:
}
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 23f0b9c..ae97ca2 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -8,6 +8,8 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_KEYWORD_PRINT,
AST_TREE_TOKEN_TYPE_FUNCTION,
AST_TREE_TOKEN_TYPE_VOID,
+ AST_TREE_TOKEN_FUNCTION_CALL,
+ AST_TREE_TOKEN_IDENTIFIER,
AST_TREE_TOKEN_NONE,
} AstTreeToken;
@@ -52,6 +54,14 @@ typedef struct AstTreeTypeFunction {
AstTree *returnType;
} AstTreeTypeFunction;
+typedef struct AstTreeFunctionCall {
+ AstTree *function;
+ AstTree **parameters;
+ size_t parameters_size;
+} AstTreeFunctionCall;
+
+typedef AstTreeVariable AstTreeIdentifier;
+
extern const char *AST_TREE_TOKEN_STRINGS[];
void astTreePrint(const AstTree *tree, int indent);
@@ -67,6 +77,8 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot);
void pushVariable(AstTreeVariables *variables, size_t *variables_size,
AstTreeVariable *variable);
+AstTreeVariable *getVariable(AstTreeVariables *variables, size_t variables_size,
+ char *name_begin, char *name_end);
AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables *variables,
size_t variables_size);
@@ -79,5 +91,13 @@ AstTree *astTreeParseTypeFunction(ParserNode *parserNode,
AstTreeVariables *variables,
size_t variables_size);
+AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
+ AstTreeVariables *variables,
+ size_t variables_size);
+
+AstTree *astTreeParseIdentifier(ParserNode *parserNode,
+ AstTreeVariables *variables,
+ size_t variables_size);
+
bool hasTypeOf(AstTree *value, AstTree *type);
bool typeIsEqual(AstTree *type0, AstTree *type1);
diff --git a/src/compiler/code-generator.c b/src/compiler/code-generator.c
index 035a471..c07bab5 100644
--- a/src/compiler/code-generator.c
+++ b/src/compiler/code-generator.c
@@ -2,6 +2,7 @@
#include "compiler/ast-tree.h"
#include "utils/log.h"
#include "utils/memory.h"
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -15,11 +16,13 @@ void codeGeneratorDelete(CodeGeneratorCodes *code) {
}
CodeGeneratorCode createGenerateCode(char *label_begin, char *label_end,
- CodeGeneratorInstruction instruction) {
+ CodeGeneratorInstruction instruction,
+ void *metadata) {
CodeGeneratorCode code = {
.label_begin = label_begin,
.label_end = label_end,
.instruction = instruction,
+ .metadata = metadata,
};
return code;
}
@@ -55,19 +58,19 @@ CodeGeneratorCodes *codeGenerator(AstTreeRoot *astTreeRoot) {
AstTreeVariable *variable = astTreeRoot->variables.data[i];
switch (variable->value->token) {
case AST_TREE_TOKEN_FUNCTION:
- codeGeneratorAstTreeFunction(variable->name_begin, variable->name_end,
- *variable->value, codes);
+ if (!codeGeneratorAstTreeFunction(variable->name_begin,
+ variable->name_end, *variable->value,
+ codes)) {
+ return NULL;
+ }
continue;
case AST_TREE_TOKEN_KEYWORD_PRINT:
- generateCodePushCode(
- codes,
- createGenerateCode(NULL, NULL, CODE_GENERATOR_INSTRUCTION_PRINT));
- continue;
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
case AST_TREE_TOKEN_NONE:
}
printLog("Bad token %d", variable->value->token);
+ return NULL;
}
return codes;
@@ -84,8 +87,30 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end,
case AST_TREE_TOKEN_KEYWORD_PRINT:
generateCodePushCode(
codes, createGenerateCode(label_begin, label_end,
- CODE_GENERATOR_INSTRUCTION_PRINT));
+ CODE_GENERATOR_INSTRUCTION_PRINT, NULL));
+ goto OK;
+ case AST_TREE_TOKEN_FUNCTION_CALL: {
+ AstTreeFunctionCall *metadata = tree.metadata;
+ AstTree *function = metadata->function;
+ if (metadata->parameters_size != 0) {
+ printLog("Not implemented");
+ exit(0);
+ }
+ if (function->token != AST_TREE_TOKEN_IDENTIFIER) {
+ printLog("Not implemented");
+ exit(0);
+ }
+ AstTreeIdentifier *function_metadata = function->metadata;
+ CodeGeneratorCall *callMetadata = a404m_malloc(sizeof(*callMetadata));
+ callMetadata->label_begin = function_metadata->name_begin;
+ callMetadata->label_end = function_metadata->name_end;
+ generateCodePushCode(codes,
+ createGenerateCode(label_begin, label_end,
+ CODE_GENERATOR_INSTRUCTION_CALL,
+ callMetadata));
+ }
goto OK;
+ case AST_TREE_TOKEN_IDENTIFIER:
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_TYPE_FUNCTION:
case AST_TREE_TOKEN_TYPE_VOID:
@@ -98,9 +123,9 @@ bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end,
label_end = NULL;
}
- generateCodePushCode(codes,
- createGenerateCode(label_begin, label_end,
- CODE_GENERATOR_INSTRUCTION_RET));
+ generateCodePushCode(codes, createGenerateCode(label_begin, label_end,
+ CODE_GENERATOR_INSTRUCTION_RET,
+ NULL));
return true;
}
@@ -154,6 +179,18 @@ char *codeGeneratorToFlatASM(const CodeGeneratorCodes *codes) {
strlen(INST));
}
continue;
+ case CODE_GENERATOR_INSTRUCTION_CALL: {
+ CodeGeneratorCall *metadata = code.metadata;
+ constexpr char CALL_INST[] = "call ";
+ codeGeneratorAppendFlatASMCommand(&fasm, &fasm_size, &fasm_inserted,
+ CALL_INST, strlen(CALL_INST));
+ codeGeneratorAppendFlatASMCommand(
+ &fasm, &fasm_size, &fasm_inserted, metadata->label_begin,
+ metadata->label_end - metadata->label_begin);
+ codeGeneratorAppendFlatASMCommand(&fasm, &fasm_size, &fasm_inserted, "\n",
+ 1);
+ }
+ continue;
case CODE_GENERATOR_INSTRUCTION_RET: {
constexpr char INST[] = "ret\n";
codeGeneratorAppendFlatASMCommand(&fasm, &fasm_size, &fasm_inserted, INST,
diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h
index f9ac6c9..94552ed 100644
--- a/src/compiler/code-generator.h
+++ b/src/compiler/code-generator.h
@@ -6,6 +6,7 @@
typedef enum CodeGeneratorInstruction : uint8_t {
CODE_GENERATOR_INSTRUCTION_PRINT,
+ CODE_GENERATOR_INSTRUCTION_CALL,
CODE_GENERATOR_INSTRUCTION_RET,
} CodeGeneratorInstruction;
@@ -13,8 +14,14 @@ typedef struct CodeGeneratorCode {
char *label_begin;
char *label_end;
CodeGeneratorInstruction instruction;
+ void *metadata;
} CodeGeneratorCode;
+typedef struct CodeGeneratorCall {
+ char *label_begin;
+ char *label_end;
+} CodeGeneratorCall;
+
typedef struct CodeGeneratorCodes {
CodeGeneratorCode *codes;
size_t codes_size;
@@ -23,7 +30,7 @@ typedef struct CodeGeneratorCodes {
void codeGeneratorDelete(CodeGeneratorCodes *code);
CodeGeneratorCode createGenerateCode(char *label_begin, char *label_end,
- CodeGeneratorInstruction instruction);
+ CodeGeneratorInstruction instruction,void *metadata);
CodeGeneratorCode *newGenerateCode(char *label_begin, char *label_end,
CodeGeneratorInstruction instruction);
@@ -32,8 +39,9 @@ void generateCodePushCode(CodeGeneratorCodes *codes, CodeGeneratorCode code);
CodeGeneratorCodes *codeGenerator(AstTreeRoot *astTreeRoot);
-bool codeGeneratorAstTreeFunction(char *label_begin,char *label_end,AstTree astTree, CodeGeneratorCodes *codes);
+bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end,
+ AstTree astTree, CodeGeneratorCodes *codes);
char *codeGeneratorToFlatASM(const CodeGeneratorCodes *codes);
-bool codeGeneratorFlatASMExec(const char *filePath,const char *fasm);
+bool codeGeneratorFlatASMExec(const char *filePath, const char *fasm);
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:
diff --git a/src/compiler/parser.h b/src/compiler/parser.h
index 7d98074..fb65358 100644
--- a/src/compiler/parser.h
+++ b/src/compiler/parser.h
@@ -22,6 +22,8 @@ typedef enum ParserToken {
PARSER_TOKEN_FUNCTION_DEFINITION,
+ PARSER_TOKEN_FUNCTION_CALL,
+
PARSER_TOKEN_NONE,
} ParserToken;
@@ -63,9 +65,14 @@ typedef struct ParserNodeArray {
size_t size;
} ParserNodeArray;
+typedef struct ParserNodeFunctionCall {
+ ParserNode *function;
+ ParserNodeArray *params;
+} ParserNodeFunctionCall;
+
typedef ParserNode ParserNodeEOLMetadata;
-void parserNodePrint(const ParserNode *node,int indent);
+void parserNodePrint(const ParserNode *node, int indent);
void parserNodeDelete(ParserNode *node);
ParserNode *parser(LexerNodeArray lexed);