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:
|
distinct from exact-width Brolang primitives:
|
||||||
|
|
||||||
```bro
|
```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`
|
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
|
```bro
|
||||||
native :: import "../include/native.h"
|
native :: import "../include/native.h"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = native.imported_add(20, 22)
|
_ = native.imported_add(20, 22)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -63,11 +63,11 @@ from Brolang requires an explicit unwrap:
|
|||||||
```bro
|
```bro
|
||||||
native :: import "../include/native.h"
|
native :: import "../include/native.h"
|
||||||
|
|
||||||
double :: c_func(value c_int) c_int {
|
double c_func(value c_int) c_int {
|
||||||
return value + value
|
return value + value
|
||||||
}
|
}
|
||||||
|
|
||||||
call_mapper :: func(mapper native.Imported_Mapper) c_int {
|
call_mapper func(mapper native.Imported_Mapper) c_int {
|
||||||
return mapper?(21)
|
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:
|
Bodyless manual and imported C functions may be variadic:
|
||||||
|
|
||||||
```bro
|
```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
|
Zero-terminated byte strings can be passed directly to immutable C character
|
||||||
pointers without making `u8` and `c_char` generally interchangeable:
|
pointers without making `u8` and `c_char` generally interchangeable:
|
||||||
|
|
||||||
```bro
|
```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)
|
_ = printf("answer: %d\n", 42)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -223,7 +223,7 @@
|
|||||||
|
|
||||||
14.5. backward type-demand propagation through call boundaries (DEFERRED)
|
14.5. backward type-demand propagation through call boundaries (DEFERRED)
|
||||||
- a callee's result/return demand flows back through the function body to constrain
|
- 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
|
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
|
- 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
|
(`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 `!`:
|
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.
|
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
|
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:
|
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:
|
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
|
start_line Line = p.line
|
||||||
p.advance()
|
p.advance()
|
||||||
|
|
||||||
@@ -1086,7 +1086,7 @@ The `try` keyword unwraps a successful result or returns early with the error:
|
|||||||
|
|
||||||
```
|
```
|
||||||
ProcessError :: alias IoError | ParseError
|
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
|
data :: try read_file(path) # read_file also returns []u8 ! ProcessError in v1
|
||||||
ast :: try parse(data) # parse also returns Ast ! ProcessError in v1
|
ast :: try parse(data) # parse also returns Ast ! ProcessError in v1
|
||||||
return ast
|
return ast
|
||||||
@@ -1195,7 +1195,7 @@ Brolang provides a **thread-local global heap allocator** that is:
|
|||||||
```
|
```
|
||||||
import "std/mem/heap"
|
import "std/mem/heap"
|
||||||
|
|
||||||
process :: func(input []u8) u64 {
|
process func(input []u8) u64 {
|
||||||
# heap used for internal temporary work — does not escape
|
# heap used for internal temporary work — does not escape
|
||||||
temp := heap.alloc(u8, size: input.len * 2)
|
temp := heap.alloc(u8, size: input.len * 2)
|
||||||
defer heap.free(temp)
|
defer heap.free(temp)
|
||||||
@@ -1227,20 +1227,20 @@ import "std/mem"
|
|||||||
import "std/mem/heap"
|
import "std/mem/heap"
|
||||||
|
|
||||||
# Allocation escapes via return value — requires allocator
|
# 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)
|
result := allocator.alloc(u8, size: input.len)
|
||||||
mem.copy(result, input)
|
mem.copy(result, input)
|
||||||
return result # caller manages this memory
|
return result # caller manages this memory
|
||||||
}
|
}
|
||||||
|
|
||||||
# Allocation escapes via mutable parameter — requires allocator
|
# 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)
|
obj.buffer = allocator.alloc(u8, size: 100)
|
||||||
# caller now knows heap memory was written into obj
|
# caller now knows heap memory was written into obj
|
||||||
}
|
}
|
||||||
|
|
||||||
# No allocation escapes — no allocator needed
|
# No allocation escapes — no allocator needed
|
||||||
process :: func(input: []u8) u64 {
|
process func(input: []u8) u64 {
|
||||||
temp := heap.alloc(u8, size: input.len)
|
temp := heap.alloc(u8, size: input.len)
|
||||||
defer heap.free(temp)
|
defer heap.free(temp)
|
||||||
# ... work with temp ...
|
# ... work with temp ...
|
||||||
@@ -1248,11 +1248,11 @@ process :: func(input: []u8) u64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# No heap allocation at all — no allocator needed
|
# No heap allocation at all — no allocator needed
|
||||||
reset :: func(obj: @mut MyStruct) void {
|
reset func(obj: @mut MyStruct) void {
|
||||||
obj.count = 0
|
obj.count = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
data := duplicate("hello", heap)
|
data := duplicate("hello", heap)
|
||||||
defer heap.free(data)
|
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"
|
||||||
import "std/mem/heap"
|
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 manages its own backing memory via heap
|
||||||
arena := mem.Arena.init(heap, capacity: mem.megabytes(1))
|
arena := mem.Arena.init(heap, capacity: mem.megabytes(1))
|
||||||
defer arena.deinit()
|
defer arena.deinit()
|
||||||
@@ -1333,17 +1333,17 @@ EntitySystem :: struct {
|
|||||||
pool: mem.Pool(Entity),
|
pool: mem.Pool(Entity),
|
||||||
}
|
}
|
||||||
|
|
||||||
init_entities :: func(allocator: @mem.Allocator) EntitySystem {
|
init_entities func(allocator: @mem.Allocator) EntitySystem {
|
||||||
return EntitySystem{
|
return EntitySystem{
|
||||||
pool = mem.Pool(Entity).init(allocator, capacity: 10_000),
|
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
|
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
|
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"
|
import "std/mem"
|
||||||
|
|
||||||
# Function that uses caller's allocator
|
# 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)
|
buffer := allocator.alloc(u8, size: input.len)
|
||||||
defer allocator.free(buffer)
|
defer allocator.free(buffer)
|
||||||
|
|
||||||
@@ -1367,7 +1367,7 @@ parse :: func(input: []u8, allocator: @mem.Allocator) !ParseResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Caller decides which allocator to use
|
# Caller decides which allocator to use
|
||||||
main :: func() void {
|
main func() void {
|
||||||
# use an arena for this parsing work
|
# use an arena for this parsing work
|
||||||
arena := mem.Arena.init(heap, capacity: mem.kilobytes(64))
|
arena := mem.Arena.init(heap, capacity: mem.kilobytes(64))
|
||||||
defer arena.deinit()
|
defer arena.deinit()
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ Metrics :: struct {
|
|||||||
make_source :: proc(repetitions: int, allocator := context.allocator) -> string {
|
make_source :: proc(repetitions: int, allocator := context.allocator) -> string {
|
||||||
builder := strings.builder_make(allocator)
|
builder := strings.builder_make(allocator)
|
||||||
defer strings.builder_destroy(&builder)
|
defer strings.builder_destroy(&builder)
|
||||||
strings.write_string(&builder, "identity :: func(value int) int { return value }\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")
|
strings.write_string(&builder, "main func() i32 {\n\tacc i32 = 0\n")
|
||||||
for _ in 0 ..< repetitions {
|
for _ in 0 ..< repetitions {
|
||||||
strings.write_string(&builder, "\t_ = identity(acc)\n\tacc = acc + 1\n")
|
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
|
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
|
type_syntax := types.INVALID
|
||||||
if is_type_token(current(parser).kind) {
|
if is_type_token(current(parser).kind) {
|
||||||
type_syntax = parse_type(parser)
|
type_syntax = parse_type(parser)
|
||||||
@@ -2271,6 +2276,8 @@ parse_top_level :: proc(parser: ^Parser) {
|
|||||||
|
|
||||||
if operator.kind == .Colon_Colon &&
|
if operator.kind == .Colon_Colon &&
|
||||||
(current(parser).kind == .Keyword_Func || current(parser).kind == .Keyword_C_Func) {
|
(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
|
c_abi := current(parser).kind == .Keyword_C_Func
|
||||||
parse_function(parser, name, c_abi)
|
parse_function(parser, name, c_abi)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ emit_functions :: proc(b: ^strings.Builder, result: ^cimport.Result, record_name
|
|||||||
wrote = true
|
wrote = true
|
||||||
continue
|
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)
|
render_c_func(b, result, function.params, function.param_names, function.result, function.variadic, record_names)
|
||||||
strings.write_byte(b, '\n')
|
strings.write_byte(b, '\n')
|
||||||
wrote = true
|
wrote = true
|
||||||
|
|||||||
+365
-312
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,8 @@ Buffer :: c_struct {
|
|||||||
length c_ulong
|
length c_ulong
|
||||||
}
|
}
|
||||||
|
|
||||||
get_buffer :: c_func() @Buffer
|
get_buffer c_func() @Buffer
|
||||||
verify :: c_func(
|
verify c_func(
|
||||||
char_value c_char,
|
char_value c_char,
|
||||||
schar_value c_schar,
|
schar_value c_schar,
|
||||||
uchar_value c_uchar,
|
uchar_value c_uchar,
|
||||||
@@ -21,7 +21,7 @@ verify :: c_func(
|
|||||||
longdouble_value c_longdouble,
|
longdouble_value c_longdouble,
|
||||||
) i32
|
) i32
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
buffer @Buffer :: get_buffer()
|
buffer @Buffer :: get_buffer()
|
||||||
_ = buffer^.data
|
_ = buffer^.data
|
||||||
_ = buffer^.length
|
_ = buffer^.length
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
native :: import "../include/native.h"
|
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
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
double_value :: c_func(value c_int) c_int {
|
double_value c_func(value c_int) c_int {
|
||||||
return value + value
|
return value + value
|
||||||
}
|
}
|
||||||
|
|
||||||
call_mapper :: func(mapper native.Imported_Mapper) c_int {
|
call_mapper func(mapper native.Imported_Mapper) c_int {
|
||||||
return mapper?(21)
|
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
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = native.imported_add(pass_alias(20), 22)
|
_ = native.imported_add(pass_alias(20), 22)
|
||||||
_ = native.imported_scalar(3, 4)
|
_ = native.imported_scalar(3, 4)
|
||||||
_ = native.child_value(7)
|
_ = native.child_value(7)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
first :: import "../header/include/native.h"
|
first :: import "../header/include/native.h"
|
||||||
second :: 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"
|
first :: import "first.h"
|
||||||
second :: import "second.h"
|
second :: import "second.h"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = first.conflict_global
|
_ = first.conflict_global
|
||||||
_ = second.conflict_global
|
_ = second.conflict_global
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
native :: import "../header/include/native.h"
|
native :: import "../header/include/native.h"
|
||||||
child :: import "../header/include/child.h"
|
child :: import "../header/include/child.h"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = native.child_value(1)
|
_ = native.child_value(1)
|
||||||
_ = child.child_value(2)
|
_ = child.child_value(2)
|
||||||
native.child_shared_global = 7
|
native.child_shared_global = 7
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
native :: import "native.h"
|
native :: import "native.h"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = native.main
|
_ = native.main
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
variable :: import "variable.h"
|
variable :: import "variable.h"
|
||||||
function :: import "function.h"
|
function :: import "function.h"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = variable.conflict_symbol
|
_ = variable.conflict_symbol
|
||||||
_ = function.conflict_symbol()
|
_ = function.conflict_symbol()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
native :: import "../header/include/native.h"
|
native :: import "../header/include/native.h"
|
||||||
|
|
||||||
use_callback :: c_func(value native.Imported_Callback) void
|
use_callback c_func(value native.Imported_Callback) void
|
||||||
use_union :: c_func(value native.Imported_Union) void
|
use_union c_func(value native.Imported_Union) void
|
||||||
use_enum :: c_func(value native.Imported_Enum) void
|
use_enum c_func(value native.Imported_Enum) void
|
||||||
use_opaque :: c_func(value native.Imported_Handle) void
|
use_opaque c_func(value native.Imported_Handle) void
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = native.IMPORTED_BAD_EXPR
|
_ = native.IMPORTED_BAD_EXPR
|
||||||
_ = native.IMPORTED_REDEFINED_BAD
|
_ = native.IMPORTED_REDEFINED_BAD
|
||||||
_ = native.IMPORTED_GONE
|
_ = native.IMPORTED_GONE
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
native :: import "native.h"
|
native :: import "native.h"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = native.write
|
_ = 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)
|
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)
|
_ = printf("answer: %d\n", 42)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,21 +4,21 @@ Manual :: c_struct {
|
|||||||
value c_int
|
value c_int
|
||||||
}
|
}
|
||||||
|
|
||||||
mirror_manual :: c_func(value Manual) Manual {
|
mirror_manual c_func(value Manual) Manual {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
mirror_large :: c_func(value native.Large) native.Large {
|
mirror_large c_func(value native.Large) native.Large {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
native_pair :: func(value native.Pair) native.Pair {
|
native_pair func(value native.Pair) native.Pair {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
global_pair native.Pair :: native.Pair { left = 1, right = 2 }
|
global_pair native.Pair :: native.Pair { left = 1, right = 2 }
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
pair native.Pair = native_pair(global_pair)
|
pair native.Pair = native_pair(global_pair)
|
||||||
pair.left = 10
|
pair.left = 10
|
||||||
pair = native.echo_pair(pair)
|
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
|
# the importer must not recurse forever populating it, and the checker must accept the
|
||||||
# self-referential `?*mut Node` field as C-layout-compatible.
|
# self-referential `?*mut Node` field as C-layout-compatible.
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
node native.Node = native.Node { next = none, value = 7 }
|
node native.Node = native.Node { next = none, value = 7 }
|
||||||
if node.next |_| {
|
if node.next |_| {
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import "/definitely/not/a/brolang/package"
|
import "/definitely/not/a/brolang/package"
|
||||||
|
|
||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
math i32 :: 7
|
math i32 :: 7
|
||||||
import "../math"
|
import "../math"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return math
|
return math
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
left :: import "../math"
|
left :: import "../math"
|
||||||
right :: import "../math"
|
right :: import "../math"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return left.value + right.value
|
return left.value + right.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../math"
|
import "../math"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return math.sum(local_value, math.value)
|
return math.sum(local_value, math.value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
value i32 :: 2
|
value i32 :: 2
|
||||||
|
|
||||||
sum :: func(a, b i32) i32 {
|
sum func(a, b i32) i32 {
|
||||||
return a + b
|
return a + b
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import "../left"
|
import "../left"
|
||||||
import "../right"
|
import "../right"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = left.same()
|
_ = left.same()
|
||||||
_ = right.same()
|
_ = right.same()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
same :: c_func() int {
|
same c_func() int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
same :: c_func() int {
|
same c_func() int {
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ import "../b"
|
|||||||
|
|
||||||
seed i32 :: 4
|
seed i32 :: 4
|
||||||
|
|
||||||
run :: func() i32 {
|
run func() i32 {
|
||||||
return b.value
|
return b.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../a"
|
import "../a"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return a.run()
|
return a.run()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "./level_three"
|
import "./level_three"
|
||||||
|
|
||||||
value :: func() i32 {
|
value func() i32 {
|
||||||
return level_three.value
|
return level_three.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "./level_two"
|
import "./level_two"
|
||||||
|
|
||||||
value :: func() i32 {
|
value func() i32 {
|
||||||
return level_two.value()
|
return level_two.value()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "./level_one"
|
import "./level_one"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return level_one.value()
|
return level_one.value()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import "../bad-name"
|
import "../bad-name"
|
||||||
|
|
||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
math :: import "../math"
|
math :: import "../math"
|
||||||
math :: import "../math"
|
math :: import "../math"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return math.value
|
return math.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import "../eager"
|
import "../eager"
|
||||||
|
|
||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import "../empty"
|
import "../empty"
|
||||||
|
|
||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
good :: import "../bad-name"
|
good :: import "../bad-name"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return good.value
|
return good.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import "../not_package.bro"
|
import "../not_package.bro"
|
||||||
|
|
||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../math"
|
import "../math"
|
||||||
|
|
||||||
used_here :: func() int {
|
used_here func() int {
|
||||||
return math.value
|
return math.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
not_imported_here :: func() int {
|
not_imported_here func() int {
|
||||||
return math.value
|
return math.value
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = used_here()
|
_ = used_here()
|
||||||
_ = not_imported_here()
|
_ = not_imported_here()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import "../left"
|
import "../left"
|
||||||
import "../right"
|
import "../right"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = left.same()
|
_ = left.same()
|
||||||
_ = right.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"
|
import "../math"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return math.identity(127 + 1)
|
return math.identity(127 + 1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
identity :: func(value int) int {
|
identity func(value int) int {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../a"
|
import "../a"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = a.value
|
_ = a.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return math.value
|
return math.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../dep"
|
import "../dep"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return dep.main()
|
return dep.main()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return 7
|
return 7
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import "../math"
|
import "../math"
|
||||||
|
|
||||||
unused :: func() int {
|
unused func() int {
|
||||||
return math.missing
|
return math.missing
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import "../missing"
|
import "../missing"
|
||||||
|
|
||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../missing"
|
import "../missing"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = missing.value
|
_ = missing.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../bridge"
|
import "../bridge"
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = bridge.value
|
_ = bridge.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../math"
|
import "../math"
|
||||||
|
|
||||||
read :: func() i32 {
|
read func() i32 {
|
||||||
return math.value
|
return math.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import "../broken"
|
import "../broken"
|
||||||
|
|
||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import "../math"
|
import "../math"
|
||||||
|
|
||||||
read :: func(value i8) int {
|
read func(value i8) int {
|
||||||
return math.value
|
return math.value
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return read(1)
|
return read(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../b"
|
import "../b"
|
||||||
|
|
||||||
one :: func(value int) i32 {
|
one func(value int) i32 {
|
||||||
return b.two(value)
|
return b.two(value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../a"
|
import "../a"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return a.one(1)
|
return a.one(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../a"
|
import "../a"
|
||||||
|
|
||||||
two :: func(value int) i32 {
|
two func(value int) i32 {
|
||||||
return a.one(value)
|
return a.one(value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../math"
|
import "../math"
|
||||||
|
|
||||||
from_a :: func() i32 {
|
from_a func() i32 {
|
||||||
return math.value
|
return math.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import "../math"
|
import "../math"
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return from_a() + math.value
|
return from_a() + math.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ self :: import "."
|
|||||||
|
|
||||||
value i32 :: 5
|
value i32 :: 5
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return self.value
|
return self.value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import "../math"
|
import "../math"
|
||||||
|
|
||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
# innermost enclosing loop. Each section returns a distinct code on failure so
|
# innermost enclosing loop. Each section returns a distinct code on failure so
|
||||||
# a regression points at the broken behaviour; success falls through to 42.
|
# 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.
|
# 1. `break` out of a `while` once i reaches 5.
|
||||||
i i32 = 0
|
i i32 = 0
|
||||||
a i32 = 0
|
a i32 = 0
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Milestone 6: compound assignment (`+=`, `-=`, `*=`, `/=`) and the binary
|
# Milestone 6: compound assignment (`+=`, `-=`, `*=`, `/=`) and the binary
|
||||||
# arithmetic operators `-`, `*`, `/` with multiplicative precedence.
|
# arithmetic operators `-`, `*`, `/` with multiplicative precedence.
|
||||||
|
|
||||||
check_float :: func() i32 {
|
check_float func() i32 {
|
||||||
x f64 = 10.0
|
x f64 = 10.0
|
||||||
x /= 4.0 # 2.5
|
x /= 4.0 # 2.5
|
||||||
x *= 2.0 # 5.0
|
x *= 2.0 # 5.0
|
||||||
@@ -13,7 +13,7 @@ check_float :: func() i32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
check_unsigned :: func() i32 {
|
check_unsigned func() i32 {
|
||||||
n u32 = 100
|
n u32 = 100
|
||||||
n /= 7 # 14 (truncating integer division)
|
n /= 7 # 14 (truncating integer division)
|
||||||
n -= 4 # 10
|
n -= 4 # 10
|
||||||
@@ -23,7 +23,7 @@ check_unsigned :: func() i32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
total i32 = 0
|
total i32 = 0
|
||||||
total += 10 # 10
|
total += 10 # 10
|
||||||
total -= 3 # 7
|
total -= 3 # 7
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# Milestone 5: conditional optional unwrapping, guards, and multi-unwrap.
|
# 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
|
counter^ = counter^ + 1
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
total i32 = 0
|
total i32 = 0
|
||||||
|
|
||||||
# present optional scalar -> binds v to the unwrapped value
|
# present optional scalar -> binds v to the unwrapped value
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
main :: func() void {
|
main func() void {
|
||||||
value i8 :: 127 + 1
|
value i8 :: 127 + 1
|
||||||
_ = value
|
_ = value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
main :: func() void {
|
main func() void {
|
||||||
_ = 127 + 1
|
_ = 127 + 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
main :: func() void {
|
main func() void {
|
||||||
_ = 9223372036854775807 + 1
|
_ = 9223372036854775807 + 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# Milestone 5 foundation: booleans, comparisons, logical ops, if/else if/else.
|
# 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.
|
# 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 {
|
if n < 0 {
|
||||||
return 1
|
return 1
|
||||||
} else if n == 0 {
|
} 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
|
# A bool-returning function with a visible side effect, used to prove
|
||||||
# short-circuit evaluation: it must only print when actually evaluated.
|
# short-circuit evaluation: it must only print when actually evaluated.
|
||||||
noisy :: func() bool {
|
noisy func() bool {
|
||||||
_ = printf("rhs-evaluated\n")
|
_ = printf("rhs-evaluated\n")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
total i32 = 0
|
total i32 = 0
|
||||||
|
|
||||||
# comparisons drive if / else if / else
|
# comparisons drive if / else if / else
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
a int :: b
|
a int :: b
|
||||||
b int :: a
|
b int :: a
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = 1
|
_ = 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
a int :: b
|
a int :: b
|
||||||
b int :: a
|
b int :: a
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = a
|
_ = a
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
# The return value is captured before defers run, so the mutation here does not
|
# The return value is captured before defers run, so the mutation here does not
|
||||||
# change what is returned (Zig semantics).
|
# change what is returned (Zig semantics).
|
||||||
spill_check :: func() i32 {
|
spill_check func() i32 {
|
||||||
x i32 = 5
|
x i32 = 5
|
||||||
defer x = 999
|
defer x = 999
|
||||||
return x
|
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
|
# A function-scope defer runs only at function exit; a `break` runs the loop-body
|
||||||
# defer but NOT the enclosing function-scope defer.
|
# defer but NOT the enclosing function-scope defer.
|
||||||
enclosing_defer_check :: func() i32 {
|
enclosing_defer_check func() i32 {
|
||||||
v i32 = 0
|
v i32 = 0
|
||||||
defer v = v + 100
|
defer v = v + 100
|
||||||
for 0..3 |i| {
|
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
|
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.
|
# 1. return value captured before defers run.
|
||||||
if (spill_check() != 5) return 101
|
if (spill_check() != 5) return 101
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
UserID :: distinct u32
|
UserID :: distinct u32
|
||||||
|
|
||||||
make :: func(value u32) UserID {
|
make func(value u32) UserID {
|
||||||
return UserID(value)
|
return UserID(value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ WrappedID :: distinct LocalID
|
|||||||
|
|
||||||
static_id LocalID :: LocalID(42)
|
static_id LocalID :: LocalID(42)
|
||||||
|
|
||||||
take :: func(value LocalID) LocalID {
|
take func(value LocalID) LocalID {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
id LocalID :: LocalID(7)
|
id LocalID :: LocalID(7)
|
||||||
copy LocalID = take(id)
|
copy LocalID = take(id)
|
||||||
maybe ?LocalID = copy
|
maybe ?LocalID = copy
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ Animal :: enum {
|
|||||||
cat
|
cat
|
||||||
}
|
}
|
||||||
|
|
||||||
favorite :: func() Animal {
|
favorite func() Animal {
|
||||||
return .cat
|
return .cat
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ State :: enum(u16) {
|
|||||||
|
|
||||||
initial State :: State.started
|
initial State :: State.started
|
||||||
|
|
||||||
same :: func(left State, right State) bool {
|
same func(left State, right State) bool {
|
||||||
return left == right
|
return left == right
|
||||||
}
|
}
|
||||||
|
|
||||||
identity :: c_func(value State) State {
|
identity c_func(value State) State {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
state State = identity(.running)
|
state State = identity(.running)
|
||||||
values [2]State :: [.started, State.stopped]
|
values [2]State :: [.started, State.stopped]
|
||||||
animal animals.Animal :: animals.Animal.dog
|
animal animals.Animal :: animals.Animal.dog
|
||||||
|
|||||||
@@ -28,37 +28,37 @@ BoxB :: union(enum) {
|
|||||||
|
|
||||||
Box :: alias BoxA | BoxB
|
Box :: alias BoxA | BoxB
|
||||||
|
|
||||||
maybe :: func(value i32) i32 ! BasicError {
|
maybe func(value i32) i32 ! BasicError {
|
||||||
if (value == 0) return .bad
|
if (value == 0) return .bad
|
||||||
return value + 1
|
return value + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
via_try :: func(value i32) i32 ! BasicError {
|
via_try func(value i32) i32 ! BasicError {
|
||||||
unwrapped :: try maybe(value)
|
unwrapped :: try maybe(value)
|
||||||
return unwrapped + 1
|
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 == 0) return DetailError{ code = 5 }
|
||||||
if (value == 1) return .empty
|
if (value == 1) return .empty
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
pick :: func(value Both) i32 {
|
pick func(value Both) i32 {
|
||||||
match value {
|
match value {
|
||||||
.left: return 10
|
.left: return 10
|
||||||
.right: return 20
|
.right: return 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
payload :: func(value Box) i32 {
|
payload func(value Box) i32 {
|
||||||
match value {
|
match value {
|
||||||
.a |n|: return n
|
.a |n|: return n
|
||||||
.b: return 3
|
.b: return 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
acc i32 = 0
|
acc i32 = 0
|
||||||
|
|
||||||
a :: maybe(0) catch 7
|
a :: maybe(0) catch 7
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# Milestone 5: ranges and sequence for loops.
|
# Milestone 5: ranges and sequence for loops.
|
||||||
|
|
||||||
pass :: func(value range) range {
|
pass func(value range) range {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
total i32 = 0
|
total i32 = 0
|
||||||
|
|
||||||
items [3]mut i32 = [1, 2, 3]
|
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
|
calls^ = calls^ + 1
|
||||||
return 0..end
|
return 0..end
|
||||||
}
|
}
|
||||||
|
|
||||||
global_range :: 0..1
|
global_range :: 0..1
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
total i32 = 0
|
total i32 = 0
|
||||||
|
|
||||||
first u8 = 254
|
first u8 = 254
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
bad int = 1
|
bad int = 1
|
||||||
|
|
||||||
read_bad :: func() int {
|
read_bad func() int {
|
||||||
return bad
|
return bad
|
||||||
}
|
}
|
||||||
|
|
||||||
derived :: read_bad()
|
derived :: read_bad()
|
||||||
|
|
||||||
main :: func() void {}
|
main func() void {}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
bad int = 1
|
bad int = 1
|
||||||
|
|
||||||
read_bad :: func() int {
|
read_bad func() int {
|
||||||
return bad
|
return bad
|
||||||
}
|
}
|
||||||
|
|
||||||
derived :: read_bad()
|
derived :: read_bad()
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = derived
|
_ = derived
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
bad int = 4
|
bad int = 4
|
||||||
|
|
||||||
read_bad :: func() int {
|
read_bad func() int {
|
||||||
return bad
|
return bad
|
||||||
}
|
}
|
||||||
|
|
||||||
derived int :: read_bad()
|
derived int :: read_bad()
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = 1
|
_ = 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
bad int = 4
|
bad int = 4
|
||||||
|
|
||||||
read_bad :: func() int {
|
read_bad func() int {
|
||||||
return bad
|
return bad
|
||||||
}
|
}
|
||||||
|
|
||||||
derived int :: read_bad()
|
derived int :: read_bad()
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = derived
|
_ = derived
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
broken :: func(value int) int {
|
broken func(value int) int {
|
||||||
return missing + value
|
return missing + value
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = 1
|
_ = 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
bad int = 4
|
bad int = 4
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = 1
|
_ = 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
broken :: func(value int) int {
|
broken func(value int) int {
|
||||||
return missing + value
|
return missing + value
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = broken(1)
|
_ = broken(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
bad int = 4
|
bad int = 4
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = bad
|
_ = bad
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
return 4
|
return 4
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
main :: func() int {
|
main func() int {
|
||||||
return 3
|
return 3
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
take :: func(value i8) i8 {
|
take func(value i8) i8 {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
bad_return :: func() i8 {
|
bad_return func() i8 {
|
||||||
return missing
|
return missing
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = take(missing)
|
_ = take(missing)
|
||||||
_ = bad_return()
|
_ = bad_return()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Box :: union(enum) {
|
|||||||
|
|
||||||
# Statement match with payload capture; every variant returns, so the function needs
|
# Statement match with payload capture; every variant returns, so the function needs
|
||||||
# no trailing return (the desugared if/else chain covers all paths).
|
# no trailing return (the desugared if/else chain covers all paths).
|
||||||
describe :: func(d Data) i32 {
|
describe func(d Data) i32 {
|
||||||
match d {
|
match d {
|
||||||
.dog |age|: return age + 1
|
.dog |age|: return age + 1
|
||||||
.bird |wingspan|: return wingspan + 2
|
.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.
|
# 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 {
|
result :: match s {
|
||||||
.square |side|: side * side
|
.square |side|: side * side
|
||||||
.circle |r|: {
|
.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
|
# 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).
|
# 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 {
|
v :: match d {
|
||||||
.dog, .bird |n|: n
|
.dog, .bird |n|: n
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
make_box :: func() Box {
|
make_box func() Box {
|
||||||
return Box{ point = Point{ x = 4, y = 0 } }
|
return Box{ point = Point{ x = 4, y = 0 } }
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
acc i32 = 0
|
acc i32 = 0
|
||||||
|
|
||||||
dog Data = Data{ dog = 9 }
|
dog Data = Data{ dog = 9 }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
value i32 = 1
|
value i32 = 1
|
||||||
value = value + 2
|
value = value + 2
|
||||||
return value
|
return value
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
take :: func(value i8) i8 {
|
take func(value i8) i8 {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
_ = take(128)
|
_ = 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 i8 = 127
|
||||||
_ = value + 1
|
_ = value + 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
x int :: 2
|
x int :: 2
|
||||||
|
|
||||||
sum_c :: c_func(a, b int) int {
|
sum_c c_func(a, b int) int {
|
||||||
return a + b
|
return a + b
|
||||||
}
|
}
|
||||||
|
|
||||||
sum_brolang :: func(a, b int) int {
|
sum_brolang func(a, b int) int {
|
||||||
return a + b
|
return a + b
|
||||||
}
|
}
|
||||||
|
|
||||||
main :: func() void {
|
main func() void {
|
||||||
y int = 4
|
y int = 4
|
||||||
a_add_b_c :: sum_c(1, 2)
|
a_add_b_c :: sum_c(1, 2)
|
||||||
a_add_b_brolang :: sum_brolang(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
|
return 40 + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
answer int :: make_value()
|
answer int :: make_value()
|
||||||
|
|
||||||
main :: func() i32 {
|
main func() i32 {
|
||||||
_ = answer
|
_ = answer
|
||||||
return 0
|
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