check number of arguments at runtime
This commit is contained in:
parent
5e55668b92
commit
1a886ee50f
|
@ -929,7 +929,7 @@ codegen_call_vm(pic_state *pic, codegen_context *cxt, pic_value proc, size_t len
|
|||
|
||||
#define VM(uid, op) \
|
||||
if (sym == uid) { \
|
||||
emit_n(pic, cxt, op); \
|
||||
emit_i(pic, cxt, op, len); \
|
||||
emit_ret(pic, cxt, tailpos); \
|
||||
return true; \
|
||||
}
|
||||
|
@ -937,29 +937,24 @@ codegen_call_vm(pic_state *pic, codegen_context *cxt, pic_value proc, size_t len
|
|||
/*
|
||||
TODO:
|
||||
- call-with-values, values, >, >=
|
||||
- more than 2 arguments for add, sub, mul, ...
|
||||
*/
|
||||
|
||||
sym = pic_sym_ptr(pic_list_ref(pic, proc, 1));
|
||||
|
||||
if (len == 3) { /* binary operator */
|
||||
VM(pic->uCONS, OP_CONS)
|
||||
VM(pic->uADD, OP_ADD)
|
||||
VM(pic->uSUB, OP_SUB)
|
||||
VM(pic->uMUL, OP_MUL)
|
||||
VM(pic->uDIV, OP_DIV)
|
||||
VM(pic->uEQ, OP_EQ)
|
||||
VM(pic->uLT, OP_LT)
|
||||
VM(pic->uLE, OP_LE)
|
||||
}
|
||||
if (len == 2) { /* unary operator */
|
||||
VM(pic->uCAR, OP_CAR)
|
||||
VM(pic->uCDR, OP_CDR)
|
||||
VM(pic->uNILP, OP_NILP)
|
||||
VM(pic->uSYMBOLP, OP_SYMBOLP)
|
||||
VM(pic->uPAIRP, OP_PAIRP)
|
||||
VM(pic->uNOT, OP_NOT)
|
||||
}
|
||||
VM(pic->uEQ, OP_EQ)
|
||||
VM(pic->uLT, OP_LT)
|
||||
VM(pic->uLE, OP_LE)
|
||||
VM(pic->uADD, OP_ADD)
|
||||
VM(pic->uSUB, OP_SUB)
|
||||
VM(pic->uMUL, OP_MUL)
|
||||
VM(pic->uDIV, OP_DIV)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -839,8 +839,15 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
NEXT;
|
||||
}
|
||||
|
||||
#define check_args(name, n) do { \
|
||||
if (c.u.i != n + 1) { \
|
||||
goto L_CALL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
CASE(OP_CONS) {
|
||||
pic_value a, b;
|
||||
check_args("cons", 2);
|
||||
pic_gc_protect(pic, b = POP());
|
||||
pic_gc_protect(pic, a = POP());
|
||||
(void)POP();
|
||||
|
@ -850,6 +857,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_CAR) {
|
||||
pic_value p;
|
||||
check_args("car", 1);
|
||||
p = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_car(pic, p));
|
||||
|
@ -857,6 +865,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_CDR) {
|
||||
pic_value p;
|
||||
check_args("cdr", 1);
|
||||
p = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_cdr(pic, p));
|
||||
|
@ -864,6 +873,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_NILP) {
|
||||
pic_value p;
|
||||
check_args("null?", 1);
|
||||
p = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_bool_value(pic_nil_p(p)));
|
||||
|
@ -871,6 +881,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_SYMBOLP) {
|
||||
pic_value p;
|
||||
check_args("symbol?", 1);
|
||||
p = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_bool_value(pic_sym_p(p)));
|
||||
|
@ -878,6 +889,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_PAIRP) {
|
||||
pic_value p;
|
||||
check_args("pair?", 1);
|
||||
p = POP();
|
||||
(void)POP();
|
||||
PUSH(pic_bool_value(pic_pair_p(p)));
|
||||
|
@ -885,6 +897,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_NOT) {
|
||||
pic_value v;
|
||||
check_args("not", 1);
|
||||
v = pic_false_p(POP()) ? pic_true_value() : pic_false_value();
|
||||
(void)POP();
|
||||
PUSH(v);
|
||||
|
@ -893,6 +906,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
|
||||
CASE(OP_ADD) {
|
||||
pic_value a, b;
|
||||
check_args("+", 2);
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
|
@ -901,6 +915,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_SUB) {
|
||||
pic_value a, b;
|
||||
check_args("-", 2);
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
|
@ -909,6 +924,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_MUL) {
|
||||
pic_value a, b;
|
||||
check_args("*", 2);
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
|
@ -917,6 +933,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_DIV) {
|
||||
pic_value a, b;
|
||||
check_args("/", 2);
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
|
@ -925,6 +942,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_EQ) {
|
||||
pic_value a, b;
|
||||
check_args("=", 2);
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
|
@ -933,6 +951,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_LE) {
|
||||
pic_value a, b;
|
||||
check_args("<", 2);
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
|
@ -941,6 +960,7 @@ pic_apply(pic_state *pic, struct pic_proc *proc, pic_value args)
|
|||
}
|
||||
CASE(OP_LT) {
|
||||
pic_value a, b;
|
||||
check_args("<=", 2);
|
||||
b = POP();
|
||||
a = POP();
|
||||
(void)POP();
|
||||
|
|
Loading…
Reference in New Issue