add support for arithmetic operations
This commit is contained in:
parent
2d4a5ed1ea
commit
a5dcaba970
|
@ -16,7 +16,8 @@ typedef struct {
|
||||||
pic_value *sp;
|
pic_value *sp;
|
||||||
pic_value *stbase, *stend;
|
pic_value *stbase, *stend;
|
||||||
|
|
||||||
pic_value sDEFINE, sCONS, sADD;
|
pic_value sDEFINE, sCONS;
|
||||||
|
pic_value sADD, sSUB, sMUL, sDIV;
|
||||||
struct pic_env *global_env;
|
struct pic_env *global_env;
|
||||||
|
|
||||||
struct heap_page *heap;
|
struct heap_page *heap;
|
||||||
|
|
|
@ -10,6 +10,9 @@ enum pic_instruction {
|
||||||
OP_CALL,
|
OP_CALL,
|
||||||
OP_CONS,
|
OP_CONS,
|
||||||
OP_ADD,
|
OP_ADD,
|
||||||
|
OP_SUB,
|
||||||
|
OP_MUL,
|
||||||
|
OP_DIV,
|
||||||
OP_STOP
|
OP_STOP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct parser_control {
|
||||||
"(" return tLPAREN;
|
"(" return tLPAREN;
|
||||||
")" return tRPAREN;
|
")" return tRPAREN;
|
||||||
[1-9][0-9]* { yylval.datum = pic_float_value(atoi(yytext)); return tNUMBER; }
|
[1-9][0-9]* { yylval.datum = pic_float_value(atoi(yytext)); return tNUMBER; }
|
||||||
[a-z0-9A-Z]+ { yylval.datum = pic_intern_cstr(p->pic, yytext); return tSYMBOL; }
|
[a-z0-9A-Z+-/*]+ { yylval.datum = pic_intern_cstr(p->pic, yytext); return tSYMBOL; }
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,10 @@ pic_open()
|
||||||
|
|
||||||
pic->sDEFINE = pic_intern_cstr(pic, "define");
|
pic->sDEFINE = pic_intern_cstr(pic, "define");
|
||||||
pic->sCONS = pic_intern_cstr(pic, "cons");
|
pic->sCONS = pic_intern_cstr(pic, "cons");
|
||||||
pic->sADD = pic_intern_cstr(pic, "add");
|
pic->sADD = pic_intern_cstr(pic, "+");
|
||||||
|
pic->sSUB = pic_intern_cstr(pic, "-");
|
||||||
|
pic->sMUL = pic_intern_cstr(pic, "*");
|
||||||
|
pic->sDIV = pic_intern_cstr(pic, "/");
|
||||||
|
|
||||||
/* global environment */
|
/* global environment */
|
||||||
pic->global_env = pic_new_empty_env();
|
pic->global_env = pic_new_empty_env();
|
||||||
|
|
61
src/vm.c
61
src/vm.c
|
@ -101,7 +101,7 @@ print_irep(pic_state *pic, struct pic_irep *irep)
|
||||||
puts("OP_PUSHNIL");
|
puts("OP_PUSHNIL");
|
||||||
break;
|
break;
|
||||||
case OP_PUSHNUM:
|
case OP_PUSHNUM:
|
||||||
printf("OP_PUSHNUM\t%f\n", irep->code[i].u.f);
|
printf("OP_PUSHNUM\t%g\n", irep->code[i].u.f);
|
||||||
break;
|
break;
|
||||||
case OP_PUSHUNDEF:
|
case OP_PUSHUNDEF:
|
||||||
puts("OP_PUSHUNDEF");
|
puts("OP_PUSHUNDEF");
|
||||||
|
@ -121,6 +121,15 @@ print_irep(pic_state *pic, struct pic_irep *irep)
|
||||||
case OP_ADD:
|
case OP_ADD:
|
||||||
puts("OP_ADD");
|
puts("OP_ADD");
|
||||||
break;
|
break;
|
||||||
|
case OP_SUB:
|
||||||
|
puts("OP_SUB");
|
||||||
|
break;
|
||||||
|
case OP_MUL:
|
||||||
|
puts("OP_MUL");
|
||||||
|
break;
|
||||||
|
case OP_DIV:
|
||||||
|
puts("OP_DIV");
|
||||||
|
break;
|
||||||
case OP_STOP:
|
case OP_STOP:
|
||||||
puts("OP_STOP");
|
puts("OP_STOP");
|
||||||
break;
|
break;
|
||||||
|
@ -133,11 +142,14 @@ static void pic_gen_call(pic_state *, struct pic_irep *, pic_value, struct pic_e
|
||||||
static void
|
static void
|
||||||
pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *env)
|
pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *env)
|
||||||
{
|
{
|
||||||
pic_value sDEFINE, sCONS, sADD;
|
pic_value sDEFINE, sCONS, sADD, sSUB, sMUL, sDIV;
|
||||||
|
|
||||||
sDEFINE = pic->sDEFINE;
|
sDEFINE = pic->sDEFINE;
|
||||||
sCONS = pic->sCONS;
|
sCONS = pic->sCONS;
|
||||||
sADD = pic->sADD;
|
sADD = pic->sADD;
|
||||||
|
sSUB = pic->sSUB;
|
||||||
|
sMUL = pic->sMUL;
|
||||||
|
sDIV = pic->sDIV;
|
||||||
|
|
||||||
switch (pic_type(obj)) {
|
switch (pic_type(obj)) {
|
||||||
case PIC_TT_SYMBOL: {
|
case PIC_TT_SYMBOL: {
|
||||||
|
@ -185,6 +197,30 @@ pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *en
|
||||||
irep->clen++;
|
irep->clen++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (pic_eq_p(pic, proc, sSUB)) {
|
||||||
|
/* generate args in reverse order*/
|
||||||
|
pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))), env);
|
||||||
|
pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, obj)), env);
|
||||||
|
irep->code[irep->clen].insn = OP_SUB;
|
||||||
|
irep->clen++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (pic_eq_p(pic, proc, sMUL)) {
|
||||||
|
/* generate args in reverse order*/
|
||||||
|
pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))), env);
|
||||||
|
pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, obj)), env);
|
||||||
|
irep->code[irep->clen].insn = OP_MUL;
|
||||||
|
irep->clen++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (pic_eq_p(pic, proc, sDIV)) {
|
||||||
|
/* generate args in reverse order*/
|
||||||
|
pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, pic_cdr(pic, obj))), env);
|
||||||
|
pic_gen(pic, irep, pic_car(pic, pic_cdr(pic, obj)), env);
|
||||||
|
irep->code[irep->clen].insn = OP_DIV;
|
||||||
|
irep->clen++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
pic_gen_call(pic, irep, obj, env);
|
pic_gen_call(pic, irep, obj, env);
|
||||||
break;
|
break;
|
||||||
|
@ -325,6 +361,27 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
|
||||||
PUSH(pic_float_value(pic_float(a) + pic_float(b)));
|
PUSH(pic_float_value(pic_float(a) + pic_float(b)));
|
||||||
NEXT;
|
NEXT;
|
||||||
}
|
}
|
||||||
|
CASE(OP_SUB) {
|
||||||
|
pic_value a, b;
|
||||||
|
a = POP();
|
||||||
|
b = POP();
|
||||||
|
PUSH(pic_float_value(pic_float(a) - pic_float(b)));
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
|
CASE(OP_MUL) {
|
||||||
|
pic_value a, b;
|
||||||
|
a = POP();
|
||||||
|
b = POP();
|
||||||
|
PUSH(pic_float_value(pic_float(a) * pic_float(b)));
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
|
CASE(OP_DIV) {
|
||||||
|
pic_value a, b;
|
||||||
|
a = POP();
|
||||||
|
b = POP();
|
||||||
|
PUSH(pic_float_value(pic_float(a) / pic_float(b)));
|
||||||
|
NEXT;
|
||||||
|
}
|
||||||
CASE(OP_STOP) {
|
CASE(OP_STOP) {
|
||||||
goto STOP;
|
goto STOP;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue