diff --git a/cranelift-backend/src/lib.rs b/cranelift-backend/src/lib.rs index bf4d052..5f56c5c 100644 --- a/cranelift-backend/src/lib.rs +++ b/cranelift-backend/src/lib.rs @@ -334,6 +334,8 @@ impl FuncBuilder<'_, '_> { self.bl.ins().stack_store(v, slot, offset); offset += align as i32; } + self.values[arg as usize] = + Some(Ok(self.bl.ins().stack_addr(cir::types::I64, slot, 0))) } else { let loc = arg_vals.take(..abi_meta.arg_count).unwrap(); debug_assert_eq!(loc.len(), 1); @@ -516,6 +518,8 @@ impl FuncBuilder<'_, '_> { Err(self.block_of(block)) } Kind::Call { func, unreachable, args } => { + assert_ne!(func, hbty::Func::ECA, "@eca is not supported"); + if unreachable { todo!() } else { diff --git a/smh.hb b/smh.hb new file mode 100644 index 0000000..8273941 --- /dev/null +++ b/smh.hb @@ -0,0 +1,31 @@ +ResultInner := fn($T: type, $E: type): type return union {ok: T, err: E} + +Result := fn($T: type, $E: type): type return struct { + inner: ResultInner(T, E), + is_ok: bool, + + $ok := fn(k: T): Self return .(.{ok: k}, true) + $err := fn(k: E): Self return .(.{err: k}, false) + $unwrap := fn(self: Self): T return self.expect("Panic: Unwrap on Error Variant.\0".ptr) + $unwrap_unchecked := fn(self: Self): T return self.inner.ok + unwrap_or := fn(self: Self, v: T): T if self.is_ok return self.inner.ok else return v + unwrap_or_else := fn(self: Self, $F: type): T if self.is_ok return self.inner.ok else return F(self.inner.err) + expect := fn(self: Self, msg: ^u8): T if self.is_ok return self.inner.ok else { + @eca(0, msg) + die + } +} + +SomeError := enum { + SkillIssue, +} + +div := fn(a: uint, b: uint): Result(uint, SomeError) { + if b != 0 return Result(uint, SomeError).ok(a / b) + return Result(uint, SomeError).err(.SkillIssue) +} + +main := fn(): uint { + a := div(100, 0) + return a.expect("goof\0".ptr) +}