summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-01-24 04:12:03 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-01-24 04:12:03 +0330
commit5d46c19b25a05a289ccecfa38bc0be849af87877 (patch)
tree04498dd1e3ece62449f96864c0c8d1bd7ebc37f4
parent76272a881916b466f42f78ba16c696a843628d08 (diff)
add types and type checking (not complete)
-rw-r--r--Makefile3
-rw-r--r--src/compiler/ast-tree.c245
-rw-r--r--src/compiler/ast-tree.h29
-rw-r--r--src/compiler/code-generator.c7
-rw-r--r--src/compiler/lexer.c7
-rw-r--r--src/compiler/parser.c101
-rw-r--r--test/main.felan7
7 files changed, 318 insertions, 81 deletions
diff --git a/Makefile b/Makefile
index 4e1eb13..afdc991 100644
--- a/Makefile
+++ b/Makefile
@@ -56,6 +56,9 @@ test: $(EXEC_FILE)
val-test: $(EXEC_FILE)
valgrind --log-file="val.log" --leak-check=full --track-origins=yes --show-leak-kinds=all -s $(EXEC_FILE) test/main.felan build/out
+gdb-test: $(EXEC_FILE)
+ gdb $(EXEC_FILE) test/main.felan build/out
+
# $@ = left hand of :
# $< = right hand of : first one of them
# $^ = right hand of : all
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 3fe867e..76ee706 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -6,9 +6,9 @@
#include <stdlib.h>
const char *AST_TREE_TOKEN_STRINGS[] = {
- "AST_TREE_TOKEN_FUNCTION",
- "AST_TREE_TOKEN_KEYWORD_PRINT",
- "AST_TREE_TOKEN_NONE",
+ "AST_TREE_TOKEN_FUNCTION", "AST_TREE_TOKEN_KEYWORD_PRINT",
+ "AST_TREE_TOKEN_NONE", "AST_TREE_TOKEN_TYPE_FUNCTION",
+ "AST_TREE_TOKEN_TYPE_VOID",
};
void astTreePrint(const AstTree *tree, int indent) {
@@ -16,20 +16,48 @@ void astTreePrint(const AstTree *tree, int indent) {
printf(" ");
printf("{token=\"%s\"", AST_TREE_TOKEN_STRINGS[tree->token]);
switch (tree->token) {
- case AST_TREE_TOKEN_FUNCTION:
- AstTreeScope *metadata = tree->metadata;
+ case AST_TREE_TOKEN_FUNCTION: {
+ AstTreeFunction *metadata = tree->metadata;
printf(",\n");
for (int i = 0; i < indent; ++i)
printf(" ");
+ printf("arguments=[\n");
+ for (size_t i = 0; i < metadata->arguments_size; ++i) {
+ // astTreePrint(metadata->arguments[i], indent + 1); // TODO: do it
+ printf(",\n");
+ }
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("],\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
printf("expressions=[\n");
- for (size_t i = 0; i < metadata->expressions_size; ++i) {
- astTreePrint(&metadata->expressions[i], indent + 1);
+ for (size_t i = 0; i < metadata->scope.expressions_size; ++i) {
+ astTreePrint(&metadata->scope.expressions[i], indent + 1);
printf(",\n");
}
for (int i = 0; i < indent; ++i)
printf(" ");
printf("]");
+ }
+ goto RETURN_SUCCESS;
case AST_TREE_TOKEN_KEYWORD_PRINT:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ goto RETURN_SUCCESS;
+ case AST_TREE_TOKEN_TYPE_FUNCTION: {
+ AstTreeTypeFunction *metadata = tree->metadata;
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("arguments=[\n");
+ for (size_t i = 0; i < metadata->arguments_size; ++i) {
+ astTreePrint(metadata->arguments[i], indent + 1);
+ printf(",\n");
+ }
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("]");
+ }
goto RETURN_SUCCESS;
case AST_TREE_TOKEN_NONE:
}
@@ -54,16 +82,30 @@ void astTreeRootPrint(const AstTreeRoot *root) {
void astTreeDestroy(AstTree tree) {
switch (tree.token) {
- case AST_TREE_TOKEN_FUNCTION:
+ case AST_TREE_TOKEN_FUNCTION: {
AstTreeScope *metadata = tree.metadata;
for (size_t i = 0; i < metadata->expressions_size; ++i) {
astTreeDestroy(metadata->expressions[i]);
}
free(metadata->expressions);
free(metadata);
+ }
+ return;
case AST_TREE_TOKEN_KEYWORD_PRINT:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ return;
+ case AST_TREE_TOKEN_TYPE_FUNCTION: {
+ AstTreeTypeFunction *metadata = tree.metadata;
+ for (size_t i = 0; i < metadata->arguments_size; ++i) {
+ astTreeDelete(metadata->arguments[i]);
+ }
+ free(metadata->arguments);
+ free(metadata->returnType);
+ free(metadata);
+ }
return;
case AST_TREE_TOKEN_NONE:
+ break;
}
printLog("Bad token '%d'", tree.token);
exit(1);
@@ -128,13 +170,23 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
ParserNode *node = (ParserNodeEOLMetadata *)nodes->data[i]->metadata;
ParserNodeVariableMetadata *node_metadata = node->metadata;
- // TODO: check type
- AstTree *tree = astTreeParse(node_metadata->value, &root->variables, 1);
- if (tree == NULL) {
+ AstTree *type = astTreeParse(node_metadata->type, &root->variables, 1);
+ if (type == NULL) {
+ goto RETURN_ERROR;
+ }
+
+ AstTree *value = astTreeParse(node_metadata->value, &root->variables, 1);
+ if (value == NULL) {
goto RETURN_ERROR;
}
- root->variables.data[i]->value = tree;
+ if (!hasTypeOf(value, type)) {
+ printLog("Type mismatch");
+ goto RETURN_ERROR;
+ }
+
+ root->variables.data[i]->type = type;
+ root->variables.data[i]->value = value;
}
return root;
@@ -163,14 +215,16 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables *variables,
return newAstTree(AST_TREE_TOKEN_KEYWORD_PRINT, NULL);
case PARSER_TOKEN_FUNCTION_DEFINITION:
return astTreeParseFunction(parserNode, variables, variables_size);
+ case PARSER_TOKEN_TYPE_FUNCTION:
+ return astTreeParseTypeFunction(parserNode, variables, variables_size);
+ case PARSER_TOKEN_TYPE_VOID:
+ return newAstTree(AST_TREE_TOKEN_TYPE_VOID, NULL);
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_TYPE_VOID:
- case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_NONE:
case PARSER_TOKEN_ROOT:
}
@@ -182,14 +236,55 @@ AstTree *astTreeParseFunction(ParserNode *parserNode,
AstTreeVariables *variables,
size_t variables_size) {
ParserNodeFunctionDefnitionMetadata *node_metadata = parserNode->metadata;
+ ParserNodeArray *node_arguments = node_metadata->arguments->metadata;
ParserNodeArray *body = node_metadata->body->metadata;
- AstTreeScope *scope = a404m_malloc(sizeof(*scope));
-
size_t expressions_size = 0;
- scope->expressions =
- a404m_malloc(expressions_size * sizeof(*scope->expressions));
- scope->expressions_size = 0;
+ AstTreeScope scope = {
+ .expressions =
+ a404m_malloc(expressions_size * sizeof(*scope.expressions)),
+ .expressions_size = 0,
+ .variables = NULL,
+ .variables_size = 0,
+ };
+
+ AstTreeFunction *function = a404m_malloc(sizeof(*function));
+
+ size_t arguments_size = 0;
+ function->arguments =
+ a404m_malloc(arguments_size * sizeof(*function->arguments));
+ function->arguments_size = 0;
+
+ if ((function->returnType = astTreeParse(node_metadata->returnType, variables,
+ variables_size)) == NULL) {
+ goto RETURN_ERROR;
+ }
+
+ for (size_t i = 0; i < node_arguments->size; ++i) {
+ ParserNode *arg = node_arguments->data[i];
+ ParserNodeVariableMetadata *arg_metadata = arg->metadata;
+ if (arg_metadata->value != NULL) {
+ printLog("arguments can't have default values (for now)");
+ goto RETURN_ERROR;
+ }
+
+ AstTree *type = astTreeParse(arg_metadata->type, variables, variables_size);
+ if (type == NULL) {
+ goto RETURN_ERROR;
+ }
+
+ if (function->arguments_size == arguments_size) {
+ arguments_size += arguments_size / 2 + 1;
+ function->arguments = a404m_realloc(
+ function->arguments, arguments_size * sizeof(*function->arguments));
+ }
+
+ function->arguments[function->arguments_size].value = NULL;
+ function->arguments[function->arguments_size].type = type;
+ function->arguments[function->arguments_size].name_begin = arg_metadata->name->str_begin;
+ function->arguments[function->arguments_size].name_end = arg_metadata->name->str_end;
+ function->arguments_size += 1;
+ }
for (size_t i = 0; i < body->size; ++i) {
ParserNode *eol = body->data[i];
@@ -204,27 +299,117 @@ AstTree *astTreeParseFunction(ParserNode *parserNode,
goto RETURN_ERROR;
}
- if (expressions_size == scope->expressions_size) {
+ if (expressions_size == scope.expressions_size) {
expressions_size += expressions_size / 2 + 1;
- scope->expressions = a404m_realloc(
- scope->expressions, expressions_size * sizeof(*scope->expressions));
+ scope.expressions = a404m_realloc(
+ scope.expressions, expressions_size * sizeof(*scope.expressions));
}
- scope->expressions[scope->expressions_size] = *tree;
- scope->expressions_size += 1;
+ scope.expressions[scope.expressions_size] = *tree;
+ scope.expressions_size += 1;
free(tree);
}
- scope->expressions =
- a404m_realloc(scope->expressions,
- scope->expressions_size * sizeof(*scope->expressions));
+ scope.expressions = a404m_realloc(
+ scope.expressions, scope.expressions_size * sizeof(*scope.expressions));
+
+ function->scope = scope;
- AstTree *result = newAstTree(AST_TREE_TOKEN_FUNCTION, scope);
+ AstTree *result = newAstTree(AST_TREE_TOKEN_FUNCTION, function);
return result;
RETURN_ERROR:
- free(scope->expressions);
- free(scope);
+ free(function);
+ free(scope.expressions);
+ return NULL;
+}
+
+AstTree *astTreeParseTypeFunction(ParserNode *parserNode,
+ AstTreeVariables *variables,
+ size_t variables_size) {
+ ParserNodeTypeFunctionMetadata *metadata = parserNode->metadata;
+ ParserNodeArray *node_arguments = metadata->arguments->metadata;
+
+ AstTreeTypeFunction *typeFunction = a404m_malloc(sizeof(*typeFunction));
+
+ size_t arguments_size = 0;
+ typeFunction->arguments =
+ a404m_malloc(arguments_size * sizeof(*typeFunction->arguments));
+ typeFunction->arguments_size = 0;
+
+ for (size_t i = 0; i < node_arguments->size; ++i) {
+ ParserNodeVariableMetadata *arg_metadata =
+ node_arguments->data[i]->metadata;
+ if (arg_metadata->value != NULL) {
+ printLog("arguments can't have default values (for now)");
+ goto RETURN_ERROR;
+ }
+
+ AstTree *type = astTreeParse(arg_metadata->type, variables, variables_size);
+ if (type == NULL) {
+ goto RETURN_ERROR;
+ }
+
+ if (typeFunction->arguments_size == arguments_size) {
+ arguments_size += arguments_size / 2 + 1;
+ typeFunction->arguments =
+ a404m_realloc(typeFunction->arguments,
+ arguments_size * sizeof(*typeFunction->arguments));
+ }
+
+ typeFunction->arguments[typeFunction->arguments_size] = type;
+ typeFunction->arguments_size += 1;
+ }
+
+ if ((typeFunction->returnType = astTreeParse(metadata->returnType, variables,
+ variables_size)) == NULL) {
+ goto RETURN_ERROR;
+ }
+
+ AstTree *tree = a404m_malloc(sizeof(*tree));
+ tree->metadata = typeFunction;
+ tree->token = AST_TREE_TOKEN_TYPE_FUNCTION;
+ return tree;
+
+RETURN_ERROR:
return NULL;
}
+
+bool hasTypeOf(AstTree *value, AstTree *type) {
+ switch (type->token) {
+ case AST_TREE_TOKEN_TYPE_FUNCTION:
+ AstTreeTypeFunction *typeMetadata = type->metadata;
+ switch (value->token) {
+ case AST_TREE_TOKEN_FUNCTION: {
+ AstTreeFunction *valueMetadata = value->metadata;
+ if (typeMetadata->arguments_size != valueMetadata->arguments_size) {
+ return false;
+ }
+ for (size_t i = 0; i < typeMetadata->arguments_size; ++i) {
+ if (!typeIsEqual(typeMetadata->arguments[i],
+ valueMetadata->arguments[i].type)) {
+ return false;
+ }
+ }
+ return typeIsEqual(typeMetadata->returnType, valueMetadata->returnType);
+ }
+ case AST_TREE_TOKEN_KEYWORD_PRINT:
+ case AST_TREE_TOKEN_TYPE_FUNCTION:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ return false;
+ case AST_TREE_TOKEN_NONE:
+ }
+ goto ERROR;
+ case AST_TREE_TOKEN_FUNCTION:
+ case AST_TREE_TOKEN_KEYWORD_PRINT:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ return false;
+ case AST_TREE_TOKEN_NONE:
+ }
+ERROR:
+ printLog("Bad token '%d'", type->token);
+ exit(1);
+}
+
+bool typeIsEqual(AstTree *type0, AstTree *type1) { return true; }
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 758d113..23f0b9c 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -6,12 +6,11 @@
typedef enum AstTreeToken {
AST_TREE_TOKEN_FUNCTION,
AST_TREE_TOKEN_KEYWORD_PRINT,
+ AST_TREE_TOKEN_TYPE_FUNCTION,
+ AST_TREE_TOKEN_TYPE_VOID,
AST_TREE_TOKEN_NONE,
} AstTreeToken;
-typedef struct AstTreeType {
-} AstTreeType;
-
typedef struct AstTree {
AstTreeToken token;
void *metadata;
@@ -20,7 +19,7 @@ typedef struct AstTree {
typedef struct AstTreeVariable {
char *name_begin;
char *name_end;
- AstTreeType type;
+ AstTree *type;
AstTree *value;
} AstTreeVariable;
@@ -40,9 +39,22 @@ typedef struct AstTreeScope {
size_t expressions_size;
} AstTreeScope;
+typedef struct AstTreeFunction {
+ AstTreeVariable *arguments;
+ size_t arguments_size;
+ AstTreeScope scope;
+ AstTree *returnType;
+} AstTreeFunction;
+
+typedef struct AstTreeTypeFunction {
+ AstTree **arguments;
+ size_t arguments_size;
+ AstTree *returnType;
+} AstTreeTypeFunction;
+
extern const char *AST_TREE_TOKEN_STRINGS[];
-void astTreePrint(const AstTree *tree,int indent);
+void astTreePrint(const AstTree *tree, int indent);
void astTreeRootPrint(const AstTreeRoot *root);
void astTreeDestroy(AstTree tree);
@@ -62,3 +74,10 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables *variables,
AstTree *astTreeParseFunction(ParserNode *parserNode,
AstTreeVariables *variables,
size_t variables_size);
+
+AstTree *astTreeParseTypeFunction(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 67fba4c..932202a 100644
--- a/src/compiler/code-generator.c
+++ b/src/compiler/code-generator.c
@@ -73,10 +73,11 @@ CodeGeneratorCodes *codeGenerator(AstTreeRoot *astTreeRoot) {
bool codeGeneratorAstTreeFunction(char *label_begin, char *label_end,
AstTree astTree, CodeGeneratorCodes *codes) {
- AstTreeScope *scope = astTree.metadata;
+ AstTreeFunction *metadata = astTree.metadata;
+ AstTreeScope scope = metadata->scope;
- for (size_t i = 0; i < scope->expressions_size; ++i) {
- AstTree tree = scope->expressions[i];
+ for (size_t i = 0; i < scope.expressions_size; ++i) {
+ AstTree tree = scope.expressions[i];
switch (tree.token) {
case AST_TREE_TOKEN_KEYWORD_PRINT:
generateCodePushCode(
diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c
index f248641..8994bce 100644
--- a/src/compiler/lexer.c
+++ b/src/compiler/lexer.c
@@ -123,14 +123,11 @@ LexerNodeArray lexer(char *str) {
lexerPushClear(&result, &result_size, iter, &node_str_begin,
&node_token, LEXER_TOKEN_NUMBER);
}
- } else if (isSymbol(c)) {
- if (node_token != LEXER_TOKEN_SYMBOL) {
+ } else if (isSymbol(c) || isSingleSymbol(c)) {
+ if (node_token != LEXER_TOKEN_SYMBOL || isSingleSymbol(*node_str_begin)) {
lexerPushClear(&result, &result_size, iter, &node_str_begin,
&node_token, LEXER_TOKEN_SYMBOL);
}
- } else if (isSingleSymbol(c)) {
- lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token,
- LEXER_TOKEN_SYMBOL);
} else {
RETURN_ERROR:
free(result.data);
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 12c7ca9..7ec9e1c 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -166,7 +166,23 @@ void parserNodePrint(const ParserNode *node, int indent) {
printf(" ");
}
goto RETURN_SUCCESS;
- case PARSER_TOKEN_TYPE_FUNCTION:
+ case PARSER_TOKEN_TYPE_FUNCTION: {
+ const ParserNodeTypeFunctionMetadata *metadata = node->metadata;
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("arguments=\n");
+ parserNodePrint(metadata->arguments, indent + 1);
+ printf(",\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ printf("returnType=\n");
+ parserNodePrint(metadata->returnType, indent + 1);
+ printf("\n");
+ for (int i = 0; i < indent; ++i)
+ printf(" ");
+ }
+ goto RETURN_SUCCESS;
case PARSER_TOKEN_NONE:
}
printLog("Bad token '%d'", node->token);
@@ -218,7 +234,14 @@ void parserNodeDelete(ParserNode *node) {
free(metadata);
}
goto RETURN_SUCCESS;
- case PARSER_TOKEN_TYPE_FUNCTION:
+ case PARSER_TOKEN_TYPE_FUNCTION: {
+ ParserNodeTypeFunctionMetadata *metadata = node->metadata;
+ parserNodeDelete(metadata->arguments);
+ parserNodeDelete(metadata->returnType);
+ free(metadata);
+ }
+ goto RETURN_SUCCESS;
+
case PARSER_TOKEN_NONE:
}
printLog("Bad token '%d'", node->token);
@@ -416,7 +439,6 @@ ParserNode *parserComma(LexerNode *node, LexerNode *begin, ParserNode *parent) {
return NULL;
}
}
- printLog("%s", PARSER_TOKEN_STRINGS[parserNodeBefore->token]);
return node->parserNode = parserNodeBefore->parent = newParserNode(
PARSER_TOKEN_SYMBOL_COMMA, node->str_begin, node->str_end,
(ParserNodeEOLMetadata *)parserNodeBefore, parent);
@@ -504,11 +526,6 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
if (bodyNode >= end || bodyNode->parserNode == NULL) {
body = NULL;
- // TODO: implement
- // if body is not there then it is a function type not a function
- // definition
- printLog("Not implemented");
- return NULL;
} else {
body = getUntilCommonParent(bodyNode->parserNode, parent);
if (body == NULL || body->token != PARSER_TOKEN_SYMBOL_CURLY_BRACKET) {
@@ -534,16 +551,28 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
return NULL;
}
- ParserNodeFunctionDefnitionMetadata *metadata =
- a404m_malloc(sizeof(*metadata));
+ if (body != NULL) {
+ ParserNodeFunctionDefnitionMetadata *metadata =
+ a404m_malloc(sizeof(*metadata));
- metadata->body = body;
- metadata->arguments = params;
- metadata->returnType = retType;
+ metadata->body = body;
+ metadata->arguments = params;
+ metadata->returnType = retType;
- return params->parent = retType->parent = body->parent = node->parserNode =
- newParserNode(PARSER_TOKEN_FUNCTION_DEFINITION, params->str_begin,
- body->str_end, metadata, parent);
+ return params->parent = retType->parent = body->parent = node->parserNode =
+ newParserNode(PARSER_TOKEN_FUNCTION_DEFINITION,
+ params->str_begin, body->str_end, metadata,
+ parent);
+ } else {
+ ParserNodeTypeFunctionMetadata *metadata = a404m_malloc(sizeof(*metadata));
+
+ metadata->arguments = params;
+ metadata->returnType = retType;
+
+ return params->parent = retType->parent = node->parserNode =
+ newParserNode(PARSER_TOKEN_TYPE_FUNCTION, params->str_begin,
+ retType->str_end, metadata, parent);
+ }
}
ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end,
@@ -561,7 +590,8 @@ ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end,
ParserNode *name = getUntilCommonParent(nameNode->parserNode, parent);
if (name->token != PARSER_TOKEN_IDENTIFIER) {
- printLog("Name should be identifier");
+ printLog("Name should be identifier but got '%s'",
+ PARSER_TOKEN_STRINGS[name->token]);
return NULL;
} else {
name->parent = variableNode;
@@ -570,6 +600,7 @@ ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end,
LexerNode *node1 = node + 1;
ParserNode *type;
+ ParserNode *value;
if (node1 >= end) {
printLog("Bad variable definition");
@@ -588,21 +619,31 @@ ParserNode *parserVariable(LexerNode *node, LexerNode *begin, LexerNode *end,
return NULL;
}
type->parent = variableNode;
- printLog("Here is");
+ for (++node1; node1 < end && getUntilCommonParent(node1->parserNode,
+ parent) == variableNode;
+ ++node1) {
+ }
+ if (node1 < end && node1->token == LEXER_TOKEN_SYMBOL_COLON) {
+ node1->parserNode = variableNode;
+ } else {
+ node1 = NULL;
+ value = NULL;
+ }
}
- LexerNode *valueNode = node + 2;
- ParserNode *value;
-
- if (valueNode >= end || valueNode->parserNode == NULL) {
- value = NULL;
- } else {
- value = getUntilCommonParent(valueNode->parserNode, parent);
- if (!isValue(value)) {
+ if (node1 != NULL) {
+ LexerNode *valueNode = node1 + 1;
+ if (valueNode >= end || valueNode->parserNode == NULL) {
printLog("No value");
return NULL;
+ } else {
+ value = getUntilCommonParent(valueNode->parserNode, parent);
+ if (!isValue(value)) {
+ printLog("No value");
+ return NULL;
+ }
+ value->parent = variableNode;
}
- value->parent = variableNode;
}
ParserNodeVariableMetadata *metadata = a404m_malloc(sizeof(*metadata));
@@ -626,13 +667,9 @@ RETURN_ERROR:
}
bool isAllArguments(const ParserNodeArray *nodes) {
- printLog("%d", nodes->size);
for (size_t i = 0; i < nodes->size; ++i) {
const ParserNode *node = nodes->data[i];
if (node->token != PARSER_TOKEN_SYMBOL_COMMA && i + 1 != nodes->size) {
- printLog("%d %s %d %.*s", i, PARSER_TOKEN_STRINGS[node->token],
- node->token, (int)(node->str_end - node->str_begin),
- node->str_begin);
return false;
}
}
@@ -663,6 +700,7 @@ bool isExpression(ParserNode *node) {
bool isType(ParserNode *node) {
switch (node->token) {
case PARSER_TOKEN_TYPE_VOID:
+ case PARSER_TOKEN_TYPE_FUNCTION:
return true;
case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_CONSTANT:
@@ -670,7 +708,6 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_FUNCTION_DEFINITION:
case PARSER_TOKEN_KEYWORD_PRINT:
case PARSER_TOKEN_ROOT:
- case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_SYMBOL_EOL:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
case PARSER_TOKEN_SYMBOL_COMMA:
diff --git a/test/main.felan b/test/main.felan
index 6d26e52..92881c9 100644
--- a/test/main.felan
+++ b/test/main.felan
@@ -1,8 +1,3 @@
-main :: () -> void {
- print;
-};
-
-a :: (b:void,c:void) -> void {
- print;
+main : ()->void : () -> void {
print;
};