writeonce/compiler/test/golden/bc/residual.expected
shoney.arickathil ebf82ca9c0 feat: json encode/decode + as, .wob v2 class metadata — log-watcher compiles
docs/examples/log-watcher (1285 lines, 7 files) now compiles clean: 0
diagnostics, a 35KB .wob written. corpus 71/0, woc runtest 565/0, every wovm
unit gate green (both dispatch flavors).

- .wob v2: each class row gains three u32 per-field arrays — the field's NAME
  constant, the CLASS it refers to (or the json-raw marker), and a container
  field's ELEMENT kinds. json is then a runtime service driven by metadata
  instead of per-type generated code. loader/emitter/disassembler/test
  assembler all read and write v2; field-name constants are interned with the
  rest of the pool (interning during serialization silently loses them)
- runtime/src/json.c (new): encode by static kind + object headers + class
  table (nested records need no static knowledge); decode parses and BINDS
  straight into the target class — keys matched to field names, nested objects
  built as the field's class, arrays as a multi of the field's element kind,
  unknown keys skipped, absent keys nil. Malformed input is nil, never a trap
- `as`: `json.decode(text) as T` is the one cast this language has (WO-E403
  for any other `as`, and for a bare json.decode with no target type). Its
  result is `?T`, which is why the decode and the target are one instruction
- json.Value: a reserved type name for a value the source does not inspect —
  the raw JSON slice, kind TEXT, re-emitted verbatim by encode
- docs: 00-wob-format.md is now the v2 reference (class metadata, TRY/ENDTRY,
  the whole builtin surface, WO_T_IO); 08-builtin-surface.md documents the
  text/container builtins, the OS modules with their predeclared records, and
  json's two documented limits (Bool encodes 0/1, floats truncate)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 17:08:46 +02:00

158 lines
3.9 KiB
Text

== CONSTANTS ==
k0 TEXT "Item"
k1 TEXT "Bag"
k2 TEXT "n"
k3 TEXT "items"
k4 TEXT "touch"
k5 TEXT "pair"
k6 TEXT "fixed"
k7 TEXT "touch3"
k8 TEXT "triple"
k9 TEXT "write_through"
k10 TEXT "main"
k11 INT 0
k12 INT 1
k13 INT 5
k14 INT 2
k15 INT 3
== CLASSES ==
c0 Item flags=- fields=[n:SCALAR]
c1 Bag flags=- fields=[items:MULTI]
== INTERFACES ==
== VTABLES ==
== METHODS ==
m0 touch args=2 regs=4 [free fn]
lines: 0->19
drops: (none)
0000 GETF r2, r0, f0
0001 GETF r3, r1, f0
0002 ADD r2, r2, r3
0003 RET r2
m1 pair args=3 regs=9 [free fn]
lines: 0->23
drops: (none)
0000 GETF r7, r0, f0
0001 MOVE r8, r1
0002 BUILTIN r5, r7, multi_get
0003 GETF r7, r0, f0
0004 MOVE r8, r2
0005 BUILTIN r6, r7, multi_get
0006 MOVE r3, r5
0007 MOVE r4, r6
0008 BORROW_X r3
0009 BORROW_X r4
0010 CALL r5, m0
0011 RELEASE_X r4
0012 RELEASE_X r3
0013 MOVE r3, r5
0014 RET r3
m2 fixed args=1 regs=5 [free fn]
lines: 0->27
drops: (none)
0000 GETF r3, r0, f0
0001 LOADK r4, k11
0002 BUILTIN r1, r3, multi_get
0003 GETF r3, r0, f0
0004 LOADK r4, k12
0005 BUILTIN r2, r3, multi_get
0006 CALL r1, m0
0007 RET r1
m3 touch3 args=3 regs=7 [free fn]
lines: 0->37
drops: (none)
0000 GETF r4, r0, f0
0001 GETF r5, r1, f0
0002 ADD r3, r4, r5
0003 GETF r6, r2, f0
0004 ADD r3, r3, r6
0005 RET r3
m4 triple args=4 regs=12 [free fn]
lines: 0->41
drops: (none)
0000 GETF r10, r0, f0
0001 MOVE r11, r1
0002 BUILTIN r7, r10, multi_get
0003 GETF r10, r0, f0
0004 MOVE r11, r2
0005 BUILTIN r8, r10, multi_get
0006 GETF r10, r0, f0
0007 MOVE r11, r3
0008 BUILTIN r9, r10, multi_get
0009 MOVE r4, r7
0010 MOVE r5, r8
0011 MOVE r6, r9
0012 BORROW_X r4
0013 BORROW_X r5
0014 BORROW_X r6
0015 CALL r7, m3
0016 RELEASE_X r6
0017 RELEASE_X r5
0018 RELEASE_X r4
0019 MOVE r4, r7
0020 RET r4
m5 write_through args=3 regs=7 [free fn]
lines: 0->49 3->50 6->51 12->52
drops: (none)
0000 GETF r4, r0, f0
0001 MOVE r5, r1
0002 BUILTIN r3, r4, multi_get
0003 GETF r5, r0, f0
0004 MOVE r6, r2
0005 BUILTIN r4, r5, multi_get
0006 LOADK r5, k13
0007 BORROW_X r4
0008 BORROW_S r3
0009 SETF r4, f0, r5
0010 RELEASE_S r3
0011 RELEASE_X r4
0012 GETF r5, r3, f0
0013 RET r5
m6 main args=0 regs=6 [free fn] [ENTRY]
lines: 0->56 3->57 8->58 13->59 18->60 24->61 28->62 35->63 41->55
drops: pc 3 owned={r0} gc={}
drops: pc 42 owned={} gc={}
0000 NEW r0, c1
0001 BUILTIN r1, kinds=0x01, multi_new
0002 SETF r0, f0, r1
0003 GETF r1, r0, f0
0004 NEW r2, c0
0005 LOADK r3, k12
0006 SETF r2, f0, r3
0007 BUILTIN r1, r1, multi_push
0008 GETF r1, r0, f0
0009 NEW r2, c0
0010 LOADK r3, k14
0011 SETF r2, f0, r3
0012 BUILTIN r1, r1, multi_push
0013 GETF r1, r0, f0
0014 NEW r2, c0
0015 LOADK r3, k15
0016 SETF r2, f0, r3
0017 BUILTIN r1, r1, multi_push
0018 MOVE r2, r0
0019 LOADK r3, k11
0020 LOADK r4, k12
0021 CALL r2, m1
0022 MOVE r1, r2
0023 BUILTIN r1, r1, print_int
0024 MOVE r2, r0
0025 CALL r2, m2
0026 MOVE r1, r2
0027 BUILTIN r1, r1, print_int
0028 MOVE r2, r0
0029 LOADK r3, k11
0030 LOADK r4, k12
0031 LOADK r5, k14
0032 CALL r2, m4
0033 MOVE r1, r2
0034 BUILTIN r1, r1, print_int
0035 MOVE r2, r0
0036 LOADK r3, k11
0037 LOADK r4, k12
0038 CALL r2, m5
0039 MOVE r1, r2
0040 BUILTIN r1, r1, print_int
0041 DROP r0
0042 RET0
== ENTRY ==
m6