fast compile
This commit is contained in:
parent
4a8e59e04b
commit
03792f85de
|
@ -331,9 +331,8 @@ pic_expand(pic_state *pic, pic_value expr, struct pic_env *env)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef kvec_t(pic_sym *) svec_t;
|
KHASH_DECLARE(a, pic_sym *, int)
|
||||||
|
KHASH_DEFINE2(a, pic_sym *, int, 0, kh_ptr_hash_func, kh_ptr_hash_equal)
|
||||||
#define kv_push_sym(v, x) kv_push(pic_sym *, (v), (x))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scope object
|
* scope object
|
||||||
|
@ -341,8 +340,8 @@ typedef kvec_t(pic_sym *) svec_t;
|
||||||
|
|
||||||
typedef struct analyze_scope {
|
typedef struct analyze_scope {
|
||||||
int depth;
|
int depth;
|
||||||
bool varg;
|
pic_sym *rest; /* Nullable */
|
||||||
svec_t args, locals, captures; /* rest args variable is counted as a local */
|
khash_t(a) args, locals, captures; /* rest args variable is counted as a local */
|
||||||
pic_value defer;
|
pic_value defer;
|
||||||
struct analyze_scope *up;
|
struct analyze_scope *up;
|
||||||
} analyze_scope;
|
} analyze_scope;
|
||||||
|
@ -364,6 +363,7 @@ analyze_state_init(analyze_state *state, pic_state *pic)
|
||||||
{
|
{
|
||||||
pic_sym *sym;
|
pic_sym *sym;
|
||||||
khiter_t it;
|
khiter_t it;
|
||||||
|
int ret;
|
||||||
|
|
||||||
state->pic = pic;
|
state->pic = pic;
|
||||||
state->scope = NULL;
|
state->scope = NULL;
|
||||||
|
@ -372,7 +372,7 @@ analyze_state_init(analyze_state *state, pic_state *pic)
|
||||||
push_scope(state, &state->s, pic_nil_value());
|
push_scope(state, &state->s, pic_nil_value());
|
||||||
|
|
||||||
pic_dict_for_each (sym, pic->globals, it) {
|
pic_dict_for_each (sym, pic->globals, it) {
|
||||||
kv_push_sym(state->scope->locals, sym);
|
kh_put(a, &state->scope->locals, sym, &ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,26 +383,24 @@ analyze_state_destroy(analyze_state *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
analyze_args(pic_state *pic, pic_value formals, bool *varg, svec_t *args, svec_t *locals)
|
analyze_args(pic_state *pic, pic_value formals, analyze_scope *scope)
|
||||||
{
|
{
|
||||||
pic_value v, t;
|
pic_value v, t;
|
||||||
pic_sym *sym;
|
int ret;
|
||||||
|
|
||||||
for (v = formals; pic_pair_p(v); v = pic_cdr(pic, v)) {
|
for (v = formals; pic_pair_p(v); v = pic_cdr(pic, v)) {
|
||||||
t = pic_car(pic, v);
|
t = pic_car(pic, v);
|
||||||
if (! pic_sym_p(t)) {
|
if (! pic_sym_p(t)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sym = pic_sym_ptr(t);
|
kh_put(a, &scope->args, pic_sym_ptr(t), &ret);
|
||||||
kv_push_sym(*args, sym);
|
|
||||||
}
|
}
|
||||||
if (pic_nil_p(v)) {
|
if (pic_nil_p(v)) {
|
||||||
*varg = false;
|
scope->rest = NULL;
|
||||||
}
|
}
|
||||||
else if (pic_sym_p(v)) {
|
else if (pic_sym_p(v)) {
|
||||||
*varg = true;
|
scope->rest = pic_sym_ptr(v);
|
||||||
sym = pic_sym_ptr(v);
|
kh_put(a, &scope->locals, pic_sym_ptr(v), &ret);
|
||||||
kv_push_sym(*locals, sym);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -415,16 +413,14 @@ static bool
|
||||||
push_scope(analyze_state *state, analyze_scope *scope, pic_value formals)
|
push_scope(analyze_state *state, analyze_scope *scope, pic_value formals)
|
||||||
{
|
{
|
||||||
pic_state *pic = state->pic;
|
pic_state *pic = state->pic;
|
||||||
bool varg;
|
|
||||||
|
|
||||||
kv_init(scope->args);
|
kh_init(a, &scope->args);
|
||||||
kv_init(scope->locals);
|
kh_init(a, &scope->locals);
|
||||||
kv_init(scope->captures);
|
kh_init(a, &scope->captures);
|
||||||
|
|
||||||
if (analyze_args(pic, formals, &varg, &scope->args, &scope->locals)) {
|
if (analyze_args(pic, formals, scope)) {
|
||||||
scope->up = state->scope;
|
scope->up = state->scope;
|
||||||
scope->depth = scope->up ? scope->up->depth + 1 : 0;
|
scope->depth = scope->up ? scope->up->depth + 1 : 0;
|
||||||
scope->varg = varg;
|
|
||||||
scope->defer = pic_nil_value();
|
scope->defer = pic_nil_value();
|
||||||
|
|
||||||
state->scope = scope;
|
state->scope = scope;
|
||||||
|
@ -432,9 +428,9 @@ push_scope(analyze_state *state, analyze_scope *scope, pic_value formals)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
kv_destroy(scope->args);
|
kh_destroy(a, &scope->args);
|
||||||
kv_destroy(scope->locals);
|
kh_destroy(a, &scope->locals);
|
||||||
kv_destroy(scope->captures);
|
kh_destroy(a, &scope->captures);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -446,9 +442,9 @@ pop_scope(analyze_state *state)
|
||||||
analyze_scope *scope;
|
analyze_scope *scope;
|
||||||
|
|
||||||
scope = state->scope;
|
scope = state->scope;
|
||||||
kv_destroy(scope->args);
|
kh_destroy(a, &scope->args);
|
||||||
kv_destroy(scope->locals);
|
kh_destroy(a, &scope->locals);
|
||||||
kv_destroy(scope->captures);
|
kh_destroy(a, &scope->captures);
|
||||||
|
|
||||||
scope = scope->up;
|
scope = scope->up;
|
||||||
state->scope = scope;
|
state->scope = scope;
|
||||||
|
@ -457,34 +453,15 @@ pop_scope(analyze_state *state)
|
||||||
static bool
|
static bool
|
||||||
lookup_scope(analyze_scope *scope, pic_sym *sym)
|
lookup_scope(analyze_scope *scope, pic_sym *sym)
|
||||||
{
|
{
|
||||||
size_t i;
|
return kh_get(a, &scope->args, sym) != kh_end(&scope->args) || kh_get(a, &scope->locals, sym) != kh_end(&scope->locals);
|
||||||
|
|
||||||
/* args */
|
|
||||||
for (i = 0; i < kv_size(scope->args); ++i) {
|
|
||||||
if (kv_A(scope->args, i) == sym)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/* locals */
|
|
||||||
for (i = 0; i < kv_size(scope->locals); ++i) {
|
|
||||||
if (kv_A(scope->locals, i) == sym)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
capture_var(pic_state *pic, analyze_scope *scope, pic_sym *sym)
|
capture_var(pic_state *pic, analyze_scope *scope, pic_sym *sym)
|
||||||
{
|
{
|
||||||
size_t i;
|
int ret;
|
||||||
|
|
||||||
for (i = 0; i < kv_size(scope->captures); ++i) {
|
kh_put(a, &scope->captures, sym, &ret);
|
||||||
if (kv_A(scope->captures, i) == sym) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == kv_size(scope->captures)) {
|
|
||||||
kv_push_sym(scope->captures, sym);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -511,13 +488,14 @@ define_var(analyze_state *state, pic_sym *sym)
|
||||||
{
|
{
|
||||||
pic_state *pic = state->pic;
|
pic_state *pic = state->pic;
|
||||||
analyze_scope *scope = state->scope;
|
analyze_scope *scope = state->scope;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (lookup_scope(scope, sym)) {
|
if (lookup_scope(scope, sym)) {
|
||||||
pic_warnf(pic, "redefining variable: ~s", pic_obj_value(sym));
|
pic_warnf(pic, "redefining variable: ~s", pic_obj_value(sym));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
kv_push_sym(scope->locals, sym);
|
kh_put(a, &scope->locals, sym, &ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value analyze_node(analyze_state *, pic_value, bool);
|
static pic_value analyze_node(analyze_state *, pic_value, bool);
|
||||||
|
@ -633,36 +611,40 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v
|
||||||
{
|
{
|
||||||
pic_state *pic = state->pic;
|
pic_state *pic = state->pic;
|
||||||
analyze_scope scope;
|
analyze_scope scope;
|
||||||
pic_value args, locals, varg, captures, body;
|
pic_value rest = pic_undef_value(), body;
|
||||||
|
pic_vec *args, *locals, *captures;
|
||||||
|
|
||||||
assert(pic_sym_p(name) || pic_false_p(name));
|
assert(pic_sym_p(name) || pic_false_p(name));
|
||||||
|
|
||||||
if (push_scope(state, &scope, formals)) {
|
if (push_scope(state, &scope, formals)) {
|
||||||
analyze_scope *scope = state->scope;
|
analyze_scope *scope = state->scope;
|
||||||
size_t i;
|
size_t i, j;
|
||||||
|
|
||||||
args = pic_nil_value();
|
/* analyze body */
|
||||||
for (i = kv_size(scope->args); i > 0; --i) {
|
|
||||||
pic_push(pic, pic_obj_value(kv_A(scope->args, i - 1)), args);
|
|
||||||
}
|
|
||||||
|
|
||||||
varg = scope->varg
|
|
||||||
? pic_true_value()
|
|
||||||
: pic_false_value();
|
|
||||||
|
|
||||||
/* To know what kind of local variables are defined, analyze body at first. */
|
|
||||||
body = analyze(state, pic_cons(pic, pic_obj_value(pic->uBEGIN), body_exprs), true);
|
body = analyze(state, pic_cons(pic, pic_obj_value(pic->uBEGIN), body_exprs), true);
|
||||||
|
|
||||||
analyze_deferred(state);
|
analyze_deferred(state);
|
||||||
|
|
||||||
locals = pic_nil_value();
|
args = pic_make_vec(pic, kh_size(&scope->args));
|
||||||
for (i = kv_size(scope->locals); i > 0; --i) {
|
for (i = 0; pic_pair_p(formals); formals = pic_cdr(pic, formals), i++) {
|
||||||
pic_push(pic, pic_obj_value(kv_A(scope->locals, i - 1)), locals);
|
args->data[i] = pic_car(pic, formals);
|
||||||
}
|
}
|
||||||
|
|
||||||
captures = pic_nil_value();
|
if (scope->rest != NULL) {
|
||||||
for (i = kv_size(scope->captures); i > 0; --i) {
|
rest = pic_obj_value(scope->rest);
|
||||||
pic_push(pic, pic_obj_value(kv_A(scope->captures, i - 1)), captures);
|
}
|
||||||
|
|
||||||
|
locals = pic_make_vec(pic, kh_size(&scope->locals));
|
||||||
|
for (i = kh_begin(&scope->locals), j = 0; i < kh_end(&scope->locals); ++i) {
|
||||||
|
if (kh_exist(&scope->locals, i)) {
|
||||||
|
locals->data[j++] = pic_obj_value(kh_key(&scope->locals, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
captures = pic_make_vec(pic, kh_size(&scope->captures));
|
||||||
|
for (i = kh_begin(&scope->captures), j = 0; i < kh_end(&scope->captures); ++i) {
|
||||||
|
if (kh_exist(&scope->captures, i)) {
|
||||||
|
captures->data[j++] = pic_obj_value(kh_key(&scope->captures, i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pop_scope(state);
|
pop_scope(state);
|
||||||
|
@ -671,7 +653,7 @@ analyze_procedure(analyze_state *state, pic_value name, pic_value formals, pic_v
|
||||||
pic_errorf(pic, "invalid formal syntax: ~s", formals);
|
pic_errorf(pic, "invalid formal syntax: ~s", formals);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pic_list7(pic, pic_obj_value(pic->sLAMBDA), name, args, locals, varg, captures, body);
|
return pic_list7(pic, pic_obj_value(pic->sLAMBDA), name, rest, pic_obj_value(args), pic_obj_value(locals), pic_obj_value(captures), body);
|
||||||
}
|
}
|
||||||
|
|
||||||
static pic_value
|
static pic_value
|
||||||
|
@ -1134,8 +1116,8 @@ pic_analyze(pic_state *pic, pic_value obj)
|
||||||
typedef struct codegen_context {
|
typedef struct codegen_context {
|
||||||
pic_sym *name;
|
pic_sym *name;
|
||||||
/* rest args variable is counted as a local */
|
/* rest args variable is counted as a local */
|
||||||
bool varg;
|
pic_sym *rest;
|
||||||
svec_t args, locals, captures;
|
pic_vec *args, *locals, *captures;
|
||||||
/* actual bit code sequence */
|
/* actual bit code sequence */
|
||||||
pic_code *code;
|
pic_code *code;
|
||||||
size_t clen, ccapa;
|
size_t clen, ccapa;
|
||||||
|
@ -1161,16 +1143,18 @@ typedef struct codegen_state {
|
||||||
codegen_context c, *cxt;
|
codegen_context c, *cxt;
|
||||||
} codegen_state;
|
} codegen_state;
|
||||||
|
|
||||||
static void push_codegen_context(codegen_state *, codegen_context *, pic_value, pic_value, pic_value, bool, pic_value);
|
static void push_codegen_context(codegen_state *, codegen_context *, pic_value, pic_sym *, pic_vec *, pic_vec *, pic_vec *);
|
||||||
static struct pic_irep *pop_codegen_context(codegen_state *);
|
static struct pic_irep *pop_codegen_context(codegen_state *);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
codegen_state_init(codegen_state *state, pic_state *pic)
|
codegen_state_init(codegen_state *state, pic_state *pic)
|
||||||
{
|
{
|
||||||
|
pic_vec *empty = pic_make_vec(pic, 0);
|
||||||
|
|
||||||
state->pic = pic;
|
state->pic = pic;
|
||||||
state->cxt = NULL;
|
state->cxt = NULL;
|
||||||
|
|
||||||
push_codegen_context(state, &state->c, pic_false_value(), pic_nil_value(), pic_nil_value(), false, pic_nil_value());
|
push_codegen_context(state, &state->c, pic_false_value(), NULL, empty, empty, empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pic_irep *
|
static struct pic_irep *
|
||||||
|
@ -1255,19 +1239,19 @@ create_activation(codegen_state *state)
|
||||||
regs = pic_make_reg(pic);
|
regs = pic_make_reg(pic);
|
||||||
|
|
||||||
offset = 1;
|
offset = 1;
|
||||||
for (i = 0; i < kv_size(cxt->args); ++i) {
|
for (i = 0; i < cxt->args->len; ++i) {
|
||||||
n = i + offset;
|
n = i + offset;
|
||||||
pic_reg_set(pic, regs, kv_A(cxt->args, i), pic_size_value(n));
|
pic_reg_set(pic, regs, pic_sym_ptr(cxt->args->data[i]), pic_size_value(n));
|
||||||
}
|
}
|
||||||
offset += i;
|
offset += i;
|
||||||
for (i = 0; i < kv_size(cxt->locals); ++i) {
|
for (i = 0; i < cxt->locals->len; ++i) {
|
||||||
n = i + offset;
|
n = i + offset;
|
||||||
pic_reg_set(pic, regs, kv_A(cxt->locals, i), pic_size_value(n));
|
pic_reg_set(pic, regs, pic_sym_ptr(cxt->locals->data[i]), pic_size_value(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < kv_size(cxt->captures); ++i) {
|
for (i = 0; i < cxt->captures->len; ++i) {
|
||||||
n = (size_t)pic_int(pic_reg_ref(pic, regs, kv_A(cxt->captures, i)));
|
n = (size_t)pic_int(pic_reg_ref(pic, regs, pic_sym_ptr(cxt->captures->data[i])));
|
||||||
if (n <= kv_size(cxt->args) || (cxt->varg && n == kv_size(cxt->args) + 1)) {
|
if (n <= cxt->args->len || cxt->rest == pic_sym_ptr(cxt->captures->data[i])) {
|
||||||
/* copy arguments to capture variable area */
|
/* copy arguments to capture variable area */
|
||||||
emit_i(state, OP_LREF, (int)n);
|
emit_i(state, OP_LREF, (int)n);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1278,10 +1262,9 @@ create_activation(codegen_state *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
push_codegen_context(codegen_state *state, codegen_context *cxt, pic_value name, pic_value args, pic_value locals, bool varg, pic_value captures)
|
push_codegen_context(codegen_state *state, codegen_context *cxt, pic_value name, pic_sym *rest, pic_vec *args, pic_vec *locals, pic_vec *captures)
|
||||||
{
|
{
|
||||||
pic_state *pic = state->pic;
|
pic_state *pic = state->pic;
|
||||||
pic_value var, it;
|
|
||||||
|
|
||||||
assert(pic_sym_p(name) || pic_false_p(name));
|
assert(pic_sym_p(name) || pic_false_p(name));
|
||||||
|
|
||||||
|
@ -1289,21 +1272,11 @@ push_codegen_context(codegen_state *state, codegen_context *cxt, pic_value name,
|
||||||
cxt->name = pic_false_p(name)
|
cxt->name = pic_false_p(name)
|
||||||
? pic_intern_cstr(pic, "(anonymous lambda)")
|
? pic_intern_cstr(pic, "(anonymous lambda)")
|
||||||
: pic_sym_ptr(name);
|
: pic_sym_ptr(name);
|
||||||
cxt->varg = varg;
|
cxt->rest = rest;
|
||||||
|
|
||||||
kv_init(cxt->args);
|
cxt->args = args;
|
||||||
kv_init(cxt->locals);
|
cxt->locals = locals;
|
||||||
kv_init(cxt->captures);
|
cxt->captures = captures;
|
||||||
|
|
||||||
pic_for_each (var, args, it) {
|
|
||||||
kv_push_sym(cxt->args, pic_sym_ptr(var));
|
|
||||||
}
|
|
||||||
pic_for_each (var, locals, it) {
|
|
||||||
kv_push_sym(cxt->locals, pic_sym_ptr(var));
|
|
||||||
}
|
|
||||||
pic_for_each (var, captures, it) {
|
|
||||||
kv_push_sym(cxt->captures, pic_sym_ptr(var));
|
|
||||||
}
|
|
||||||
|
|
||||||
cxt->code = pic_calloc(pic, PIC_ISEQ_SIZE, sizeof(pic_code));
|
cxt->code = pic_calloc(pic, PIC_ISEQ_SIZE, sizeof(pic_code));
|
||||||
cxt->clen = 0;
|
cxt->clen = 0;
|
||||||
|
@ -1336,10 +1309,10 @@ pop_codegen_context(codegen_state *state)
|
||||||
/* create irep */
|
/* create irep */
|
||||||
irep = (struct pic_irep *)pic_obj_alloc(pic, sizeof(struct pic_irep), PIC_TT_IREP);
|
irep = (struct pic_irep *)pic_obj_alloc(pic, sizeof(struct pic_irep), PIC_TT_IREP);
|
||||||
irep->name = state->cxt->name;
|
irep->name = state->cxt->name;
|
||||||
irep->varg = state->cxt->varg;
|
irep->varg = state->cxt->rest != NULL;
|
||||||
irep->argc = (int)kv_size(state->cxt->args) + 1;
|
irep->argc = (int)state->cxt->args->len + 1;
|
||||||
irep->localc = (int)kv_size(state->cxt->locals);
|
irep->localc = (int)state->cxt->locals->len;
|
||||||
irep->capturec = (int)kv_size(state->cxt->captures);
|
irep->capturec = (int)state->cxt->captures->len;
|
||||||
irep->code = pic_realloc(pic, state->cxt->code, sizeof(pic_code) * state->cxt->clen);
|
irep->code = pic_realloc(pic, state->cxt->code, sizeof(pic_code) * state->cxt->clen);
|
||||||
irep->clen = state->cxt->clen;
|
irep->clen = state->cxt->clen;
|
||||||
irep->irep = pic_realloc(pic, state->cxt->irep, sizeof(struct pic_irep *) * state->cxt->ilen);
|
irep->irep = pic_realloc(pic, state->cxt->irep, sizeof(struct pic_irep *) * state->cxt->ilen);
|
||||||
|
@ -1349,11 +1322,6 @@ pop_codegen_context(codegen_state *state)
|
||||||
irep->syms = pic_realloc(pic, state->cxt->syms, sizeof(pic_sym *) * state->cxt->slen);
|
irep->syms = pic_realloc(pic, state->cxt->syms, sizeof(pic_sym *) * state->cxt->slen);
|
||||||
irep->slen = state->cxt->slen;
|
irep->slen = state->cxt->slen;
|
||||||
|
|
||||||
/* finalize */
|
|
||||||
kv_destroy(cxt->args);
|
|
||||||
kv_destroy(cxt->locals);
|
|
||||||
kv_destroy(cxt->captures);
|
|
||||||
|
|
||||||
/* destroy context */
|
/* destroy context */
|
||||||
cxt = cxt->up;
|
cxt = cxt->up;
|
||||||
state->cxt = cxt;
|
state->cxt = cxt;
|
||||||
|
@ -1371,8 +1339,8 @@ index_capture(codegen_state *state, pic_sym *sym, int depth)
|
||||||
cxt = cxt->up;
|
cxt = cxt->up;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < kv_size(cxt->captures); ++i) {
|
for (i = 0; i < cxt->captures->len; ++i) {
|
||||||
if (kv_A(cxt->captures, i) == sym)
|
if (pic_sym_ptr(cxt->captures->data[i]) == sym)
|
||||||
return (int)i;
|
return (int)i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1385,13 +1353,13 @@ index_local(codegen_state *state, pic_sym *sym)
|
||||||
size_t i, offset;
|
size_t i, offset;
|
||||||
|
|
||||||
offset = 1;
|
offset = 1;
|
||||||
for (i = 0; i < kv_size(cxt->args); ++i) {
|
for (i = 0; i < cxt->args->len; ++i) {
|
||||||
if (kv_A(cxt->args, i) == sym)
|
if (pic_sym_ptr(cxt->args->data[i]) == sym)
|
||||||
return (int)(i + offset);
|
return (int)(i + offset);
|
||||||
}
|
}
|
||||||
offset += i;
|
offset += i;
|
||||||
for (i = 0; i < kv_size(cxt->locals); ++i) {
|
for (i = 0; i < cxt->locals->len; ++i) {
|
||||||
if (kv_A(cxt->locals, i) == sym)
|
if (pic_sym_ptr(cxt->locals->data[i]) == sym)
|
||||||
return (int)(i + offset);
|
return (int)(i + offset);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1444,7 +1412,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
|
|
||||||
name = pic_sym_ptr(pic_list_ref(pic, obj, 1));
|
name = pic_sym_ptr(pic_list_ref(pic, obj, 1));
|
||||||
if ((i = index_capture(state, name, 0)) != -1) {
|
if ((i = index_capture(state, name, 0)) != -1) {
|
||||||
emit_i(state, OP_LREF, i + (int)kv_size(cxt->args) + (int)kv_size(cxt->locals) + 1);
|
emit_i(state, OP_LREF, i + (int)cxt->args->len + (int)cxt->locals->len + 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit_i(state, OP_LREF, index_local(state, name));
|
emit_i(state, OP_LREF, index_local(state, name));
|
||||||
|
@ -1479,7 +1447,7 @@ codegen(codegen_state *state, pic_value obj)
|
||||||
|
|
||||||
name = pic_sym_ptr(pic_list_ref(pic, var, 1));
|
name = pic_sym_ptr(pic_list_ref(pic, var, 1));
|
||||||
if ((i = index_capture(state, name, 0)) != -1) {
|
if ((i = index_capture(state, name, 0)) != -1) {
|
||||||
emit_i(state, OP_LSET, i + (int)kv_size(cxt->args) + (int)kv_size(cxt->locals) + 1);
|
emit_i(state, OP_LSET, i + (int)cxt->args->len + (int)cxt->locals->len + 1);
|
||||||
emit_n(state, OP_PUSHUNDEF);
|
emit_n(state, OP_PUSHUNDEF);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1697,18 +1665,22 @@ codegen_lambda(codegen_state *state, pic_value obj)
|
||||||
{
|
{
|
||||||
pic_state *pic = state->pic;
|
pic_state *pic = state->pic;
|
||||||
codegen_context cxt;
|
codegen_context cxt;
|
||||||
pic_value name, args, locals, closes, body;
|
pic_value name, rest_opt, body;
|
||||||
bool varg;
|
pic_sym *rest = NULL;
|
||||||
|
pic_vec *args, *locals, *captures;
|
||||||
|
|
||||||
name = pic_list_ref(pic, obj, 1);
|
name = pic_list_ref(pic, obj, 1);
|
||||||
args = pic_list_ref(pic, obj, 2);
|
rest_opt = pic_list_ref(pic, obj, 2);
|
||||||
locals = pic_list_ref(pic, obj, 3);
|
if (pic_sym_p(rest_opt)) {
|
||||||
varg = pic_true_p(pic_list_ref(pic, obj, 4));
|
rest = pic_sym_ptr(rest_opt);
|
||||||
closes = pic_list_ref(pic, obj, 5);
|
}
|
||||||
|
args = pic_vec_ptr(pic_list_ref(pic, obj, 3));
|
||||||
|
locals = pic_vec_ptr(pic_list_ref(pic, obj, 4));
|
||||||
|
captures = pic_vec_ptr(pic_list_ref(pic, obj, 5));
|
||||||
body = pic_list_ref(pic, obj, 6);
|
body = pic_list_ref(pic, obj, 6);
|
||||||
|
|
||||||
/* inner environment */
|
/* inner environment */
|
||||||
push_codegen_context(state, &cxt, name, args, locals, varg, closes);
|
push_codegen_context(state, &cxt, name, rest, args, locals, captures);
|
||||||
{
|
{
|
||||||
/* body */
|
/* body */
|
||||||
codegen(state, body);
|
codegen(state, body);
|
||||||
|
|
Loading…
Reference in New Issue