diff --git a/include/picrin/irep.h b/include/picrin/irep.h index f8b62885..e9efe627 100644 --- a/include/picrin/irep.h +++ b/include/picrin/irep.h @@ -3,6 +3,8 @@ enum pic_instruction { OP_PUSHNIL, + OP_PUSHTRUE, + OP_PUSHFALSE, OP_PUSHNUM, OP_PUSHUNDEF, OP_GREF, diff --git a/include/picrin/value.h b/include/picrin/value.h index 2bca6f0a..fc627138 100644 --- a/include/picrin/value.h +++ b/include/picrin/value.h @@ -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 diff --git a/src/parse.y b/src/parse.y index bff7e832..5582c769 100644 --- a/src/parse.y +++ b/src/parse.y @@ -19,7 +19,7 @@ struct parser_control { } %token tLPAREN tRPAREN tDOT -%token tSYMBOL tNUMBER +%token tSYMBOL tNUMBER tBOOLEAN %type datum simple_datum symbol compound_datum %type 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 ; diff --git a/src/port.c b/src/port.c index e6ddbbb0..08a2b190 100644 --- a/src/port.c +++ b/src/port.c @@ -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)); diff --git a/src/scan.l b/src/scan.l index fe82f6c3..22765a59 100644 --- a/src/scan.l +++ b/src/scan.l @@ -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; } diff --git a/src/value.c b/src/value.c index 9b8becfd..52aca41a 100644 --- a/src/value.c +++ b/src/value.c @@ -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) { diff --git a/src/vm.c b/src/vm.c index 60bf32c2..c84f9522 100644 --- a/src/vm.c +++ b/src/vm.c @@ -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;