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;
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 */
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;
}
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) {
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");