support boolean values

This commit is contained in:
Yuichi Nishiwaki 2013-10-16 13:17:01 +09:00
parent a6920c192f
commit ff646e05dd
7 changed files with 86 additions and 4 deletions

View File

@ -3,6 +3,8 @@
enum pic_instruction {
OP_PUSHNIL,
OP_PUSHTRUE,
OP_PUSHFALSE,
OP_PUSHNUM,
OP_PUSHUNDEF,
OP_GREF,

View File

@ -3,8 +3,10 @@
enum pic_vtype {
PIC_VTYPE_NIL,
PIC_VTYPE_FLOAT,
PIC_VTYPE_TRUE,
PIC_VTYPE_FALSE,
PIC_VTYPE_UNDEF,
PIC_VTYPE_FLOAT,
PIC_VTYPE_HEAP
};
@ -19,6 +21,7 @@ typedef struct {
enum pic_tt {
/* immediate */
PIC_TT_NIL,
PIC_TT_BOOL,
PIC_TT_FLOAT,
PIC_TT_UNDEF,
/* heap */
@ -54,12 +57,17 @@ struct pic_proc;
enum pic_tt pic_type(pic_value);
pic_value pic_nil_value();
pic_value pic_true_value();
pic_value pic_false_value();
pic_value pic_bool_value(bool);
pic_value pic_undef_value();
pic_value pic_obj_value(void *);
pic_value pic_float_value(double);
#define pic_float(v) ((v).u.f)
#define pic_nil_p(v) (pic_type(v) == PIC_TT_NIL)
#define pic_nil_p(v) ((v).type == PIC_VTYPE_NIL)
#define pic_true_p(v) ((v).type == PIC_VTYPE_TRUE)
#define pic_false_p(v) ((v).type == PIC_VTYPE_FALSE)
#endif

View File

@ -19,7 +19,7 @@ struct parser_control {
}
%token tLPAREN tRPAREN tDOT
%token <datum> tSYMBOL tNUMBER
%token <datum> tSYMBOL tNUMBER tBOOLEAN
%type <datum> datum simple_datum symbol compound_datum
%type <datum> number list list_tail
@ -45,6 +45,7 @@ datum
simple_datum
: symbol
| number
| boolean
;
symbol
@ -58,6 +59,10 @@ number
: tNUMBER
;
boolean
: tBOOLEAN
;
compound_datum
: list
;

View File

@ -11,6 +11,12 @@ pic_debug(pic_state *pic, pic_value obj)
case PIC_TT_NIL:
printf("()");
break;
case PIC_TT_BOOL:
if (pic_true_p(obj))
printf("#t");
else
printf("#f");
break;
case PIC_TT_PAIR:
printf("(");
pic_debug(pic, pic_car(pic, obj));

View File

@ -14,6 +14,9 @@ struct parser_control {
%option nounput
/* boolean */
boolean #t|#f|#true|#false
/* symbol */
identifier [a-z0-9A-Z+-/*?<=>_]+
@ -22,13 +25,14 @@ digit [0-9]
real {sign}{ureal}|{infnan}
ureal {digit}+|\.{digit}+|{digit}+\.{digit}*
sign [+-]?
infnan (\+inf\.0|-inf\.0|\+nan\.0|-nan\.0)
infnan "+inf.0"|"-inf.0"|"+nan.0"|"-nan.0"
%%
[ \t\n\r] /* skip whitespace */
"(" return tLPAREN;
")" return tRPAREN;
{boolean} { yylval.datum = pic_bool_value(strcmp(yytext, "#t") == 0 || strcmp(yytext, "#true") == 0); return tBOOLEAN; }
{real} { yylval.datum = pic_float_value(atof(yytext)); return tNUMBER; }
{identifier} { yylval.datum = pic_intern_cstr(p->pic, yytext); return tSYMBOL; }

View File

@ -8,6 +8,9 @@ pic_type(pic_value v)
switch (v.type) {
case PIC_VTYPE_NIL:
return PIC_TT_NIL;
case PIC_VTYPE_TRUE:
case PIC_VTYPE_FALSE:
return PIC_TT_BOOL;
case PIC_VTYPE_FLOAT:
return PIC_TT_FLOAT;
case PIC_VTYPE_UNDEF:
@ -27,6 +30,36 @@ pic_nil_value()
return v;
}
pic_value
pic_true_value()
{
pic_value v;
v.type = PIC_VTYPE_TRUE;
v.u.data = NULL;
return v;
}
pic_value
pic_false_value()
{
pic_value v;
v.type = PIC_VTYPE_FALSE;
v.u.data = NULL;
return v;
}
pic_value
pic_bool_value(bool b)
{
pic_value v;
v.type = b ? PIC_VTYPE_TRUE : PIC_VTYPE_FALSE;
v.u.data = NULL;
return v;
}
pic_value
pic_obj_value(void *ptr)
{

View File

@ -110,6 +110,12 @@ print_irep(pic_state *pic, struct pic_irep *irep)
case OP_PUSHNIL:
puts("OP_PUSHNIL");
break;
case OP_PUSHTRUE:
puts("OP_PUSHTRUE");
break;
case OP_PUSHFALSE:
puts("OP_PUSHFALSE");
break;
case OP_PUSHNUM:
printf("OP_PUSHNUM\t%g\n", irep->code[i].u.f);
break;
@ -259,6 +265,16 @@ pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *en
break;
}
}
case PIC_TT_BOOL: {
if (pic_true_p(obj)) {
irep->code[irep->clen].insn = OP_PUSHTRUE;
}
else {
irep->code[irep->clen].insn = OP_PUSHFALSE;
}
irep->clen++;
break;
}
case PIC_TT_FLOAT: {
irep->code[irep->clen].insn = OP_PUSHNUM;
irep->code[irep->clen].u.f = pic_float(obj);
@ -380,6 +396,14 @@ pic_run(pic_state *pic, struct pic_proc *proc, pic_value args)
PUSH(pic_nil_value());
NEXT;
}
CASE(OP_PUSHTRUE) {
PUSH(pic_true_value());
NEXT;
}
CASE(OP_PUSHFALSE) {
PUSH(pic_false_value());
NEXT;
}
CASE(OP_PUSHNUM) {
PUSH(pic_float_value(pc->u.f));
NEXT;