cleanup analyzer

This commit is contained in:
Yuichi Nishiwaki 2015-06-27 18:47:16 +09:00
parent 5633bbefae
commit 36c498e7d7
1 changed files with 67 additions and 141 deletions

View File

@ -157,12 +157,12 @@ expand_lambda(pic_state *pic, pic_value expr, struct pic_env *env)
deferred = pic_list1(pic, pic_nil_value()); deferred = pic_list1(pic, pic_nil_value());
formal = expand_list(pic, pic_cadr(pic, expr), in, deferred); formal = expand_list(pic, pic_list_ref(pic, expr, 1), in, deferred);
body = expand_list(pic, pic_cddr(pic, expr), in, deferred); body = expand(pic, pic_list_ref(pic, expr, 2), in, deferred);
expand_deferred(pic, deferred, in); expand_deferred(pic, deferred, in);
return pic_cons(pic, pic_obj_value(pic->uLAMBDA), pic_cons(pic, formal, body)); return pic_list3(pic, pic_obj_value(pic->uLAMBDA), formal, body);
} }
static pic_value static pic_value
@ -297,28 +297,30 @@ typedef struct analyze_scope {
struct analyze_scope *up; struct analyze_scope *up;
} analyze_scope; } analyze_scope;
static bool analyze_args(pic_state *, pic_value, analyze_scope *); static void
analyzer_scope_init(pic_state *pic, analyze_scope *scope, pic_value formal, analyze_scope *up)
static bool
analyzer_scope_init(pic_state *pic, analyze_scope *scope, pic_value formals, analyze_scope *up)
{ {
int ret;
kh_init(a, &scope->args); kh_init(a, &scope->args);
kh_init(a, &scope->locals); kh_init(a, &scope->locals);
kh_init(a, &scope->captures); kh_init(a, &scope->captures);
if (analyze_args(pic, formals, scope)) { /* analyze formal */
scope->up = up; for (; pic_pair_p(formal); formal = pic_cdr(pic, formal)) {
scope->depth = up ? up->depth + 1 : 0; kh_put(a, &scope->args, pic_sym_ptr(pic_car(pic, formal)), &ret);
scope->defer = pic_nil_value(); }
if (pic_nil_p(formal)) {
return true; scope->rest = NULL;
} }
else { else {
kh_destroy(a, &scope->args); scope->rest = pic_sym_ptr(formal);
kh_destroy(a, &scope->locals); kh_put(a, &scope->locals, pic_sym_ptr(formal), &ret);
kh_destroy(a, &scope->captures);
return false;
} }
scope->up = up;
scope->depth = up ? up->depth + 1 : 0;
scope->defer = pic_nil_value();
} }
static void static void
@ -329,33 +331,6 @@ analyzer_scope_destroy(pic_state *pic, analyze_scope *scope)
kh_destroy(a, &scope->captures); kh_destroy(a, &scope->captures);
} }
static bool
analyze_args(pic_state *pic, pic_value formals, analyze_scope *scope)
{
pic_value v, t;
int ret;
for (v = formals; pic_pair_p(v); v = pic_cdr(pic, v)) {
t = pic_car(pic, v);
if (! pic_sym_p(t)) {
return false;
}
kh_put(a, &scope->args, pic_sym_ptr(t), &ret);
}
if (pic_nil_p(v)) {
scope->rest = NULL;
}
else if (pic_sym_p(v)) {
scope->rest = pic_sym_ptr(v);
kh_put(a, &scope->locals, pic_sym_ptr(v), &ret);
}
else {
return false;
}
return true;
}
static bool static bool
search_scope(analyze_scope *scope, pic_sym *sym) search_scope(analyze_scope *scope, pic_sym *sym)
{ {
@ -482,66 +457,58 @@ analyze_deferred(pic_state *pic, analyze_scope *scope)
} }
static pic_value static pic_value
analyze_procedure(pic_state *pic, analyze_scope *up, pic_value name, pic_value formals, pic_value body_exprs) analyze_procedure(pic_state *pic, analyze_scope *up, pic_value name, pic_value formals, pic_value body)
{ {
analyze_scope s, *scope = &s; analyze_scope s, *scope = &s;
pic_value rest = pic_undef_value(), body; pic_value rest = pic_undef_value();
pic_vec *args, *locals, *captures; pic_vec *args, *locals, *captures;
size_t i, j;
assert(pic_sym_p(name) || pic_false_p(name)); assert(pic_sym_p(name) || pic_false_p(name));
if (analyzer_scope_init(pic, scope, formals, up)) { analyzer_scope_init(pic, scope, formals, up);
size_t i, j;
/* analyze body */ /* analyze body */
body = analyze(pic, scope, pic_cons(pic, pic_obj_value(pic->uBEGIN), body_exprs), true); body = analyze(pic, scope, body, true);
analyze_deferred(pic, scope); analyze_deferred(pic, scope);
args = pic_make_vec(pic, kh_size(&scope->args)); args = pic_make_vec(pic, kh_size(&scope->args));
for (i = 0; pic_pair_p(formals); formals = pic_cdr(pic, formals), i++) { for (i = 0; pic_pair_p(formals); formals = pic_cdr(pic, formals), i++) {
args->data[i] = pic_car(pic, formals); args->data[i] = pic_car(pic, formals);
}
if (scope->rest != NULL) {
rest = pic_obj_value(scope->rest);
}
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));
}
}
analyzer_scope_destroy(pic, scope);
} }
else {
pic_errorf(pic, "invalid formal syntax: ~s", formals); if (scope->rest != NULL) {
rest = pic_obj_value(scope->rest);
} }
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));
}
}
analyzer_scope_destroy(pic, scope);
return pic_list7(pic, pic_obj_value(pic->sLAMBDA), name, rest, pic_obj_value(args), pic_obj_value(locals), pic_obj_value(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
analyze_lambda(pic_state *pic, analyze_scope *scope, pic_value obj) analyze_lambda(pic_state *pic, analyze_scope *scope, pic_value obj)
{ {
pic_value formals, body_exprs; pic_value formals, body;
if (pic_length(pic, obj) < 2) {
pic_errorf(pic, "syntax error");
}
formals = pic_list_ref(pic, obj, 1); formals = pic_list_ref(pic, obj, 1);
body_exprs = pic_list_tail(pic, obj, 2); body = pic_list_ref(pic, obj, 2);
return analyze_defer(pic, scope, pic_false_value(), formals, body_exprs); return analyze_defer(pic, scope, pic_false_value(), formals, body);
} }
static pic_value static pic_value
@ -558,31 +525,21 @@ analyze_define(pic_state *pic, analyze_scope *scope, pic_value obj)
pic_value var, val; pic_value var, val;
pic_sym *sym; pic_sym *sym;
if (pic_length(pic, obj) != 3) { sym = pic_sym_ptr(pic_list_ref(pic, obj, 1));
pic_errorf(pic, "syntax error");
}
var = pic_list_ref(pic, obj, 1);
if (! pic_sym_p(var)) {
pic_errorf(pic, "syntax error");
} else {
sym = pic_sym_ptr(var);
}
var = analyze_declare(pic, scope, sym); var = analyze_declare(pic, scope, sym);
if (pic_pair_p(pic_list_ref(pic, obj, 2)) if (pic_pair_p(pic_list_ref(pic, obj, 2))
&& pic_sym_p(pic_list_ref(pic, pic_list_ref(pic, obj, 2), 0)) && pic_sym_p(pic_list_ref(pic, pic_list_ref(pic, obj, 2), 0))
&& pic_sym_ptr(pic_list_ref(pic, pic_list_ref(pic, obj, 2), 0)) == pic->uLAMBDA) { && pic_sym_ptr(pic_list_ref(pic, pic_list_ref(pic, obj, 2), 0)) == pic->uLAMBDA) {
pic_value formals, body_exprs; pic_value formals, body;
/* restore (define (foo ...) ...) structure */
formals = pic_list_ref(pic, pic_list_ref(pic, obj, 2), 1); formals = pic_list_ref(pic, pic_list_ref(pic, obj, 2), 1);
body_exprs = pic_list_tail(pic, pic_list_ref(pic, obj, 2), 2); body = pic_list_ref(pic, pic_list_ref(pic, obj, 2), 2);
val = analyze_defer(pic, scope, pic_obj_value(sym), formals, body_exprs); val = analyze_defer(pic, scope, pic_obj_value(sym), formals, body);
} else { } else {
if (pic_length(pic, obj) != 3) {
pic_errorf(pic, "syntax error");
}
val = analyze(pic, scope, pic_list_ref(pic, obj, 2), false); val = analyze(pic, scope, pic_list_ref(pic, obj, 2), false);
} }
@ -594,18 +551,9 @@ analyze_if(pic_state *pic, analyze_scope *scope, pic_value obj, bool tailpos)
{ {
pic_value cond, if_true, if_false; pic_value cond, if_true, if_false;
if_false = pic_undef_value(); if_true = pic_list_ref(pic, obj, 2);
switch (pic_length(pic, obj)) { if_false = pic_list_ref(pic, obj, 3);
default:
pic_errorf(pic, "syntax error");
case 4:
if_false = pic_list_ref(pic, obj, 3);
PIC_FALLTHROUGH;
case 3:
if_true = pic_list_ref(pic, obj, 2);
}
/* analyze in order */
cond = analyze(pic, scope, pic_list_ref(pic, obj, 1), false); cond = analyze(pic, scope, pic_list_ref(pic, obj, 1), false);
if_true = analyze(pic, scope, if_true, tailpos); if_true = analyze(pic, scope, if_true, tailpos);
if_false = analyze(pic, scope, if_false, tailpos); if_false = analyze(pic, scope, if_false, tailpos);
@ -616,26 +564,15 @@ analyze_if(pic_state *pic, analyze_scope *scope, pic_value obj, bool tailpos)
static pic_value static pic_value
analyze_begin(pic_state *pic, analyze_scope *scope, pic_value obj, bool tailpos) analyze_begin(pic_state *pic, analyze_scope *scope, pic_value obj, bool tailpos)
{ {
pic_value seq; pic_value beg1, beg2;
bool tail;
switch (pic_length(pic, obj)) { beg1 = pic_list_ref(pic, obj, 1);
case 1: beg2 = pic_list_ref(pic, obj, 2);
return analyze(pic, scope, pic_undef_value(), tailpos);
case 2: beg1 = analyze(pic, scope, beg1, false);
return analyze(pic, scope, pic_list_ref(pic, obj, 1), tailpos); beg2 = analyze(pic, scope, beg2, tailpos);
default:
seq = pic_list1(pic, pic_obj_value(pic->sBEGIN)); return pic_list3(pic, pic_obj_value(pic->sBEGIN), beg1, beg2);
for (obj = pic_cdr(pic, obj); ! pic_nil_p(obj); obj = pic_cdr(pic, obj)) {
if (pic_nil_p(pic_cdr(pic, obj))) {
tail = tailpos;
} else {
tail = false;
}
seq = pic_cons(pic, analyze(pic, scope, pic_car(pic, obj), tail), seq);
}
return pic_reverse(pic, seq);
}
} }
static pic_value static pic_value
@ -643,15 +580,7 @@ analyze_set(pic_state *pic, analyze_scope *scope, pic_value obj)
{ {
pic_value var, val; pic_value var, val;
if (pic_length(pic, obj) != 3) {
pic_errorf(pic, "syntax error");
}
var = pic_list_ref(pic, obj, 1); var = pic_list_ref(pic, obj, 1);
if (! pic_sym_p(var)) {
pic_errorf(pic, "syntax error");
}
val = pic_list_ref(pic, obj, 2); val = pic_list_ref(pic, obj, 2);
var = analyze(pic, scope, var, false); var = analyze(pic, scope, var, false);
@ -663,9 +592,6 @@ analyze_set(pic_state *pic, analyze_scope *scope, pic_value obj)
static pic_value static pic_value
analyze_quote(pic_state *pic, pic_value obj) analyze_quote(pic_state *pic, pic_value obj)
{ {
if (pic_length(pic, obj) != 2) {
pic_errorf(pic, "syntax error");
}
return pic_list2(pic, pic_obj_value(pic->sQUOTE), pic_list_ref(pic, obj, 1)); return pic_list2(pic, pic_obj_value(pic->sQUOTE), pic_list_ref(pic, obj, 1));
} }