Skip to content

Commit

Permalink
Refactor function AST
Browse files Browse the repository at this point in the history
  • Loading branch information
bamless committed May 12, 2024
1 parent a75f224 commit 393d645
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 94 deletions.
47 changes: 19 additions & 28 deletions include/jstar/parse/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
43 changes: 21 additions & 22 deletions src/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -140,32 +140,31 @@ 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;
c->loops = NULL;
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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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);
}

Expand All @@ -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);
Expand All @@ -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;
Expand Down
39 changes: 15 additions & 24 deletions src/parse/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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: {
Expand Down

0 comments on commit 393d645

Please sign in to comment.