Add more built-in boolean-specific instructions.
This commit is contained in:
parent
73441dc93b
commit
9fc0ff961d
|
@ -287,6 +287,7 @@ struct case_strategy_bool {
|
||||||
repr_type repr,
|
repr_type repr,
|
||||||
std::vector<instruction_ptr>& into) {
|
std::vector<instruction_ptr>& into) {
|
||||||
branch->expr->compile(env_ptr(new env_offset(1, env)), into);
|
branch->expr->compile(env_ptr(new env_offset(1, env)), into);
|
||||||
|
into.push_back(instruction_ptr(new instruction_slide(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t case_count(const type* type) {
|
size_t case_count(const type* type) {
|
||||||
|
|
|
@ -6,6 +6,9 @@ std::string op_name(binop op) {
|
||||||
case MINUS: return "-";
|
case MINUS: return "-";
|
||||||
case TIMES: return "*";
|
case TIMES: return "*";
|
||||||
case DIVIDE: return "/";
|
case DIVIDE: return "/";
|
||||||
|
case MODULO: return "%";
|
||||||
|
case EQUALS: return "==";
|
||||||
|
case LESS_EQUALS: return "<=";
|
||||||
}
|
}
|
||||||
return "??";
|
return "??";
|
||||||
}
|
}
|
||||||
|
@ -16,6 +19,9 @@ std::string op_action(binop op) {
|
||||||
case MINUS: return "minus";
|
case MINUS: return "minus";
|
||||||
case TIMES: return "times";
|
case TIMES: return "times";
|
||||||
case DIVIDE: return "divide";
|
case DIVIDE: return "divide";
|
||||||
|
case MODULO: return "modulo";
|
||||||
|
case EQUALS: return "equals";
|
||||||
|
case LESS_EQUALS: return "less_equals";
|
||||||
}
|
}
|
||||||
return "??";
|
return "??";
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,10 @@ enum binop {
|
||||||
PLUS,
|
PLUS,
|
||||||
MINUS,
|
MINUS,
|
||||||
TIMES,
|
TIMES,
|
||||||
DIVIDE
|
DIVIDE,
|
||||||
|
MODULO,
|
||||||
|
EQUALS,
|
||||||
|
LESS_EQUALS,
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string op_name(binop op);
|
std::string op_name(binop op);
|
||||||
|
|
|
@ -153,7 +153,7 @@ void instruction_if::gen_llvm(llvm_context& ctx, llvm::Function* f) const {
|
||||||
ctx.builder.CreateBr(resume_block);
|
ctx.builder.CreateBr(resume_block);
|
||||||
|
|
||||||
ctx.builder.SetInsertPoint(zero_block);
|
ctx.builder.SetInsertPoint(zero_block);
|
||||||
for(auto& instruction : on_true) {
|
for(auto& instruction : on_false) {
|
||||||
instruction->gen_llvm(ctx, f);
|
instruction->gen_llvm(ctx, f);
|
||||||
}
|
}
|
||||||
ctx.builder.CreateBr(resume_block);
|
ctx.builder.CreateBr(resume_block);
|
||||||
|
@ -184,6 +184,9 @@ void instruction_binop::gen_llvm(llvm_context& ctx, Function* f) const {
|
||||||
case MINUS: result = ctx.builder.CreateSub(left_int, right_int); break;
|
case MINUS: result = ctx.builder.CreateSub(left_int, right_int); break;
|
||||||
case TIMES: result = ctx.builder.CreateMul(left_int, right_int); break;
|
case TIMES: result = ctx.builder.CreateMul(left_int, right_int); break;
|
||||||
case DIVIDE: result = ctx.builder.CreateSDiv(left_int, right_int); break;
|
case DIVIDE: result = ctx.builder.CreateSDiv(left_int, right_int); break;
|
||||||
|
case MODULO: result = ctx.builder.CreateSRem(left_int, right_int); break;
|
||||||
|
case EQUALS: result = ctx.builder.CreateICmpEQ(left_int, right_int); break;
|
||||||
|
case LESS_EQUALS: result = ctx.builder.CreateICmpSLE(left_int, right_int); break;
|
||||||
}
|
}
|
||||||
ctx.create_push(f, ctx.create_num(f, result));
|
ctx.create_push(f, ctx.create_num(f, result));
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,10 +34,16 @@ void prelude_types(definition_group& defs, type_env_ptr env) {
|
||||||
type_ptr binop_type = type_ptr(new type_arr(
|
type_ptr binop_type = type_ptr(new type_arr(
|
||||||
int_type_app,
|
int_type_app,
|
||||||
type_ptr(new type_arr(int_type_app, int_type_app))));
|
type_ptr(new type_arr(int_type_app, int_type_app))));
|
||||||
|
type_ptr cmp_type = type_ptr(new type_arr(
|
||||||
|
int_type_app,
|
||||||
|
type_ptr(new type_arr(int_type_app, bool_type_app))));
|
||||||
env->bind("+", binop_type, visibility::global);
|
env->bind("+", binop_type, visibility::global);
|
||||||
env->bind("-", binop_type, visibility::global);
|
env->bind("-", binop_type, visibility::global);
|
||||||
env->bind("*", binop_type, visibility::global);
|
env->bind("*", binop_type, visibility::global);
|
||||||
env->bind("/", binop_type, visibility::global);
|
env->bind("/", binop_type, visibility::global);
|
||||||
|
env->bind("%", binop_type, visibility::global);
|
||||||
|
env->bind("==", cmp_type, visibility::global);
|
||||||
|
env->bind("<=", cmp_type, visibility::global);
|
||||||
|
|
||||||
env->bind("True", bool_type_app, visibility::global);
|
env->bind("True", bool_type_app, visibility::global);
|
||||||
env->bind("False", bool_type_app, visibility::global);
|
env->bind("False", bool_type_app, visibility::global);
|
||||||
|
@ -146,6 +152,9 @@ void gen_llvm(global_scope& scope) {
|
||||||
gen_llvm_internal_op(ctx, MINUS);
|
gen_llvm_internal_op(ctx, MINUS);
|
||||||
gen_llvm_internal_op(ctx, TIMES);
|
gen_llvm_internal_op(ctx, TIMES);
|
||||||
gen_llvm_internal_op(ctx, DIVIDE);
|
gen_llvm_internal_op(ctx, DIVIDE);
|
||||||
|
gen_llvm_internal_op(ctx, MODULO);
|
||||||
|
gen_llvm_internal_op(ctx, EQUALS);
|
||||||
|
gen_llvm_internal_op(ctx, LESS_EQUALS);
|
||||||
gen_llvm_boolean_constructor(ctx, "True", true);
|
gen_llvm_boolean_constructor(ctx, "True", true);
|
||||||
gen_llvm_boolean_constructor(ctx, "False", false);
|
gen_llvm_boolean_constructor(ctx, "False", false);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,9 @@ using yyscan_t = void*;
|
||||||
%token TIMES
|
%token TIMES
|
||||||
%token MINUS
|
%token MINUS
|
||||||
%token DIVIDE
|
%token DIVIDE
|
||||||
|
%token MODULO
|
||||||
|
%token EQUALS
|
||||||
|
%token LESS_EQUALS
|
||||||
%token <int> INT
|
%token <int> INT
|
||||||
%token DEFN
|
%token DEFN
|
||||||
%token DATA
|
%token DATA
|
||||||
|
@ -51,7 +54,7 @@ using yyscan_t = void*;
|
||||||
%type <std::vector<parsed_type_ptr>> typeList
|
%type <std::vector<parsed_type_ptr>> typeList
|
||||||
%type <definition_group> definitions
|
%type <definition_group> definitions
|
||||||
%type <parsed_type_ptr> type nonArrowType typeListElement
|
%type <parsed_type_ptr> type nonArrowType typeListElement
|
||||||
%type <ast_ptr> aAdd aMul case let lambda app appBase
|
%type <ast_ptr> aEq aAdd aMul case let lambda app appBase
|
||||||
%type <definition_data_ptr> data
|
%type <definition_data_ptr> data
|
||||||
%type <definition_defn_ptr> defn
|
%type <definition_defn_ptr> defn
|
||||||
%type <branch_ptr> branch
|
%type <branch_ptr> branch
|
||||||
|
@ -73,7 +76,7 @@ definitions
|
||||||
;
|
;
|
||||||
|
|
||||||
defn
|
defn
|
||||||
: DEFN LID lowercaseParams EQUAL OCURLY aAdd CCURLY
|
: DEFN LID lowercaseParams EQUAL OCURLY aEq CCURLY
|
||||||
{ $$ = definition_defn_ptr(
|
{ $$ = definition_defn_ptr(
|
||||||
new definition_defn(std::move($2), std::move($3), std::move($6), @$)); }
|
new definition_defn(std::move($2), std::move($3), std::move($6), @$)); }
|
||||||
;
|
;
|
||||||
|
@ -83,6 +86,12 @@ lowercaseParams
|
||||||
| lowercaseParams LID { $$ = std::move($1); $$.push_back(std::move($2)); }
|
| lowercaseParams LID { $$ = std::move($1); $$.push_back(std::move($2)); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
aEq
|
||||||
|
: aAdd EQUALS aAdd { $$ = ast_ptr(new ast_binop(EQUALS, std::move($1), std::move($3), @$)); }
|
||||||
|
| aAdd LESS_EQUALS aAdd { $$ = ast_ptr(new ast_binop(LESS_EQUALS, std::move($1), std::move($3), @$)); }
|
||||||
|
| aAdd { $$ = std::move($1); }
|
||||||
|
;
|
||||||
|
|
||||||
aAdd
|
aAdd
|
||||||
: aAdd PLUS aMul { $$ = ast_ptr(new ast_binop(PLUS, std::move($1), std::move($3), @$)); }
|
: aAdd PLUS aMul { $$ = ast_ptr(new ast_binop(PLUS, std::move($1), std::move($3), @$)); }
|
||||||
| aAdd MINUS aMul { $$ = ast_ptr(new ast_binop(MINUS, std::move($1), std::move($3), @$)); }
|
| aAdd MINUS aMul { $$ = ast_ptr(new ast_binop(MINUS, std::move($1), std::move($3), @$)); }
|
||||||
|
@ -92,6 +101,7 @@ aAdd
|
||||||
aMul
|
aMul
|
||||||
: aMul TIMES app { $$ = ast_ptr(new ast_binop(TIMES, std::move($1), std::move($3), @$)); }
|
: aMul TIMES app { $$ = ast_ptr(new ast_binop(TIMES, std::move($1), std::move($3), @$)); }
|
||||||
| aMul DIVIDE app { $$ = ast_ptr(new ast_binop(DIVIDE, std::move($1), std::move($3), @$)); }
|
| aMul DIVIDE app { $$ = ast_ptr(new ast_binop(DIVIDE, std::move($1), std::move($3), @$)); }
|
||||||
|
| aMul MODULO app { $$ = ast_ptr(new ast_binop(MODULO, std::move($1), std::move($3), @$)); }
|
||||||
| app { $$ = std::move($1); }
|
| app { $$ = std::move($1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -104,7 +114,7 @@ appBase
|
||||||
: INT { $$ = ast_ptr(new ast_int($1, @$)); }
|
: INT { $$ = ast_ptr(new ast_int($1, @$)); }
|
||||||
| LID { $$ = ast_ptr(new ast_lid(std::move($1), @$)); }
|
| LID { $$ = ast_ptr(new ast_lid(std::move($1), @$)); }
|
||||||
| UID { $$ = ast_ptr(new ast_uid(std::move($1), @$)); }
|
| UID { $$ = ast_ptr(new ast_uid(std::move($1), @$)); }
|
||||||
| OPAREN aAdd CPAREN { $$ = std::move($2); }
|
| OPAREN aEq CPAREN { $$ = std::move($2); }
|
||||||
| case { $$ = std::move($1); }
|
| case { $$ = std::move($1); }
|
||||||
| let { $$ = std::move($1); }
|
| let { $$ = std::move($1); }
|
||||||
| lambda { $$ = std::move($1); }
|
| lambda { $$ = std::move($1); }
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
\* { return yy::parser::make_TIMES(drv.location); }
|
\* { return yy::parser::make_TIMES(drv.location); }
|
||||||
- { return yy::parser::make_MINUS(drv.location); }
|
- { return yy::parser::make_MINUS(drv.location); }
|
||||||
\/ { return yy::parser::make_DIVIDE(drv.location); }
|
\/ { return yy::parser::make_DIVIDE(drv.location); }
|
||||||
|
% { return yy::parser::make_MODULO(drv.location); }
|
||||||
|
== { return yy::parser::make_EQUALS(drv.location); }
|
||||||
|
\<= { return yy::parser::make_LESS_EQUALS(drv.location); }
|
||||||
[0-9]+ { return yy::parser::make_INT(atoi(yytext), drv.location); }
|
[0-9]+ { return yy::parser::make_INT(atoi(yytext), drv.location); }
|
||||||
defn { return yy::parser::make_DEFN(drv.location); }
|
defn { return yy::parser::make_DEFN(drv.location); }
|
||||||
data { return yy::parser::make_DATA(drv.location); }
|
data { return yy::parser::make_DATA(drv.location); }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user