tests: the map-scoped tables' example and rejected fixtures
examples/lang/permap (two maps, a chunked table with a negative, a positive and a missing chunk, constants and fn by name, a nested list, a cross-row @Ref, a reload shrinking in place, a bad file's file:line:col; built under arena strict with an @On frame root), --check fixtures for a wrong field, a wrong type, an unknown constant and a dangling cross-row @Ref, @Ref(PerMap) on an int, as PREFIX, and a @Unit warning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
2f4860ae71
commit
5a751434ac
17 changed files with 181 additions and 0 deletions
3
examples/lang/permap/maps/alpha/instances/-1_0.lres
Normal file
3
examples/lang/permap/maps/alpha/instances/-1_0.lres
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# the chunk west of the origin: {cx} is -1
|
||||
t1 { kind: MDL_TENT, x: -10.0, z: 3.0 }
|
||||
t2 { kind: 2, x: -20.5 }
|
||||
1
examples/lang/permap/maps/alpha/instances/0_2.lres
Normal file
1
examples/lang/permap/maps/alpha/instances/0_2.lres
Normal file
|
|
@ -0,0 +1 @@
|
|||
r1 { kind: 1, x: 3.0, z: 130.0 }
|
||||
6
examples/lang/permap/maps/alpha/props.lres
Normal file
6
examples/lang/permap/maps/alpha/props.lres
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# alpha's props: a constant by name, a nested list of records, a list of strings, a nested
|
||||
# record, a fn by name, and a cross-row @Ref (home names a row of alpha's spots.lres)
|
||||
tent { model: MDL_TENT, yaw: 90.0, role: "camp", home: "fire", tags: ["guy", "fly"],
|
||||
pts: [{ x: 1.0, z: 2.0 }, { x: 3.5, z: -4 }], at: { x: 5 }, pick: fn twice }
|
||||
bench { model: MDL_BENCH, scale: G_SCALE, lit: true, home: "" }
|
||||
sign { model: 3, role: "say \"hi\"" }
|
||||
2
examples/lang/permap/maps/alpha/spots.lres
Normal file
2
examples/lang/permap/maps/alpha/spots.lres
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
fire { kind: "camp", x: 1.0 }
|
||||
view { kind: "view", x: -2.5 }
|
||||
2
examples/lang/permap/maps/bad/one/props.lres
Normal file
2
examples/lang/permap/maps/bad/one/props.lres
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# a field PropRow does not have (a map one directory down, which --check does not read as a map)
|
||||
lamp { model: 1, colour: 3 }
|
||||
2
examples/lang/permap/maps/beta/props.lres
Normal file
2
examples/lang/permap/maps/beta/props.lres
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# fewer rows than alpha: a reload shrinks the table in place
|
||||
crate { model: 12, pts: [{ x: 9.0 }] }
|
||||
1
examples/lang/permap/maps/beta/spots.lres
Normal file
1
examples/lang/permap/maps/beta/spots.lres
Normal file
|
|
@ -0,0 +1 @@
|
|||
dock { kind: "work" }
|
||||
4
examples/lang/permap/package.ludic
Normal file
4
examples/lang/permap/package.ludic
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# the map-scoped tables' example (permap.ludic): its maps are the directories under maps/, and its
|
||||
# frame code is held to the arena's region rule - the generated verbs keep nothing a frame makes
|
||||
maps "maps"
|
||||
arena strict
|
||||
86
examples/lang/permap/permap.ludic
Normal file
86
examples/lang/permap/permap.ludic
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# permap.ludic — map-scoped tables: a @PerMap registry's rows are not compiled in, they are read
|
||||
# from `<maps root>/<map>/<file>` when a map loads (package.ludic says `maps "maps"`), and a
|
||||
# @Chunked one a chunk at a time. The compiler writes the table's state and its verbs - props_load,
|
||||
# props_find, props_path; instances_in, _out, _slot, _find - and pools every row, list and record, so
|
||||
# a reload refills them in place and allocates nothing past the table's high water.
|
||||
#
|
||||
# Running it prints: yes yes 3 7 90 2 -4 fly 5 42 0 9 3 yes 8 / yes 1 -1 0 crate 12 1 0 0 21 same examples/lang/permap/maps/beta/density/a.png / 0 1 2 2 7 1 0 1 1 / -1 1 0 2 3 / no 0 examples/lang/permap/maps/bad/one/props.lres:2:18: PropRow has no field colour
|
||||
program PerMap {
|
||||
numbers float
|
||||
const MDL_TENT: int = 7
|
||||
const MDL_BENCH: int = MDL_TENT + 2
|
||||
const G_SCALE: float = 1.5
|
||||
property Pt { x: float = 0.0, z: float = 0.0 }
|
||||
# a place on the map, found by key
|
||||
property Spot {
|
||||
key: string = ""
|
||||
@OneOf("camp", "view", "work") kind: string = "view"
|
||||
x: float = 0.0
|
||||
}
|
||||
@PerMap @ByKey registry Spots of Spot from "spots.lres"
|
||||
# a prop placed on the map
|
||||
property PropRow {
|
||||
key: string = ""
|
||||
model: int = 0
|
||||
@Unit("deg") yaw: float = 0.0
|
||||
scale: float = 1.0
|
||||
lit: bool = false
|
||||
role: string = ""
|
||||
@Ref(Spots) home: string = ""
|
||||
pts: []Pt = new []Pt
|
||||
tags: []string = new []string
|
||||
at: Pt = new Pt
|
||||
pick: fn(int) -> int = fn keep_n
|
||||
}
|
||||
@PerMap @ByKey registry Props of PropRow from "props.lres"
|
||||
property InstRow { key: string = "", kind: int = 0, x: float = 0.0, z: float = 0.0 }
|
||||
@PerMap @Chunked(64) registry Instances of InstRow from "instances/{cx}_{cz}.lres"
|
||||
# a frame's streaming: the ring moved, a chunk comes in and one goes out - frame code, which the
|
||||
# region rule (`arena strict` in package.ludic) holds to keeping nothing it makes
|
||||
event Stream { cx: int = 0, cz: int = 0 }
|
||||
@On(Stream) handler Streamed(inst: mut Instances, props: Props) {
|
||||
let s = instances_in(inst, "alpha", cx, cz)
|
||||
if s >= 0 and props_find(props, "tent") < 0 { instances_out(inst, cx, cz) }
|
||||
}
|
||||
function keep_n(n: int) -> int { return n }
|
||||
function twice(n: int) -> int { return n * 2 }
|
||||
function yn(b: bool) -> string {
|
||||
if b { return "yes" }
|
||||
return "no"
|
||||
}
|
||||
entry (props: mut Props, spots: mut Spots, inst: mut Instances) {
|
||||
# a whole-map table: constants by name, a nested list, a cross-row @Ref found by its key
|
||||
let a = props_load(props, "alpha")
|
||||
let s = spots_load(spots, "alpha")
|
||||
let t = props.rows[props_find(props, "tent")]
|
||||
let pick = t.pick
|
||||
let bench = props.rows[props_find(props, "bench")]
|
||||
let sign = props.rows[2]
|
||||
var out = `{yn(a)} {yn(s)} {len(props.rows)} {t.model} {int(t.yaw)} {len(t.pts)} {int(t.pts[1].z)} {t.tags[1]} {int(t.at.x)} {pick(21)} {spots_find(spots, t.home)}`
|
||||
out = out + ` {bench.model} {int(bench.scale * 2.0)} {yn(bench.lit)} {len(sign.role)}`
|
||||
# a reload with fewer rows: row 0's record is reused, reset and refilled - no stale row, no stale list
|
||||
let kept = props.rows[0]
|
||||
let b = props_load(props, "beta")
|
||||
let c = props.rows[0]
|
||||
var same = "new"
|
||||
if c == kept { same = "same" }
|
||||
let pick2 = c.pick
|
||||
out = out + ` / {yn(b)} {len(props.rows)} {props_find(props, "tent")} {props_find(props, "crate")} {c.key} {c.model} {len(c.pts)} {len(c.tags)} {len(c.role)} {pick2(21)} {same} {props_path(props, "density/a.png")}`
|
||||
# a chunked table: a negative and a positive chunk, and one with no file (an empty chunk)
|
||||
let s1 = instances_in(inst, "alpha", -1, 0)
|
||||
let s2 = instances_in(inst, "alpha", 0, 2)
|
||||
let s3 = instances_in(inst, "alpha", 5, 5)
|
||||
out = out + ` / {s1} {s2} {s3} {len(inst.chunks[s1].rows)} {inst.chunks[s1].rows[0].kind} {len(inst.chunks[s2].rows)} {len(inst.chunks[s3].rows)} {instances_find(inst, s1, "t2")} {instances_slot(inst, 0, 2)}`
|
||||
# out and in again: the free slot is taken back, nothing new is made
|
||||
instances_out(inst, -1, 0)
|
||||
let gone = instances_slot(inst, -1, 0)
|
||||
let s4 = instances_in(inst, "alpha", 0, 2)
|
||||
let s5 = instances_in(inst, "alpha", -1, 0)
|
||||
out = out + ` / {gone} {s4} {s5} {len(inst.chunks[s5].rows)} {len(inst.chunks)}`
|
||||
# a wrong file: false, an empty table, and the error at its line and column
|
||||
let bad = props_load(props, "bad/one")
|
||||
out = out + ` / {yn(bad)} {len(props.rows)} {props.err}`
|
||||
print(out)
|
||||
emit Stream(cx: 0, cz: 2)
|
||||
}
|
||||
}
|
||||
5
examples/rejected/permap_maps/maps/m1/props.lres
Normal file
5
examples/rejected/permap_maps/maps/m1/props.lres
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
tent { model: MDL_TENT, home: "fire" }
|
||||
lamp { model: 1, colour: 3 }
|
||||
crate { model: "big" }
|
||||
bench { model: MDL_BENCH }
|
||||
sign { model: 2, scale: 0.5, home: "nowhere" }
|
||||
1
examples/rejected/permap_maps/maps/m1/spots.lres
Normal file
1
examples/rejected/permap_maps/maps/m1/spots.lres
Normal file
|
|
@ -0,0 +1 @@
|
|||
fire { x: 1.0 }
|
||||
2
examples/rejected/permap_maps/package.ludic
Normal file
2
examples/rejected/permap_maps/package.ludic
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# permap_maps.ludic's maps, each file with one thing `ludicc --check` must refuse
|
||||
maps "maps"
|
||||
19
examples/rejected/permap_maps/permap_maps.ludic
Normal file
19
examples/rejected/permap_maps/permap_maps.ludic
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# permap_maps.ludic - `ludicc --check` reads every map directory and checks its tables against their
|
||||
# records. maps/m1 holds four mistakes, each refused at its file, line and column: a field the
|
||||
# record lacks, a value of the wrong type, a constant nobody declared, and a key naming no row.
|
||||
program PerMapMaps {
|
||||
numbers float
|
||||
const MDL_TENT: int = 7
|
||||
property Spot { key: string = "", x: float = 0.0 }
|
||||
@PerMap registry Spots of Spot from "spots.lres"
|
||||
property PropRow {
|
||||
key: string = ""
|
||||
model: int = 0
|
||||
scale: float = 1.0
|
||||
@Ref(Spots) home: string = ""
|
||||
}
|
||||
@PerMap @ByKey registry Props of PropRow from "props.lres"
|
||||
entry (props: mut Props) {
|
||||
print(`{props_load(props, "m1")}`)
|
||||
}
|
||||
}
|
||||
7
examples/rejected/permap_prefix.ludic
Normal file
7
examples/rejected/permap_prefix.ludic
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# permap_prefix.ludic - a @PerMap registry's keys are not known when the program compiles, so it has
|
||||
# no `as PREFIX` and no constants
|
||||
program PerMapPrefix {
|
||||
property Spot { key: string = "" }
|
||||
@PerMap registry Spots of Spot as SPOT from "spots.lres"
|
||||
entry { print(1) }
|
||||
}
|
||||
12
examples/rejected/permap_ref_int.ludic
Normal file
12
examples/rejected/permap_ref_int.ludic
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# permap_ref_int.ludic - an @Ref into a @PerMap registry names a row by its key: a map's rows have
|
||||
# no index a program could hold, so the field is a string
|
||||
program PerMapRefInt {
|
||||
property Spot { key: string = "" }
|
||||
@PerMap registry Spots of Spot from "spots.lres"
|
||||
property Npc {
|
||||
key: string = ""
|
||||
@Ref(Spots) home: int = 0
|
||||
}
|
||||
@PerMap registry Npcs of Npc from "npcs.lres"
|
||||
entry { print(1) }
|
||||
}
|
||||
6
examples/rejected/permap_unit.ludic
Normal file
6
examples/rejected/permap_unit.ludic
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# permap_unit.ludic - @Unit's spellings are ASCII, one per unit: "°" builds, with a warning naming
|
||||
# "deg" (it lives among the rejected examples for the warning it draws, not for an error)
|
||||
program PerMapUnit {
|
||||
property Sign { @Unit("°") yaw: float = 0.0, @Unit("m/s") speed: float = 0.0 }
|
||||
entry { print(1) }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue