]> git.deglebe.com Git - barec/barec.git/commitdiff
properly parse function calls
authorThomas Bruce <tdb@tdbio.me>
Thu, 20 Feb 2025 05:56:41 +0000 (00:56 -0500)
committerThomas Bruce <tdb@tdbio.me>
Thu, 20 Feb 2025 05:56:41 +0000 (00:56 -0500)
lexer.h
parser.c

diff --git a/lexer.h b/lexer.h
index bfd7d19c850a06feb4004ef0f763c4f6c79edde6..4fc77dd0003847ab0fa06909a5226c6f0fc3b735 100644 (file)
--- 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
index a02250e906f104b0bf79e19ccdeca81ad411bdd1..0bac1fafa0db9f92e39f13a90596d7bbef2e52e7 100644 (file)
--- 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");