Changeset 11676 for lang/c

Show
Ignore:
Timestamp:
05/16/08 08:42:21 (6 months ago)
Author:
mokehehe
Message:

任意個の引数の受け取り
関数呼び出し時の引数の数のチェック

Location:
lang/c/misc/mlisp
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • lang/c/misc/mlisp/core/c_compiler.cpp

    r11648 r11676  
    238238} 
    239239 
    240  
     240/// �h�b�g�̏o�Ă����u��� 
     241static SExp dotted_pos(SExp ls) { 
     242        for (int pos = 0; ; ls = cdr(ls), ++pos) { 
     243                if (nilp(ls))   return nil; 
     244                if (!consp(ls)) return int2s(pos); 
     245        } 
     246} 
     247 
     248/// ���ŏ��ƍő����߂�static SExp get_var_min_max(SExp vars) { 
     249        SExp pos = dotted_pos(vars); 
     250        if (!nilp(pos)) { 
     251                return cons(pos, int2s(-1)); 
     252        } else { 
     253                SExp l = int2s(length(vars)); 
     254                return cons(l, l); 
     255        } 
     256} 
     257 
     258/// �h�b�g�΂𐳋K�`�ɒ��� 
     259static SExp dotted2proper(SExp ls) { 
     260        if (consp(ls)) { 
     261                SExp last = last_pair(ls); 
     262                if (nilp(cdr(last))) { 
     263                        return ls; 
     264                } else { 
     265                        SExp copy = list_copy(ls); 
     266                        SExp last = last_pair(copy); 
     267                        rplacd(last, cons(cdr(last), nil)); 
     268                        return copy; 
     269                } 
     270        } else { 
     271                return list(1, ls); 
     272        } 
     273} 
     274 
     275 
     276 
     277//============================================================================= 
     278 
     279/// ����void init_compile(void) { 
     280} 
     281 
     282SExp compile_block(SExp sexps, SExp e, SExp s, SExp next) { 
     283        SExp d = cdr(sexps); 
     284        SExp nx = nilp(d) ? next : compile_block(d, e, s, next); 
     285        return compile(car(sexps), e, s, nx); 
     286} 
     287 
     288static SExp compile_define(SExp var, SExp body, SExp e, SExp s, SExp next) { 
     289        while (consp(var)) { 
     290                body = list(1, append2(list(2, intern("lambda"), cdr(var)), body)); 
     291                var = car(var); 
     292        } 
     293        return compile(car(body), e, s, list(3, DEFINE, var, next)); 
     294} 
    241295 
    242296 
     
    252306                return compile_pair_loop(cdr(args), compile(car(args), e, s, list(2, ARGUMENT, c)), e, s, next); 
    253307        } 
    254 } 
    255  
    256  
    257 //============================================================================= 
    258  
    259 /// ����void init_compile(void) { 
    260 } 
    261  
    262 SExp compile_block(SExp sexps, SExp e, SExp s, SExp next) { 
    263         SExp d = cdr(sexps); 
    264         SExp nx = nilp(d) ? next : compile_block(d, e, s, next); 
    265         return compile(car(sexps), e, s, nx); 
    266 } 
    267  
    268 static SExp compile_define(SExp var, SExp body, SExp e, SExp s, SExp next) { 
    269         while (consp(var)) { 
    270                 body = list(3, intern("lambda"), cdr(var), body); 
    271                 var = car(var); 
    272         } 
    273         return compile(body, e, s, list(3, DEFINE, var, next)); 
    274308} 
    275309 
     
    286320                        SExp vars = cadr(x); 
    287321                        SExp body = cddr(x); 
    288                         SExp non_local = find_free(body, vars); 
     322                        SExp var_min_max = get_var_min_max(vars); 
     323                        SExp mvars = dotted2proper(vars); 
     324                        SExp non_local = find_free(body, mvars); 
    289325                        SExp free = filter_member(append2(car(e), cdr(e)), non_local); 
    290                         SExp sets = find_sets(body, vars); 
    291  
    292                         SExp boxes = make_boxes(sets, vars, compile_block(body, cons(vars, free), set_union(sets, set_intersect(s, free)), list(1, RETURN))); 
    293                         return collect_free(free, e, list(4, CLOSE, int2s(length(free)), boxes, next)); 
     326                        SExp sets = find_sets(body, mvars); 
     327                        SExp cbody = compile_block(body, cons(mvars, free), set_union(sets, set_intersect(s, free)), list(1, RETURN)); 
     328 
     329                        SExp boxes = make_boxes(sets, mvars, cbody); 
     330                        return collect_free(free, e, list(5, CLOSE, int2s(length(free)), var_min_max, boxes, next)); 
    294331                } else if (eq(op, intern("if"))) { 
    295332                        SExp test = cadr(x); 
     
    325362                } else if (eq(op, intern("define"))) { 
    326363                        SExp var = cadr(x); 
    327                         SExp body = caddr(x); 
     364                        SExp body = cddr(x); 
    328365                        return compile_define(var, body, e, s, next); 
    329366                } else { 
  • lang/c/misc/mlisp/core/s_util.h

    r11550 r11676  
    6565__inline SExp cadddr(SExp s)    { return car(cdddr(s)); } 
    6666__inline SExp cddddr(SExp s)    { return cdr(cdddr(s)); } 
     67__inline SExp caddddr(SExp s)   { return car(cddddr(s)); } 
     68__inline SExp cdddddr(SExp s)   { return cdr(cddddr(s)); } 
    6769 
    6870 
  • lang/c/misc/mlisp/core/sexp.cpp

    r11550 r11676  
    248248 
    249249 
    250 SExp gen_cfunc(SCFunc cfunc, int b_macro, int minnarg, int maxnarg) 
    251 { 
     250SExp gen_cfunc(SCFunc cfunc, int b_macro, int minnarg, int maxnarg) { 
    252251        Procedure* p = (Procedure*)salloc(sizeof(Procedure), FALSE); 
    253252        p->type = tProc; 
     
    264263 
    265264 
    266 SExp gen_closure(SExp body, SExp env) 
    267 { 
     265SExp gen_closure(SExp body, SExp env, int minarg, int maxarg) { 
    268266        bool b_macro = false; 
    269267        Procedure* p = (Procedure*)salloc(sizeof(Procedure), FALSE); 
     
    272270        p->u.cell.s = body; 
    273271        p->u.cell.e = env; 
    274         p->minnarg = -1; 
    275         p->maxnarg = -1; 
     272        p->minnarg = minarg; 
     273        p->maxnarg = maxarg; 
    276274 
    277275        SExp s; 
  • lang/c/misc/mlisp/core/v_vm.cpp

    r11643 r11676  
    106106// �N���[�W�� 
    107107 
    108 static SExp closure(SExp body, int n, int s) { 
    109 #if 0 
    110         SExp v = make_vector(n + 1); 
    111         vector_set(v, 0, body); 
    112         for (int i=0; i<n; ++i) { 
    113                 vector_set(v, i+1, index(s, i)); 
    114         } 
    115         return v; 
    116 #else 
     108static SExp closure(int minarg, int maxarg, SExp body, int n, int s) { 
    117109        SExp v = nil; 
    118110        if (n > 0) { 
     
    122114                } 
    123115        } 
    124         return gen_closure(body, v); 
    125 #endif 
     116        return gen_closure(body, v, minarg, maxarg); 
    126117} 
    127118 
    128119static SExp closure_body(SExp c) { 
    129 #if 0 
    130         return vector_ref(c, 0); 
    131 #else 
    132120        Procedure* p = (Procedure*)c.ptr; 
    133121        assert(type_check(c, tProc)); 
    134122        assert(p->get_func_type() == Procedure::Cell); 
    135123        return p->u.cell.s; 
    136 #endif 
    137124} 
    138125 
     
    149136 
    150137 
     138 
     139/// ������F�b�N 
     140static bool check_arg_num(Procedure* proc, int n) { 
     141        if (proc->maxnarg >= proc->minnarg) { 
     142                return (proc->minnarg <= n && n <= proc->maxnarg); 
     143        } else { 
     144                return proc->minnarg <= n; 
     145        } 
     146} 
     147 
     148static void modify_args(Procedure* proc, int n, int s) { 
     149        if (proc->minnarg != proc->maxnarg) { 
     150                SExp rest = nil; 
     151                for (int i=n; --i >= proc->minnarg; ) { 
     152                        rest = cons(index(s, i), rest); 
     153                } 
     154                index_set(s, proc->minnarg, rest); 
     155        } 
     156} 
     157 
     158 
    151159//============================================================================= 
    152160 
     
    170178 
    171179static SExp continuation(int s) { 
    172         return closure(list(3, REFER_LOCAL, int2s(0), list(3, NUATE, save_stack(s), list(2, RETURN, int2s(0)))), 
    173                                    0, 
    174                                    0); 
     180        SExp body = list(3, REFER_LOCAL, int2s(0), list(3, NUATE, save_stack(s), list(2, RETURN, int2s(0)))); 
     181        return closure(1, 1, body, 0, 0); 
    175182} 
    176183 
     
    243250                } else if (op == CLOSE) { 
    244251                        sint n = s2int(cadr(x)); 
    245                         SExp body = caddr(x); 
    246                         SExp xx = cadddr(x); 
    247                         a = closure(body, n, s);        x = xx; s -= n; 
     252                        SExp var_min_max = caddr(x); 
     253                        SExp body = cadddr(x); 
     254                        SExp xx = caddddr(x); 
     255 
     256                        int minarg = s2int(car(var_min_max)); 
     257                        int maxarg = s2int(cdr(var_min_max)); 
     258                        a = closure(minarg, maxarg, body, n, s);        x = xx; s -= n; 
    248259                } else if (op == BOX) { 
    249260                        sint n = s2int(cadr(x)); 
     
    262273                        x = xx; 
    263274                } else if (op == APPLY) { 
    264                         SExp argnum = cadr(x); 
    265                         int ss = push(argnum, s); 
    266275                        if (type_of(a) == tProc) { 
     276                                SExp argnum = cadr(x); 
     277                                int ss = push(argnum, s); 
     278                                int n = s2int(argnum); 
    267279                                Procedure* proc = (Procedure*)a.ptr; 
    268                                 switch (proc->get_func_type()) { 
    269                                 case Procedure::Builtin: 
    270                                         { 
    271                                                 SCFunc cfunc = proc->u.cfunc; 
    272                                                 SExp res = (*cfunc)(ss); 
    273                                                 a = res; 
    274                                                 s = vm_return(&x, &f, &c, ss); 
     280                                if (check_arg_num(proc, n)) { 
     281                                        modify_args(proc, n, s); 
     282                                        switch (proc->get_func_type()) { 
     283                                        case Procedure::Builtin: 
     284                                                { 
     285                                                        SCFunc cfunc = proc->u.cfunc; 
     286                                                        SExp res = (*cfunc)(ss); 
     287                                                        a = res; 
     288                                                        s = vm_return(&x, &f, &c, ss); 
     289                                                } 
     290                                                break; 
     291                                        case Procedure::Cell: 
     292                                                { 
     293                                                        x = closure_body(a);    f = ss; c = a;  s = ss; 
     294                                                } 
     295                                                break; 
    275296                                        } 
    276                                         break; 
    277                                 case Procedure::Cell: 
    278                                         { 
    279                                                 x = closure_body(a);    f = ss; c = a;  s = ss; 
    280                                         } 
    281                                         break; 
     297                                } else { 
     298                                        runtime_error("wrong number of argument"); 
    282299                                } 
    283300                        } else { 
  • lang/c/misc/mlisp/inc/sexp.h

    r11551 r11676  
    106106SExp gen_cfunc(SCFunc cfunc, int b_macro, int minnarg, int maxnarg); 
    107107 
    108 SExp gen_closure(SExp body, SExp env); 
     108SExp gen_closure(SExp body, SExp env, int minarg, int maxarg); 
    109109 
    110110/// s���𐮐��ɕϊ� 
  • lang/c/misc/mlisp/readme.txt

    r11648 r11676  
    4444 
    4545* ToDo 
    46 -[v] �X�^�b�N�x�[�X�ɒu��������-[x] �C�ӌ‚̈��󂯎� 
     46-[v] �X�^�b�N�x�[�X�ɒu��������-[v] �C�ӌ‚̈��󂯎� 
    4747-[x] �}�N����� 
    4848--[x] macroexpand ��- C �������[�o���̊֐���яo�������ɂ���- �unil�v�ut�v���V���{���Ȃ̂ŁA�R���p�C�������V���{���Q�ƂɂȂ�Ă��܂�