The git repo for the project now has a way to encode predicates, which I figured was a good first step towards adding some useful control flow (IF+LOOPS). Specifically, the toy language/compiler now supports the following operators:
- <
- <=
- >
- >=
- EQ
- NE
This list works for any floating point or integer type (including BOOL, which is like “INT1”). I also added AND,OR,XOR (for integer types, including BOOL.) The grammar has a NOT operator, but it’s not implemented in the parser yet.
Here’s a sample program:
My MLIR is:
module { toy.program { toy.declare "b" : i1 toy.declare "i1" : i1 toy.declare "l16" : i16 %true = arith.constant true toy.assign "i1", %true : i1 %c-100_i64 = arith.constant -100 : i64 toy.assign "l16", %c-100_i64 : i64 %0 = toy.load "i1" : i1 %1 = toy.load "l16" : i16 %2 = "toy.less"(%0, %1) : (i1, i16) -> i1 toy.assign "b", %2 : i1 %3 = toy.load "b" : i1 toy.print %3 : i1 %4 = toy.load "i1" : i1 %5 = toy.load "l16" : i16 %6 = "toy.less"(%5, %4) : (i16, i1) -> i1 toy.assign "b", %6 : i1 %7 = toy.load "b" : i1 toy.print %7 : i1 toy.exit } }
Here’s the LLVM-IR after lowering:
declare void @__toy_print_f64(double) declare void @__toy_print_i64(i64) define i32 @main() !dbg !4 { %1 = alloca i1, i64 1, align 1, !dbg !8 #dbg_declare(ptr %1, !9, !DIExpression(), !8) %2 = alloca i1, i64 1, align 1, !dbg !11 #dbg_declare(ptr %2, !12, !DIExpression(), !11) %3 = alloca i16, i64 1, align 2, !dbg !13 #dbg_declare(ptr %3, !14, !DIExpression(), !13) store i1 true, ptr %2, align 1, !dbg !16 store i16 -100, ptr %3, align 2, !dbg !17 %4 = load i1, ptr %2, align 1, !dbg !18 %5 = load i16, ptr %3, align 2, !dbg !18 %6 = zext i1 %4 to i16, !dbg !18 %7 = icmp slt i16 %6, %5, !dbg !18 store i1 %7, ptr %1, align 1, !dbg !18 %8 = load i1, ptr %1, align 1, !dbg !19 %9 = zext i1 %8 to i64, !dbg !19 call void @__toy_print_i64(i64 %9), !dbg !19 %10 = load i1, ptr %2, align 1, !dbg !20 %11 = load i16, ptr %3, align 2, !dbg !20 %12 = zext i1 %10 to i16, !dbg !20 %13 = icmp slt i16 %11, %12, !dbg !20 store i1 %13, ptr %1, align 1, !dbg !20 %14 = load i1, ptr %1, align 1, !dbg !21 %15 = zext i1 %14 to i64, !dbg !21 call void @__toy_print_i64(i64 %15), !dbg !21 ret i32 0, !dbg !8 }
I’m going to want to try to refactor the type conversion logic, as what I have now in lowering is pretty clunky.