From 5716b1c9a72a25110f8a19ec2d72801de5da0f90 Mon Sep 17 00:00:00 2001 From: David Gonzalez Martin Date: Sun, 22 Jun 2025 15:58:31 -0600 Subject: [PATCH] wip --- tests/global.bbb | 3 +- tests/tests.bbb | 803 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 805 insertions(+), 1 deletion(-) create mode 100644 tests/tests.bbb diff --git a/tests/global.bbb b/tests/global.bbb index 1859a25..ddb293e 100644 --- a/tests/global.bbb +++ b/tests/global.bbb @@ -1,5 +1,6 @@ result: s32 = 0; -[export] main = fn [cc(c)] () s32 { +[export] main = fn [cc(c)] () s32 +{ return result; } diff --git a/tests/tests.bbb b/tests/tests.bbb new file mode 100644 index 0000000..e9590f9 --- /dev/null +++ b/tests/tests.bbb @@ -0,0 +1,803 @@ +require = fn (ok: u1) void +{ + if (!ok) + { + #trap(); + } +} + +return_constant = fn () s32 // This is a comment +// This is a comment +{ // This is a comment + // This is a comment + return 0; // This is a comment +}// This is a comment +// This is a comment + +constant_add = fn () s32 +{ + return -1 + 1; +} + +constant_and = fn () s32 +{ + return 1 & 2; +} + +constant_div = fn () s32 +{ + return 0 / 5; +} + +constant_mul = fn () s32 +{ + return 1 * 0; +} + +constant_rem = fn () s32 +{ + return 5 % 5; +} + +constant_or = fn () s32 +{ + return 0 % 0; +} + +constant_sub = fn () s32 +{ + return 1 - 1; +} + +constant_xor = fn () s32 +{ + return 0 ^ 0; +} + +constant_shift_left = fn () s32 +{ + return 0 << 1; +} + +constant_shift_right = fn () s32 +{ + return 0 >> 1; +} + +minimal_stack = fn () s32 +{ + >a: s32 = 0; + return a; +} + +minimal_stack_arithmetic0 = fn () s32 +{ + >a: s32 = 1; + return a - 1; +} + +minimal_stack_arithmetic1 = fn () s32 +{ + >a: s32 = 1; + >b = a - 1; + return b; +} + +minimal_stack_arithmetic2 = fn () s32 +{ + >a: s32 = 1; + >b = 1 - a; + return b; +} + +stack_negation = fn () s32 +{ + >v: s32 = 0; + return -v; +} + +stack_add = fn () s32 +{ + >a: s32 = -1; + >b: s32 = 1; + return a + b; +} + +stack_sub = fn () s32 +{ + >a: s32 = 1; + >b: s32 = 1; + return a - b; +} + +extend = fn () s32 +{ + >a: s8 = 0; + return #extend(a); +} + +integer_max = fn () s32 +{ + >a = #integer_max(u64); + return #truncate(a + 1); +} + +integer_hex = fn () s32 +{ + >result: s32 = 0x0; + return result; +} + +basic_pointer = fn () s32 +{ + >a: s32 = 0; + >pointer = &a; + return pointer.&; +} + +basic_call_foo = fn () s32 +{ + return 0; +} + +basic_call = fn () s32 +{ + return basic_call_foo(); +} + +basic_branch = fn () s32 +{ + >result: s32 = 1; + if (result != 1) + { + return 1; + } + else + { + return 0; + } +} + +basic_array = fn () s32 +{ + >array: [_]s32 = [3, 2, 1, 0]; + return array[3]; +} + +BasicEnum = enum +{ + zero = 0, + one = 1, + two = 2, + three = 3, +} + +basic_enum = fn () s32 +{ + >a: BasicEnum = .three; + >b: BasicEnum = .two; + >c: BasicEnum = .one; + >a_int: s32 = #extend(#int_from_enum(a)); + >b_int: s32 = #extend(#int_from_enum(b)); + >c_int: s32 = #extend(#int_from_enum(c)); + + return a_int - (b_int + c_int); +} + +basic_slice_receiver = fn (slice: []u8) void +{ + require(slice.length == 3); + require(slice[0] == 0); + require(slice[1] == 1); + require(slice[2] == 2); +} + +basic_slice = fn () void +{ + >a: [_]u8 = [0, 1, 2]; + basic_slice_receiver(a[..]); +} + +basic_string = fn () void +{ + >string = "abc"; + require(string[0] == 'a'); + require(string[1] == 'b'); + require(string[2] == 'c'); +} + +basic_varargs_function = fn [cc(c)] (first_arg: u32, ...) void +{ + require(first_arg == 123456789); + + >va = #va_start(); + + >a = #va_arg(&va, u32); + + require(a == 987654321); + + >first_arg_b = #va_arg(&va, u32); + require(first_arg == first_arg_b); +} + +basic_varargs = fn () void +{ + >first_arg: u32 = 123456789; + >a: u32 = 987654321; + basic_varargs_function(first_arg, a, first_arg); +} + +c_string_length = fn (c_string: &u8) u64 +{ + >it = c_string; + + while (it.&) + { + it = it + 1; + } + + return #int_from_pointer(it) - #int_from_pointer(c_string); +} + +basic_while = fn (argc: s32, argv: &&u8) void +{ + require(argc != 0); + + >first_arg = argv[0]; + require(first_arg != zero); + + >arg_length = c_string_length(first_arg); + require(arg_length != 0); + + require(first_arg[arg_length] == 0); +} + +pointer_function = fn (v: &s32) void +{ + v.& = 1; +} + +pointer = fn () s32 +{ + >value: s32 = 0; + pointer_function(&value); + return #extend(value == 0); +} + +pointer_cast = fn () s32 +{ + >result: u32 = 0; + >p = &result; + >signed_pointer: &s32 = #pointer_cast(p); + return signed_pointer.&; +} + +u1_return_foo = fn () u1 +{ + >result: u1 = 0; + return result; +} + +u1_return = fn () s32 +{ + >result = u1_return_foo(); + return #extend(result); +} + +local_type_inference_foo = fn () s32 +{ + return 0; +} + +local_type_inference = fn () s32 +{ + >a: s32 = 0; + >result = local_type_inference_foo() + a; + return result; +} + +basic_global_foo: s32 = 0; + +basic_global = fn () s32 +{ + return basic_global_foo; +} + +basic_function_pointer_callback = fn () s32 +{ + return 123; +} + +basic_function_pointer = fn () s32 +{ + >function_pointer = &basic_function_pointer_callback; + return function_pointer() - 123; +} + +[extern] strlen = fn [cc(c)] (string: &u8) s64; + +basic_extern = fn () void +{ + >length = strlen("abc"); + require(length == 3); +} + +basic_byte_size = fn () void +{ + >sizeofu8: u8 = #byte_size(u8); + require(sizeofu8 == 1); + >sizeofu16: u8 = #byte_size(u16); + require(sizeofu16 == 2); + >sizeofs32: s32 = #byte_size(s32); + require(sizeofs32 == 4); + >sizeofs64: s32 = #byte_size(s64); + require(sizeofs64 == 8); +} + +unsigned_assignment_operators = fn(n: s32) s32 +{ + >result: u32 = #extend(n); + result >>= 1; + result <<= 1; + result ^= 1; + result |= 1; + result &= 1; + result += 1; + result -= 1; + result /= 1; + result %= 1; + result *= 0; + + return #extend(result); +} + +assignment_operators = fn () s32 +{ + >result: s32 = 0; + >pointer = &result; + pointer -= 1; + pointer += 1; + result >>= 1; + result <<= 1; + result ^= 1; + result |= 1; + result &= 1; + result += 1; + result -= 1; + result /= 1; + result %= 1; + result *= 0; + return unsigned_assignment_operators(result); +} + +not_pointer = fn () s32 +{ + >a: s32 = 0; + >ptr = &a; + >b = !ptr; + return #extend(b); +} + +BasicBitField = bits u8 +{ + a: u2, + b: u2, + c: u2, + d: u2, +} + +basic_bits = fn () void +{ + >bf: BasicBitField = { + .a = 3, + .b = 2, + .c = 2, + .d = 3, + }; + + require(bf.a == 3); + require(bf.b == 2); + require(bf.c == 2); + require(bf.d == 3); +} + +BitsNoBackingType = bits +{ + a: u1, + b: u1, +} + +bits_no_backing_type = fn () void +{ + >bf: BitsNoBackingType = { + .a = 1, + .b = 1, + }; + + require(bf.a == 1); + require(bf.b == 1); +} + +BitsU1 = bits u32 +{ + a: u1, + b: u1, + c: u1, +} + +bits_return_u1_function = fn () u1 +{ + >b1: BitsU1 = { + .a = 1, + .b = 1, + .c = 0, + }; + + return b1.c; +} + +bits_return_u1 = fn () void +{ + >b1 = bits_return_u1_function(); + require(b1 == 0); +} + +BitsZero = bits +{ + a: u1, + b: u1, + c: u1, +} + +bits_zero = fn () void +{ + >a_bz: BitsZero = zero; + + require(a_bz.a == 0); + require(a_bz.b == 0); + require(a_bz.c == 0); + + >b_bz: BitsZero = { + .a = 1, + .b = 1, + zero, + }; + + require(b_bz.a == 1); + require(b_bz.b == 1); + require(b_bz.c == 0); +} + +basic_comparison_trivial = fn (a: s32, b: s32) u1 +{ + return a + 1 == b + 1; +} + +basic_comparison = fn (argument_count: s32) void +{ + require(basic_comparison_trivial(argument_count, argument_count)); +} + +BasicGlobalStruct = struct +{ + a: u32, + b: u32, + c: u32, +} + +basic_global_struct_variable: BasicGlobalStruct = { + .a = 1, + .b = 2, + .c = 3, +}; + +basic_global_struct = fn () void +{ + require(basic_global_struct_variable.a == 1); + require(basic_global_struct_variable.b == 2); + require(basic_global_struct_variable.c == 3); +} + +if_no_else = fn () s32 +{ + >a: s32 = 5; + if (a == 2) + { + return 1; + } + + return 0; +} + +if_no_else_void = fn () void +{ + >result: s32 = 0; + if (result != 0) + { + #trap(); + } +} + +Indirect = struct +{ + a: u32, + b: u32, + c: u32, + d: u32, + e: u32, + f: u32, +} + +indirect_ret = fn [cc(c)] () Indirect +{ + return { .a = 56, .b = 57, .c = 58, .d = 59, .e = 60, .f = 61 }; +} + +indirect_arg = fn [cc(c)] (s: Indirect) void +{ + require(s.a == 56); + require(s.b == 57); + require(s.c == 58); + require(s.d == 59); + require(s.e == 60); + require(s.f == 61); +} + +basic_indirect = fn () void +{ + >s = indirect_ret(); + require(s.a == 56); + require(s.b == 57); + require(s.c == 58); + require(s.d == 59); + require(s.e == 60); + require(s.f == 61); + indirect_arg(s); +} + +IndirectVarArgs = struct +{ + a: u64, + b: u64, + c: u64, + d: u64, + e: u64 + f: u64, + g: u64, + h: u64, + i: u64, + j: u64 +} + +indirect_varargs_function = fn [cc(c)] (first_arg: u32, ...) void +{ + if (first_arg != 123456789) + { + #trap(); + } + + >va = #va_start(); + + >s = #va_arg(&va, IndirectVarArgs); + require(s.a == 9); + require(s.b == 8); + require(s.c == 7); + require(s.d == 6); + require(s.e == 5); + require(s.f == 4); + require(s.g == 3); + require(s.h == 2); + require(s.i == 1); + require(s.j == 0); +} + +indirect_varargs = fn () void +{ + >first_arg: u32 = 123456789; + >s: IndirectVarArgs = { + .a = 9, + .b = 8, + .c = 7, + .d = 6, + .e = 5, + .f = 4, + .g = 3, + .h = 2, + .i = 1, + .j = 0, + }; + indirect_varargs_function(first_arg, s); +} + +return_type_builtin = fn () s32 +{ + >result: #ReturnType = 0; + return result; +} + +Struct_u64_u64 = struct +{ + a: u64, + b: u64, +} + +return_struct_u64_u64_function = fn [cc(c)] () Struct_u64_u64 +{ + return { .a = 1, .b = 2 }; +} + +return_struct_u64_u64 = fn [cc(c)] () s32 +{ + >r = return_struct_u64_u64_function(); + return #truncate(r.a + r.b - 3); +} + +select = fn () s32 +{ + >boolean: u1 = 1; + >left: s32 = 0; + >right: s32 = 1; + return #select(boolean, left, right); +} + +slice2 = fn (argc: s32, argv: &&u8) void +{ + require(argc != 0); + >arg_ptr = argv[0]; + >a1 = arg_ptr[0..c_string_length(arg_ptr)]; + >a2 = a1[1..]; + + require(a1.pointer == a2.pointer - 1); + require(a1.length == a2.length + 1); +} + +[export] main = fn [cc(c)] (argc: s32, argv: &&u8, envp: &&u8) s32 +{ + >rc = return_constant(); + require(rc == 0); + + >const_add = constant_add(); + require(const_add == 0); + + >const_and = constant_and(); + require(const_and == 0); + + >const_div = constant_div(); + require(const_div == 0); + + >const_mul = constant_mul(); + require(const_mul == 0); + + >const_rem = constant_rem(); + require(const_rem == 0); + + >const_or = constant_or(); + require(const_or == 0); + + >const_sub = constant_sub(); + require(const_sub == 0); + + >const_xor = constant_xor(); + require(const_xor == 0); + + >const_shift_left = constant_shift_left(); + require(const_shift_left == 0); + + >const_shift_right = constant_shift_right(); + require(const_shift_right == 0); + + >min_stack = minimal_stack(); + require(min_stack == 0); + + >min_stack_arithmetic0 = minimal_stack_arithmetic0(); + require(min_stack_arithmetic0 == 0); + + >min_stack_arithmetic1 = minimal_stack_arithmetic1(); + require(min_stack_arithmetic1 == 0); + + >min_stack_arithmetic2 = minimal_stack_arithmetic2(); + require(min_stack_arithmetic2 == 0); + + >st_neg = stack_negation(); + require(st_neg == 0); + + >st_add = stack_add(); + require(st_add == 0); + + >st_sub = stack_sub(); + require(st_sub == 0); + + >ext = extend(); + require(ext == 0); + + >int_max = integer_max(); + require(int_max == 0); + + >int_hex = integer_hex(); + require(int_hex == 0); + + >b_pointer = basic_pointer(); + require(b_pointer == 0); + + >b_call = basic_call(); + require(b_call == 0); + + >b_branch = basic_branch(); + require(b_branch == 0); + + >b_array = basic_array(); + require(b_array == 0); + + >b_enum = basic_enum(); + require(b_enum == 0); + + basic_slice(); + + basic_string(); + + basic_varargs(); + + basic_while(argc, argv); + + >p = pointer(); + require(p == 0); + + >pc = pointer_cast(); + require(pc == 0); + + >u1_ret = u1_return(); + require(u1_ret == 0); + + >lti = local_type_inference(); + require(lti == 0); + + >bg = basic_global(); + require(bg == 0); + + >bfp = basic_function_pointer(); + require(bfp == 0); + + basic_extern(); + + basic_byte_size(); + + >assignment_ops = assignment_operators(); + require(assignment_ops == 0); + + >np = not_pointer(); + require(np == 0); + + basic_bits(); + + bits_no_backing_type(); + + bits_return_u1(); + + bits_zero(); + + basic_comparison(argc); + + basic_global_struct(); + + >if_ne = if_no_else(); + require(if_ne == 0); + + if_no_else_void(); + + basic_indirect(); + + indirect_varargs(); + + >rtb = return_type_builtin(); + require(rtb == 0); + + >rs6464 = return_struct_u64_u64(); + require(rs6464 == 0); + + >sel = select(); + require(sel == 0); + + slice2(argc, argv); + + return 0; +}