From e2741f85801874e16acca4cc1fb253052fa67419 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Fri, 28 Mar 2014 11:42:57 +0900 Subject: [PATCH 1/5] [refactor] analyze_define --- src/codegen.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index aabca6b6..9cf1c472 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -349,6 +349,7 @@ analyze_define(analyze_state *state, pic_value obj) { pic_state *pic = state->pic; pic_value var, val; + pic_sym sym; if (pic_length(pic, obj) < 2) { pic_error(pic, "syntax error"); @@ -356,24 +357,28 @@ analyze_define(analyze_state *state, pic_value obj) var = pic_list_ref(pic, obj, 1); if (pic_pair_p(var)) { - val = pic_cons(pic, pic_symbol_value(pic->sLAMBDA), - pic_cons(pic, pic_list_tail(pic, var, 1), - pic_list_tail(pic, obj, 2))); var = pic_list_ref(pic, var, 0); } - else { + if (! pic_sym_p(var)) { + pic_error(pic, "syntax error"); + } else { + sym = pic_sym(var); + } + + define_var(state, sym); + + var = analyze(state, var, false); + + if (pic_pair_p(pic_list_ref(pic, obj, 1))) { + val = pic_cons(pic, pic_symbol_value(pic->sLAMBDA), + pic_cons(pic, pic_list_tail(pic, pic_list_ref(pic, obj, 1), 1), + pic_list_tail(pic, obj, 2))); + } else { if (pic_length(pic, obj) != 3) { pic_error(pic, "syntax error"); } val = pic_list_ref(pic, obj, 2); } - if (! pic_sym_p(var)) { - pic_error(pic, "syntax error"); - } - - define_var(state, pic_sym(var)); - - var = analyze(state, var, false); val = analyze(state, val, false); return pic_list3(pic, pic_symbol_value(pic->sSETBANG), var, val); From e47bd63762ff4557c50426ae059fc42ee0190600 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Fri, 28 Mar 2014 11:48:26 +0900 Subject: [PATCH 2/5] [refactor] add analyze_declare --- src/codegen.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 9cf1c472..76a62c7e 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -344,6 +344,14 @@ analyze_var(analyze_state *state, pic_value obj) } } +static pic_value +analyze_declare(analyze_state *state, pic_sym var) +{ + define_var(state, var); + + return analyze_var(state, pic_sym_value(var)); +} + static pic_value analyze_define(analyze_state *state, pic_value obj) { @@ -364,10 +372,7 @@ analyze_define(analyze_state *state, pic_value obj) } else { sym = pic_sym(var); } - - define_var(state, sym); - - var = analyze(state, var, false); + var = analyze_declare(state, sym); if (pic_pair_p(pic_list_ref(pic, obj, 1))) { val = pic_cons(pic, pic_symbol_value(pic->sLAMBDA), From 3215ba2677e392b713b353a6c07a2513f222cdb0 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Fri, 28 Mar 2014 11:49:09 +0900 Subject: [PATCH 3/5] cleanup. move analyze_lambda --- src/codegen.c | 102 +++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 76a62c7e..d07b656c 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -344,6 +344,57 @@ analyze_var(analyze_state *state, pic_value obj) } } +static pic_value +analyze_lambda(analyze_state *state, pic_value obj) +{ + pic_state *pic = state->pic; + pic_value formals, args, locals, varg, captures, body; + + if (pic_length(pic, obj) < 2) { + pic_error(pic, "syntax error"); + } + + formals = pic_car(pic, pic_cdr(pic, obj)); + + if (push_scope(state, formals)) { + analyze_scope *scope = state->scope; + pic_sym *var; + size_t i; + + args = pic_nil_value(); + for (i = scope->args.size; i > 0; --i) { + var = xv_get(&scope->args, i - 1); + pic_push(pic, pic_sym_value(*var), 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_sym_value(pic->sBEGIN), pic_list_tail(pic, obj, 2)), true); + + locals = pic_nil_value(); + for (i = scope->locals.size; i > 0; --i) { + var = xv_get(&scope->locals, i - 1); + pic_push(pic, pic_sym_value(*var), locals); + } + + captures = pic_nil_value(); + for (i = scope->captures.size; i > 0; --i) { + var = xv_get(&scope->captures, i - 1); + pic_push(pic, pic_sym_value(*var), captures); + } + + pop_scope(state); + } + else { + pic_errorf(pic, "invalid formal syntax: ~s", args); + } + + return pic_list6(pic, pic_sym_value(pic->sLAMBDA), args, locals, varg, captures, body); +} + static pic_value analyze_declare(analyze_state *state, pic_sym var) { @@ -475,57 +526,6 @@ analyze_quote(analyze_state *state, pic_value obj) return obj; } -static pic_value -analyze_lambda(analyze_state *state, pic_value obj) -{ - pic_state *pic = state->pic; - pic_value formals, args, locals, varg, captures, body; - - if (pic_length(pic, obj) < 2) { - pic_error(pic, "syntax error"); - } - - formals = pic_car(pic, pic_cdr(pic, obj)); - - if (push_scope(state, formals)) { - analyze_scope *scope = state->scope; - pic_sym *var; - size_t i; - - args = pic_nil_value(); - for (i = scope->args.size; i > 0; --i) { - var = xv_get(&scope->args, i - 1); - pic_push(pic, pic_sym_value(*var), 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_sym_value(pic->sBEGIN), pic_list_tail(pic, obj, 2)), true); - - locals = pic_nil_value(); - for (i = scope->locals.size; i > 0; --i) { - var = xv_get(&scope->locals, i - 1); - pic_push(pic, pic_sym_value(*var), locals); - } - - captures = pic_nil_value(); - for (i = scope->captures.size; i > 0; --i) { - var = xv_get(&scope->captures, i - 1); - pic_push(pic, pic_sym_value(*var), captures); - } - - pop_scope(state); - } - else { - pic_errorf(pic, "invalid formal syntax: ~s", args); - } - - return pic_list6(pic, pic_sym_value(pic->sLAMBDA), args, locals, varg, captures, body); -} - #define ARGC_ASSERT_GE(n) do { \ if (pic_length(pic, obj) < (n) + 1) { \ pic_error(pic, "wrong number of arguments"); \ From c86c153e53e7d5b02a264058a9d99624efa082f8 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Fri, 28 Mar 2014 12:03:22 +0900 Subject: [PATCH 4/5] when procedual-define is analyzed, don't create a lambda expression inside, call analyze_procedure directly instead. --- src/codegen.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index d07b656c..59f01553 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -345,16 +345,10 @@ analyze_var(analyze_state *state, pic_value obj) } static pic_value -analyze_lambda(analyze_state *state, pic_value obj) +analyze_procedure(analyze_state *state, pic_value formals, pic_value body_exprs) { pic_state *pic = state->pic; - pic_value formals, args, locals, varg, captures, body; - - if (pic_length(pic, obj) < 2) { - pic_error(pic, "syntax error"); - } - - formals = pic_car(pic, pic_cdr(pic, obj)); + pic_value args, locals, varg, captures, body; if (push_scope(state, formals)) { analyze_scope *scope = state->scope; @@ -372,7 +366,7 @@ analyze_lambda(analyze_state *state, pic_value obj) : pic_false_value(); /* To know what kind of local variables are defined, analyze body at first. */ - body = analyze(state, pic_cons(pic, pic_sym_value(pic->sBEGIN), pic_list_tail(pic, obj, 2)), true); + body = analyze(state, pic_cons(pic, pic_sym_value(pic->sBEGIN), body_exprs), true); locals = pic_nil_value(); for (i = scope->locals.size; i > 0; --i) { @@ -395,6 +389,22 @@ analyze_lambda(analyze_state *state, pic_value obj) return pic_list6(pic, pic_sym_value(pic->sLAMBDA), args, locals, varg, captures, body); } +static pic_value +analyze_lambda(analyze_state *state, pic_value obj) +{ + pic_state *pic = state->pic; + pic_value formals, body_exprs; + + if (pic_length(pic, obj) < 2) { + pic_error(pic, "syntax error"); + } + + formals = pic_list_ref(pic, obj, 1); + body_exprs = pic_list_tail(pic, obj, 2); + + return analyze_procedure(state, formals, body_exprs); +} + static pic_value analyze_declare(analyze_state *state, pic_sym var) { @@ -426,16 +436,18 @@ analyze_define(analyze_state *state, pic_value obj) var = analyze_declare(state, sym); if (pic_pair_p(pic_list_ref(pic, obj, 1))) { - val = pic_cons(pic, pic_symbol_value(pic->sLAMBDA), - pic_cons(pic, pic_list_tail(pic, pic_list_ref(pic, obj, 1), 1), - pic_list_tail(pic, obj, 2))); + pic_value formals, body_exprs; + + formals = pic_list_tail(pic, pic_list_ref(pic, obj, 1), 1); + body_exprs = pic_list_tail(pic, obj, 2); + + val = analyze_procedure(state, formals, body_exprs); } else { if (pic_length(pic, obj) != 3) { pic_error(pic, "syntax error"); } - val = pic_list_ref(pic, obj, 2); + val = analyze(state, pic_list_ref(pic, obj, 2), false); } - val = analyze(state, val, false); return pic_list3(pic, pic_symbol_value(pic->sSETBANG), var, val); } From 010ee9ddb64b1a658232b16004f1c713181d1c7c Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Fri, 28 Mar 2014 12:07:02 +0900 Subject: [PATCH 5/5] get rid of redundant symbol to value cast --- src/codegen.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 59f01553..a2a02e26 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -324,13 +324,11 @@ analyze_free_var(analyze_state *state, pic_sym sym, int depth) } static pic_value -analyze_var(analyze_state *state, pic_value obj) +analyze_var(analyze_state *state, pic_sym sym) { pic_state *pic = state->pic; - pic_sym sym; int depth; - sym = pic_sym(obj); if ((depth = find_var(state, sym)) == -1) { pic_errorf(pic, "unbound variable %s", pic_symbol_name(pic, sym)); } @@ -410,7 +408,7 @@ analyze_declare(analyze_state *state, pic_sym var) { define_var(state, var); - return analyze_var(state, pic_sym_value(var)); + return analyze_var(state, var); } static pic_value @@ -708,7 +706,7 @@ analyze_node(analyze_state *state, pic_value obj, bool tailpos) switch (pic_type(obj)) { case PIC_TT_SYMBOL: { - return analyze_var(state, obj); + return analyze_var(state, pic_sym(obj)); } case PIC_TT_PAIR: { pic_value proc;