Skip to content

Commit

Permalink
feat: add comparison operators
Browse files Browse the repository at this point in the history
This commit adds the >,>=,<=,<,==,!= operators to the language. It also
contains a rewrite of how tests are performed so that instead of using
*.mun files, the test are written in Rust which enables testing of
individual test cases with a little more ease.
  • Loading branch information
baszalmstra committed Oct 25, 2019
1 parent b6d5864 commit 2f892f5
Show file tree
Hide file tree
Showing 86 changed files with 1,494 additions and 647 deletions.
4 changes: 3 additions & 1 deletion crates/mun_codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ md5="0.6.1"
array-init="0.1.0"
tempfile = "3"
lazy_static = "1.4.0"
test_utils = { path="../test_utils"}

[dev-dependencies]
insta = "0.12.0"

[build-dependencies]
lazy_static = "1.4.0"
Expand Down
55 changes: 53 additions & 2 deletions crates/mun_codegen/src/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ use crate::{IrDatabase, Module, OptimizationLevel};
use inkwell::builder::Builder;
use inkwell::passes::{PassManager, PassManagerBuilder};
use inkwell::types::{AnyTypeEnum, BasicTypeEnum};
use inkwell::{FloatPredicate, IntPredicate};
use mun_hir::{
self as hir, ArithOp, BinaryOp, Body, Expr, ExprId, HirDisplay, InferenceResult, Literal, Pat,
PatId, Path, Resolution, Resolver, Statement, TypeCtor,
self as hir, ArithOp, BinaryOp, Body, CmpOp, Expr, ExprId, HirDisplay, InferenceResult,
Literal, Ordering, Pat, PatId, Path, Resolution, Resolver, Statement, TypeCtor,
};
use std::collections::HashMap;
use std::mem;
Expand Down Expand Up @@ -323,6 +324,31 @@ impl<'a, 'b, D: IrDatabase> BodyIrGenerator<'a, 'b, D> {
// BinaryOp::MultiplyAssign,
// BinaryOp::RemainderAssign,
// BinaryOp::PowerAssign,
BinaryOp::CmpOp(op) => {
let (name, predicate) = match op {
CmpOp::Eq { negated: false } => ("eq", FloatPredicate::OEQ),
CmpOp::Eq { negated: true } => ("neq", FloatPredicate::ONE),
CmpOp::Ord {
ordering: Ordering::Less,
strict: false,
} => ("lesseq", FloatPredicate::OLE),
CmpOp::Ord {
ordering: Ordering::Less,
strict: true,
} => ("less", FloatPredicate::OLT),
CmpOp::Ord {
ordering: Ordering::Greater,
strict: false,
} => ("greatereq", FloatPredicate::OGE),
CmpOp::Ord {
ordering: Ordering::Greater,
strict: true,
} => ("greater", FloatPredicate::OGT),
};
self.builder
.build_float_compare(predicate, lhs, rhs, name)
.into()
}
_ => unreachable!(),
}
}
Expand All @@ -348,6 +374,31 @@ impl<'a, 'b, D: IrDatabase> BodyIrGenerator<'a, 'b, D> {
// BinaryOp::MultiplyAssign,
// BinaryOp::RemainderAssign,
// BinaryOp::PowerAssign,
BinaryOp::CmpOp(op) => {
let (name, predicate) = match op {
CmpOp::Eq { negated: false } => ("eq", IntPredicate::EQ),
CmpOp::Eq { negated: true } => ("neq", IntPredicate::NE),
CmpOp::Ord {
ordering: Ordering::Less,
strict: false,
} => ("lesseq", IntPredicate::SLE),
CmpOp::Ord {
ordering: Ordering::Less,
strict: true,
} => ("less", IntPredicate::SLT),
CmpOp::Ord {
ordering: Ordering::Greater,
strict: false,
} => ("greatereq", IntPredicate::SGE),
CmpOp::Ord {
ordering: Ordering::Greater,
strict: true,
} => ("greater", IntPredicate::SGT),
};
self.builder
.build_int_compare(predicate, lhs, rhs, name)
.into()
}
_ => unreachable!(),
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn add(a:int, b:int):int {\n a+b\n}\n\nfn subtract(a:int, b:int):int {\n a-b\n}\n\nfn multiply(a:int, b:int):int {\n a*b\n}"
---
; ModuleID = 'main.mun'
source_filename = "main.mun"

Expand All @@ -18,3 +22,4 @@ body:
%mul = mul i64 %a, %b
ret i64 %mul
}

79 changes: 79 additions & 0 deletions crates/mun_codegen/src/snapshots/test__equality_operands.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn equals(a:int, b:int):bool { a == b }\nfn not_equals(a:int, b:int):bool { a != b }\nfn less(a:int, b:int):bool { a < b }\nfn less_equal(a:int, b:int):bool { a <= b }\nfn greater(a:int, b:int):bool { a > b }\nfn greater_equal(a:int, b:int):bool { a >= b }\nfn equalsf(a:float, b:float):bool { a == b }\nfn not_equalsf(a:float, b:float):bool { a != b }\nfn lessf(a:float, b:float):bool { a < b }\nfn less_equalf(a:float, b:float):bool { a <= b }\nfn greaterf(a:float, b:float):bool { a > b }\nfn greater_equalf(a:float, b:float):bool { a >= b }"
---
; ModuleID = 'main.mun'
source_filename = "main.mun"

define i1 @equals(i64 %a, i64 %b) {
body:
%eq = icmp eq i64 %a, %b
ret i1 %eq
}

define i1 @not_equals(i64 %a, i64 %b) {
body:
%neq = icmp ne i64 %a, %b
ret i1 %neq
}

define i1 @less(i64 %a, i64 %b) {
body:
%less = icmp slt i64 %a, %b
ret i1 %less
}

define i1 @less_equal(i64 %a, i64 %b) {
body:
%lesseq = icmp sle i64 %a, %b
ret i1 %lesseq
}

define i1 @greater(i64 %a, i64 %b) {
body:
%greater = icmp sgt i64 %a, %b
ret i1 %greater
}

define i1 @greater_equal(i64 %a, i64 %b) {
body:
%greatereq = icmp sge i64 %a, %b
ret i1 %greatereq
}

define i1 @equalsf(double %a, double %b) {
body:
%eq = fcmp oeq double %a, %b
ret i1 %eq
}

define i1 @not_equalsf(double %a, double %b) {
body:
%neq = fcmp one double %a, %b
ret i1 %neq
}

define i1 @lessf(double %a, double %b) {
body:
%less = fcmp olt double %a, %b
ret i1 %less
}

define i1 @less_equalf(double %a, double %b) {
body:
%lesseq = fcmp ole double %a, %b
ret i1 %lesseq
}

define i1 @greaterf(double %a, double %b) {
body:
%greater = fcmp ogt double %a, %b
ret i1 %greater
}

define i1 @greater_equalf(double %a, double %b) {
body:
%greatereq = fcmp oge double %a, %b
ret i1 %greatereq
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn main() {\n}"
---
; ModuleID = 'main.mun'
source_filename = "main.mun"

define void @main() {
body:
ret void
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn main(a:int):int {\n a\n}"
---
; ModuleID = 'main.mun'
source_filename = "main.mun"

define i64 @main(i64 %a) {
body:
ret i64 %a
}

Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn add_impl(a:int, b:int):int {\n a+b\n}\n\nfn add(a:int, b:int):int {\n add_impl(a,b)\n}\n\nfn test():int {\n add(4,5)\n add_impl(4,5)\n add(4,5)\n}"
---
; ModuleID = 'main.mun'
source_filename = "main.mun"

Expand Down Expand Up @@ -28,3 +32,4 @@ body:
%add2 = call i64 %add_ptr1(i64 4, i64 5)
ret i64 %add2
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn main() {\n let a = 3+3.0;\n let b = 3.0+3;\n}"
---
error 2:13: mismatched type
error 3:15: mismatched type
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn main(a:int):int {\n let b = a+1\n b\n}"
---
; ModuleID = 'main.mun'
source_filename = "main.mun"

Expand All @@ -6,3 +10,4 @@ body:
%add = add i64 %a, 1
ret i64 %add
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn main():int {\n 0\n}"
---
; ModuleID = 'main.mun'
source_filename = "main.mun"

define i64 @main() {
body:
ret i64 0
}

Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
source: crates/mun_codegen/src/test.rs
expression: "fn add(a:int, b:int):int {\n let result = a\n result += b\n result\n}\n\nfn subtract(a:int, b:int):int {\n let result = a\n result -= b\n result\n}\n\nfn multiply(a:int, b:int):int {\n let result = a\n result *= b\n result\n}"
---
; ModuleID = 'main.mun'
source_filename = "main.mun"

Expand All @@ -18,3 +22,4 @@ body:
%mul = mul i64 %a, %b
ret i64 %a
}

Loading

0 comments on commit 2f892f5

Please sign in to comment.