no :: in func decls
This commit is contained in:
@@ -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)
|
||||
}
|
||||
```
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
first :: import "../header/include/native.h"
|
||||
second :: import "../header/include/native.h"
|
||||
|
||||
main :: func() void {}
|
||||
main func() void {}
|
||||
|
||||
@@ -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,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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,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)
|
||||
|
||||
@@ -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,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,6 +1,6 @@
|
||||
left :: import "../math"
|
||||
right :: import "../math"
|
||||
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return left.value + right.value
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "../math"
|
||||
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return math.sum(local_value, math.value)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
value i32 :: 2
|
||||
|
||||
sum :: func(a, b i32) i32 {
|
||||
sum func(a, b i32) i32 {
|
||||
return a + b
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import "../left"
|
||||
import "../right"
|
||||
|
||||
main :: func() void {
|
||||
main func() void {
|
||||
_ = left.same()
|
||||
_ = right.same()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
same :: c_func() int {
|
||||
same c_func() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
same :: c_func() int {
|
||||
same c_func() int {
|
||||
return 2
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@ import "../b"
|
||||
|
||||
seed i32 :: 4
|
||||
|
||||
run :: func() i32 {
|
||||
run func() i32 {
|
||||
return b.value
|
||||
}
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
import "./level_two"
|
||||
|
||||
value :: func() i32 {
|
||||
value func() i32 {
|
||||
return level_two.value()
|
||||
}
|
||||
|
||||
@@ -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,6 +1,6 @@
|
||||
math :: import "../math"
|
||||
math :: import "../math"
|
||||
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return math.value
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import "../eager"
|
||||
|
||||
main :: func() void {}
|
||||
main func() void {}
|
||||
|
||||
@@ -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,3 +1,3 @@
|
||||
import "../not_package.bro"
|
||||
|
||||
main :: func() void {}
|
||||
main func() void {}
|
||||
|
||||
@@ -1 +1 @@
|
||||
main :: func() void {}
|
||||
main func() void {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "../math"
|
||||
|
||||
used_here :: func() int {
|
||||
used_here func() int {
|
||||
return math.value
|
||||
}
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
import "../math"
|
||||
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return math.identity(127 + 1)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
identity :: func(value int) int {
|
||||
identity func(value int) int {
|
||||
return value
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "../a"
|
||||
|
||||
main :: func() void {
|
||||
main func() void {
|
||||
_ = a.value
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return math.value
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "../dep"
|
||||
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return dep.main()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return 7
|
||||
}
|
||||
|
||||
@@ -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,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,5 +1,5 @@
|
||||
import "../b"
|
||||
|
||||
one :: func(value int) i32 {
|
||||
one func(value int) i32 {
|
||||
return b.two(value)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "../a"
|
||||
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return a.one(1)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "../a"
|
||||
|
||||
two :: func(value int) i32 {
|
||||
two func(value int) i32 {
|
||||
return a.one(value)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "../math"
|
||||
|
||||
from_a :: func() i32 {
|
||||
from_a func() i32 {
|
||||
return math.value
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import "../math"
|
||||
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return from_a() + math.value
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@ self :: import "."
|
||||
|
||||
value i32 :: 5
|
||||
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return self.value
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import "../math"
|
||||
|
||||
main :: func() void {}
|
||||
main func() void {}
|
||||
|
||||
@@ -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,3 +1,3 @@
|
||||
main :: func() void {
|
||||
main func() void {
|
||||
_ = 127 + 1
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
main :: func() void {
|
||||
main func() void {
|
||||
_ = 9223372036854775807 + 1
|
||||
}
|
||||
|
||||
@@ -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,6 +1,6 @@
|
||||
a int :: b
|
||||
b int :: a
|
||||
|
||||
main :: func() void {
|
||||
main func() void {
|
||||
_ = 1
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
a int :: b
|
||||
b int :: a
|
||||
|
||||
main :: func() void {
|
||||
main func() void {
|
||||
_ = a
|
||||
}
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
UserID :: distinct u32
|
||||
|
||||
make :: func(value u32) UserID {
|
||||
make func(value u32) UserID {
|
||||
return UserID(value)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -3,6 +3,6 @@ Animal :: enum {
|
||||
cat
|
||||
}
|
||||
|
||||
favorite :: func() Animal {
|
||||
favorite func() Animal {
|
||||
return .cat
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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,3 +1,3 @@
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
return 4
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
main :: func() i32 {
|
||||
main func() i32 {
|
||||
value i32 = 1
|
||||
value = value + 2
|
||||
return value
|
||||
|
||||
@@ -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 @@
|
||||
main :: func() i32 { return 7 }
|
||||
main func() i32 { return 7 }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
main :: func() void {
|
||||
main func() void {
|
||||
value i8 = 127
|
||||
_ = value + 1
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user