From 393d64572eb4656a3f53b90b7dd8fd25fb86c6d1 Mon Sep 17 00:00:00 2001 From: Fabrizio Pietrucci Date: Mon, 13 May 2024 00:46:05 +0200 Subject: [PATCH] Refactor function AST --- include/jstar/parse/ast.h | 47 ++++++++++++++++----------------------- src/compiler.c | 43 +++++++++++++++++------------------ src/parse/ast.c | 39 +++++++++++++------------------- src/parse/parser.c | 32 ++++++++++---------------- 4 files changed, 67 insertions(+), 94 deletions(-) diff --git a/include/jstar/parse/ast.h b/include/jstar/parse/ast.h index b2d2a64c..3d90e32b 100644 --- a/include/jstar/parse/ast.h +++ b/include/jstar/parse/ast.h @@ -137,15 +137,21 @@ typedef enum JStarStmtType { typedef struct FormalArg { enum { - ARG, + SIMPLE, UNPACK } type; union { - JStarIdentifier arg; + JStarIdentifier simple; ext_vector(JStarIdentifier) unpack; } as; } FormalArg; +typedef struct FormalArgs { + ext_vector(FormalArg) args; + ext_vector(JStarExpr*) defaults; + JStarIdentifier vararg; +} FormalArgs; + struct JStarDecl { ext_vector(JStarExpr*) decorators; bool isStatic; @@ -157,17 +163,13 @@ struct JStarDecl { } var; struct { JStarIdentifier id; - ext_vector(FormalArg) formalArgs; - ext_vector(JStarExpr*) defArgs; - JStarIdentifier vararg; + FormalArgs formalArgs; bool isGenerator; JStarStmt* body; } fun; struct { JStarIdentifier id; - ext_vector(FormalArg) formalArgs; - ext_vector(JStarExpr*) defArgs; - JStarIdentifier vararg; + FormalArgs formalArgs; } native; struct { JStarIdentifier id; @@ -245,11 +247,8 @@ JSTAR_API bool jsrIdentifierEq(const JStarIdentifier* id1, const JStarIdentifier // EXPRESSION NODES // ----------------------------------------------------------------------------- -JSTAR_API JStarExpr* jsrFuncLiteral(int line, ext_vector(FormalArg) args, - ext_vector(JStarExpr*) defArgs, JStarTok* vararg, - bool isGenerator, JStarStmt* body); -JSTAR_API JStarExpr* jsrTernaryExpr(int line, JStarExpr* cond, JStarExpr* thenExpr, - JStarExpr* elseExpr); +JSTAR_API JStarExpr* jsrFuncLiteral(int line, const FormalArgs* args, bool isGenerator, JStarStmt* body); +JSTAR_API JStarExpr* jsrTernaryExpr(int line, JStarExpr* cond, JStarExpr* thenExpr, JStarExpr* elseExpr); JSTAR_API JStarExpr* jsrCompundAssExpr(int line, JStarTokType op, JStarExpr* lval, JStarExpr* rval); JSTAR_API JStarExpr* jsrAccessExpr(int line, JStarExpr* left, const char* name, size_t length); JSTAR_API JStarExpr* jsrSuperLiteral(int line, JStarTok* name, JStarExpr* args); @@ -276,21 +275,13 @@ JSTAR_API void jsrExprFree(JStarExpr* e); // STATEMENT NODES // ----------------------------------------------------------------------------- -JSTAR_API JStarStmt* jsrFuncDecl(int line, JStarTok* name, ext_vector(FormalArg) args, - ext_vector(JStarExpr*) defArgs, JStarTok* vararg, bool isGenerator, - JStarStmt* body); -JSTAR_API JStarStmt* jsrNativeDecl(int line, JStarTok* name, ext_vector(FormalArg) args, - ext_vector(JStarExpr*) defArgs, JStarTok* vararg); -JSTAR_API JStarStmt* jsrForStmt(int line, JStarStmt* init, JStarExpr* cond, JStarExpr* act, - JStarStmt* body); -JSTAR_API JStarStmt* jsrClassDecl(int line, JStarTok* clsName, JStarExpr* sup, - ext_vector(JStarStmt*) methods); -JSTAR_API JStarStmt* jsrImportStmt(int line, ext_vector(JStarIdentifier) modules, - ext_vector(JStarIdentifier) names, JStarTok* as); -JSTAR_API JStarStmt* jsrVarDecl(int line, bool isUnpack, ext_vector(JStarIdentifier) ids, - JStarExpr* init); -JSTAR_API JStarStmt* jsrTryStmt(int line, JStarStmt* blck, ext_vector(JStarStmt*) excs, - JStarStmt* ensure); +JSTAR_API JStarStmt* jsrFuncDecl(int line, const JStarTok* name, const FormalArgs* args, bool isGenerator, JStarStmt* body); +JSTAR_API JStarStmt* jsrNativeDecl(int line, JStarTok* name, const FormalArgs* args); +JSTAR_API JStarStmt* jsrForStmt(int line, JStarStmt* init, JStarExpr* cond, JStarExpr* act, JStarStmt* body); +JSTAR_API JStarStmt* jsrClassDecl(int line, JStarTok* clsName, JStarExpr* sup, ext_vector(JStarStmt*) methods); +JSTAR_API JStarStmt* jsrImportStmt(int line, ext_vector(JStarIdentifier) modules, ext_vector(JStarIdentifier) names, JStarTok* as); +JSTAR_API JStarStmt* jsrVarDecl(int line, bool isUnpack, ext_vector(JStarIdentifier) ids, JStarExpr* init); +JSTAR_API JStarStmt* jsrTryStmt(int line, JStarStmt* blck, ext_vector(JStarStmt*) excs, JStarStmt* ensure); JSTAR_API JStarStmt* jsrIfStmt(int line, JStarExpr* cond, JStarStmt* thenStmt, JStarStmt* elseStmt); JSTAR_API JStarStmt* jsrForEachStmt(int line, JStarStmt* varDecl, JStarExpr* iter, JStarStmt* body); JSTAR_API JStarStmt* jsrExceptStmt(int line, JStarExpr* cls, JStarTok* varName, JStarStmt* block); diff --git a/src/compiler.c b/src/compiler.c index 5abb8044..ec151c4c 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -125,7 +125,7 @@ struct Compiler { Local locals[MAX_LOCALS]; Upvalue upvalues[MAX_LOCALS]; - ext_vector(char*) synthetic_names; + ext_vector(char*) syntheticNames; ext_vector(JStarIdentifier)* globals; ext_vector(FwdRef)* fwdRefs; @@ -140,17 +140,16 @@ struct Compiler { static void initCompiler(Compiler* c, JStarVM* vm, Compiler* prev, ObjModule* module, const char* file, FuncType type, ext_vector(JStarIdentifier) * globals, ext_vector(FwdRef) * fwdRefs, JStarStmt* ast) { + vm->currCompiler = c; c->vm = vm; c->module = module; c->file = file; c->prev = prev; c->type = type; - c->synthetic_names = NULL; c->globals = globals; c->fwdRefs = fwdRefs; c->ast = ast; - // 1 For the receiver - c->stackUsage = 1; + c->stackUsage = 1; // 1 for the receiver (always present) c->func = NULL; c->depth = 0; c->localsCount = 0; @@ -158,14 +157,14 @@ static void initCompiler(Compiler* c, JStarVM* vm, Compiler* prev, ObjModule* mo c->tryDepth = 0; c->tryBlocks = NULL; c->hadError = false; - vm->currCompiler = c; + c->syntheticNames = NULL; } static void endCompiler(Compiler* c) { - ext_vec_foreach(char** it, c->synthetic_names) { + ext_vec_foreach(char** it, c->syntheticNames) { free(*it); } - ext_vec_free(c->synthetic_names); + ext_vec_free(c->syntheticNames); if(c->prev != NULL) { c->prev->hadError |= c->hadError; @@ -1712,15 +1711,15 @@ static void compileLoopExitStmt(Compiler* c, JStarStmt* s) { static void compileFormalArg(Compiler* c, const FormalArg* arg, int argIdx, int line) { switch(arg->type) { - case ARG: { - Variable var = declareVar(c, &arg->as.arg, false, line); + case SIMPLE: { + Variable var = declareVar(c, &arg->as.simple, false, line); defineVar(c, &var, line); break; } case UNPACK: { char* name = malloc(sizeof(UNPACK_ARG_FMT) + STRLEN_FOR_INT(int) + 1); sprintf(name, UNPACK_ARG_FMT, argIdx); - ext_vec_push_back(c->synthetic_names, name); + ext_vec_push_back(c->syntheticNames, name); JStarIdentifier id = createIdentifier(name); @@ -1753,9 +1752,9 @@ static void unpackFormalArgs(Compiler* c, ext_vector(FormalArg) args, int line) } static ObjFunction* function(Compiler* c, ObjModule* m, ObjString* name, JStarStmt* s) { - size_t defaults = ext_vec_size(s->as.decl.as.fun.defArgs); - size_t arity = ext_vec_size(s->as.decl.as.fun.formalArgs); - JStarIdentifier* varargName = &s->as.decl.as.fun.vararg; + size_t defaults = ext_vec_size(s->as.decl.as.fun.formalArgs.defaults); + size_t arity = ext_vec_size(s->as.decl.as.fun.formalArgs.args); + const JStarIdentifier* varargName = &s->as.decl.as.fun.formalArgs.vararg; bool isVararg = varargName->name != NULL; // Allocate a new function. We need to push `name` on the stack in case a collection happens @@ -1764,7 +1763,7 @@ static ObjFunction* function(Compiler* c, ObjModule* m, ObjString* name, JStarSt c->func->proto.name = name; pop(c->vm); - addFunctionDefaults(c, &c->func->proto, s->as.decl.as.fun.defArgs); + addFunctionDefaults(c, &c->func->proto, s->as.decl.as.fun.formalArgs.defaults); // Add the receiver. // In the case of functions the receiver is the function itself. @@ -1774,7 +1773,7 @@ static ObjFunction* function(Compiler* c, ObjModule* m, ObjString* name, JStarSt initializeLocal(c, receiverLocal); int argIdx = 0; - ext_vec_foreach(const FormalArg* arg, s->as.decl.as.fun.formalArgs) { + ext_vec_foreach(const FormalArg* arg, s->as.decl.as.fun.formalArgs.args) { compileFormalArg(c, arg, argIdx, s->line); } @@ -1787,7 +1786,7 @@ static ObjFunction* function(Compiler* c, ObjModule* m, ObjString* name, JStarSt emitOpcode(c, OP_GENERATOR, s->line); } - unpackFormalArgs(c, s->as.decl.as.fun.formalArgs, s->line); + unpackFormalArgs(c, s->as.decl.as.fun.formalArgs.args, s->line); JStarStmt* body = s->as.decl.as.fun.body; compileStatements(c, body->as.blockStmt.stmts); @@ -1812,20 +1811,20 @@ static ObjFunction* function(Compiler* c, ObjModule* m, ObjString* name, JStarSt } static ObjNative* native(Compiler* c, ObjModule* m, ObjString* name, JStarStmt* s) { - size_t defCount = ext_vec_size(s->as.decl.as.native.defArgs); - size_t arity = ext_vec_size(s->as.decl.as.native.formalArgs); - JStarIdentifier* vararg = &s->as.decl.as.native.vararg; - bool isVararg = vararg->name != NULL; + size_t defaults = ext_vec_size(s->as.decl.as.fun.formalArgs.defaults); + size_t arity = ext_vec_size(s->as.decl.as.fun.formalArgs.args); + const JStarIdentifier* varargName = &s->as.decl.as.fun.formalArgs.vararg; + bool isVararg = varargName->name != NULL; // Allocate a new native. We need to push `name` on the stack in case a collection happens push(c->vm, OBJ_VAL(name)); - ObjNative* native = newNative(c->vm, c->func->proto.module, arity, defCount, isVararg); + ObjNative* native = newNative(c->vm, c->func->proto.module, arity, defaults, isVararg); native->proto.name = name; pop(c->vm); // Push the native on the stack in case `addFunctionDefaults` triggers a collection push(c->vm, OBJ_VAL(native)); - addFunctionDefaults(c, &native->proto, s->as.decl.as.native.defArgs); + addFunctionDefaults(c, &native->proto, s->as.decl.as.native.formalArgs.defaults); pop(c->vm); return native; diff --git a/src/parse/ast.c b/src/parse/ast.c index 157b23dc..083663f4 100644 --- a/src/parse/ast.c +++ b/src/parse/ast.c @@ -155,11 +155,9 @@ JStarExpr* jsrCompundAssExpr(int line, JStarTokType op, JStarExpr* lval, JStarEx return e; } -JStarExpr* jsrFuncLiteral(int line, ext_vector(FormalArg) args, - ext_vector(JStarExpr*) defArgs, JStarTok* vararg, bool isGenerator, - JStarStmt* body) { +JStarExpr* jsrFuncLiteral(int line, const FormalArgs* args, bool isGenerator, JStarStmt* body) { JStarExpr* e = newExpr(line, JSR_FUNC_LIT); - e->as.funLit.func = jsrFuncDecl(line, &(JStarTok){0}, args, defArgs, vararg, isGenerator, body); + e->as.funLit.func = jsrFuncDecl(line, &(JStarTok){0}, args, isGenerator, body); return e; } @@ -267,26 +265,19 @@ static JStarStmt* newDecl(int line, JStarStmtType type) { // Declarations -JStarStmt* jsrFuncDecl(int line, JStarTok* name, ext_vector(FormalArg) args, - ext_vector(JStarExpr*) defArgs, JStarTok* varargName, bool isGenerator, - JStarStmt* body) { +JStarStmt* jsrFuncDecl(int line, const JStarTok* name, const FormalArgs* args, bool isGenerator, JStarStmt* body) { JStarStmt* f = newDecl(line, JSR_FUNCDECL); f->as.decl.as.fun.id = (JStarIdentifier){name->length, name->lexeme}; - f->as.decl.as.fun.formalArgs = args; - f->as.decl.as.fun.defArgs = defArgs; - f->as.decl.as.fun.vararg = (JStarIdentifier){varargName->length, varargName->lexeme}; - f->as.decl.as.fun.isGenerator = isGenerator; + f->as.decl.as.fun.formalArgs = *args; f->as.decl.as.fun.body = body; + f->as.decl.as.fun.isGenerator = isGenerator; return f; } -JStarStmt* jsrNativeDecl(int line, JStarTok* name, ext_vector(FormalArg) args, - ext_vector(JStarExpr*) defArgs, JStarTok* varargName) { +JStarStmt* jsrNativeDecl(int line, JStarTok* name, const FormalArgs* args) { JStarStmt* n = newDecl(line, JSR_NATIVEDECL); n->as.decl.as.native.id = (JStarIdentifier){name->length, name->lexeme}; - n->as.decl.as.native.formalArgs = args; - n->as.decl.as.native.defArgs = defArgs; - n->as.decl.as.fun.vararg = (JStarIdentifier){varargName->length, varargName->lexeme}; + n->as.decl.as.native.formalArgs = *args; return n; } @@ -463,31 +454,31 @@ void jsrStmtFree(JStarStmt* s) { } case JSR_FUNCDECL: { freeDeclaration(s); - ext_vec_foreach(FormalArg* arg, s->as.decl.as.fun.formalArgs) { + ext_vec_foreach(FormalArg* arg, s->as.decl.as.fun.formalArgs.args) { if (arg->type == UNPACK){ ext_vec_free(arg->as.unpack); } } - ext_vec_free(s->as.decl.as.fun.formalArgs); - ext_vec_foreach(JStarExpr** e, s->as.decl.as.fun.defArgs) { + ext_vec_free(s->as.decl.as.fun.formalArgs.args); + ext_vec_foreach(JStarExpr** e, s->as.decl.as.fun.formalArgs.defaults) { jsrExprFree(*e); } - ext_vec_free(s->as.decl.as.fun.defArgs); + ext_vec_free(s->as.decl.as.fun.formalArgs.defaults); jsrStmtFree(s->as.decl.as.fun.body); break; } case JSR_NATIVEDECL: { freeDeclaration(s); - ext_vec_foreach(FormalArg* arg, s->as.decl.as.fun.formalArgs) { + ext_vec_foreach(FormalArg* arg, s->as.decl.as.fun.formalArgs.args) { if (arg->type == UNPACK){ ext_vec_free(arg->as.unpack); } } - ext_vec_free(s->as.decl.as.native.formalArgs); - ext_vec_foreach(JStarExpr** e, s->as.decl.as.native.defArgs) { + ext_vec_free(s->as.decl.as.fun.formalArgs.args); + ext_vec_foreach(JStarExpr** e, s->as.decl.as.fun.formalArgs.defaults) { jsrExprFree(*e); } - ext_vec_free(s->as.decl.as.native.defArgs); + ext_vec_free(s->as.decl.as.fun.formalArgs.defaults); break; } case JSR_CLASSDECL: { diff --git a/src/parse/parser.c b/src/parse/parser.c index 7a2653f4..26d6c7a4 100644 --- a/src/parse/parser.c +++ b/src/parse/parser.c @@ -337,12 +337,6 @@ static JStarExpr* expression(Parser* p, bool parseTuple); static JStarExpr* literal(Parser* p); static JStarExpr* tupleLiteral(Parser* p); -typedef struct FormalArgs { - ext_vector(FormalArg) arguments; - ext_vector(JStarExpr*) defaults; - JStarTok vararg; -} FormalArgs; - static FormalArg parseUnpackArgument(Parser* p) { ext_vector(JStarIdentifier) names = NULL; require(p, TOK_LPAREN); @@ -380,7 +374,7 @@ static FormalArgs formalArgs(Parser* p, JStarTokType open, JStarTokType close) { arg = parseUnpackArgument(p); } else { JStarTok argument = advance(p); - arg = (FormalArg){.type = ARG, .as = {.arg = createIdentifier(&argument)}}; + arg = (FormalArg){.type = SIMPLE, .as = {.simple = createIdentifier(&argument)}}; } skipNewLines(p); @@ -395,7 +389,7 @@ static FormalArgs formalArgs(Parser* p, JStarTokType open, JStarTokType close) { break; } - ext_vec_push_back(args.arguments, arg); + ext_vec_push_back(args.args, arg); if(!match(p, close)) { require(p, TOK_COMMA); @@ -417,8 +411,8 @@ static FormalArgs formalArgs(Parser* p, JStarTokType open, JStarTokType close) { error(p, "Default argument must be a constant"); } - FormalArg arg = {.type = ARG, .as = {.arg = createIdentifier(&argument)}}; - ext_vec_push_back(args.arguments, arg); + FormalArg arg = {.type = SIMPLE, .as = {.simple = createIdentifier(&argument)}}; + ext_vec_push_back(args.args, arg); ext_vec_push_back(args.defaults, constant); if(!match(p, close)) { @@ -431,7 +425,8 @@ static FormalArgs formalArgs(Parser* p, JStarTokType open, JStarTokType close) { advance(p); skipNewLines(p); - args.vararg = require(p, TOK_IDENTIFIER); + JStarTok vararg = require(p, TOK_IDENTIFIER); + args.vararg = createIdentifier(&vararg); skipNewLines(p); } @@ -748,8 +743,7 @@ static JStarStmt* funcDecl(Parser* p, bool parseCtor) { JStarStmt* body = blockStmt(p); require(p, TOK_END); - JStarStmt* decl = jsrFuncDecl(line, &funcName, args.arguments, args.defaults, &args.vararg, - p->function->isGenerator, body); + JStarStmt* decl = jsrFuncDecl(line, &funcName, &args, p->function->isGenerator, body); endFunction(p); @@ -775,7 +769,7 @@ static JStarStmt* nativeDecl(Parser* p, bool parseCtor) { FormalArgs args = formalArgs(p, TOK_LPAREN, TOK_RPAREN); requireStmtEnd(p); - return jsrNativeDecl(line, &funcName, args.arguments, args.defaults, &args.vararg); + return jsrNativeDecl(line, &funcName, &args); } static JStarStmt* classDecl(Parser* p) { @@ -945,8 +939,8 @@ static JStarStmt* parseProgram(Parser* p) { } // Top level function doesn't have name or arguments, so pass them empty - return jsrFuncDecl(0, &(JStarTok){0}, NULL, NULL, &(JStarTok){0}, false, - jsrBlockStmt(0, stmts)); + FormalArgs args = {0}; + return jsrFuncDecl(0, &(JStarTok){0}, &args, false, jsrBlockStmt(0, stmts)); } // ----------------------------------------------------------------------------- @@ -1294,8 +1288,7 @@ static JStarExpr* funcLiteral(Parser* p) { JStarStmt* body = blockStmt(p); require(p, TOK_END); - JStarExpr* lit = jsrFuncLiteral(line, args.arguments, args.defaults, &args.vararg, - p->function->isGenerator, body); + JStarExpr* lit = jsrFuncLiteral(line, &args, p->function->isGenerator, body); endFunction(p); @@ -1317,8 +1310,7 @@ static JStarExpr* funcLiteral(Parser* p) { ext_vec_push_back(anonFuncStmts, jsrReturnStmt(line, e)); JStarStmt* body = jsrBlockStmt(line, anonFuncStmts); - JStarExpr* lit = jsrFuncLiteral(line, args.arguments, args.defaults, &args.vararg, - p->function->isGenerator, body); + JStarExpr* lit = jsrFuncLiteral(line, &args, p->function->isGenerator, body); endFunction(p);