mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
- Order of attribute declaration is changed for `alias`. - Added `LANGUAGE_DEV_VERSION` env constant. - Rename `anyfault` -> `fault`. - Changed `fault` -> `faultdef`. - Added `attrdef` instead of `alias` for attribute aliases.
153 lines
4.3 KiB
Plaintext
153 lines
4.3 KiB
Plaintext
// #target: macos-x64
|
|
module demo;
|
|
import libc;
|
|
import std::io;
|
|
|
|
faultdef DIVISION_BY_ZERO;
|
|
|
|
fn int foo() { return 123; }
|
|
fn int bar() { return 0; }
|
|
|
|
fn double? divide(int a, int b)
|
|
{
|
|
if (b == 0) return DIVISION_BY_ZERO?;
|
|
return (double)(a) / (double)(b);
|
|
|
|
}
|
|
|
|
// Rethrowing an error uses "?" suffix
|
|
fn void? testMayError()
|
|
{
|
|
divide(foo(), bar())!;
|
|
}
|
|
|
|
fn void main()
|
|
{
|
|
// ratio has an optional type.
|
|
double? ratio = divide(foo(), bar());
|
|
|
|
// Handle the error
|
|
if (catch err = ratio)
|
|
{
|
|
if (err == DIVISION_BY_ZERO)
|
|
{
|
|
libc::printf("Division by zero\n");
|
|
return;
|
|
}
|
|
libc::printf("Unexpected error!");
|
|
return;
|
|
}
|
|
// Flow typing makes "ratio"
|
|
// have the type double here.
|
|
libc::printf("Ratio was %f\n", ratio);
|
|
}
|
|
|
|
/* #expect: demo.ll
|
|
|
|
|
|
define i64 @demo.divide(ptr %0, i32 %1, i32 %2) #0 {
|
|
entry:
|
|
%reterr = alloca i64, align 8
|
|
%eq = icmp eq i32 %2, 0
|
|
br i1 %eq, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %entry
|
|
ret i64 ptrtoint (ptr @demo.DIVISION_BY_ZERO to i64)
|
|
|
|
if.exit: ; preds = %entry
|
|
%sifp = sitofp i32 %1 to double
|
|
%sifp1 = sitofp i32 %2 to double
|
|
%fdiv = fdiv double %sifp, %sifp1
|
|
store double %fdiv, ptr %0, align 8
|
|
ret i64 0
|
|
}
|
|
|
|
define i64 @demo.testMayError() #0 {
|
|
entry:
|
|
%error_var = alloca i64, align 8
|
|
%retparam = alloca double, align 8
|
|
%0 = call i32 @demo.foo()
|
|
%1 = call i32 @demo.bar()
|
|
%2 = call i64 @demo.divide(ptr %retparam, i32 %0, i32 %1)
|
|
%not_err = icmp eq i64 %2, 0
|
|
%3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
|
br i1 %3, label %after_check, label %assign_optional
|
|
|
|
assign_optional: ; preds = %entry
|
|
store i64 %2, ptr %error_var, align 8
|
|
br label %guard_block
|
|
|
|
after_check: ; preds = %entry
|
|
br label %noerr_block
|
|
|
|
guard_block: ; preds = %assign_optional
|
|
%4 = load i64, ptr %error_var, align 8
|
|
ret i64 %4
|
|
|
|
noerr_block: ; preds = %after_check
|
|
ret i64 0
|
|
}
|
|
|
|
define void @demo.main() #0 {
|
|
entry:
|
|
%ratio = alloca double, align 8
|
|
%ratio.f = alloca i64, align 8
|
|
%retparam = alloca double, align 8
|
|
%err = alloca i64, align 8
|
|
%0 = call i32 @demo.foo()
|
|
%1 = call i32 @demo.bar()
|
|
%2 = call i64 @demo.divide(ptr %retparam, i32 %0, i32 %1)
|
|
%not_err = icmp eq i64 %2, 0
|
|
%3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
|
br i1 %3, label %after_check, label %assign_optional
|
|
|
|
assign_optional: ; preds = %entry
|
|
store i64 %2, ptr %ratio.f, align 8
|
|
br label %after_assign
|
|
|
|
after_check: ; preds = %entry
|
|
%4 = load double, ptr %retparam, align 8
|
|
store double %4, ptr %ratio, align 8
|
|
store i64 0, ptr %ratio.f, align 8
|
|
br label %after_assign
|
|
|
|
after_assign: ; preds = %after_check, %assign_optional
|
|
br label %testblock
|
|
|
|
testblock: ; preds = %after_assign
|
|
%optval = load i64, ptr %ratio.f, align 8
|
|
%not_err1 = icmp eq i64 %optval, 0
|
|
%5 = call i1 @llvm.expect.i1(i1 %not_err1, i1 true)
|
|
br i1 %5, label %after_check3, label %assign_optional2
|
|
|
|
assign_optional2: ; preds = %testblock
|
|
store i64 %optval, ptr %err, align 8
|
|
br label %end_block
|
|
|
|
after_check3: ; preds = %testblock
|
|
store i64 0, ptr %err, align 8
|
|
br label %end_block
|
|
|
|
end_block: ; preds = %after_check3, %assign_optional2
|
|
%6 = load i64, ptr %err, align 8
|
|
%i2b = icmp ne i64 %6, 0
|
|
br i1 %i2b, label %if.then, label %if.exit5
|
|
|
|
if.then: ; preds = %end_block
|
|
%7 = load i64, ptr %err, align 8
|
|
%eq = icmp eq i64 %7, ptrtoint (ptr @demo.DIVISION_BY_ZERO to i64)
|
|
br i1 %eq, label %if.then4, label %if.exit
|
|
|
|
if.then4: ; preds = %if.then
|
|
%8 = call i32 (ptr, ...) @printf(ptr @.str)
|
|
ret void
|
|
|
|
if.exit: ; preds = %if.then
|
|
%9 = call i32 (ptr, ...) @printf(ptr @.str.1)
|
|
ret void
|
|
|
|
if.exit5: ; preds = %end_block
|
|
%10 = load double, ptr %ratio, align 8
|
|
%11 = call i32 (ptr, ...) @printf(ptr @.str.2, double %10)
|
|
ret void
|
|
} |