mutable decl syntax change
This commit is contained in:
+2
-1
@@ -8,7 +8,8 @@ roadmap and milestone history.
|
||||
### source, declarations, and packages
|
||||
|
||||
- newline-terminated statements and `#` comments
|
||||
- immutable `::` bindings, typed mutable `=` locals/globals, and `_` sinks
|
||||
- immutable `name :: value` / `name Type :: value` bindings and mutable `name := value` / `name Type := value` bindings
|
||||
- `=` is assignment, including `_ = value` sinks; keyed record initializers and named struct field defaults also use `=`
|
||||
- immutable package globals, mutable runtime globals, function-local mutable locals, and mutable declarations initialized with `undefined`
|
||||
- package-level functions, globals, native type declarations, and `Name :: alias T`
|
||||
- directory packages with merged declarations
|
||||
|
||||
@@ -222,7 +222,7 @@ Current prototype features:
|
||||
|
||||
- Newline-terminated, multiline statements; `}` may terminate a block's final statement
|
||||
- `#` comments
|
||||
- Immutable `::` bindings, typed mutable `=` locals/globals, and `_` sinks
|
||||
- Immutable inferred/typed `::` bindings, mutable inferred/typed `:=` locals/globals, and `_` sinks
|
||||
- Exact-width signed/unsigned integers, `f32`, `f64`, `isize`, `usize`, and loose integer-constrained `int`
|
||||
- Target-dependent atomic `c_*` primitive types, `c_func`, complete `c_struct`, `opaque`, `anyopaque`, and V1 `ptrcast!(T, ptr)`
|
||||
- Arrays, sentinel arrays, single-item pointers, many-item pointers, sentinel many-item pointers, slices, sentinel slices, strings, character literals, optionals, and native structs
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
- unsigned integers, floats, and target-dependent c scalar types
|
||||
- atomic `c_*` primitive types remain distinct until target-aware lowering
|
||||
- `c_func`, complete `c_struct`, and pointer-only `opaque`; `c` remains an ordinary identifier
|
||||
- keep binding mutability (`::` / `=`) separate from element or pointee mutability (`mut`)
|
||||
- keep binding mutability (`::` / `:=`) separate from element or pointee mutability (`mut`)
|
||||
- arrays and indexing
|
||||
- `[N]T`: array with `N` logical elements
|
||||
- `[N;S]T`: array with `N` logical elements followed by sentinel `S`
|
||||
@@ -184,7 +184,7 @@
|
||||
- undefined values are assigned a poison value (0xaa...)
|
||||
- allows for something like:
|
||||
```
|
||||
a int = undefined
|
||||
a int := undefined
|
||||
if (condition) {
|
||||
a = 42
|
||||
} else {
|
||||
@@ -323,7 +323,7 @@
|
||||
- a `{ ... }` on the right of a declaration or assignment is a *value block*: its final
|
||||
statement must be `yield <expr>`, which supplies the block's value (the block analogue
|
||||
of `return`). Supported: `x :: { ...; yield v }` (untyped — the local takes the yield's
|
||||
natural type), `x T = { ... }` (coerces to `T`), and `target = { ... }` (coerces to the
|
||||
natural type), `x T := { ... }` (coerces to `T`), and `target = { ... }` (coerces to the
|
||||
target's type, including complex targets like `a[i] = { ... }`)
|
||||
- the yielded value is captured *before* the block's defers run (a defer that mutates a
|
||||
block local can't change what is yielded), reusing the `return` spill-to-temp pattern
|
||||
@@ -695,9 +695,9 @@
|
||||
27.8 source-defined mutable runtime globals (implemented)
|
||||
- allow mutable global declarations in Brolang source for process-global runtime
|
||||
state, matching the writable-global support already needed for imported C globals
|
||||
- require source type syntax and an initializer; constraints (`int`/`float`/`range`)
|
||||
and inferred array counts may resolve through the existing inference fixpoint, but
|
||||
the final type must be concrete runtime storage
|
||||
- require an initializer and infer or explicitly declare a concrete runtime storage type;
|
||||
constraints (`int`/`float`/`range`) and inferred array counts resolve through the existing
|
||||
inference fixpoint
|
||||
- emit source-defined mutable globals as writable globals, not constants
|
||||
- allow `undefined` initializers for runtime storage initialized explicitly by a function
|
||||
- allow assignment, address-taking, field/index mutation, and pointer passing under
|
||||
@@ -774,7 +774,7 @@
|
||||
improving layout or specialization
|
||||
- the smallest fitting feature is call-local inference of omitted comptime type arguments:
|
||||
```
|
||||
values ArrayList(i32) = arraylist.init(mem.c_allocator)
|
||||
values ArrayList(i32) := arraylist.init(mem.c_allocator)
|
||||
defer arraylist.deinit(&values)
|
||||
try arraylist.append(&values, 42)
|
||||
```
|
||||
@@ -988,9 +988,9 @@ f: f32 = 3.14
|
||||
bits := bitcast(f, u32) # IEEE 754 representation
|
||||
|
||||
# pointer casts
|
||||
buf *u8 = get_buffer()
|
||||
ints *u32 = ptrcast!(u32, buf) # element type change, same pointer shape
|
||||
writable *mut u8 = constcast!(buf) # explicit unsafe mutability restoration
|
||||
buf *u8 := get_buffer()
|
||||
ints *u32 := ptrcast!(u32, buf) # element type change, same pointer shape
|
||||
writable *mut u8 := constcast!(buf) # explicit unsafe mutability restoration
|
||||
```
|
||||
|
||||
## A word on multi-unwrap
|
||||
@@ -1069,8 +1069,7 @@ layer:
|
||||
```bro
|
||||
UserID :: distinct u32
|
||||
OuterID :: distinct UserID
|
||||
|
||||
index usize = 42
|
||||
index usize := 42
|
||||
id UserID :: UserID(index)
|
||||
raw u32 :: u32(id)
|
||||
outer OuterID :: OuterID(id)
|
||||
@@ -1222,7 +1221,7 @@ data :: {
|
||||
}
|
||||
|
||||
# match arms
|
||||
label []u8 = match p {
|
||||
label []u8 := match p {
|
||||
.high: "HIGH", # single expression: implicit yield
|
||||
.low: {
|
||||
log("low priority")
|
||||
@@ -1231,7 +1230,7 @@ label []u8 = match p {
|
||||
}
|
||||
|
||||
# catch handlers (planned; block form deferred in milestone 23 v1)
|
||||
data []u8 = read(path) catch |e| {
|
||||
data []u8 := read(path) catch |e| {
|
||||
log(e)
|
||||
yield fallback_data # block: explicit yield
|
||||
}
|
||||
@@ -1252,7 +1251,7 @@ result :: if a {
|
||||
}
|
||||
|
||||
# yielding to a variable
|
||||
result int = if a {
|
||||
result int := if a {
|
||||
yield 1
|
||||
} else if b {
|
||||
yield 2
|
||||
@@ -1482,7 +1481,7 @@ Fallible functions use ordinary `return` for both channels. If the returned expr
|
||||
|
||||
```
|
||||
parse_section func(p: @mut Parser) void ! ParseError {
|
||||
start_line Line = p.line
|
||||
start_line Line := p.line
|
||||
p.advance()
|
||||
|
||||
# ... parsing logic ...
|
||||
@@ -1497,7 +1496,7 @@ Since errors are just union values, you can also construct them separately:
|
||||
|
||||
```
|
||||
# Construct error value (it's just a union)
|
||||
e ParseError = .timeout{500}
|
||||
e ParseError := .timeout{500}
|
||||
|
||||
# Return it via error channel later
|
||||
return e
|
||||
@@ -1647,7 +1646,7 @@ Brolang provides a libc-backed allocator value:
|
||||
mem :: import "@std/mem"
|
||||
|
||||
process func(input []u8) u64 {
|
||||
temp ?*mut u8 = mem.alloc(mem.c_allocator, input.len * 2, 1)
|
||||
temp ?*mut u8 := mem.alloc(mem.c_allocator, input.len * 2, 1)
|
||||
defer mem.free(mem.c_allocator, temp, input.len * 2, 1)
|
||||
|
||||
# ... work with temp ...
|
||||
@@ -1677,7 +1676,7 @@ mem :: import "@std/mem"
|
||||
|
||||
# Allocation escapes via return value — requires allocator
|
||||
duplicate func(input []u8, allocator mem.Allocator) ?*mut u8 {
|
||||
result ?*mut u8 = mem.alloc(allocator, input.len, 1)
|
||||
result ?*mut u8 := mem.alloc(allocator, input.len, 1)
|
||||
mem.copy(result, input)
|
||||
return result # caller manages this memory
|
||||
}
|
||||
@@ -1690,7 +1689,7 @@ init func(obj @mut MyStruct, allocator mem.Allocator) void {
|
||||
|
||||
# No allocation escapes — no allocator needed
|
||||
process func(input []u8) u64 {
|
||||
temp ?*mut u8 = mem.alloc(mem.c_allocator, input.len, 1)
|
||||
temp ?*mut u8 := mem.alloc(mem.c_allocator, input.len, 1)
|
||||
defer mem.free(mem.c_allocator, temp, input.len, 1)
|
||||
# ... work with temp ...
|
||||
return compute_hash(temp)
|
||||
|
||||
@@ -5952,7 +5952,7 @@ infer_statements :: proc(
|
||||
#partial switch statement.kind {
|
||||
case .Declaration:
|
||||
if statement.expr == ast.INVALID_EXPR {
|
||||
// Value block (`x :: { ... yield v }` / `x T = { ... }`): register the
|
||||
// Value block (`x :: { ... yield v }` / `x T := { ... }`): register the
|
||||
// binding (its declared type when annotated, else left open) and walk
|
||||
// the block body. The build pass resolves the yielded value's type
|
||||
// independently — value blocks don't join the demand fixpoint.
|
||||
@@ -6026,7 +6026,7 @@ infer_statements :: proc(
|
||||
continue
|
||||
}
|
||||
expected_assignment := types.INVALID
|
||||
if statement.target != ast.INVALID_EXPR {
|
||||
if statement.target != ast.INVALID_EXPR && !symbol.is_valid(statement.name) {
|
||||
expected_assignment = infer_expr(checker, statement.target, locals^[:], pkg, file, demanded, local_types)
|
||||
target_expr := checker.ast_module.exprs[statement.target]
|
||||
if target_expr.kind == .Name && !symbol.is_valid(target_expr.qualifier) {
|
||||
@@ -6055,7 +6055,7 @@ infer_statements :: proc(
|
||||
// type onto open-constant operands and poison their family. Operands of an
|
||||
// arithmetic RHS resolve from their own authoritative uses.
|
||||
rhs_is_arith := is_arith_kind(checker.ast_module.exprs[statement.expr].kind)
|
||||
if statement.target != ast.INVALID_EXPR {
|
||||
if statement.target != ast.INVALID_EXPR && !symbol.is_valid(statement.name) {
|
||||
target_type := expected_assignment
|
||||
target_expr := checker.ast_module.exprs[statement.target]
|
||||
if target_expr.kind == .Name && !symbol.is_valid(target_expr.qualifier) {
|
||||
@@ -10922,7 +10922,7 @@ build_block :: proc(
|
||||
}
|
||||
switch statement.kind {
|
||||
case .Declaration:
|
||||
// A value block (`x :: { ... yield v }` / `x T = { ... }`): the parser
|
||||
// A value block (`x :: { ... yield v }` / `x T := { ... }`): the parser
|
||||
// leaves `expr` invalid and stashes the block in `body`. Build it, then
|
||||
// declare the local from the yielded value (its type for an untyped `::`).
|
||||
if statement.expr == ast.INVALID_EXPR {
|
||||
@@ -11123,7 +11123,7 @@ build_block :: proc(
|
||||
ctx.problematic^ = ctx.problematic^ || checker.module.exprs[value].kind == .Invalid
|
||||
}
|
||||
case .Assignment:
|
||||
if statement.target != ast.INVALID_EXPR {
|
||||
if statement.target != ast.INVALID_EXPR && !symbol.is_valid(statement.name) {
|
||||
target_expr := build_expr(
|
||||
checker, statement.target, ctx.locals^[:], ctx.global_reads, ctx.calls,
|
||||
types.INVALID, ctx.pkg, ctx.file,
|
||||
@@ -14349,18 +14349,6 @@ build_globals :: proc(checker: ^Checker) {
|
||||
)
|
||||
expr = invalid_hir_expr(checker, global.span, diagnostic)
|
||||
}
|
||||
if !global.immutable {
|
||||
if !types.is_valid(global.type) {
|
||||
diagnostic = source.addf(
|
||||
checker.diagnostics,
|
||||
global.span,
|
||||
"mutable global '%s' requires a type annotation",
|
||||
symbol_text(checker, global.name),
|
||||
)
|
||||
global_type = types.I64
|
||||
expr = invalid_hir_expr(checker, global.span, diagnostic, global_type)
|
||||
}
|
||||
}
|
||||
static_value, is_static := static_integer_value(&checker.module, expr)
|
||||
is_static = is_static && diagnostic == source.INVALID_DIAGNOSTIC && global.immutable
|
||||
_ = hir.global_id(len(checker.module.globals))
|
||||
|
||||
@@ -133,9 +133,16 @@ lex :: proc(
|
||||
case ':':
|
||||
start := cursor
|
||||
cursor += 1
|
||||
if cursor < len(bytes) && bytes[cursor] == ':' {
|
||||
cursor += 1
|
||||
append_token(&stream, source_file, .Colon_Colon, start, cursor)
|
||||
if cursor < len(bytes) {
|
||||
if bytes[cursor] == ':' {
|
||||
cursor += 1
|
||||
append_token(&stream, source_file, .Colon_Colon, start, cursor)
|
||||
} else if bytes[cursor] == '=' {
|
||||
cursor += 1
|
||||
append_token(&stream, source_file, .Colon_Equal, start, cursor)
|
||||
} else {
|
||||
append_token(&stream, source_file, .Colon, start, cursor)
|
||||
}
|
||||
} else {
|
||||
append_token(&stream, source_file, .Colon, start, cursor)
|
||||
}
|
||||
|
||||
@@ -1868,15 +1868,35 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
had_type = true
|
||||
}
|
||||
operator := current(parser)
|
||||
if operator.kind == .Colon_Colon || operator.kind == .Equal {
|
||||
if had_type && operator.kind == .Equal {
|
||||
diagnostic := source.add(
|
||||
parser.diagnostics,
|
||||
operator.span,
|
||||
"mutable declarations use ':=' instead of '='",
|
||||
)
|
||||
for current(parser).kind != .Newline &&
|
||||
current(parser).kind != .Right_Brace &&
|
||||
current(parser).kind != .Eof {
|
||||
advance(parser)
|
||||
}
|
||||
id := ast.stmt_id(len(parser.module.statements))
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
kind=.Invalid,
|
||||
span=span_from(name.span, operator.span),
|
||||
expr=ast.INVALID_EXPR,
|
||||
diagnostic=diagnostic,
|
||||
})
|
||||
return id
|
||||
}
|
||||
is_sink := name.kind == .Underscore && operator.kind == .Equal
|
||||
if operator.kind == .Colon_Colon || operator.kind == .Colon_Equal || is_sink {
|
||||
advance(parser)
|
||||
skip_newlines(parser)
|
||||
kind := ast.Stmt_Kind.Assignment
|
||||
immutable := false
|
||||
if operator.kind == .Colon_Colon || had_type {
|
||||
kind = .Declaration
|
||||
immutable = operator.kind == .Colon_Colon
|
||||
kind := ast.Stmt_Kind.Declaration
|
||||
if is_sink {
|
||||
kind = .Assignment
|
||||
}
|
||||
immutable := operator.kind == .Colon_Colon
|
||||
// A labeled value block (`x :: blk: { … yield :blk v }`): the label lets a
|
||||
// `yield :blk` exit the block past a nested `if`. Block-init body + label.
|
||||
if current(parser).kind == .Identifier && peek(parser).kind == .Colon {
|
||||
@@ -1954,6 +1974,11 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
}
|
||||
|
||||
expr := parse_expression(parser)
|
||||
assignment_name := symbol.INVALID
|
||||
target_expr := parser.module.exprs[expr]
|
||||
if target_expr.kind == .Name && !symbol.is_valid(target_expr.qualifier) {
|
||||
assignment_name = target_expr.name
|
||||
}
|
||||
if _, ok := allow(parser, .Equal); ok {
|
||||
skip_newlines(parser)
|
||||
// A labeled value block assigned to a complex target (`a[i] = blk: { … }`).
|
||||
@@ -1964,6 +1989,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
kind=.Assignment,
|
||||
span=span_from(parser.module.exprs[expr].span, previous(parser).span),
|
||||
name=assignment_name,
|
||||
target=expr,
|
||||
label=label,
|
||||
expr=ast.INVALID_EXPR,
|
||||
@@ -1980,6 +2006,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
kind=.Assignment,
|
||||
span=span_from(parser.module.exprs[expr].span, brace.span),
|
||||
name=assignment_name,
|
||||
target=expr,
|
||||
expr=ast.INVALID_EXPR,
|
||||
body=body,
|
||||
@@ -1995,6 +2022,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
kind=.Assignment,
|
||||
span=span_from(parser.module.exprs[expr].span, previous(parser).span),
|
||||
name=assignment_name,
|
||||
target=expr,
|
||||
value_control_flow=true,
|
||||
expr=ast.INVALID_EXPR,
|
||||
@@ -2008,6 +2036,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id {
|
||||
append(&parser.module.statements, ast.Stmt{
|
||||
kind=.Assignment,
|
||||
span=span_from(parser.module.exprs[expr].span, parser.module.exprs[value].span),
|
||||
name=assignment_name,
|
||||
target=expr,
|
||||
expr=value,
|
||||
diagnostic=source.INVALID_DIAGNOSTIC,
|
||||
@@ -3312,8 +3341,16 @@ parse_top_level :: proc(parser: ^Parser) {
|
||||
type_syntax = parse_type(parser)
|
||||
}
|
||||
operator := current(parser)
|
||||
if operator.kind != .Colon_Colon && operator.kind != .Equal {
|
||||
source.add(parser.diagnostics, operator.span, "expected '::' or '=' after top-level name")
|
||||
if operator.kind == .Equal {
|
||||
source.add(parser.diagnostics, operator.span, "mutable declarations use ':=' instead of '='")
|
||||
for current(parser).kind != .Newline && current(parser).kind != .Eof {
|
||||
advance(parser)
|
||||
}
|
||||
_ = finish_statement(parser)
|
||||
return
|
||||
}
|
||||
if operator.kind != .Colon_Colon && operator.kind != .Colon_Equal {
|
||||
source.add(parser.diagnostics, operator.span, "expected '::' or ':=' after top-level name")
|
||||
_ = finish_statement(parser)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ append_runner :: proc(
|
||||
fmt.sbprintf(&builder, "%s.%s() catch |_| ", alias, symbol.resolve(symbols, test.name))
|
||||
strings.write_string(&builder, "{\n\t\treturn .expectation_failed\n\t}\n}\n\n")
|
||||
}
|
||||
strings.write_string(&builder, "main func() i32 {\n\tfailed i32 = 0\n")
|
||||
strings.write_string(&builder, "main func() i32 {\n\tfailed i32 := 0\n")
|
||||
for entry, index in tests {
|
||||
test_id := entry.function
|
||||
test := module.functions[test_id]
|
||||
|
||||
@@ -16,6 +16,7 @@ Kind :: enum u8 {
|
||||
Underscore,
|
||||
Colon,
|
||||
Colon_Colon,
|
||||
Colon_Equal,
|
||||
Equal,
|
||||
Equal_Equal,
|
||||
Bang,
|
||||
|
||||
+466
-362
File diff suppressed because it is too large
Load Diff
@@ -79,8 +79,8 @@ read_command func() Command {
|
||||
if rl.IsMouseButtonPressed(rl.MOUSE_BUTTON_LEFT) return .spawn{ rl.GetMousePosition() }
|
||||
if rl.IsKeyPressed(rl.KEY_SPACE) return .clear
|
||||
|
||||
fx f32 = 0.0
|
||||
fy f32 = 0.0
|
||||
fx f32 := 0.0
|
||||
fy f32 := 0.0
|
||||
if rl.IsKeyDown(rl.KEY_A) fx -= FORCE
|
||||
if rl.IsKeyDown(rl.KEY_D) fx += FORCE
|
||||
if rl.IsKeyDown(rl.KEY_W) fy -= FORCE
|
||||
@@ -130,14 +130,14 @@ step func(b @mut Ball) void {
|
||||
|
||||
draw_ball func(b @Ball, highlight bool) void {
|
||||
col :: color_for(b.kind)
|
||||
center rl.Vector2 = rl.Vector2{ x = b.x, y = b.y }
|
||||
center rl.Vector2 := rl.Vector2{ x = b.x, y = b.y }
|
||||
match b.kind {
|
||||
.circle: rl.DrawCircleV(center, b.radius, col)
|
||||
.square: rl.DrawPoly(center, 4, b.radius, 45.0, col)
|
||||
.triangle: rl.DrawPoly(center, 3, b.radius, 0.0, col)
|
||||
}
|
||||
if highlight {
|
||||
ring rl.Color = rl.Color{ r = 250, g = 245, b = 200, a = 255 }
|
||||
ring rl.Color := rl.Color{ r = 250, g = 245, b = 200, a = 255 }
|
||||
rl.DrawPoly(center, 24, b.radius + RING_PAD, 0.0, ring)
|
||||
}
|
||||
}
|
||||
@@ -152,11 +152,11 @@ main func() i32 {
|
||||
`[click] spawn a shape [WASD/arrows] blow wind
|
||||
`[space] clear
|
||||
|
||||
balls [CAP]mut Ball = undefined
|
||||
count usize = 0 # number of live balls, in slots 0..count
|
||||
kc Kind = .circle # next kind to spawn
|
||||
spin f32 = 1.0 # rotates spawn velocity for variety
|
||||
at_cap bool = false # show the "at capacity" banner
|
||||
balls [CAP]mut Ball := undefined
|
||||
count usize := 0 # number of live balls, in slots 0..count
|
||||
kc Kind := .circle # next kind to spawn
|
||||
spin f32 := 1.0 # rotates spawn velocity for variety
|
||||
at_cap bool := false # show the "at capacity" banner
|
||||
|
||||
bg :: rl.Color{ r = 24, g = 26, b = 34, a = 255 }
|
||||
text :: rl.Color{ r = 225, g = 225, b = 230, a = 255 }
|
||||
@@ -211,7 +211,7 @@ main func() i32 {
|
||||
# --- which shape is under the cursor? (optional via a value-loop) ---
|
||||
mouse :: rl.GetMousePosition()
|
||||
sel :: for 0..(count) |i| hover: {
|
||||
c rl.Vector2 = rl.Vector2{ x = balls[i].x, y = balls[i].y }
|
||||
c rl.Vector2 := rl.Vector2{ x = balls[i].x, y = balls[i].y }
|
||||
if rl.CheckCollisionPointCircle(mouse, c, balls[i].radius) yield :hover i
|
||||
yield null
|
||||
}
|
||||
@@ -222,7 +222,7 @@ main func() i32 {
|
||||
|
||||
for (&balls) |@b, i| {
|
||||
if (i >= count) break
|
||||
hot bool = false
|
||||
hot bool := false
|
||||
if sel |s| {
|
||||
if (s == i) hot = true # true only for the hovered ball
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ native_pair func(value native.Pair) native.Pair {
|
||||
global_pair native.Pair :: native.Pair { left = 1, right = 2 }
|
||||
|
||||
main func() i32 {
|
||||
pair native.Pair = native_pair(global_pair)
|
||||
pair native.Pair := native_pair(global_pair)
|
||||
pair.left = 10
|
||||
pair = native.echo_pair(pair)
|
||||
pairs [1]native.Pair :: [pair]
|
||||
@@ -33,7 +33,7 @@ main func() i32 {
|
||||
tail = 13,
|
||||
})
|
||||
arrays native.Arrays :: native.echo_arrays(native.Arrays { values = [14, 15, 16] })
|
||||
choice native.Choice = native.Choice { decimal = 1.0 }
|
||||
choice native.Choice := native.Choice { decimal = 1.0 }
|
||||
choice.integer = 17
|
||||
choice = native.echo_choice(choice)
|
||||
forward native.Forward :: native.echo_forward(native.Forward { value = 19 })
|
||||
|
||||
@@ -5,7 +5,7 @@ native :: import "../include/native.h"
|
||||
# self-referential `?*mut Node` field as C-layout-compatible.
|
||||
|
||||
main func() i32 {
|
||||
node native.Node = native.Node { next = null, value = 7 }
|
||||
node native.Node := native.Node { next = null, value = 7 }
|
||||
if node.next |_| {
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
hide helper func() i32 {
|
||||
thing Thing = Thing { value = value }
|
||||
thing Thing := Thing { value = value }
|
||||
return thing.value
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ hide Local_Distinct :: distinct i32
|
||||
hide Local_Alias :: alias i32
|
||||
|
||||
hide value :: 1
|
||||
hide mutable_value i32 = 1
|
||||
hide mutable_value i32 := 1
|
||||
|
||||
_foreign c_func() i32 {
|
||||
return 1
|
||||
@@ -39,6 +39,6 @@ hide Local_C_Record :: c_struct {
|
||||
}
|
||||
|
||||
from_a func() i32 {
|
||||
record Local_C_Record = Local_C_Record { value = 0 }
|
||||
record Local_C_Record := Local_C_Record { value = 0 }
|
||||
return helper() + local_foreign() + i32(record.value)
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ Box :: struct {
|
||||
}
|
||||
|
||||
from_b func(_input i32) i32 {
|
||||
_local Box = Box { _value = _input }
|
||||
record _C_Record = _C_Record { value = 0 }
|
||||
thing Thing = Thing { value = value }
|
||||
_local Box := Box { _value = _input }
|
||||
record _C_Record := _C_Record { value = 0 }
|
||||
thing Thing := Thing { value = value }
|
||||
return helper() + thing.value + _local._value + _foreign() + i32(record.value) + dep._visible()
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
bad = 1
|
||||
bad := undefined
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
main func() i32 {
|
||||
n usize = 4
|
||||
items [n]mut i32 = undefined
|
||||
n usize := 4
|
||||
items [n]mut i32 := undefined
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ State :: struct {
|
||||
diagnostics std.ArrayList(ScanDiagnostic)
|
||||
}
|
||||
|
||||
arrlist_test std.ArrayList(Token) = arraylist.init(mem.c_allocator)
|
||||
arrlist_test std.ArrayList(Token) := arraylist.init(mem.c_allocator)
|
||||
|
||||
init func(allocator mem.Allocator) State {
|
||||
return State {
|
||||
@@ -44,11 +44,11 @@ run func() i32 ! mem.AllocError {
|
||||
state State :: init(mem.c_allocator)
|
||||
_ = state
|
||||
|
||||
values std.ArrayList(i32) = arraylist.init(mem.c_allocator)
|
||||
values std.ArrayList(i32) := arraylist.init(mem.c_allocator)
|
||||
defer arraylist.deinit(&values)
|
||||
if (values.items.len != 0 or values.capacity != 0) return 1
|
||||
|
||||
i usize = 0
|
||||
i usize := 0
|
||||
while i < 20 : i += 1 {
|
||||
arraylist.append(&values, i32(i)) catch |_| {
|
||||
return .out_of_memory
|
||||
@@ -71,7 +71,7 @@ run func() i32 ! mem.AllocError {
|
||||
}
|
||||
if (values.items.len != 1 or values.items[0] != 7 or values.capacity != capacity) return 7
|
||||
|
||||
empty_values arraylist.ArrayList([0]u8) = arraylist.init(mem.c_allocator)
|
||||
empty_values arraylist.ArrayList([0]u8) := arraylist.init(mem.c_allocator)
|
||||
defer arraylist.deinit(&empty_values)
|
||||
zero [0]u8 :: []
|
||||
arraylist.append(&empty_values, zero) catch |_| {
|
||||
@@ -79,8 +79,8 @@ run func() i32 ! mem.AllocError {
|
||||
}
|
||||
if (empty_values.items.len != 1) return 8
|
||||
|
||||
failed arraylist.ArrayList(i32) = arraylist.init(i32, fail_allocator)
|
||||
failed_as_expected bool = false
|
||||
failed arraylist.ArrayList(i32) := arraylist.init(i32, fail_allocator)
|
||||
failed_as_expected bool := false
|
||||
arraylist.append(&failed, 1) catch |_| {
|
||||
failed_as_expected = true
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ c_count_shift func(value u8, count c_uint) u8 {
|
||||
c_count_fold u8 :: c_count_shift(3, 2)
|
||||
|
||||
main func() i32 {
|
||||
buffer Buffer = undefined
|
||||
buffer Buffer := undefined
|
||||
if (folded != 0) return 1
|
||||
if (contextual != 255) return 28
|
||||
if (contextual_shift != 128) return 29
|
||||
@@ -50,7 +50,7 @@ main func() i32 {
|
||||
if ((c_ushort(240) xor c_ushort(255)) != 15) return 26
|
||||
if ((c_longlong(64) <<| 60) != maxval!(c_longlong)) return 27
|
||||
|
||||
value u8 = 3
|
||||
value u8 := 3
|
||||
value <<= 2
|
||||
value |= 1
|
||||
value xor= 5
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
main func() i32 {
|
||||
# 1. `break` out of a `while` once i reaches 5.
|
||||
i i32 = 0
|
||||
a i32 = 0
|
||||
i i32 := 0
|
||||
a i32 := 0
|
||||
while i < 100 : i += 1 {
|
||||
if (i == 5) break
|
||||
a += 1
|
||||
@@ -16,7 +16,7 @@ main func() i32 {
|
||||
if (a != 5) return 101
|
||||
|
||||
# 2. `continue` past n == 3 while summing 0..9 (45 - 3 = 42).
|
||||
b i32 = 0
|
||||
b i32 := 0
|
||||
for 0..10 |n| {
|
||||
if (n == 3) continue
|
||||
b = b + n
|
||||
@@ -25,7 +25,7 @@ main func() i32 {
|
||||
|
||||
# 3. Nested loops: the inner `break` exits only the inner loop, so the outer
|
||||
# loop still runs all three iterations (each contributing one y == 0 pass).
|
||||
c i32 = 0
|
||||
c i32 := 0
|
||||
for 0..3 |x| {
|
||||
for 0..3 |y| {
|
||||
if (y == 1) break
|
||||
@@ -38,7 +38,7 @@ main func() i32 {
|
||||
# 4. `continue` on the final element of an inclusive range bounded by the
|
||||
# element type's maximum must exit cleanly, not overflow the increment.
|
||||
hi u8 :: 255
|
||||
d i32 = 0
|
||||
d i32 := 0
|
||||
for 0..=hi |v| {
|
||||
if (v == 255) continue
|
||||
d += 1
|
||||
@@ -47,7 +47,7 @@ main func() i32 {
|
||||
|
||||
# 5. `while true` is exitable via `break` (so it is not an infinite loop and
|
||||
# the code after it is reachable).
|
||||
e i32 = 0
|
||||
e i32 := 0
|
||||
while true {
|
||||
e += 1
|
||||
if (e == 7) break
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Compound assignment (`+=`, `-=`, `*=`, `/=`) and explicit integer division.
|
||||
|
||||
check_float func() i32 {
|
||||
x f64 = 10.0
|
||||
x f64 := 10.0
|
||||
x /= 4.0 # 2.5
|
||||
x *= 2.0 # 5.0
|
||||
x -= 1.0 # 4.0
|
||||
@@ -13,7 +13,7 @@ check_float func() i32 {
|
||||
}
|
||||
|
||||
check_unsigned func() i32 {
|
||||
n u32 = 100
|
||||
n u32 := 100
|
||||
n = divtrunc!(n, 7) # 14
|
||||
n -= 4 # 10
|
||||
if n == 10 {
|
||||
@@ -23,7 +23,7 @@ check_unsigned func() i32 {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
total i32 = 0
|
||||
total i32 := 0
|
||||
total += 10 # 10
|
||||
total -= 3 # 7
|
||||
total *= 4 # 28
|
||||
@@ -33,7 +33,7 @@ main func() i32 {
|
||||
total = total + 2 * 3 - 4
|
||||
|
||||
# compound assignment as a while-loop update
|
||||
i i32 = 0
|
||||
i i32 := 0
|
||||
while i < 5 : i += 1 {
|
||||
total += 1 # +5 => 21
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ nested func(value int) int {
|
||||
}
|
||||
|
||||
make_array func($N usize) [N]u8 {
|
||||
data [N]u8 = undefined
|
||||
data [N]u8 := undefined
|
||||
return data
|
||||
}
|
||||
|
||||
|
||||
@@ -14,13 +14,13 @@ id func($T type, value T) T {
|
||||
}
|
||||
|
||||
buffer func($T type, $N usize, value T) [N]T {
|
||||
data [N]T = undefined
|
||||
data [N]T := undefined
|
||||
_ = value
|
||||
return data
|
||||
}
|
||||
|
||||
zero func($T type) T {
|
||||
value T = undefined
|
||||
value T := undefined
|
||||
return value
|
||||
}
|
||||
|
||||
@@ -86,12 +86,12 @@ main func() i32 {
|
||||
if fixed_len(&fixed) != 3 {
|
||||
return 7
|
||||
}
|
||||
assigned i32 = 1
|
||||
assigned i32 := 1
|
||||
assigned = zero()
|
||||
_ = assigned
|
||||
_ = take_i32(zero())
|
||||
_ = return_zero()
|
||||
optional ?u32 = null
|
||||
optional ?u32 := null
|
||||
if !same_type(?u32, optional) {
|
||||
return 8
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ make_point func() Point {
|
||||
}
|
||||
|
||||
sum_loop func(limit i32) i32 {
|
||||
total i32 = 0
|
||||
i i32 = 0
|
||||
total i32 := 0
|
||||
i i32 := 0
|
||||
while i < limit {
|
||||
i += 1
|
||||
if i == 2 {
|
||||
@@ -45,8 +45,8 @@ sum_loop func(limit i32) i32 {
|
||||
}
|
||||
|
||||
sum_for func() i32 {
|
||||
total i32 = 0
|
||||
values [_]i32 = [1, 2, 3]
|
||||
total i32 := 0
|
||||
values [_]i32 := [1, 2, 3]
|
||||
for values |value, index| {
|
||||
total += value + index
|
||||
}
|
||||
@@ -54,7 +54,7 @@ sum_for func() i32 {
|
||||
}
|
||||
|
||||
defer_value func() i32 {
|
||||
value i32 = 1
|
||||
value i32 := 1
|
||||
{
|
||||
defer value += 10
|
||||
value += 1
|
||||
@@ -140,7 +140,7 @@ use_try func() i32 ! Error {
|
||||
}
|
||||
|
||||
ct_errdefer func(fail bool) i32 ! Error {
|
||||
trace i32 = 0
|
||||
trace i32 := 0
|
||||
defer trace = trace * 10 + 1
|
||||
errdefer |err| {
|
||||
if (err == .bad) trace = trace * 10 + 2
|
||||
@@ -151,7 +151,7 @@ ct_errdefer func(fail bool) i32 ! Error {
|
||||
}
|
||||
|
||||
ct_try_errdefer func() i32 ! Error {
|
||||
trace i32 = 0
|
||||
trace i32 := 0
|
||||
defer trace = trace * 10 + 4
|
||||
errdefer |err| {
|
||||
if (err == .bad) trace = trace * 10 + 5
|
||||
@@ -185,20 +185,20 @@ alias_add func(left @mut i32, right @mut i32) void {
|
||||
}
|
||||
|
||||
storage_mutation func() i32 {
|
||||
values [3]mut i32 = [1, 2, 3]
|
||||
values [3]mut i32 := [1, 2, 3]
|
||||
values[0] += 1
|
||||
bump_ptr(&values[1])
|
||||
|
||||
view []mut i32 = values[..]
|
||||
view []mut i32 := values[..]
|
||||
for view |@item| {
|
||||
item^ += 1
|
||||
}
|
||||
|
||||
pointer *mut i32 = view.ptr
|
||||
pointer *mut i32 := view.ptr
|
||||
pointer[2] += 1
|
||||
alias_add(&values[0], &view[0])
|
||||
|
||||
box Box = Box { point = Point { x = 2, y = 3 } }
|
||||
box Box := Box { point = Point { x = 2, y = 3 } }
|
||||
match box {
|
||||
.point |@p|: p.x += values[1]
|
||||
.empty: values[0] = values[0]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
make_array func($N usize) [N]u8 {
|
||||
data [N]u8 = undefined
|
||||
data [N]u8 := undefined
|
||||
return data
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,10 @@ observe func(counter @mut i32, value ?i32) ?i32 {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
total i32 = 0
|
||||
total i32 := 0
|
||||
|
||||
# present optional scalar -> binds v to the unwrapped value
|
||||
a ?i32 = 40
|
||||
a ?i32 := 40
|
||||
if a |v| {
|
||||
total = total + v # 40
|
||||
} else {
|
||||
@@ -17,7 +17,7 @@ main func() i32 {
|
||||
}
|
||||
|
||||
# null -> else branch taken; the binding is not in scope there
|
||||
b ?i32 = null
|
||||
b ?i32 := null
|
||||
if b |v| {
|
||||
total = total + v
|
||||
} else {
|
||||
@@ -25,20 +25,20 @@ main func() i32 {
|
||||
}
|
||||
|
||||
# optional pointer present -> binds q to a non-null @i32; deref proves it
|
||||
n i32 = 0
|
||||
p ?@i32 = &n
|
||||
n i32 := 0
|
||||
p ?@i32 := &n
|
||||
if p |q| {
|
||||
total = total + q^ # +0
|
||||
}
|
||||
|
||||
# optional pointer null -> skipped
|
||||
z ?@i32 = null
|
||||
z ?@i32 := null
|
||||
if z |_| {
|
||||
total = total + 1000
|
||||
}
|
||||
|
||||
# guarded multi-unwrap exposes every capture to the guard and then-block
|
||||
age ?i32 = 2
|
||||
age ?i32 := 2
|
||||
if a and age |value, years : value + years == 42| {
|
||||
total = total
|
||||
} else {
|
||||
@@ -46,7 +46,7 @@ main func() i32 {
|
||||
}
|
||||
|
||||
# parenthesized chains and three-value unwraps are equivalent
|
||||
bonus ?i32 = 0
|
||||
bonus ?i32 := 0
|
||||
if (a and age and bonus) |value, years, extra : value + years + extra == 42| {
|
||||
total = total
|
||||
} else {
|
||||
@@ -64,7 +64,7 @@ main func() i32 {
|
||||
}
|
||||
|
||||
# a failed unwrap prevents later expressions from being evaluated
|
||||
calls i32 = 0
|
||||
calls i32 := 0
|
||||
if b and observe(&calls, age) |missing, observed| {
|
||||
total = total + missing + observed
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ noisy func() bool {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
total i32 = 0
|
||||
total i32 := 0
|
||||
|
||||
# comparisons drive if / else if / else
|
||||
total = total + classify(-5) # 1
|
||||
@@ -45,9 +45,9 @@ main func() i32 {
|
||||
}
|
||||
|
||||
# block scoping: inner bindings do not escape the block
|
||||
x i32 = 1
|
||||
x i32 := 1
|
||||
if x == 1 {
|
||||
inner_x i32 = 100
|
||||
inner_x i32 := 100
|
||||
if inner_x == 100 {
|
||||
total = total + 5 # 40
|
||||
}
|
||||
|
||||
@@ -7,7 +7,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 {
|
||||
x i32 = 5
|
||||
x i32 := 5
|
||||
defer x = 999
|
||||
return x
|
||||
}
|
||||
@@ -15,7 +15,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 {
|
||||
v i32 = 0
|
||||
v i32 := 0
|
||||
defer v = v + 100
|
||||
for 0..3 |i| {
|
||||
defer v = v + 1
|
||||
@@ -89,7 +89,7 @@ main func() i32 {
|
||||
if (spill_check() != 5) return 101
|
||||
|
||||
# 2. LIFO ordering, run at end of each loop iteration.
|
||||
r i32 = 0
|
||||
r i32 := 0
|
||||
for 0..1 |i| {
|
||||
defer r = r * 2 + 1 # registered first -> runs last
|
||||
defer r = r * 2 # registered second -> runs first
|
||||
@@ -99,16 +99,16 @@ main func() i32 {
|
||||
|
||||
# 3. scoped bare block + scoped defer (defer fires at the closing brace, and
|
||||
# the block-local is not visible afterwards).
|
||||
a i32 = 1
|
||||
a i32 := 1
|
||||
{
|
||||
defer a = 4
|
||||
c i32 = 3
|
||||
c i32 := 3
|
||||
_ = c
|
||||
}
|
||||
if (a != 4) return 103
|
||||
|
||||
# 4. `defer { ... }` block: all its statements run (in order) at scope close.
|
||||
s i32 = 0
|
||||
s i32 := 0
|
||||
{
|
||||
defer {
|
||||
s = s + 1
|
||||
@@ -119,7 +119,7 @@ main func() i32 {
|
||||
if (s != 60) return 104 # 5 -> 6 -> 60
|
||||
|
||||
# 5. `break` flushes the loop-body defer.
|
||||
bc i32 = 0
|
||||
bc i32 := 0
|
||||
for 0..5 |i| {
|
||||
defer bc = bc + 1
|
||||
if (i == 2) break
|
||||
@@ -127,7 +127,7 @@ main func() i32 {
|
||||
if (bc != 3) return 105 # i=0,1 fall-through + i=2 break
|
||||
|
||||
# 6. `continue` flushes the loop-body defer.
|
||||
cc i32 = 0
|
||||
cc i32 := 0
|
||||
for 0..3 |i| {
|
||||
defer cc = cc + 1
|
||||
if (i == 1) continue
|
||||
@@ -139,7 +139,7 @@ main func() i32 {
|
||||
if (enclosing_defer_check() != 2) return 107
|
||||
|
||||
# 8. errdefer is skipped on success; ordinary defers stay interleaved.
|
||||
trace i32 = 0
|
||||
trace i32 := 0
|
||||
if ((explicit_cleanup(false, &trace) catch 0) != 7 or trace != 31) return 108
|
||||
|
||||
# 9. Explicit errors run errdefer and expose the captured error.
|
||||
|
||||
@@ -24,9 +24,9 @@ take func(value LocalID) LocalID {
|
||||
|
||||
main func() i32 {
|
||||
id LocalID :: LocalID(7)
|
||||
copy LocalID = take(id)
|
||||
maybe ?LocalID = copy
|
||||
pointer @LocalID = ©
|
||||
copy LocalID := take(id)
|
||||
maybe ?LocalID := copy
|
||||
pointer @LocalID := ©
|
||||
point PointID :: PointID(Point { x = 1, y = 2 })
|
||||
bytes Bytes :: Bytes([3, 4])
|
||||
wrapped WrappedID :: WrappedID(id)
|
||||
@@ -64,15 +64,15 @@ main func() i32 {
|
||||
return 8
|
||||
}
|
||||
|
||||
arithmetic Signed = Signed(4)
|
||||
arithmetic Signed := Signed(4)
|
||||
arithmetic += 3
|
||||
arithmetic -= 2
|
||||
arithmetic *= 5
|
||||
fraction Real = Real(3.0)
|
||||
fraction Real := Real(3.0)
|
||||
fraction /= 2.0
|
||||
if arithmetic != 25 or fraction != 1.5 { return 9 }
|
||||
|
||||
bits Mask = Mask(3)
|
||||
bits Mask := Mask(3)
|
||||
bits |= 8
|
||||
bits xor= 2
|
||||
bits &= 9
|
||||
@@ -81,18 +81,18 @@ main func() i32 {
|
||||
bits <<|= u8(5)
|
||||
if bits != 255 { return 10 }
|
||||
|
||||
values [10]u8 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
values [10]u8 := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
if values[LocalID(4)] != 4 { return 11 }
|
||||
section []u8 = values[LocalID(2)..LocalID(5)]
|
||||
section []u8 := values[LocalID(2)..LocalID(5)]
|
||||
if section.len != 3 or section[usize(0)] != 2 or section[usize(2)] != 4 { return 12 }
|
||||
|
||||
if u32(id) != 7 or usize(id) != 7 or f64(id) != 7.0 { return 13 }
|
||||
extracted LocalID = LocalID(wrapped)
|
||||
extracted LocalID := LocalID(wrapped)
|
||||
if extracted != id { return 14 }
|
||||
|
||||
minimum Signed = minval!(Signed)
|
||||
maximum Mask = maxval!(Mask)
|
||||
nested_max WrappedID = maxval!(WrappedID)
|
||||
minimum Signed := minval!(Signed)
|
||||
maximum Mask := maxval!(Mask)
|
||||
nested_max WrappedID := maxval!(WrappedID)
|
||||
if i32(minimum) != minval!(i32) or u8(maximum) != 255 or u32(nested_max) != maxval!(u32) {
|
||||
return 15
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ identity c_func(value State) State {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
state State = identity(.running)
|
||||
state State := identity(.running)
|
||||
values [2]State :: [.started, State.stopped]
|
||||
animal animals.Animal :: animals.Animal.dog
|
||||
if same(state, .running) and
|
||||
|
||||
@@ -125,7 +125,7 @@ inline_detail func(value i32) i32 ! union(enum) {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
acc i32 = 0
|
||||
acc i32 := 0
|
||||
|
||||
a :: maybe(0) catch 7
|
||||
b :: maybe(4) catch 99
|
||||
@@ -166,11 +166,11 @@ main func() i32 {
|
||||
|
||||
acc = acc + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p
|
||||
acc = acc + pick(.left)
|
||||
r Right = .right
|
||||
r Right := .right
|
||||
acc = acc + pick(r)
|
||||
box BoxA = .a{8}
|
||||
box BoxA := .a{8}
|
||||
acc = acc + payload(box)
|
||||
empty BoxB = .b
|
||||
empty BoxB := .b
|
||||
acc = acc + payload(empty)
|
||||
acc = acc + payload(.a{9})
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ pass func(value range) range {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
total i32 = 0
|
||||
total i32 := 0
|
||||
|
||||
items [3]mut i32 = [1, 2, 3]
|
||||
items [3]mut i32 := [1, 2, 3]
|
||||
for items |item, index| {
|
||||
total = total + item
|
||||
_ = index
|
||||
@@ -17,7 +17,7 @@ main func() i32 {
|
||||
item^ = item^ + 1
|
||||
}
|
||||
|
||||
view []mut i32 = items[..]
|
||||
view []mut i32 := items[..]
|
||||
for view |@item, index| {
|
||||
item^ = item^ + 1
|
||||
_ = index
|
||||
|
||||
@@ -6,23 +6,23 @@ make_range func(calls @mut i32, end usize) range {
|
||||
global_range :: 0..1
|
||||
|
||||
main func() i32 {
|
||||
total i32 = 0
|
||||
total i32 := 0
|
||||
|
||||
first u8 = 254
|
||||
last u8 = 255
|
||||
first u8 := 254
|
||||
last u8 := 255
|
||||
for first..=last |value| {
|
||||
_ = value
|
||||
total = total + 1
|
||||
}
|
||||
|
||||
signed_start i8 = -2
|
||||
signed_end i8 = 1
|
||||
signed_start i8 := -2
|
||||
signed_end i8 := 1
|
||||
for signed_start..signed_end |value| {
|
||||
_ = value
|
||||
total = total + 1
|
||||
}
|
||||
|
||||
limit usize = 3
|
||||
limit usize := 3
|
||||
for 0..(limit + 1) |value| {
|
||||
_ = value
|
||||
total = total + 1
|
||||
@@ -41,19 +41,19 @@ main func() i32 {
|
||||
total = total + 100
|
||||
}
|
||||
|
||||
empty [0]i32 = []
|
||||
empty [0]i32 := []
|
||||
for empty |value| {
|
||||
_ = value
|
||||
total = total + 100
|
||||
}
|
||||
|
||||
pointed i32 = 3
|
||||
pointers [1]@mut i32 = [&pointed]
|
||||
pointed i32 := 3
|
||||
pointers [1]@mut i32 := [&pointed]
|
||||
for pointers |pointer| {
|
||||
total = total + pointer^
|
||||
}
|
||||
|
||||
calls i32 = 0
|
||||
calls i32 := 0
|
||||
for make_range(&calls, 2) |value| {
|
||||
_ = value
|
||||
total = total + 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
main func() i32 {
|
||||
items [3]mut i32 = undefined
|
||||
i int = 1
|
||||
items [3]mut i32 := undefined
|
||||
i int := 1
|
||||
items[i] = 42
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
main func() i32 {
|
||||
items [3]mut i32 = undefined
|
||||
i i32 = 1
|
||||
items [3]mut i32 := undefined
|
||||
i i32 := 1
|
||||
items[i] = 42
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@ main func() i32 {
|
||||
return 2
|
||||
}
|
||||
|
||||
a Value = .number{41}
|
||||
b Value = .number{41}
|
||||
a Value := .number{41}
|
||||
b Value := .number{41}
|
||||
if !equal_value(a, b) or equal_value(a, .pair{left = 41, right = 0}) {
|
||||
return 3
|
||||
}
|
||||
@@ -78,8 +78,8 @@ main func() i32 {
|
||||
return 4
|
||||
}
|
||||
|
||||
pair_a Value = .pair{left = 2, right = 3}
|
||||
pair_b Value = .pair{left = 2, right = 3}
|
||||
pair_a Value := .pair{left = 2, right = 3}
|
||||
pair_b Value := .pair{left = 2, right = 3}
|
||||
if !equal_value(pair_a, pair_b) or !equal_value(.empty, .empty) {
|
||||
return 5
|
||||
}
|
||||
@@ -88,7 +88,7 @@ main func() i32 {
|
||||
return 6
|
||||
}
|
||||
|
||||
empty Value = .empty
|
||||
empty Value := .empty
|
||||
increment(&empty)
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
bad int = 4
|
||||
bad int := 4
|
||||
|
||||
read_bad func() int {
|
||||
return bad
|
||||
|
||||
@@ -85,7 +85,7 @@ bad_writer func() io.Writer {
|
||||
}
|
||||
|
||||
rejects_bad_read func() bool {
|
||||
buffer [1]mut u8 = [0]
|
||||
buffer [1]mut u8 := [0]
|
||||
_ = io.read(bad_reader(), buffer[..]) catch |err| {
|
||||
return err == .read_failed
|
||||
}
|
||||
@@ -108,7 +108,7 @@ rejects_bad_write func() bool {
|
||||
|
||||
main func(init process.Init) i32 {
|
||||
system io.Io :: init.io
|
||||
buffer [2]mut u8 = [0, 0]
|
||||
buffer [2]mut u8 := [0, 0]
|
||||
count usize :: io.read(ok_reader(), buffer[..]) catch 0
|
||||
if count != 2 or buffer[0] != 'o' or buffer[1] != 'k' {
|
||||
return 1
|
||||
|
||||
@@ -63,18 +63,18 @@ make_box func() Box {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
acc i32 = 0
|
||||
acc i32 := 0
|
||||
|
||||
dog Data = Data{ dog = 9 }
|
||||
bird Data = Data{ bird = 38 }
|
||||
dog Data := Data{ dog = 9 }
|
||||
bird Data := Data{ bird = 38 }
|
||||
acc = acc + describe(dog) + describe(bird) # 10 + 40 = 50
|
||||
|
||||
# same-type multi-pattern capture
|
||||
acc = acc + payload_of(dog) + payload_of(bird) # 9 + 38 = 47
|
||||
|
||||
# enum statement match, exhaustive, with a multi-pattern arm
|
||||
a Animal = .bird
|
||||
rank i32 = 0
|
||||
a Animal := .bird
|
||||
rank i32 := 0
|
||||
match a {
|
||||
.dog, .cat: rank = 1
|
||||
.bird: rank = 3
|
||||
@@ -89,7 +89,7 @@ main func() i32 {
|
||||
acc = acc + legs # +2
|
||||
|
||||
# scalar match: a range arm, a multi-literal arm, and a mandatory else
|
||||
bucket i32 = 0
|
||||
bucket i32 := 0
|
||||
match rank {
|
||||
0..3: bucket = 1 # exclusive 0,1,2 — does not include 3
|
||||
3, 4: bucket = 5 # rank is 3
|
||||
@@ -98,8 +98,8 @@ main func() i32 {
|
||||
acc = acc + bucket # +5
|
||||
|
||||
# void-payload variant: contextual construction (`.empty` coerces to Box) + no-capture arm
|
||||
e Box = .empty
|
||||
hit i32 = 0
|
||||
e Box := .empty
|
||||
hit i32 := 0
|
||||
match e {
|
||||
.point |pt|: hit = pt.x
|
||||
.empty: hit = 7
|
||||
@@ -107,7 +107,7 @@ main func() i32 {
|
||||
acc = acc + hit # +7
|
||||
|
||||
# pointer capture mutates the subject's payload in place
|
||||
b Box = Box{ point = Point{ x = 1, y = 2 } }
|
||||
b Box := Box{ point = Point{ x = 1, y = 2 } }
|
||||
match b {
|
||||
.point |@p|: p.x = 10
|
||||
.empty: hit = hit
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mem :: import "@std/mem"
|
||||
|
||||
raw_allocator_test func() i32 {
|
||||
resized ?*mut u8 = mem.raw_realloc(mem.c_allocator, null, 0, 4, 1)
|
||||
resized ?*mut u8 := mem.raw_realloc(mem.c_allocator, null, 0, 4, 1)
|
||||
if resized |bytes| {
|
||||
bytes[0] = 10
|
||||
bytes[1] = 20
|
||||
@@ -11,7 +11,7 @@ raw_allocator_test func() i32 {
|
||||
return 20
|
||||
}
|
||||
|
||||
grown ?*mut u8 = mem.raw_realloc(mem.c_allocator, resized, 4, 8, 1)
|
||||
grown ?*mut u8 := mem.raw_realloc(mem.c_allocator, resized, 4, 8, 1)
|
||||
if grown |bytes| {
|
||||
resized = grown
|
||||
if bytes[0] != 10 or bytes[1] != 20 or bytes[2] != 30 or bytes[3] != 40 {
|
||||
@@ -23,7 +23,7 @@ raw_allocator_test func() i32 {
|
||||
return 22
|
||||
}
|
||||
|
||||
shrunk ?*mut u8 = mem.raw_realloc(mem.c_allocator, resized, 8, 2, 1)
|
||||
shrunk ?*mut u8 := mem.raw_realloc(mem.c_allocator, resized, 8, 2, 1)
|
||||
if shrunk |bytes| {
|
||||
resized = shrunk
|
||||
if bytes[0] != 10 or bytes[1] != 20 {
|
||||
@@ -35,7 +35,7 @@ raw_allocator_test func() i32 {
|
||||
return 24
|
||||
}
|
||||
|
||||
invalid ?*mut u8 = mem.raw_realloc(mem.c_allocator, resized, 2, 4, 24)
|
||||
invalid ?*mut u8 := mem.raw_realloc(mem.c_allocator, resized, 2, 4, 24)
|
||||
if invalid |memory| {
|
||||
mem.raw_free(mem.c_allocator, memory, 4, 24)
|
||||
mem.raw_free(mem.c_allocator, resized, 2, 1)
|
||||
@@ -54,14 +54,14 @@ raw_allocator_test func() i32 {
|
||||
return 27
|
||||
}
|
||||
|
||||
over_aligned ?*mut u8 = mem.raw_alloc(mem.c_allocator, 4, 32)
|
||||
over_aligned ?*mut u8 := mem.raw_alloc(mem.c_allocator, 4, 32)
|
||||
if over_aligned |bytes| {
|
||||
bytes[0] = 11
|
||||
bytes[1] = 22
|
||||
} else {
|
||||
return 28
|
||||
}
|
||||
over_aligned_grown ?*mut u8 = mem.raw_realloc(mem.c_allocator, over_aligned, 4, 8, 32)
|
||||
over_aligned_grown ?*mut u8 := mem.raw_realloc(mem.c_allocator, over_aligned, 4, 8, 32)
|
||||
if over_aligned_grown |bytes| {
|
||||
if bytes[0] != 11 or bytes[1] != 22 {
|
||||
mem.raw_free(mem.c_allocator, over_aligned_grown, 8, 32)
|
||||
@@ -73,19 +73,19 @@ raw_allocator_test func() i32 {
|
||||
return 30
|
||||
}
|
||||
|
||||
zero_alignment ?*mut u8 = mem.raw_alloc(mem.c_allocator, 8, 0)
|
||||
zero_alignment ?*mut u8 := mem.raw_alloc(mem.c_allocator, 8, 0)
|
||||
if zero_alignment |memory| {
|
||||
mem.raw_free(mem.c_allocator, memory, 8, 0)
|
||||
return 1
|
||||
}
|
||||
|
||||
bad_alignment ?*mut u8 = mem.raw_alloc(mem.c_allocator, 8, 24)
|
||||
bad_alignment ?*mut u8 := mem.raw_alloc(mem.c_allocator, 8, 24)
|
||||
if bad_alignment |memory| {
|
||||
mem.raw_free(mem.c_allocator, memory, 8, 24)
|
||||
return 2
|
||||
}
|
||||
|
||||
aligned ?*mut u8 = mem.raw_alloc(mem.c_allocator, 64, 32)
|
||||
aligned ?*mut u8 := mem.raw_alloc(mem.c_allocator, 64, 32)
|
||||
defer mem.raw_free(mem.c_allocator, aligned, 64, 32)
|
||||
if aligned |bytes| {
|
||||
bytes[0] = 1
|
||||
|
||||
@@ -21,9 +21,9 @@ task_list_init func(allocator mem.Allocator) TaskList {
|
||||
}
|
||||
|
||||
alloc_i32s func(allocator mem.Allocator, count usize) ?[]mut i32 {
|
||||
fallback [1]mut i32 = undefined
|
||||
failed bool = false
|
||||
values []mut i32 = mem.alloc(allocator, count) catch |_| {
|
||||
fallback [1]mut i32 := undefined
|
||||
failed bool := false
|
||||
values []mut i32 := mem.alloc(allocator, count) catch |_| {
|
||||
failed = true
|
||||
yield (&fallback).ptr[..0]
|
||||
}
|
||||
@@ -42,14 +42,14 @@ task_list_reserve func(list @mut TaskList, capacity usize) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
new_ids ?[]mut i32 = alloc_i32s(list.allocator, capacity)
|
||||
new_priorities ?[]mut i32 = alloc_i32s(list.allocator, capacity)
|
||||
new_durations ?[]mut i32 = alloc_i32s(list.allocator, capacity)
|
||||
new_ids ?[]mut i32 := alloc_i32s(list.allocator, capacity)
|
||||
new_priorities ?[]mut i32 := alloc_i32s(list.allocator, capacity)
|
||||
new_durations ?[]mut i32 := alloc_i32s(list.allocator, capacity)
|
||||
|
||||
if (new_ids and new_priorities and new_durations) |ids, priorities, durations| {
|
||||
if list.len > 0 {
|
||||
if (list.ids and list.priorities and list.durations) |old_ids, old_priorities, old_durations| {
|
||||
i usize = 0
|
||||
i usize := 0
|
||||
while i < list.len : i += 1 {
|
||||
ids[i] = old_ids[i]
|
||||
priorities[i] = old_priorities[i]
|
||||
@@ -82,7 +82,7 @@ task_list_reserve func(list @mut TaskList, capacity usize) bool {
|
||||
|
||||
task_list_push func(list @mut TaskList, id i32, priority i32, duration i32) bool {
|
||||
if list.len == list.capacity {
|
||||
new_capacity usize = 2
|
||||
new_capacity usize := 2
|
||||
if list.capacity != 0 {
|
||||
new_capacity = list.capacity * 2
|
||||
}
|
||||
@@ -92,7 +92,7 @@ task_list_push func(list @mut TaskList, id i32, priority i32, duration i32) bool
|
||||
}
|
||||
|
||||
if (list.ids and list.priorities and list.durations) |ids, priorities, durations| {
|
||||
index usize = list.len
|
||||
index usize := list.len
|
||||
ids[index] = id
|
||||
priorities[index] = priority
|
||||
durations[index] = duration
|
||||
@@ -113,11 +113,11 @@ task_list_best_id func(list @mut TaskList) i32 {
|
||||
}
|
||||
|
||||
if (list.ids and list.priorities and list.durations) |ids, priorities, durations| {
|
||||
best_index usize = 0
|
||||
best_score i32 = task_score(priorities[0], durations[0])
|
||||
i usize = 1
|
||||
best_index usize := 0
|
||||
best_score i32 := task_score(priorities[0], durations[0])
|
||||
i usize := 1
|
||||
while i < list.len : i += 1 {
|
||||
score i32 = task_score(priorities[i], durations[i])
|
||||
score i32 := task_score(priorities[i], durations[i])
|
||||
if score > best_score {
|
||||
best_score = score
|
||||
best_index = i
|
||||
@@ -130,9 +130,9 @@ task_list_best_id func(list @mut TaskList) i32 {
|
||||
}
|
||||
|
||||
task_list_total_duration func(list @mut TaskList) i32 {
|
||||
total i32 = 0
|
||||
total i32 := 0
|
||||
if list.durations |durations| {
|
||||
i usize = 0
|
||||
i usize := 0
|
||||
while i < list.len : i += 1 {
|
||||
total += durations[i]
|
||||
}
|
||||
@@ -152,7 +152,7 @@ task_list_deinit func(list @mut TaskList) void {
|
||||
}
|
||||
|
||||
task_list_test func() i32 {
|
||||
tasks TaskList = task_list_init(mem.c_allocator)
|
||||
tasks TaskList := task_list_init(mem.c_allocator)
|
||||
defer task_list_deinit(&tasks)
|
||||
|
||||
if task_list_push(&tasks, 101, 3, 5) == false {
|
||||
|
||||
@@ -30,8 +30,8 @@ hide probe_vtable mem.AllocatorVTable :: mem.AllocatorVTable {
|
||||
typed_allocator_test func() i32 {
|
||||
if (sizeof!(mem.Allocator) != 16) return 31
|
||||
|
||||
first_calls [1]mut usize = [0]
|
||||
second_calls [1]mut usize = [0]
|
||||
first_calls [1]mut usize := [0]
|
||||
second_calls [1]mut usize := [0]
|
||||
first_allocator mem.Allocator :: mem.Allocator {
|
||||
context = &first_calls,
|
||||
vtable = &probe_vtable,
|
||||
@@ -47,9 +47,9 @@ typed_allocator_test func() i32 {
|
||||
_ = mem.raw_alloc(second_allocator, 1, 1)
|
||||
if (first_calls[0] != 3 or second_calls[0] != 1) return 32
|
||||
|
||||
i32_fallback [1]mut i32 = undefined
|
||||
empty_failed bool = false
|
||||
empty []mut i32 = mem.alloc(first_allocator, 0) catch |_| {
|
||||
i32_fallback [1]mut i32 := undefined
|
||||
empty_failed bool := false
|
||||
empty []mut i32 := mem.alloc(first_allocator, 0) catch |_| {
|
||||
empty_failed = true
|
||||
yield (&i32_fallback).ptr[..0]
|
||||
}
|
||||
@@ -57,9 +57,9 @@ typed_allocator_test func() i32 {
|
||||
mem.free(first_allocator, empty)
|
||||
if (first_calls[0] != 3) return 33
|
||||
|
||||
zero_sized_fallback [1]mut [0]u8 = undefined
|
||||
zero_sized_failed bool = false
|
||||
zero_sized []mut [0]u8 = mem.alloc([0]u8, first_allocator, 3) catch |_| {
|
||||
zero_sized_fallback [1]mut [0]u8 := undefined
|
||||
zero_sized_failed bool := false
|
||||
zero_sized []mut [0]u8 := mem.alloc([0]u8, first_allocator, 3) catch |_| {
|
||||
zero_sized_failed = true
|
||||
yield (&zero_sized_fallback).ptr[..0]
|
||||
}
|
||||
@@ -68,22 +68,22 @@ typed_allocator_test func() i32 {
|
||||
mem.free([0]u8, first_allocator, zero_sized)
|
||||
if (first_calls[0] != 3) return 35
|
||||
|
||||
u64_fallback [1]mut u64 = undefined
|
||||
overflow_fallback_failed bool = false
|
||||
overflow_fallback []mut u64 = mem.alloc(first_allocator, 0) catch |_| {
|
||||
u64_fallback [1]mut u64 := undefined
|
||||
overflow_fallback_failed bool := false
|
||||
overflow_fallback []mut u64 := mem.alloc(first_allocator, 0) catch |_| {
|
||||
overflow_fallback_failed = true
|
||||
yield (&u64_fallback).ptr[..0]
|
||||
}
|
||||
if (overflow_fallback_failed) return 37
|
||||
overflow_failed bool = false
|
||||
overflow_failed bool := false
|
||||
_ = mem.alloc(u64, first_allocator, maxval!(usize)) catch |_| {
|
||||
overflow_failed = true
|
||||
yield overflow_fallback
|
||||
}
|
||||
if (overflow_failed == false or first_calls[0] != 3) return 40
|
||||
|
||||
typed_failed bool = false
|
||||
typed []mut i32 = mem.alloc(mem.c_allocator, 4) catch |_| {
|
||||
typed_failed bool := false
|
||||
typed []mut i32 := mem.alloc(mem.c_allocator, 4) catch |_| {
|
||||
typed_failed = true
|
||||
yield (&i32_fallback).ptr[..0]
|
||||
}
|
||||
|
||||
@@ -48,26 +48,26 @@ score_for func(k Kind) i32 {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
items [LEN]mut i32 = undefined
|
||||
items [LEN]mut i32 := undefined
|
||||
items[0] = 10
|
||||
items[1] = 20
|
||||
|
||||
idx u8 = 2
|
||||
idx u8 := 2
|
||||
items[idx] = items[0] + items[1]
|
||||
if (items[2] != 30) return 1
|
||||
|
||||
native_i i32 = 12
|
||||
native_i i32 := 12
|
||||
if (take_c_int(native_i) != 12) return 2
|
||||
|
||||
native_u u8 = 7
|
||||
native_u u8 := 7
|
||||
if (take_c_uchar(native_u) != 7) return 3
|
||||
|
||||
native_f f32 = 3.25
|
||||
native_f f32 := 3.25
|
||||
cf :: take_c_float(native_f)
|
||||
if (cf < 3.0 or cf > 4.0) return 4
|
||||
if (cf == 0.0) return 5
|
||||
|
||||
native_d f64 = 5.0
|
||||
native_d f64 := 5.0
|
||||
cd :: take_c_double(native_d)
|
||||
if (cd != 5.0) return 6
|
||||
|
||||
|
||||
@@ -86,8 +86,8 @@ main func(init process.Init) i32 {
|
||||
}
|
||||
|
||||
writer io.Writer :: io.stdout(init.io)
|
||||
positive f64 = 1.0
|
||||
zero f64 = 0.0
|
||||
positive f64 := 1.0
|
||||
zero f64 := 0.0
|
||||
infinity f64 :: positive / zero
|
||||
nan f64 :: zero / zero
|
||||
io.print(writer, "{} {} {} {} {s} {d} {b} {o} {x} {X} {c} {e} {{}} {d} {b} {} {} {e}\n", {
|
||||
|
||||
@@ -2,11 +2,11 @@ Point :: struct {
|
||||
x i32
|
||||
}
|
||||
|
||||
counter int = 0
|
||||
ratio float = 1
|
||||
span range = 0..2
|
||||
point Point = Point { x = 1 }
|
||||
values [_]mut i32 = [10, 20]
|
||||
counter := i32(0)
|
||||
ratio := 1.0
|
||||
span := 0..2
|
||||
point Point := Point { x = 1 }
|
||||
values [_]mut i32 := [10, 20]
|
||||
|
||||
bump func(value @mut i32) void {
|
||||
value^ += 1
|
||||
@@ -19,7 +19,7 @@ main func() i32 {
|
||||
point.x += counter
|
||||
values[1] = point.x
|
||||
|
||||
total i32 = counter + point.x + values[1]
|
||||
total i32 := counter + point.x + values[1]
|
||||
for span |i| {
|
||||
total += i
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
main func() i32 {
|
||||
value i32 = 1
|
||||
value := i32(1)
|
||||
value = value + 2
|
||||
return value
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
main func() void {
|
||||
value i8 = 127
|
||||
value i8 := 127
|
||||
_ = value + 1
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ sum_brolang func(a, b int) int {
|
||||
}
|
||||
|
||||
main func() void {
|
||||
y int = 4
|
||||
y int := 4
|
||||
a_add_b_c :: sum_c(1, 2)
|
||||
a_add_b_brolang :: sum_brolang(1, 2)
|
||||
_ = y
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
main func() i32 {
|
||||
flag bool = true
|
||||
flag bool := true
|
||||
value :: i32(flag)
|
||||
return value
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ Thing :: union(enum) {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
x Data = Data{ bird = 37 }
|
||||
y Thing = Thing{ a = 5 }
|
||||
x Data := Data{ bird = 37 }
|
||||
y Thing := Thing{ a = 5 }
|
||||
return x.bird + y.a
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ format func() []u8 {
|
||||
}
|
||||
|
||||
sum func($T type, value T) i32 {
|
||||
total i32 = 0
|
||||
total i32 := 0
|
||||
match typeinfo!(T) {
|
||||
.record |record|: inline for record.fields |field| {
|
||||
total += i32(field!(value, field.name))
|
||||
@@ -20,7 +20,7 @@ sum func($T type, value T) i32 {
|
||||
}
|
||||
|
||||
static_control func($T type, value T) i32 {
|
||||
total i32 = 0
|
||||
total i32 := 0
|
||||
match typeinfo!(T) {
|
||||
.record |record|: inline for record.fields |field| {
|
||||
{
|
||||
@@ -49,7 +49,7 @@ row_value func(row Row) i32 {
|
||||
}
|
||||
|
||||
static_aggregates func() i32 {
|
||||
total i32 = 0
|
||||
total i32 := 0
|
||||
inline for {Row {value = 2}, Row {value = 40}} |row| {
|
||||
total += row_value(row)
|
||||
}
|
||||
@@ -57,7 +57,7 @@ static_aggregates func() i32 {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
numbers Numbers = Numbers {1, 2, 39}
|
||||
numbers Numbers := Numbers {1, 2, 39}
|
||||
singleton :: {42,}
|
||||
empty :: {}
|
||||
block_value :: {
|
||||
|
||||
@@ -4,6 +4,6 @@ Val :: union {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
x Val = Val{ n = 42 }
|
||||
x Val := Val{ n = 42 }
|
||||
return x.n
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
warn_only func(value i32, unused i32) i32 {
|
||||
local i32 = 1
|
||||
write_only i32 = 2
|
||||
local i32 := 1
|
||||
write_only i32 := 2
|
||||
write_only = 3
|
||||
consumed i32 = value
|
||||
consumed i32 := value
|
||||
_ = consumed
|
||||
return value
|
||||
}
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
# Milestone 5: boolean while loops with optional post-iteration updates.
|
||||
|
||||
return_before_update func() i32 {
|
||||
i i32 = 0
|
||||
i i32 := 0
|
||||
while true : i = i + 1 {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
total i32 = 0
|
||||
total i32 := 0
|
||||
|
||||
# ordinary condition and update
|
||||
i u32 = 0
|
||||
i u32 := 0
|
||||
while i < 5 : i = i + 1 {
|
||||
total = total + 2
|
||||
}
|
||||
|
||||
# equivalent parenthesized header
|
||||
j u32 = 0
|
||||
j u32 := 0
|
||||
while (j < 4) : (j = j + 1) {
|
||||
total = total + 3
|
||||
}
|
||||
|
||||
# nested loops and body-local storage
|
||||
outer u32 = 0
|
||||
outer u32 := 0
|
||||
while outer < 2 : outer = outer + 1 {
|
||||
inner u32 = 0
|
||||
inner u32 := 0
|
||||
while inner < 3 : inner = inner + 1 {
|
||||
total = total + 2
|
||||
}
|
||||
@@ -33,9 +33,9 @@ main func() i32 {
|
||||
|
||||
# Body-local storage stays scoped to the body. The update still targets
|
||||
# the mutable k declared before the loop.
|
||||
k u32 = 0
|
||||
k u32 := 0
|
||||
while k < 4 : k = k + 1 {
|
||||
body_k u32 = 100
|
||||
body_k u32 := 100
|
||||
if body_k == 100 {
|
||||
total = total + 2
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ basic func() i32 {
|
||||
|
||||
# Typed `T =`: the yield coerces to the annotation.
|
||||
typed func() i64 {
|
||||
x i64 = {
|
||||
x i64 := {
|
||||
yield 100
|
||||
}
|
||||
return x
|
||||
@@ -29,7 +29,7 @@ typed func() i64 {
|
||||
# local, but the captured value is unchanged.
|
||||
spill func() i32 {
|
||||
v :: {
|
||||
n i32 = 5
|
||||
n i32 := 5
|
||||
defer n = 999
|
||||
yield n
|
||||
}
|
||||
@@ -38,7 +38,7 @@ spill func() i32 {
|
||||
|
||||
# Reassignment into an existing mutable local.
|
||||
reassign func() i32 {
|
||||
r i32 = 0
|
||||
r i32 := 0
|
||||
r = {
|
||||
yield 7
|
||||
}
|
||||
@@ -61,13 +61,13 @@ vif_untyped func(sel i32) i32 {
|
||||
|
||||
# Typed `T =`: every branch coerces to the annotation.
|
||||
vif_typed func(sel i32) i32 {
|
||||
r i32 = if (sel == 0) { yield 100 } else { yield 200 }
|
||||
r i32 := if (sel == 0) { yield 100 } else { yield 200 }
|
||||
return r
|
||||
}
|
||||
|
||||
# Assigned into an existing local.
|
||||
vif_reassign func(sel i32) i32 {
|
||||
r i32 = 0
|
||||
r i32 := 0
|
||||
r = if (sel == 0) { yield 7 } else { yield 9 }
|
||||
return r
|
||||
}
|
||||
@@ -76,7 +76,7 @@ vif_reassign func(sel i32) i32 {
|
||||
# the yield.
|
||||
vif_defer func() i32 {
|
||||
r :: if (true) {
|
||||
n i32 = 5
|
||||
n i32 := 5
|
||||
defer n = 999
|
||||
yield n
|
||||
} else {
|
||||
@@ -123,7 +123,7 @@ loop_none func() i32 {
|
||||
|
||||
# Labeled `while` value loop (label follows the `: update` clause).
|
||||
loop_while func() i32 {
|
||||
n i32 = 0
|
||||
n i32 := 0
|
||||
found :: while n < 100 : n += 1 blk: {
|
||||
if (n == 8) yield :blk n
|
||||
yield null
|
||||
@@ -199,7 +199,7 @@ lblock func(sel i32) i32 {
|
||||
# the block's defer runs.
|
||||
lblock_defer func() i32 {
|
||||
r :: blk: {
|
||||
n i32 = 5
|
||||
n i32 := 5
|
||||
defer n = 999
|
||||
if (true) yield :blk n
|
||||
yield :blk 0
|
||||
@@ -235,7 +235,7 @@ yield_outer func(target i32) i32 {
|
||||
|
||||
# Plain `break :outer` exits an outer loop from an inner loop.
|
||||
break_outer func() i32 {
|
||||
count i32 = 0
|
||||
count i32 := 0
|
||||
for 0..3 |a| outer: {
|
||||
for 0..3 |b| {
|
||||
count += 1
|
||||
@@ -247,7 +247,7 @@ break_outer func() i32 {
|
||||
|
||||
# A labeled block *statement* (not a value source): `break :blk` exits it early.
|
||||
stmt_block func(early i32) i32 {
|
||||
x i32 = 0
|
||||
x i32 := 0
|
||||
blk: {
|
||||
x = 1
|
||||
if (early == 1) break :blk
|
||||
@@ -259,7 +259,7 @@ stmt_block func(early i32) i32 {
|
||||
# `break :search` escapes a nested loop and the block in one jump; the block's
|
||||
# defer still runs on the way out.
|
||||
stmt_block_escape func() i32 {
|
||||
hits i32 = 0
|
||||
hits i32 := 0
|
||||
search: {
|
||||
defer hits += 1000
|
||||
for 0..10 |i| {
|
||||
@@ -273,7 +273,7 @@ stmt_block_escape func() i32 {
|
||||
|
||||
# A labeled block can also be exited through an ordinary nested block.
|
||||
stmt_block_nested func() i32 {
|
||||
hits i32 = 0
|
||||
hits i32 := 0
|
||||
outer: {
|
||||
{
|
||||
hits = 1
|
||||
|
||||
@@ -28,7 +28,7 @@ reserve func($T type, list @mut ArrayList(T), min_capacity usize) void ! mem.All
|
||||
return
|
||||
}
|
||||
|
||||
new_capacity usize = 8
|
||||
new_capacity usize := 8
|
||||
if list.capacity >= 8 {
|
||||
half usize :: divtrunc!(list.capacity, 2)
|
||||
if list.capacity > maxval!(usize) - half {
|
||||
|
||||
@@ -2,7 +2,7 @@ import "@std/mem"
|
||||
import "@std/testing"
|
||||
|
||||
handles_append test {
|
||||
list ArrayList(i32) = init(mem.c_allocator)
|
||||
list ArrayList(i32) := init(mem.c_allocator)
|
||||
defer deinit(&list)
|
||||
|
||||
try append(&list, 42)
|
||||
@@ -12,7 +12,7 @@ handles_append test {
|
||||
}
|
||||
|
||||
handles_clear test {
|
||||
list ArrayList(i32) = init(mem.c_allocator)
|
||||
list ArrayList(i32) := init(mem.c_allocator)
|
||||
defer deinit(&list)
|
||||
|
||||
try append(&list, 42)
|
||||
@@ -22,7 +22,7 @@ handles_clear test {
|
||||
}
|
||||
|
||||
handles_reserve test {
|
||||
list ArrayList(i32) = init(mem.c_allocator)
|
||||
list ArrayList(i32) := init(mem.c_allocator)
|
||||
defer deinit(&list)
|
||||
|
||||
try reserve(&list, 10)
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ print func($format []u8, $Args type, args Args) void {
|
||||
}
|
||||
|
||||
hide write func(_ ?@mut anyopaque, handle io.Handle, bytes []u8) usize ! io.WriteError {
|
||||
request usize = bytes.len
|
||||
request usize := bytes.len
|
||||
maximum usize :: usize(maxval!(c_long))
|
||||
if request > maximum {
|
||||
request = maximum
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ init func(
|
||||
$E, $V type,
|
||||
values meta.EnumFieldStruct(E, ?V, some!(null)),
|
||||
) EnumMap(E, V) {
|
||||
map EnumMap(E, V) = undefined
|
||||
map EnumMap(E, V) := undefined
|
||||
|
||||
match typeinfo!(E) {
|
||||
.enum |info|: inline for info.fields |field, i| {
|
||||
|
||||
@@ -8,7 +8,7 @@ TestEnum :: enum(u8) {
|
||||
}
|
||||
|
||||
handles_sparse_enum_get test {
|
||||
names EnumMap(TestEnum, []u8) = init({
|
||||
names EnumMap(TestEnum, []u8) := init({
|
||||
ident = "identifier",
|
||||
int = "integer",
|
||||
})
|
||||
|
||||
@@ -59,7 +59,7 @@ get func(
|
||||
if (map.count == 0) return null
|
||||
|
||||
hash :: normalize(hash_key(key))
|
||||
idx usize = hash & (map.entries.len - 1)
|
||||
idx usize := hash & (map.entries.len - 1)
|
||||
|
||||
while true {
|
||||
entry :: map.entries[idx]
|
||||
@@ -98,7 +98,7 @@ put func(
|
||||
if (entry.hash == 0) continue
|
||||
|
||||
# find an empty slot
|
||||
idx usize = entry.hash & (new_entries.len - 1)
|
||||
idx usize := entry.hash & (new_entries.len - 1)
|
||||
while new_entries[idx].hash != 0 {
|
||||
idx = (idx + 1) & (new_entries.len - 1)
|
||||
}
|
||||
@@ -112,7 +112,7 @@ put func(
|
||||
|
||||
# put new entry
|
||||
hash :: normalize(hash_key(key))
|
||||
idx usize = hash & (map.entries.len - 1)
|
||||
idx usize := hash & (map.entries.len - 1)
|
||||
|
||||
while true {
|
||||
entry :: map.entries[idx]
|
||||
@@ -144,8 +144,8 @@ hide normalize func(hash usize) usize {
|
||||
#! FNV-1a hash implementation.
|
||||
#! note: vulnerable to collision attacks.
|
||||
hide str_hash func(key []u8) usize {
|
||||
hash u32 = 2166136261 # offset basis
|
||||
prime u32 = 16777619
|
||||
hash u32 := 2166136261 # offset basis
|
||||
prime u32 := 16777619
|
||||
|
||||
for key |byte| {
|
||||
product u64 :: u64(hash xor u32(byte)) * prime
|
||||
|
||||
@@ -2,7 +2,7 @@ import "@std/mem"
|
||||
import "@std/testing"
|
||||
|
||||
handles_put_and_get test {
|
||||
map StringHashMap(u32) = init(mem.c_allocator)
|
||||
map StringHashMap(u32) := init(mem.c_allocator)
|
||||
defer deinit(&map)
|
||||
|
||||
try put(&map, "key", 42)
|
||||
|
||||
+3
-3
@@ -47,7 +47,7 @@ writer func(file File) Writer {
|
||||
}
|
||||
|
||||
hide system_read func(_ ?@mut anyopaque, handle Handle, buffer []mut u8) usize ! ReadError {
|
||||
request usize = buffer.len
|
||||
request usize := buffer.len
|
||||
maximum usize :: usize(maxval!(c_long))
|
||||
if request > maximum {
|
||||
request = maximum
|
||||
@@ -69,7 +69,7 @@ hide system_read func(_ ?@mut anyopaque, handle Handle, buffer []mut u8) usize !
|
||||
}
|
||||
|
||||
hide system_write func(_ ?@mut anyopaque, handle Handle, bytes []u8) usize ! WriteError {
|
||||
request usize = bytes.len
|
||||
request usize := bytes.len
|
||||
maximum usize :: usize(maxval!(c_long))
|
||||
if request > maximum {
|
||||
request = maximum
|
||||
@@ -91,7 +91,7 @@ hide system_write func(_ ?@mut anyopaque, handle Handle, bytes []u8) usize ! Wri
|
||||
}
|
||||
|
||||
hide system_open func(_ ?@mut anyopaque, path [;0]u8, mode FileMode) Handle ! OpenError {
|
||||
flags c_int = c.O_RDONLY
|
||||
flags c_int := c.O_RDONLY
|
||||
match mode {
|
||||
.read_only: flags = c.O_RDONLY
|
||||
.write_only: flags = c.O_WRONLY
|
||||
|
||||
+19
-19
@@ -73,7 +73,7 @@ write func(output Writer, bytes []u8) usize ! WriteError {
|
||||
}
|
||||
|
||||
write_all func(output Writer, bytes []u8) void ! WriteError {
|
||||
offset usize = 0
|
||||
offset usize := 0
|
||||
while offset < bytes.len {
|
||||
count usize :: write(output, bytes[offset..]) catch |err| {
|
||||
return err
|
||||
@@ -129,12 +129,12 @@ print func(output Writer, $format []u8, $Args type, args Args) void ! WriteError
|
||||
}
|
||||
|
||||
hide write_integer_signed func(output Writer, value i64, base u64, uppercase bool) void ! WriteError {
|
||||
buffer [65]mut u8 = undefined
|
||||
end usize = buffer.len
|
||||
current i64 = value
|
||||
buffer [65]mut u8 := undefined
|
||||
end usize := buffer.len
|
||||
current i64 := value
|
||||
while true {
|
||||
digit_value i64 :: rem!(current, i64(base))
|
||||
digit u8 = 0
|
||||
digit u8 := 0
|
||||
if digit_value < 0 {
|
||||
digit = u8(-digit_value)
|
||||
} else {
|
||||
@@ -162,9 +162,9 @@ hide write_integer_signed func(output Writer, value i64, base u64, uppercase boo
|
||||
}
|
||||
|
||||
hide write_integer_unsigned func(output Writer, value u64, base u64, uppercase bool) void ! WriteError {
|
||||
buffer [65]mut u8 = undefined
|
||||
end usize = buffer.len
|
||||
current u64 = value
|
||||
buffer [65]mut u8 := undefined
|
||||
end usize := buffer.len
|
||||
current u64 := value
|
||||
while true {
|
||||
digit u8 :: u8(rem!(current, base))
|
||||
end -= 1
|
||||
@@ -206,11 +206,11 @@ hide FormatToken :: struct {
|
||||
}
|
||||
|
||||
hide parse_format func($N usize, $format []u8, $Args type) [N]mut FormatToken {
|
||||
tokens [N]mut FormatToken = undefined
|
||||
tokens [N]mut FormatToken := undefined
|
||||
for (usize(0))..format.len |index| {
|
||||
tokens[index] = FormatToken {kind = .unused, start = 0, end = 0, field = ""}
|
||||
}
|
||||
field_count usize = 0
|
||||
field_count usize := 0
|
||||
match typeinfo!(Args) {
|
||||
.record |record|: {
|
||||
if !record.is_tuple {
|
||||
@@ -221,10 +221,10 @@ hide parse_format func($N usize, $format []u8, $Args type) [N]mut FormatToken {
|
||||
else: compile_error!("io.print arguments must be a tuple")
|
||||
}
|
||||
|
||||
token_count usize = 0
|
||||
argument_count usize = 0
|
||||
literal_start usize = 0
|
||||
cursor usize = 0
|
||||
token_count usize := 0
|
||||
argument_count usize := 0
|
||||
literal_start usize := 0
|
||||
cursor usize := 0
|
||||
while cursor < format.len {
|
||||
byte :: format[cursor]
|
||||
if byte == '{' {
|
||||
@@ -243,8 +243,8 @@ hide parse_format func($N usize, $format []u8, $Args type) [N]mut FormatToken {
|
||||
literal_start = cursor
|
||||
continue
|
||||
}
|
||||
kind FormatTokenKind = .default
|
||||
width usize = 2
|
||||
kind FormatTokenKind := .default
|
||||
width usize := 2
|
||||
if next != '}' {
|
||||
if cursor + 2 >= format.len or format[cursor + 2] != '}' {
|
||||
compile_error!("io.print format expects a one-character specifier")
|
||||
@@ -353,8 +353,8 @@ hide write_integer func(output Writer, $T type, value T, base u64, uppercase boo
|
||||
hide write_float func(output Writer, $T type, value T, scientific bool) void ! WriteError {
|
||||
match typeinfo!(T) {
|
||||
.float: {
|
||||
buffer [64]mut u8 = undefined
|
||||
count c_int = 0
|
||||
buffer [64]mut u8 := undefined
|
||||
count c_int := 0
|
||||
if sizeof!(T) == 4 {
|
||||
if scientific {
|
||||
count = c.snprintf(ptrcast!(c_char, (&buffer).ptr), c_ulong(buffer.len), "%.8e", value)
|
||||
@@ -401,7 +401,7 @@ hide write_character func(output Writer, $T type, value T) void ! WriteError {
|
||||
if minval!(T) < 0 or maxval!(T) > 255 {
|
||||
compile_error!("io.print '{c}' requires an unsigned integer that fits in u8")
|
||||
}
|
||||
buffer [1]u8 = [u8(value)]
|
||||
buffer [1]u8 := [u8(value)]
|
||||
try write_all(output, buffer[..])
|
||||
}
|
||||
.distinct |backing|: if scalar_or_distinct_type(backing) {
|
||||
|
||||
+11
-11
@@ -46,7 +46,7 @@ alloc func($T type, allocator Allocator, count usize) []mut T ! AllocError {
|
||||
return .out_of_memory
|
||||
}
|
||||
|
||||
memory ?*mut u8 = raw_alloc(allocator, count * element_size, alignof!(T))
|
||||
memory ?*mut u8 := raw_alloc(allocator, count * element_size, alignof!(T))
|
||||
if memory |bytes| {
|
||||
pointer *mut T :: ptrcast!(T, bytes)
|
||||
return pointer[..count]
|
||||
@@ -75,13 +75,13 @@ realloc func($T type, allocator Allocator, memory []mut T, new_count usize) []mu
|
||||
return .out_of_memory
|
||||
}
|
||||
|
||||
old_memory ?*mut u8 = null
|
||||
old_size usize = 0
|
||||
old_memory ?*mut u8 := null
|
||||
old_size usize := 0
|
||||
if memory.len != 0 {
|
||||
old_memory = ptrcast!(u8, memory.ptr)
|
||||
old_size = memory.len * element_size
|
||||
}
|
||||
resized ?*mut u8 = raw_realloc(
|
||||
resized ?*mut u8 := raw_realloc(
|
||||
allocator,
|
||||
old_memory,
|
||||
old_size,
|
||||
@@ -119,15 +119,15 @@ empty func($T type) []mut T {
|
||||
return empty_slice(T, 0)
|
||||
}
|
||||
|
||||
hide empty_storage [1]mut u64 = [0]
|
||||
hide empty_storage [1]mut u64 := [0]
|
||||
|
||||
hide malloc_alignment usize :: 16 # ponytail: aarch64-macos libc malloc alignment assumption.
|
||||
|
||||
hide power_of_two func(value usize) bool {
|
||||
if (value == 0) return false
|
||||
current usize = value
|
||||
current usize := value
|
||||
while current > 1 {
|
||||
half usize = divtrunc!(current, 2)
|
||||
half usize := divtrunc!(current, 2)
|
||||
if (half * 2 != current) return false
|
||||
current = half
|
||||
}
|
||||
@@ -141,8 +141,8 @@ hide c_alloc func(_ ?@mut anyopaque, size usize, alignment usize) ?*mut u8 {
|
||||
return ptrcast!(u8, c.malloc(c_ulong(size)))
|
||||
}
|
||||
|
||||
memory [1]mut ?*mut anyopaque = [null]
|
||||
status c_int = c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size))
|
||||
memory [1]mut ?*mut anyopaque := [null]
|
||||
status c_int := c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size))
|
||||
if (status != 0) return null
|
||||
|
||||
return ptrcast!(u8, memory[0])
|
||||
@@ -161,9 +161,9 @@ hide c_realloc func(_ ?@mut anyopaque, memory ?*mut u8, old_size usize, new_size
|
||||
return ptrcast!(u8, c.realloc(old_memory, c_ulong(new_size)))
|
||||
}
|
||||
|
||||
new_memory ?*mut u8 = c_alloc(null, new_size, alignment)
|
||||
new_memory ?*mut u8 := c_alloc(null, new_size, alignment)
|
||||
if new_memory |new_bytes| {
|
||||
copy_size usize = old_size
|
||||
copy_size usize := old_size
|
||||
if (new_size < copy_size) copy_size = new_size
|
||||
memcopy!(new_bytes[..copy_size], old_memory[..copy_size])
|
||||
c.free(old_memory)
|
||||
|
||||
+3
-3
@@ -46,9 +46,9 @@ TypeInfo :: union(enum) {
|
||||
EnumFieldStruct func($E, $Field type, $default ?Field) type {
|
||||
match typeinfo!(E) {
|
||||
.enum |info|: {
|
||||
names [info.fields.len]mut []u8 = undefined
|
||||
field_types [info.fields.len]mut type = undefined
|
||||
defaults [info.fields.len]mut ?Field = undefined
|
||||
names [info.fields.len]mut []u8 := undefined
|
||||
field_types [info.fields.len]mut type := undefined
|
||||
defaults [info.fields.len]mut ?Field := undefined
|
||||
inline for info.fields |field, index| {
|
||||
names[index] = field.name
|
||||
field_types[index] = Field
|
||||
|
||||
@@ -42,7 +42,7 @@ distinct_reflection_exposes_immediate_backing test {
|
||||
|
||||
|
||||
enum_field_struct_defaults test {
|
||||
names TestNames = {
|
||||
names TestNames := {
|
||||
ident = "identifier",
|
||||
int = "integer",
|
||||
}
|
||||
@@ -60,7 +60,7 @@ enum_field_struct_defaults test {
|
||||
try testing.expect(false)
|
||||
}
|
||||
|
||||
empty TestNames = {}
|
||||
empty TestNames := {}
|
||||
if field!(empty, "ident") |_| {
|
||||
try testing.expect(false)
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ init func($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) {
|
||||
compile_error!("static string map has too many entries")
|
||||
}
|
||||
|
||||
keys [N]mut []u8 = undefined
|
||||
values [N]mut V = undefined
|
||||
keys [N]mut []u8 := undefined
|
||||
values [N]mut V := undefined
|
||||
|
||||
# assert no duplicate keys
|
||||
for entries |entry, i| {
|
||||
@@ -37,7 +37,7 @@ init func($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) {
|
||||
}
|
||||
|
||||
if N == 0 {
|
||||
len_indexes [0]u32 = undefined
|
||||
len_indexes [0]u32 := undefined
|
||||
return StaticStringMap(V){
|
||||
keys = keys[..],
|
||||
values = values[..],
|
||||
@@ -51,7 +51,7 @@ init func($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) {
|
||||
for 1..N |i| {
|
||||
key :: keys[i]
|
||||
value :: values[i]
|
||||
j usize = i
|
||||
j usize := i
|
||||
while j > 0 and keys[j - 1].len > key.len : j -= 1 {
|
||||
keys[j] = keys[j - 1]
|
||||
values[j] = values[j - 1]
|
||||
@@ -62,8 +62,8 @@ init func($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) {
|
||||
|
||||
min_len u32 :: u32(keys[0].len)
|
||||
max_len u32 :: u32(keys[N - 1].len)
|
||||
len_indexes [usize(max_len) + 1]mut u32 = undefined
|
||||
entry_index usize = 0
|
||||
len_indexes [usize(max_len) + 1]mut u32 := undefined
|
||||
entry_index usize := 0
|
||||
for 0..=usize(max_len) |length| {
|
||||
while entry_index < N and keys[entry_index].len < length : entry_index += 1 {}
|
||||
len_indexes[length] = u32(entry_index)
|
||||
@@ -81,10 +81,10 @@ init func($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) {
|
||||
get func($V type, map @StaticStringMap(V), key []u8) ?V {
|
||||
if (map.keys.len == 0 or key.len > maxval!(u32)) return null
|
||||
|
||||
length u32 = u32(key.len)
|
||||
length u32 := u32(key.len)
|
||||
if (length < map.min_len or length > map.max_len) return null
|
||||
|
||||
idx usize = usize(map.len_indexes[usize(length)])
|
||||
idx usize := usize(map.len_indexes[usize(length)])
|
||||
while idx < map.keys.len : idx += 1 {
|
||||
candidate :: map.keys[idx]
|
||||
if (candidate.len != key.len) return null
|
||||
|
||||
+11
-11
@@ -77,8 +77,8 @@ read_command func() Command {
|
||||
if IsMouseButtonPressed(MOUSE_BUTTON_LEFT) return .spawn{ GetMousePosition() }
|
||||
if IsKeyPressed(KEY_SPACE) return .clear
|
||||
|
||||
fx f32 = 0.0
|
||||
fy f32 = 0.0
|
||||
fx f32 := 0.0
|
||||
fy f32 := 0.0
|
||||
if IsKeyDown(KEY_A) fx -= FORCE
|
||||
if IsKeyDown(KEY_D) fx += FORCE
|
||||
if IsKeyDown(KEY_W) fy -= FORCE
|
||||
@@ -128,14 +128,14 @@ step func(b @mut Ball) void {
|
||||
|
||||
draw_ball func(b @Ball, highlight bool) void {
|
||||
col :: color_for(b.kind)
|
||||
center Vector2 = Vector2{ x = b.x, y = b.y }
|
||||
center Vector2 := Vector2{ x = b.x, y = b.y }
|
||||
match b.kind {
|
||||
.circle: DrawCircleV(center, b.radius, col)
|
||||
.square: DrawPoly(center, 4, b.radius, 45.0, col)
|
||||
.triangle: DrawPoly(center, 3, b.radius, 0.0, col)
|
||||
}
|
||||
if highlight {
|
||||
ring Color = Color{ r = 250, g = 245, b = 200, a = 255 }
|
||||
ring Color := Color{ r = 250, g = 245, b = 200, a = 255 }
|
||||
DrawPoly(center, 24, b.radius + RING_PAD, 0.0, ring)
|
||||
}
|
||||
}
|
||||
@@ -150,11 +150,11 @@ main func() i32 {
|
||||
`[click] spawn a shape [WASD/arrows] blow wind
|
||||
`[space] clear
|
||||
|
||||
balls [CAP]mut Ball = undefined
|
||||
count usize = 0 # number of live balls, in slots 0..count
|
||||
kc Kind = .circle # next kind to spawn
|
||||
spin f32 = 1.0 # rotates spawn velocity for variety
|
||||
at_cap bool = false # show the "at capacity" banner
|
||||
balls [CAP]mut Ball := undefined
|
||||
count usize := 0 # number of live balls, in slots 0..count
|
||||
kc Kind := .circle # next kind to spawn
|
||||
spin f32 := 1.0 # rotates spawn velocity for variety
|
||||
at_cap bool := false # show the "at capacity" banner
|
||||
|
||||
bg :: Color{ r = 24, g = 26, b = 34, a = 255 }
|
||||
text :: Color{ r = 225, g = 225, b = 230, a = 255 }
|
||||
@@ -209,7 +209,7 @@ main func() i32 {
|
||||
# --- which shape is under the cursor? (optional via a value-loop) ---
|
||||
mouse :: GetMousePosition()
|
||||
sel :: for 0..(count) |i| blk: {
|
||||
c Vector2 = Vector2{ x = balls[i].x, y = balls[i].y }
|
||||
c Vector2 := Vector2{ x = balls[i].x, y = balls[i].y }
|
||||
if CheckCollisionPointCircle(mouse, c, balls[i].radius) yield :blk i
|
||||
yield null
|
||||
}
|
||||
@@ -220,7 +220,7 @@ main func() i32 {
|
||||
|
||||
for (&balls) |@b, i| {
|
||||
if (i >= count) break
|
||||
hot bool = false
|
||||
hot bool := false
|
||||
if sel |s| {
|
||||
if (s == i) hot = true # true only for the hovered ball
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ hide append_token func(tokens @mut std.ArrayList(Token), kind Kind, start, end u
|
||||
}
|
||||
|
||||
lex func(source []u8, tokens @mut std.ArrayList(Token)) void ! mem.AllocError {
|
||||
cursor usize = 0
|
||||
cursor usize := 0
|
||||
while cursor < source.len {
|
||||
value u8 :: source[cursor]
|
||||
if value == ' ' or value == '\t' or value == '\r' {
|
||||
@@ -112,7 +112,7 @@ hide print_token func(source []u8, token Token) void {
|
||||
_ = c.printf("%-11s", kind_name(token.kind))
|
||||
if token.length != 0 {
|
||||
_ = c.printf(" `")
|
||||
i usize = 0
|
||||
i usize := 0
|
||||
while i < token.length : i += 1 {
|
||||
value u8 :: source[token.start + i]
|
||||
if value == '\n' {
|
||||
@@ -132,7 +132,7 @@ main func() i32 {
|
||||
` hello()
|
||||
`}
|
||||
|
||||
tokens std.ArrayList(Token) = arraylist.init(mem.c_allocator)
|
||||
tokens std.ArrayList(Token) := arraylist.init(mem.c_allocator)
|
||||
defer arraylist.deinit(&tokens)
|
||||
|
||||
lex(source, &tokens) catch |_| {
|
||||
|
||||
@@ -28,7 +28,7 @@ reserve func($T type, list @mut ArrayList(T), minimum_capacity usize) void ! mem
|
||||
return
|
||||
}
|
||||
|
||||
new_capacity usize = 8
|
||||
new_capacity usize := 8
|
||||
if list.capacity >= 8 {
|
||||
half usize :: divtrunc!(list.capacity, 2)
|
||||
if list.capacity > maxval!(usize) - half {
|
||||
|
||||
@@ -61,7 +61,7 @@ write func(writer Writer, bytes []u8) usize ! WriteError {
|
||||
}
|
||||
|
||||
write_all func(writer Writer, bytes []u8) void ! WriteError {
|
||||
offset usize = 0
|
||||
offset usize := 0
|
||||
while offset < bytes.len {
|
||||
count usize :: write(writer, bytes[offset..]) catch |err| {
|
||||
return err
|
||||
@@ -75,7 +75,7 @@ write_all func(writer Writer, bytes []u8) void ! WriteError {
|
||||
}
|
||||
|
||||
hide system_read func(_ ?*mut anyopaque, stream ReadStream, buffer []mut u8) usize ! ReadError {
|
||||
request usize = buffer.len
|
||||
request usize := buffer.len
|
||||
maximum usize :: usize(maxval!(c_long))
|
||||
if request > maximum {
|
||||
request = maximum
|
||||
@@ -93,7 +93,7 @@ hide system_read func(_ ?*mut anyopaque, stream ReadStream, buffer []mut u8) usi
|
||||
|
||||
hide system_write func(_ ?*mut anyopaque, stream WriteStream, bytes []u8) usize ! WriteError {
|
||||
fd c_int :: c_int(stream)
|
||||
request usize = bytes.len
|
||||
request usize := bytes.len
|
||||
maximum usize :: usize(maxval!(c_long))
|
||||
if request > maximum {
|
||||
request = maximum
|
||||
|
||||
@@ -32,7 +32,7 @@ eql func($T type, left, right []T) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
i usize = 0
|
||||
i usize := 0
|
||||
while i < left.len : i += 1 {
|
||||
if left[i] != right[i] {
|
||||
return false
|
||||
@@ -41,7 +41,7 @@ eql func($T type, left, right []T) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
hide empty_storage [1]mut u64 = [0]
|
||||
hide empty_storage [1]mut u64 := [0]
|
||||
|
||||
hide empty_slice func($T type, count usize) []mut T {
|
||||
pointer *mut T :: ptrcast!(T, (&empty_storage).ptr)
|
||||
@@ -65,7 +65,7 @@ alloc func($T type, allocator Allocator, count usize) []mut T ! AllocError {
|
||||
return .out_of_memory
|
||||
}
|
||||
|
||||
memory ?*mut u8 = raw_alloc(allocator, count * element_size, alignof!(T))
|
||||
memory ?*mut u8 := raw_alloc(allocator, count * element_size, alignof!(T))
|
||||
if memory |bytes| {
|
||||
pointer *mut T :: ptrcast!(T, bytes)
|
||||
return pointer[..count]
|
||||
@@ -90,13 +90,13 @@ realloc func($T type, allocator Allocator, memory []mut T, new_count usize) []mu
|
||||
return .out_of_memory
|
||||
}
|
||||
|
||||
old_memory ?*mut u8 = null
|
||||
old_size usize = 0
|
||||
old_memory ?*mut u8 := null
|
||||
old_size usize := 0
|
||||
if memory.len != 0 {
|
||||
old_memory = ptrcast!(u8, memory.ptr)
|
||||
old_size = memory.len * element_size
|
||||
}
|
||||
resized ?*mut u8 = raw_realloc(
|
||||
resized ?*mut u8 := raw_realloc(
|
||||
allocator,
|
||||
old_memory,
|
||||
old_size,
|
||||
@@ -123,9 +123,9 @@ hide power_of_two func(value usize) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
current usize = value
|
||||
current usize := value
|
||||
while current > 1 {
|
||||
half usize = divtrunc!(current, 2)
|
||||
half usize := divtrunc!(current, 2)
|
||||
if half * 2 != current {
|
||||
return false
|
||||
}
|
||||
@@ -144,8 +144,8 @@ hide c_alloc func(_ ?*mut anyopaque, size usize, alignment usize) ?*mut u8 {
|
||||
return ptrcast!(u8, c.malloc(c_ulong(size)))
|
||||
}
|
||||
|
||||
memory [1]mut ?*mut anyopaque = [null]
|
||||
status c_int = c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size))
|
||||
memory [1]mut ?*mut anyopaque := [null]
|
||||
status c_int := c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size))
|
||||
if status != 0 {
|
||||
return null
|
||||
}
|
||||
@@ -168,13 +168,13 @@ hide c_realloc func(_ ?*mut anyopaque, memory ?*mut u8, old_size usize, new_size
|
||||
return ptrcast!(u8, c.realloc(old_memory, c_ulong(new_size)))
|
||||
}
|
||||
|
||||
new_memory ?*mut u8 = c_alloc(null, new_size, alignment)
|
||||
new_memory ?*mut u8 := c_alloc(null, new_size, alignment)
|
||||
if new_memory |new_bytes| {
|
||||
copy_size usize = old_size
|
||||
copy_size usize := old_size
|
||||
if new_size < copy_size {
|
||||
copy_size = new_size
|
||||
}
|
||||
i usize = 0
|
||||
i usize := 0
|
||||
while i < copy_size : i += 1 {
|
||||
new_bytes[i] = old_memory[i]
|
||||
}
|
||||
|
||||
+4
-4
@@ -25,7 +25,7 @@ tier_bonus func(tier Tier) i32 {
|
||||
}
|
||||
|
||||
projected_score func(player Player) i32 {
|
||||
total i32 = player.score
|
||||
total i32 := player.score
|
||||
total += tier_bonus(player.tier)
|
||||
if player.active and player.streak > 2 {
|
||||
total += player.streak * 3
|
||||
@@ -42,8 +42,8 @@ apply_decay func(players []mut Player) void {
|
||||
}
|
||||
|
||||
best_player func(players []mut Player) ?@mut Player {
|
||||
best ?@mut Player = null
|
||||
best_score i32 = 0
|
||||
best ?@mut Player := null
|
||||
best_score i32 := 0
|
||||
|
||||
for players |@player| {
|
||||
score :: projected_score(player^)
|
||||
@@ -62,7 +62,7 @@ best_player func(players []mut Player) ?@mut Player {
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
players [4]mut Player = [
|
||||
players [4]mut Player := [
|
||||
Player { id = PlayerID(1), name = "Ada", tier = .gold, score = 41, streak = 4, active = true },
|
||||
Player { id = PlayerID(2), name = "Ken", tier = .silver, score = 56, streak = 1, active = true },
|
||||
Player { id = PlayerID(3), name = "Edsger", tier = .bronze, score = 64, streak = 0, active = false },
|
||||
|
||||
@@ -27,7 +27,7 @@ raw_free func(allocator Allocator, memory ?*mut u8, size usize, alignment usize)
|
||||
allocator.vtable.free(allocator.context, memory, size, alignment)
|
||||
}
|
||||
|
||||
hide empty_storage [1]mut u64 = [0]
|
||||
hide empty_storage [1]mut u64 := [0]
|
||||
|
||||
hide empty_slice func($T type, count usize) []mut T {
|
||||
pointer *mut T :: ptrcast!(T, (&empty_storage).ptr)
|
||||
@@ -47,7 +47,7 @@ alloc func($T type, allocator Allocator, count usize) []mut T ! AllocError {
|
||||
return .out_of_memory
|
||||
}
|
||||
|
||||
memory ?*mut u8 = raw_alloc(allocator, count * element_size, alignof!(T))
|
||||
memory ?*mut u8 := raw_alloc(allocator, count * element_size, alignof!(T))
|
||||
if memory |bytes| {
|
||||
pointer *mut T :: ptrcast!(T, bytes)
|
||||
return pointer[..count]
|
||||
@@ -68,9 +68,9 @@ hide power_of_two func(value usize) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
current usize = value
|
||||
current usize := value
|
||||
while current > 1 {
|
||||
half usize = current / 2
|
||||
half usize := current / 2
|
||||
if half * 2 != current {
|
||||
return false
|
||||
}
|
||||
@@ -89,8 +89,8 @@ hide c_alloc func(_ ?*mut anyopaque, size usize, alignment usize) ?*mut u8 {
|
||||
return ptrcast!(u8, c.malloc(c_ulong(size)))
|
||||
}
|
||||
|
||||
memory [1]mut ?*mut anyopaque = [null]
|
||||
status c_int = c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size))
|
||||
memory [1]mut ?*mut anyopaque := [null]
|
||||
status c_int := c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size))
|
||||
if status != 0 {
|
||||
return null
|
||||
}
|
||||
@@ -113,13 +113,13 @@ hide c_realloc func(_ ?*mut anyopaque, memory ?*mut u8, old_size usize, new_size
|
||||
return ptrcast!(u8, c.realloc(old_memory, c_ulong(new_size)))
|
||||
}
|
||||
|
||||
new_memory ?*mut u8 = c_alloc(null, new_size, alignment)
|
||||
new_memory ?*mut u8 := c_alloc(null, new_size, alignment)
|
||||
if new_memory |new_bytes| {
|
||||
copy_size usize = old_size
|
||||
copy_size usize := old_size
|
||||
if new_size < copy_size {
|
||||
copy_size = new_size
|
||||
}
|
||||
i usize = 0
|
||||
i usize := 0
|
||||
while i < copy_size : i += 1 {
|
||||
new_bytes[i] = old_memory[i]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user