From: Thomas Bruce <tdb@tdbio.me>
Date: Thu, 20 Feb 2025 05:56:41 +0000 (-0500)
Subject: properly parse function calls
X-Git-Url: https://git.deglebe.com/r/%22%24slug.html/p/w/m/p/index.html?a=commitdiff_plain;h=a6431d51a8daa891f8e0ee893c32f551025f77b6;p=barec%2Fbarec.git

properly parse function calls
---

diff --git a/lexer.h b/lexer.h
index bfd7d19..4fc77dd 100644
--- a/lexer.h
+++ b/lexer.h
@@ -28,6 +28,7 @@ typedef enum {
 	TK_LBRACE,	// `{`
 	TK_RBRACE,	// `}`
 	TK_SEMICOLON,	// `;`
+	TK_COMMA,
 	TK_GT,		// `>`
 	TK_EOF,		// EOF
 	TK_UNKNOWN	// UNKNOWN
diff --git a/parser.c b/parser.c
index a02250e..0bac1fa 100644
--- a/parser.c
+++ b/parser.c
@@ -20,7 +20,8 @@ typedef enum {
 	AST_BINARY,	// bunary expression
 	AST_NUM,	// numeric literal
 	AST_IDENT,	// identifier
-	AST_DECL	// variable declaration
+	AST_DECL,	// variable declaration
+	AST_CALL	// function calls
 } ASTKind;
 
 typedef struct ASTNode ASTNode;
@@ -35,6 +36,10 @@ struct ASTNode {
 	ASTNode* funcBody; // body block
 	int intValue;	// numeric literals
 	char* identName; // identifiers and operator string in binary nodes
+	ASTNode** args;	// array of argument nodes
+	int argCount; 	// number of arguments
+	ASTNode** params; // array of parameter nodes
+	int paramCount;	// number of parameters
 };
 
 /* utilities for creating new ast nodes */
@@ -136,11 +141,42 @@ static ASTNode* parseFunctionDefinition(void) {
 	char* funcName = strdup(g_currentToken.lexeme);
 	nextToken();
 	expect(TK_LPAREN);
+
+	/* parse parameter list, if any */
+	ASTNode** params = NULL;
+	int paramCount = 0;
+	if (g_currentToken.kind != TK_RPAREN) {
+		while (1) {
+			expect(TK_INT);
+			if (g_currentToken.kind != TK_IDENT) {
+				fprintf(stderr, "Parse err: expected identifier
+						 in parameter list, got '%s'\n",
+						 g_currentToken.lexeme);
+				exit(1);
+			}
+
+			ASTNode* param = newASTNode(AST_DECL);
+			param->identName = strdup(g_currentToken.lexeme);
+			nextToken();
+
+			paramCount++;
+			params = realloc(params, sizeof(ASTNode*) * paramCount);
+			params[paramCount - 1] = param;
+
+			if (g_currentToken.kind == TK_COMMA) 
+				nextToken();
+			else
+				break;
+		}
+	}
 	expect(TK_RPAREN);
+
 	ASTNode* body = parseCompoundStatement();
 	ASTNode* funcNode = newASTNode(AST_FUNCDEF);
 	funcNode->funcName = funcName;
 	funcNode->funcBody = body;
+	funcNode->params = params;
+	funcNode->paramCount = paramCount;
 	return funcNode;
 }
 
@@ -271,6 +307,37 @@ static ASTNode* parseFactor(void) {
 	if (g_currentToken.kind == TK_IDENT) {
 		ASTNode* node = newIdentNode(g_currentToken.lexeme);
 		nextToken();
+
+		/* check if function call */
+		if (g_currentToken.kind == TK_LPAREN) {
+			nextToken();
+			ASTNode** args = NULL;
+			int argCount = 0;
+
+			if (g_currentToken.kind != TK_RPAREN) {
+				while (true) {
+					ASTNode* arg = parseExpression();
+					argCount++;
+					args = realloc(args, sizeof(ASTNode*)
+							* argCount);
+					args[argCount - 1] = arg;
+					if (g_currentToken.kind == TK_COMMA) {
+						nextToken();
+					} else {
+						break;
+					}
+				}
+			}
+			expect(TK_RPAREN);
+
+			/* create func call astnode */
+			ASTNode* callNode = newASTNode(AST_CALL);
+			callNode->left = node;
+			callNode->args = args;
+			callNode->argCount = argCount;
+			return callNode;
+		}
+
 		return node;
 	}
 	if (g_currentToken.kind == TK_NUMBER) {
@@ -391,6 +458,29 @@ static void printAST(ASTNode* node, int indent) {
 			printIndent(indent);
 			printf("Identifier (%s)\n", node->identName);
 			break;
+		case AST_DECL:
+			printIndent(indent);
+			printf("Decl: %s\n", node->identName);
+			if (node->left) {
+				printIndent(indent + 1);
+				printf("Initializer:\n");
+				printAST(node->left, indent + 2);
+			}
+			break;
+		case AST_CALL:
+			printIndent(indent);
+			printf("FunctionCall\n");
+			printIndent(indent + 1);
+			printf("Callee:\n");
+			printAST(node->left, indent + 2);
+			if (node->left, indent + 2) {
+				printIndent(indent + 1);
+				printf("Arguments:\n");
+				for (int i = 0; i < node->argCount; i++) {
+					printAST(node->args[i], indent + 2);
+				}
+			}
+			break;
 		default:
 			printIndent(indent);
 			printf("Unknown AST node kind\n");