sprite-rs/example.fae
2022-02-28 13:09:33 -07:00

93 lines
2.3 KiB
Plaintext

// complex data is passed and manipulated in structures
struct World {
// each member is defined by name and type
u32 xsize,
u32 ysize,
BitArray current,
u32 numdots,
BitArray next,
// members can have default initialization values
i32 xmin = 1'000'000,
i32 xmax = -1,
i32 ymin = 1'000'000,
i32 ymax = -1,
}
// non-associated function, operates in the scope of its arguments only
// `fn fn_name(args) return_value { body }`
fn count_neighbors(BitArray array, i32 i, i32 j) i32 {
// local variables are declared with `let`
let c1 = i - 1;
let c2 = i;
let c3 = i + 1;
let r1 = i - 1;
let r2 = i;
let c3 = i + 1;
// associated functions of a struct can be stored in a variable
// now `g(x, y)` is shorthand for `array.get(x, y)`
let g = array.get;
// return result with trailing expression at the end of function
g(c1, r1) + g(c1, r2) + g(c1, r3) +
g(c2, r1) + g(c2, r3) +
g(c3, r1) + g(c3, r2) + g(c3, r3)
}
// associated function for the World struct
World fn set_next(i32 i, i32 j) {
// members on this World struct can be accessed with `.`
var numdots = .numdots; // mutable variables are defined with `var`
let neighbors = count_neighbors(.current, i, j);
// `if` statements are expressions
let next = if .current.get(i, j) == 0 {
if neighbors != 3 {
0
} else {
numdots++;
1
}
} else {
// Python-like `or` operator
if neighbors == 2 or neighbors == 3 {
1
} else {
numdots--;
0
}
};
if next != 0 {
// TODO: mutability rules for arguments?
if i < .xmin { .xmin = i; }
if i > .xmax { .xmax = i; }
if j < .ymin { .ymin = j; }
if j > .ymax { .ymax = j; }
}
}
World fn next_cycle() {
let xlb = .xmin - 1;
let xub = .xmax + 1;
let ylb = .ymin - 1;
let yub = .ymax + 1;
// TODO: flesh out `for` semantics
for y in ylb..yub {
for x in xlb..xub {
.set_next(x, y);
}
}
// TODO: figure out better range definitions, or ditch them altogether
for y in 0..(.ysize) {
for x in 0..(.xsize) {
// TODO: mutability rules
.current.set_bit(x, y, .next.get_bit(x, y));
}
}
}