no :: in func decls

This commit is contained in:
2026-06-30 19:31:26 +02:00
parent ae5af37b85
commit 07c560b750
107 changed files with 580 additions and 520 deletions
+7 -7
View File
@@ -14,7 +14,7 @@ types. C primitives use atomic target-dependent names and remain semantically
distinct from exact-width Brolang primitives:
```bro
strlen :: c_func(value *c_char) c_ulong
strlen c_func(value *c_char) c_ulong
```
Additional native inputs and libraries are passed to the final `zig cc`
@@ -35,7 +35,7 @@ Relative `.h` imports create synthetic package namespaces backed by libclang:
```bro
native :: import "../include/native.h"
main :: func() void {
main func() void {
_ = native.imported_add(20, 22)
}
```
@@ -63,11 +63,11 @@ from Brolang requires an explicit unwrap:
```bro
native :: import "../include/native.h"
double :: c_func(value c_int) c_int {
double c_func(value c_int) c_int {
return value + value
}
call_mapper :: func(mapper native.Imported_Mapper) c_int {
call_mapper func(mapper native.Imported_Mapper) c_int {
return mapper?(21)
}
```
@@ -75,16 +75,16 @@ call_mapper :: func(mapper native.Imported_Mapper) c_int {
Bodyless manual and imported C functions may be variadic:
```bro
log_values :: c_func(tag c_int, ...) c_int
log_values c_func(tag c_int, ...) c_int
```
Zero-terminated byte strings can be passed directly to immutable C character
pointers without making `u8` and `c_char` generally interchangeable:
```bro
printf :: c_func(format *c_char, ...) c_int
printf c_func(format *c_char, ...) c_int
main :: func() void {
main func() void {
_ = printf("answer: %d\n", 42)
}
```
+17 -17
View File
@@ -223,7 +223,7 @@
14.5. backward type-demand propagation through call boundaries (DEFERRED)
- a callee's result/return demand flows back through the function body to constrain
the caller's arguments, so `R u32 :: echo(A)` (with `echo :: func(p int) int`)
the caller's arguments, so `R u32 :: echo(A)` (with `echo func(p int) int`)
resolves A to u32 instead of erroring at the call's result coercion
- requires reversing the per-call data flow: a specialization's argument types
(`spec.args`) become outputs to solve, not just inputs — a new back-edge threaded
@@ -981,7 +981,7 @@ Milestone 23 v1 implements named error channels, native sum composition, `return
Functions that can fail declare their error type after `!`:
```
read_file :: func(path []u8) []u8 ! IoError { ... }
read_file func(path []u8) []u8 ! IoError { ... }
```
This reads as: "returns `[]u8` or fails with `IoError`." The space around `!` is idiomatic but not required.
@@ -1035,7 +1035,7 @@ Functions that can fail with multiple error types use `|` to compose a named err
```
ProcessError :: alias IoError | ParseError
process :: func(path []u8) Ast ! ProcessError { ... }
process func(path []u8) Ast ! ProcessError { ... }
```
Parentheses are optional in the composed type and can aid readability:
@@ -1053,7 +1053,7 @@ Inline error types are planned, but not part of milestone 23 v1. Use named enums
Fallible functions use ordinary `return` for both channels. If the returned expression coerces to the success type `T`, the function returns success with channel code `0`. If it coerces to the error type `E`, the function returns the error with that variant's global tag id:
```
parse_section :: func(p: @mut Parser) void ! ParseError {
parse_section func(p: @mut Parser) void ! ParseError {
start_line Line = p.line
p.advance()
@@ -1086,7 +1086,7 @@ The `try` keyword unwraps a successful result or returns early with the error:
```
ProcessError :: alias IoError | ParseError
process :: func(path []u8) Ast ! ProcessError {
process func(path []u8) Ast ! ProcessError {
data :: try read_file(path) # read_file also returns []u8 ! ProcessError in v1
ast :: try parse(data) # parse also returns Ast ! ProcessError in v1
return ast
@@ -1195,7 +1195,7 @@ Brolang provides a **thread-local global heap allocator** that is:
```
import "std/mem/heap"
process :: func(input []u8) u64 {
process func(input []u8) u64 {
# heap used for internal temporary work — does not escape
temp := heap.alloc(u8, size: input.len * 2)
defer heap.free(temp)
@@ -1227,20 +1227,20 @@ import "std/mem"
import "std/mem/heap"
# Allocation escapes via return value — requires allocator
duplicate :: func(input []u8, allocator @mem.Allocator) []u8 {
duplicate func(input []u8, allocator @mem.Allocator) []u8 {
result := allocator.alloc(u8, size: input.len)
mem.copy(result, input)
return result # caller manages this memory
}
# Allocation escapes via mutable parameter — requires allocator
init :: func(obj: @mut MyStruct, allocator: @mem.Allocator) void {
init func(obj: @mut MyStruct, allocator: @mem.Allocator) void {
obj.buffer = allocator.alloc(u8, size: 100)
# caller now knows heap memory was written into obj
}
# No allocation escapes — no allocator needed
process :: func(input: []u8) u64 {
process func(input: []u8) u64 {
temp := heap.alloc(u8, size: input.len)
defer heap.free(temp)
# ... work with temp ...
@@ -1248,11 +1248,11 @@ process :: func(input: []u8) u64 {
}
# No heap allocation at all — no allocator needed
reset :: func(obj: @mut MyStruct) void {
reset func(obj: @mut MyStruct) void {
obj.count = 0
}
main :: func() void {
main func() void {
data := duplicate("hello", heap)
defer heap.free(data)
@@ -1302,7 +1302,7 @@ For specialized needs, you create explicit allocator instances. These are not gl
import "std/mem"
import "std/mem/heap"
process_file :: func(path: []u8, allocator: @mem.Allocator) !Data {
process_file func(path: []u8, allocator: @mem.Allocator) !Data {
# arena manages its own backing memory via heap
arena := mem.Arena.init(heap, capacity: mem.megabytes(1))
defer arena.deinit()
@@ -1333,17 +1333,17 @@ EntitySystem :: struct {
pool: mem.Pool(Entity),
}
init_entities :: func(allocator: @mem.Allocator) EntitySystem {
init_entities func(allocator: @mem.Allocator) EntitySystem {
return EntitySystem{
pool = mem.Pool(Entity).init(allocator, capacity: 10_000),
}
}
spawn :: func(sys: @mut EntitySystem) @Entity {
spawn func(sys: @mut EntitySystem) @Entity {
return sys.pool.alloc() # O(1), no fragmentation
}
despawn :: func(sys: @mut EntitySystem, entity: @Entity) void {
despawn func(sys: @mut EntitySystem, entity: @Entity) void {
sys.pool.free(entity) # returned to pool for reuse
}
```
@@ -1356,7 +1356,7 @@ As described in the escaping allocation rule, when a function heap-allocates mem
import "std/mem"
# Function that uses caller's allocator
parse :: func(input: []u8, allocator: @mem.Allocator) !ParseResult {
parse func(input: []u8, allocator: @mem.Allocator) !ParseResult {
buffer := allocator.alloc(u8, size: input.len)
defer allocator.free(buffer)
@@ -1367,7 +1367,7 @@ parse :: func(input: []u8, allocator: @mem.Allocator) !ParseResult {
}
# Caller decides which allocator to use
main :: func() void {
main func() void {
# use an arena for this parsing work
arena := mem.Arena.init(heap, capacity: mem.kilobytes(64))
defer arena.deinit()
+2 -2
View File
@@ -24,8 +24,8 @@ Metrics :: struct {
make_source :: proc(repetitions: int, allocator := context.allocator) -> string {
builder := strings.builder_make(allocator)
defer strings.builder_destroy(&builder)
strings.write_string(&builder, "identity :: func(value int) int { return value }\n")
strings.write_string(&builder, "main :: func() i32 {\n\tacc i32 = 0\n")
strings.write_string(&builder, "identity func(value int) int { return value }\n")
strings.write_string(&builder, "main func() i32 {\n\tacc i32 = 0\n")
for _ in 0 ..< repetitions {
strings.write_string(&builder, "\t_ = identity(acc)\n\tacc = acc + 1\n")
}
+7
View File
@@ -2256,6 +2256,11 @@ parse_top_level :: proc(parser: ^Parser) {
}
parser.cursor = saved
}
if current(parser).kind == .Keyword_Func || current(parser).kind == .Keyword_C_Func {
c_abi := current(parser).kind == .Keyword_C_Func
parse_function(parser, name, c_abi)
return
}
type_syntax := types.INVALID
if is_type_token(current(parser).kind) {
type_syntax = parse_type(parser)
@@ -2271,6 +2276,8 @@ parse_top_level :: proc(parser: ^Parser) {
if operator.kind == .Colon_Colon &&
(current(parser).kind == .Keyword_Func || current(parser).kind == .Keyword_C_Func) {
source.add(parser.diagnostics, span_from(name.span, current(parser).span),
"function declarations do not use '::'; write 'name func(...)' or 'name c_func(...)'")
c_abi := current(parser).kind == .Keyword_C_Func
parse_function(parser, name, c_abi)
return
+1 -1
View File
@@ -279,7 +279,7 @@ emit_functions :: proc(b: ^strings.Builder, result: ^cimport.Result, record_name
wrote = true
continue
}
fmt.sbprintf(b, "%s :: ", function.name)
fmt.sbprintf(b, "%s ", function.name)
render_c_func(b, result, function.params, function.param_names, function.result, function.variadic, record_names)
strings.write_byte(b, '\n')
wrote = true
+365 -312
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -3,8 +3,8 @@ Buffer :: c_struct {
length c_ulong
}
get_buffer :: c_func() @Buffer
verify :: c_func(
get_buffer c_func() @Buffer
verify c_func(
char_value c_char,
schar_value c_schar,
uchar_value c_uchar,
@@ -21,7 +21,7 @@ verify :: c_func(
longdouble_value c_longdouble,
) i32
main :: func() i32 {
main func() i32 {
buffer @Buffer :: get_buffer()
_ = buffer^.data
_ = buffer^.length
+5 -5
View File
@@ -1,22 +1,22 @@
native :: import "../include/native.h"
pass_alias :: func(value native.imported_int_alias) native.imported_int {
pass_alias func(value native.imported_int_alias) native.imported_int {
return value
}
double_value :: c_func(value c_int) c_int {
double_value c_func(value c_int) c_int {
return value + value
}
call_mapper :: func(mapper native.Imported_Mapper) c_int {
call_mapper func(mapper native.Imported_Mapper) c_int {
return mapper?(21)
}
enum_identity :: c_func(value native.Imported_Enum) native.Imported_Enum {
enum_identity c_func(value native.Imported_Enum) native.Imported_Enum {
return value
}
main :: func() void {
main func() void {
_ = native.imported_add(pass_alias(20), 22)
_ = native.imported_scalar(3, 4)
_ = native.child_value(7)
+1 -1
View File
@@ -1,4 +1,4 @@
first :: import "../header/include/native.h"
second :: import "../header/include/native.h"
main :: func() void {}
main func() void {}
+1 -1
View File
@@ -1,7 +1,7 @@
first :: import "first.h"
second :: import "second.h"
main :: func() void {
main func() void {
_ = first.conflict_global
_ = second.conflict_global
}
+1 -1
View File
@@ -1,7 +1,7 @@
native :: import "../header/include/native.h"
child :: import "../header/include/child.h"
main :: func() void {
main func() void {
_ = native.child_value(1)
_ = child.child_value(2)
native.child_shared_global = 7
@@ -1,5 +1,5 @@
native :: import "native.h"
main :: func() void {
main func() void {
_ = native.main
}
@@ -1,7 +1,7 @@
variable :: import "variable.h"
function :: import "function.h"
main :: func() void {
main func() void {
_ = variable.conflict_symbol
_ = function.conflict_symbol()
}
+5 -5
View File
@@ -1,11 +1,11 @@
native :: import "../header/include/native.h"
use_callback :: c_func(value native.Imported_Callback) void
use_union :: c_func(value native.Imported_Union) void
use_enum :: c_func(value native.Imported_Enum) void
use_opaque :: c_func(value native.Imported_Handle) void
use_callback c_func(value native.Imported_Callback) void
use_union c_func(value native.Imported_Union) void
use_enum c_func(value native.Imported_Enum) void
use_opaque c_func(value native.Imported_Handle) void
main :: func() void {
main func() void {
_ = native.IMPORTED_BAD_EXPR
_ = native.IMPORTED_REDEFINED_BAD
_ = native.IMPORTED_GONE
@@ -1,5 +1,5 @@
native :: import "native.h"
main :: func() void {
main func() void {
_ = native.write
}
+2 -2
View File
@@ -1,5 +1,5 @@
foreign_add :: c_func(a, b i32) i32
foreign_add c_func(a, b i32) i32
main :: func() i32 {
main func() i32 {
return foreign_add(20, 22)
}
+2 -2
View File
@@ -1,5 +1,5 @@
printf :: c_func(format *c_char, ...) c_int
printf c_func(format *c_char, ...) c_int
main :: func() void {
main func() void {
_ = printf("answer: %d\n", 42)
}
+4 -4
View File
@@ -4,21 +4,21 @@ Manual :: c_struct {
value c_int
}
mirror_manual :: c_func(value Manual) Manual {
mirror_manual c_func(value Manual) Manual {
return value
}
mirror_large :: c_func(value native.Large) native.Large {
mirror_large c_func(value native.Large) native.Large {
return value
}
native_pair :: func(value native.Pair) native.Pair {
native_pair func(value native.Pair) native.Pair {
return value
}
global_pair native.Pair :: native.Pair { left = 1, right = 2 }
main :: func() i32 {
main func() i32 {
pair native.Pair = native_pair(global_pair)
pair.left = 10
pair = native.echo_pair(pair)
+1 -1
View File
@@ -4,7 +4,7 @@ native :: import "../include/native.h"
# the importer must not recurse forever populating it, and the checker must accept the
# self-referential `?*mut Node` field as C-layout-compatible.
main :: func() i32 {
main func() i32 {
node native.Node = native.Node { next = none, value = 7 }
if node.next |_| {
return 1
+1 -1
View File
@@ -1,3 +1,3 @@
import "/definitely/not/a/brolang/package"
main :: func() void {}
main func() void {}
@@ -1,6 +1,6 @@
math i32 :: 7
import "../math"
main :: func() i32 {
main func() i32 {
return math
}
+1 -1
View File
@@ -1,6 +1,6 @@
left :: import "../math"
right :: import "../math"
main :: func() i32 {
main func() i32 {
return left.value + right.value
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../math"
main :: func() i32 {
main func() i32 {
return math.sum(local_value, math.value)
}
+1 -1
View File
@@ -1,5 +1,5 @@
value i32 :: 2
sum :: func(a, b i32) i32 {
sum func(a, b i32) i32 {
return a + b
}
+1 -1
View File
@@ -1,7 +1,7 @@
import "../left"
import "../right"
main :: func() void {
main func() void {
_ = left.same()
_ = right.same()
}
+1 -1
View File
@@ -1,3 +1,3 @@
same :: c_func() int {
same c_func() int {
return 1
}
+1 -1
View File
@@ -1,3 +1,3 @@
same :: c_func() int {
same c_func() int {
return 2
}
+1 -1
View File
@@ -2,6 +2,6 @@ import "../b"
seed i32 :: 4
run :: func() i32 {
run func() i32 {
return b.value
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../a"
main :: func() i32 {
main func() i32 {
return a.run()
}
@@ -1,5 +1,5 @@
import "./level_three"
value :: func() i32 {
value func() i32 {
return level_three.value
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "./level_two"
value :: func() i32 {
value func() i32 {
return level_two.value()
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "./level_one"
main :: func() i32 {
main func() i32 {
return level_one.value()
}
@@ -1,3 +1,3 @@
import "../bad-name"
main :: func() void {}
main func() void {}
+1 -1
View File
@@ -1,6 +1,6 @@
math :: import "../math"
math :: import "../math"
main :: func() i32 {
main func() i32 {
return math.value
}
+1 -1
View File
@@ -1,3 +1,3 @@
import "../eager"
main :: func() void {}
main func() void {}
+1 -1
View File
@@ -1,3 +1,3 @@
import "../empty"
main :: func() void {}
main func() void {}
@@ -1,5 +1,5 @@
good :: import "../bad-name"
main :: func() i32 {
main func() i32 {
return good.value
}
+1 -1
View File
@@ -1,3 +1,3 @@
import "../not_package.bro"
main :: func() void {}
main func() void {}
@@ -1 +1 @@
main :: func() void {}
main func() void {}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../math"
used_here :: func() int {
used_here func() int {
return math.value
}
+2 -2
View File
@@ -1,8 +1,8 @@
not_imported_here :: func() int {
not_imported_here func() int {
return math.value
}
main :: func() void {
main func() void {
_ = used_here()
_ = not_imported_here()
}
@@ -1,7 +1,7 @@
import "../left"
import "../right"
main :: func() void {
main func() void {
_ = left.same()
_ = right.same()
}
@@ -1 +1 @@
same :: c_func() i32
same c_func() i32
@@ -1 +1 @@
same :: c_func() i32
same c_func() i32
+1 -1
View File
@@ -1,5 +1,5 @@
import "../math"
main :: func() i32 {
main func() i32 {
return math.identity(127 + 1)
}
+1 -1
View File
@@ -1,3 +1,3 @@
identity :: func(value int) int {
identity func(value int) int {
return value
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../a"
main :: func() void {
main func() void {
_ = a.value
}
+1 -1
View File
@@ -1,4 +1,4 @@
main :: func() i32 {
main func() i32 {
return math.value
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../dep"
main :: func() i32 {
main func() i32 {
return dep.main()
}
+1 -1
View File
@@ -1,3 +1,3 @@
main :: func() i32 {
main func() i32 {
return 7
}
+2 -2
View File
@@ -1,7 +1,7 @@
import "../math"
unused :: func() int {
unused func() int {
return math.missing
}
main :: func() void {}
main func() void {}
@@ -1,3 +1,3 @@
main :: func() i32 {
main func() i32 {
return 1
}
@@ -1,3 +1,3 @@
import "../missing"
main :: func() void {}
main func() void {}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../missing"
main :: func() void {
main func() void {
_ = missing.value
}
@@ -1,5 +1,5 @@
import "../bridge"
main :: func() void {
main func() void {
_ = bridge.value
}
@@ -1,5 +1,5 @@
import "../math"
read :: func() i32 {
read func() i32 {
return math.value
}
@@ -1,3 +1,3 @@
import "../broken"
main :: func() void {}
main func() void {}
@@ -1,9 +1,9 @@
import "../math"
read :: func(value i8) int {
read func(value i8) int {
return math.value
}
main :: func() i32 {
main func() i32 {
return read(1)
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../b"
one :: func(value int) i32 {
one func(value int) i32 {
return b.two(value)
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../a"
main :: func() i32 {
main func() i32 {
return a.one(1)
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../a"
two :: func(value int) i32 {
two func(value int) i32 {
return a.one(value)
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../math"
from_a :: func() i32 {
from_a func() i32 {
return math.value
}
+1 -1
View File
@@ -1,5 +1,5 @@
import "../math"
main :: func() i32 {
main func() i32 {
return from_a() + math.value
}
+1 -1
View File
@@ -2,6 +2,6 @@ self :: import "."
value i32 :: 5
main :: func() i32 {
main func() i32 {
return self.value
}
+1 -1
View File
@@ -1,3 +1,3 @@
import "../math"
main :: func() void {}
main func() void {}
+1 -1
View File
@@ -5,7 +5,7 @@
# innermost enclosing loop. Each section returns a distinct code on failure so
# a regression points at the broken behaviour; success falls through to 42.
main :: func() i32 {
main func() i32 {
# 1. `break` out of a `while` once i reaches 5.
i i32 = 0
a i32 = 0
@@ -1,7 +1,7 @@
# Milestone 6: compound assignment (`+=`, `-=`, `*=`, `/=`) and the binary
# arithmetic operators `-`, `*`, `/` with multiplicative precedence.
check_float :: func() i32 {
check_float func() i32 {
x f64 = 10.0
x /= 4.0 # 2.5
x *= 2.0 # 5.0
@@ -13,7 +13,7 @@ check_float :: func() i32 {
return 0
}
check_unsigned :: func() i32 {
check_unsigned func() i32 {
n u32 = 100
n /= 7 # 14 (truncating integer division)
n -= 4 # 10
@@ -23,7 +23,7 @@ check_unsigned :: func() i32 {
return 0
}
main :: func() i32 {
main func() i32 {
total i32 = 0
total += 10 # 10
total -= 3 # 7
@@ -1,11 +1,11 @@
# Milestone 5: conditional optional unwrapping, guards, and multi-unwrap.
observe :: func(counter @mut i32, value ?i32) ?i32 {
observe func(counter @mut i32, value ?i32) ?i32 {
counter^ = counter^ + 1
return value
}
main :: func() i32 {
main func() i32 {
total i32 = 0
# present optional scalar -> binds v to the unwrapped value
@@ -1,4 +1,4 @@
main :: func() void {
main func() void {
value i8 :: 127 + 1
_ = value
}
+1 -1
View File
@@ -1,3 +1,3 @@
main :: func() void {
main func() void {
_ = 127 + 1
}
@@ -1,3 +1,3 @@
main :: func() void {
main func() void {
_ = 9223372036854775807 + 1
}
+4 -4
View File
@@ -1,9 +1,9 @@
# Milestone 5 foundation: booleans, comparisons, logical ops, if/else if/else.
printf :: c_func(format *c_char, ...) c_int
printf c_func(format *c_char, ...) c_int
# Returns a distinct code per range using if / else if / else and comparisons.
classify :: func(n i32) i32 {
classify func(n i32) i32 {
if n < 0 {
return 1
} else if n == 0 {
@@ -17,12 +17,12 @@ classify :: func(n i32) i32 {
# A bool-returning function with a visible side effect, used to prove
# short-circuit evaluation: it must only print when actually evaluated.
noisy :: func() bool {
noisy func() bool {
_ = printf("rhs-evaluated\n")
return true
}
main :: func() i32 {
main func() i32 {
total i32 = 0
# comparisons drive if / else if / else
+1 -1
View File
@@ -1,6 +1,6 @@
a int :: b
b int :: a
main :: func() void {
main func() void {
_ = 1
}
+1 -1
View File
@@ -1,6 +1,6 @@
a int :: b
b int :: a
main :: func() void {
main func() void {
_ = a
}
+3 -3
View File
@@ -6,7 +6,7 @@
# The return value is captured before defers run, so the mutation here does not
# change what is returned (Zig semantics).
spill_check :: func() i32 {
spill_check func() i32 {
x i32 = 5
defer x = 999
return x
@@ -14,7 +14,7 @@ spill_check :: func() i32 {
# A function-scope defer runs only at function exit; a `break` runs the loop-body
# defer but NOT the enclosing function-scope defer.
enclosing_defer_check :: func() i32 {
enclosing_defer_check func() i32 {
v i32 = 0
defer v = v + 100
for 0..3 |i| {
@@ -24,7 +24,7 @@ enclosing_defer_check :: func() i32 {
return v # 0->1 (i=0 fall-through), ->2 (i=1 break); the +100 runs after capture
}
main :: func() i32 {
main func() i32 {
# 1. return value captured before defers run.
if (spill_check() != 5) return 101
+1 -1
View File
@@ -1,5 +1,5 @@
UserID :: distinct u32
make :: func(value u32) UserID {
make func(value u32) UserID {
return UserID(value)
}
+2 -2
View File
@@ -12,11 +12,11 @@ WrappedID :: distinct LocalID
static_id LocalID :: LocalID(42)
take :: func(value LocalID) LocalID {
take func(value LocalID) LocalID {
return value
}
main :: func() i32 {
main func() i32 {
id LocalID :: LocalID(7)
copy LocalID = take(id)
maybe ?LocalID = copy
+1 -1
View File
@@ -3,6 +3,6 @@ Animal :: enum {
cat
}
favorite :: func() Animal {
favorite func() Animal {
return .cat
}
+3 -3
View File
@@ -8,15 +8,15 @@ State :: enum(u16) {
initial State :: State.started
same :: func(left State, right State) bool {
same func(left State, right State) bool {
return left == right
}
identity :: c_func(value State) State {
identity c_func(value State) State {
return value
}
main :: func() i32 {
main func() i32 {
state State = identity(.running)
values [2]State :: [.started, State.stopped]
animal animals.Animal :: animals.Animal.dog
+6 -6
View File
@@ -28,37 +28,37 @@ BoxB :: union(enum) {
Box :: alias BoxA | BoxB
maybe :: func(value i32) i32 ! BasicError {
maybe func(value i32) i32 ! BasicError {
if (value == 0) return .bad
return value + 1
}
via_try :: func(value i32) i32 ! BasicError {
via_try func(value i32) i32 ! BasicError {
unwrapped :: try maybe(value)
return unwrapped + 1
}
with_detail :: func(value i32) i32 ! DetailError {
with_detail func(value i32) i32 ! DetailError {
if (value == 0) return DetailError{ code = 5 }
if (value == 1) return .empty
return value
}
pick :: func(value Both) i32 {
pick func(value Both) i32 {
match value {
.left: return 10
.right: return 20
}
}
payload :: func(value Box) i32 {
payload func(value Box) i32 {
match value {
.a |n|: return n
.b: return 3
}
}
main :: func() i32 {
main func() i32 {
acc i32 = 0
a :: maybe(0) catch 7
+2 -2
View File
@@ -1,10 +1,10 @@
# Milestone 5: ranges and sequence for loops.
pass :: func(value range) range {
pass func(value range) range {
return value
}
main :: func() i32 {
main func() i32 {
total i32 = 0
items [3]mut i32 = [1, 2, 3]
+2 -2
View File
@@ -1,11 +1,11 @@
make_range :: func(calls @mut i32, end usize) range {
make_range func(calls @mut i32, end usize) range {
calls^ = calls^ + 1
return 0..end
}
global_range :: 0..1
main :: func() i32 {
main func() i32 {
total i32 = 0
first u8 = 254
@@ -1,9 +1,9 @@
bad int = 1
read_bad :: func() int {
read_bad func() int {
return bad
}
derived :: read_bad()
main :: func() void {}
main func() void {}
@@ -1,11 +1,11 @@
bad int = 1
read_bad :: func() int {
read_bad func() int {
return bad
}
derived :: read_bad()
main :: func() void {
main func() void {
_ = derived
}
@@ -1,11 +1,11 @@
bad int = 4
read_bad :: func() int {
read_bad func() int {
return bad
}
derived int :: read_bad()
main :: func() void {
main func() void {
_ = 1
}
@@ -1,11 +1,11 @@
bad int = 4
read_bad :: func() int {
read_bad func() int {
return bad
}
derived int :: read_bad()
main :: func() void {
main func() void {
_ = derived
}
@@ -1,7 +1,7 @@
broken :: func(value int) int {
broken func(value int) int {
return missing + value
}
main :: func() void {
main func() void {
_ = 1
}
@@ -1,5 +1,5 @@
bad int = 4
main :: func() void {
main func() void {
_ = 1
}
@@ -1,7 +1,7 @@
broken :: func(value int) int {
broken func(value int) int {
return missing + value
}
main :: func() void {
main func() void {
_ = broken(1)
}
@@ -1,5 +1,5 @@
bad int = 4
main :: func() void {
main func() void {
_ = bad
}
+1 -1
View File
@@ -1,3 +1,3 @@
main :: func() i32 {
main func() i32 {
return 4
}
+1 -1
View File
@@ -1,3 +1,3 @@
main :: func() int {
main func() int {
return 3
}
@@ -1,12 +1,12 @@
take :: func(value i8) i8 {
take func(value i8) i8 {
return value
}
bad_return :: func() i8 {
bad_return func() i8 {
return missing
}
main :: func() void {
main func() void {
_ = take(missing)
_ = bad_return()
}
+5 -5
View File
@@ -30,7 +30,7 @@ Box :: union(enum) {
# Statement match with payload capture; every variant returns, so the function needs
# no trailing return (the desugared if/else chain covers all paths).
describe :: func(d Data) i32 {
describe func(d Data) i32 {
match d {
.dog |age|: return age + 1
.bird |wingspan|: return wingspan + 2
@@ -38,7 +38,7 @@ describe :: func(d Data) i32 {
}
# Value match: single-expression arms yield implicitly, a block arm yields explicitly.
area :: func(s Shape) i32 {
area func(s Shape) i32 {
result :: match s {
.square |side|: side * side
.circle |r|: {
@@ -51,18 +51,18 @@ area :: func(s Shape) i32 {
# Same-type multi-pattern capture: `.dog` and `.bird` are both i32, so one capture binds
# either payload (read once at the union's shared carrier offset).
payload_of :: func(d Data) i32 {
payload_of func(d Data) i32 {
v :: match d {
.dog, .bird |n|: n
}
return v
}
make_box :: func() Box {
make_box func() Box {
return Box{ point = Point{ x = 4, y = 0 } }
}
main :: func() i32 {
main func() i32 {
acc i32 = 0
dog Data = Data{ dog = 9 }
+1 -1
View File
@@ -1,4 +1,4 @@
main :: func() i32 {
main func() i32 {
value i32 = 1
value = value + 2
return value
+2 -2
View File
@@ -1,7 +1,7 @@
take :: func(value i8) i8 {
take func(value i8) i8 {
return value
}
main :: func() void {
main func() void {
_ = take(128)
}
+1 -1
View File
@@ -1 +1 @@
main :: func() i32 { return 7 }
main func() i32 { return 7 }
+1 -1
View File
@@ -1,4 +1,4 @@
main :: func() void {
main func() void {
value i8 = 127
_ = value + 1
}
+3 -3
View File
@@ -2,15 +2,15 @@
x int :: 2
sum_c :: c_func(a, b int) int {
sum_c c_func(a, b int) int {
return a + b
}
sum_brolang :: func(a, b int) int {
sum_brolang func(a, b int) int {
return a + b
}
main :: func() void {
main func() void {
y int = 4
a_add_b_c :: sum_c(1, 2)
a_add_b_brolang :: sum_brolang(1, 2)
+2 -2
View File
@@ -1,10 +1,10 @@
make_value :: func() int {
make_value func() int {
return 40 + 2
}
answer int :: make_value()
main :: func() i32 {
main func() i32 {
_ = answer
return 0
}

Some files were not shown because too many files have changed in this diff Show More