Quellcode durchsuchen

Lay out class instances with descriptor-prefixed field offsets (E03-S05).

Compute sizes and offsets after the declaration pass so forward references
have a kind, report E096 for instances over 65535 bytes, and record the
layout in the parser harness so declaration order is fixture-checked.

Generated with Codebuff 🤖
Co-Authored-By: Codebuff <noreply@codebuff.com>
main
Daniel Covington vor 5 Tagen
Ursprung
Commit
42a26c9cc2
14 geänderte Dateien mit 526 neuen und 11 gelöschten Zeilen
  1. +7
    -0
      newLang/docs/architecture.md
  2. +1
    -0
      newLang/docs/diagnostics.md
  3. +1
    -1
      newLang/docs/memory-map.md
  4. +107
    -0
      newLang/planning/claims/E03-S05.md
  5. +2
    -0
      newLang/scripts/build-parser-test.ps1
  6. +26
    -5
      newLang/scripts/verify-parser-test.ps1
  7. +1
    -0
      newLang/src/common/diagcat.inc
  8. +5
    -1
      newLang/src/common/parser.inc
  9. +224
    -3
      newLang/src/compiler/parser.s
  10. +98
    -1
      newLang/tests/parser/parser-test.s
  11. +17
    -0
      newLang/tests/semantic/layout.expect
  12. +27
    -0
      newLang/tests/semantic/layout.n8
  13. +4
    -0
      newLang/tests/semantic/too_big.expect
  14. +6
    -0
      newLang/tests/semantic/too_big.n8

+ 7
- 0
newLang/docs/architecture.md Datei anzeigen

@@ -204,6 +204,13 @@ result must end in `return` (an `if` only when both branches do), reported at
`end` as E150. Numeric literals are typed by context and folded (E084/E086);
arrays are never whole values (E088).

E03-S05 computes each class's instance size and field offsets after the
declaration pass, once every forward type reference has a kind. Fields keep
declaration order after the two-byte descriptor pointer with no padding; ABI
sizes are 1 for boolean/byte/char, 2 for integer/word/class reference, 4 for
an interface reference, and element size times length for an array. A class
whose instance would exceed 65535 bytes reports E096 at its declaration line.

### Pass 1 — declarations and layout

- tokenize the complete source;


+ 1
- 0
newLang/docs/diagnostics.md Datei anzeigen

@@ -85,6 +85,7 @@ After 20 errors the next one is replaced by E221 and compilation stops.
| E093 | `TYP_NOT_CLASS` | % IS NOT A CLASS |
| E094 | `TYP_ARRAY_SIGNATURE` | ARRAYS CANNOT BE PARAMETERS OR RESULTS |
| E095 | `TYP_ARRAY_LENGTH` | ARRAY LENGTH MUST NOT BE ZERO |
| E096 | `TYP_INSTANCE_TOO_LARGE` | CLASS INSTANCE TOO LARGE |

## Access (E120-E129)



+ 1
- 1
newLang/docs/memory-map.md Datei anzeigen

@@ -51,7 +51,7 @@ COMMON, DISKBUF, private ZP, SCRATCH, and MAILBOX are visible from bank 1.
| Owner | Bytes | Contents |
|---|---|---|
| `names.s` | 5,164 | 64 hash-chain heads + 255 name records of 20 bytes (D120) |
| `parser.s` | 4,608 | 18 columns of 256 bytes (`src/common/parser.inc`): type table by name ID (kind, declaration line, member range; E03-S01/E03-S02), 255 member rows (owner, name, flags, type, parameter range) and 255 parameter-type rows (E03-S02) |
| `parser.s` | 6,656 | 26 columns of 256 bytes (`src/common/parser.inc`): type table by name ID (kind, declaration line, member and implements ranges, instance size; E03-S01, E03-S05), 255 member rows (owner, name, flags, type, parameter range, field offset) and 255 parameter-type rows (E03-S02, E03-S05) |

BSS is not zeroed at load: every table must be cleared by its owner before
use (`names_init`, `parser.s` `tt_clear`). The member and parameter rows are


+ 107
- 0
newLang/planning/claims/E03-S05.md Datei anzeigen

@@ -0,0 +1,107 @@
---
story: E03-S05
owner: e03_layout
status: done
started: 2026-11-09
depends-on: [E03-S02, E03-S04]
---

# E03-S05 Claim

## Intended change

Compute every class's instance size and every field's byte offset after pass 1,
when forward type references have a kind at last, and report E096 when an
instance would exceed 65535 bytes. Instances begin with the two-byte class
descriptor pointer and keep fields in declaration order with no padding.
Add the size and offset columns to the bank-1 type and member tables, and make
the parser harness emit a deterministic layout record so a fixture can list
each class's size and its fields' offsets in declaration order.

## File area

- `src/common/parser.inc`, `src/compiler/parser.s`
- `src/common/diagcat.inc`, `docs/diagnostics.md` (E096)
- `tests/parser/parser-test.s`, `scripts/build-parser-test.ps1`,
`scripts/verify-parser-test.ps1`
- `tests/semantic/layout.n8`, `layout.expect`, `too_big.n8`, `too_big.expect`
- `docs/architecture.md`, `docs/memory-map.md`
- `planning/claims/E03-S05.md`
- generated files under `build/`

## Acceptance evidence

- [x] Field offsets begin after the class-descriptor pointer and are
deterministic: `layout.n8` declares one field of every ABI size and two
arrays; `layout.expect` records `box size 35` with offsets 2, 3, 4, 5, 7, 9,
15, 17, 21, 23, and 31 in declaration order, and `empty size 2`. The
verifier compares the whole `$FA` layout list; all 39 parser fixtures pass.
- [x] Instance size overflow/capacity is diagnosed: `too_big.n8`
(`word[40000]` = 80,000 bytes) is rejected with E096 at 1:1, matching
`too_big.expect`; the size columns saturate at `$FFFF` rather than wrapping.
- [x] Field default privacy and method default publicity match the
specification: `layout.n8` uses bare fields and one bare `public method`;
the independent source oracle in `verify-parser-test.ps1` derives every
member's access (fields private, methods public) and compares it against the
parser's 13 member rows for the fixture. The same check covers all accepted
fixtures.
- [x] MAP fixture lists sizes and offsets in declaration order:
`layout.n8`/`layout.expect` is that listing. The harness's `$FA` record is
the deterministic layout listing the future `NAME.MAP` writer will consume;
the MAP writer itself belongs to E05-S02 (`output.s`), so no `NAME.MAP` file
exists to compare yet. This is recorded under remaining risks.

## Coordination notes

- No other claim is active. No new decision: the sizes are the approved
architecture ABI (1 for boolean/byte/char, 2 for integer/word/class
reference, 4 for interface reference, element size times length for arrays)
and object layout is the approved two-byte descriptor followed by fields.
D124-D127 from E03-S04 remain proposed.
- The layout pass runs between pass 1 and pass 2, so it only uses recorded
table rows and never depends on source order or pass-2 typing.

## Work log

- `parser.inc`: added `C_TYPE_SIZE_LO/HI` (22/23) and
`C_MEM_OFFSET_LO/HI` (24/25); `TABLE_COLUMNS` is now 26. `docs/memory-map.md`
records the parser tables as 6,656 bytes.
- `parser.s`: `parse_file` calls `layout_classes` after pass 1. Helpers
`field_size_mem`, `field_size`, and `elem_size` compute a member's size from
its recorded type, and `store_field_offset` writes the current offset into
the member row. A class starts at 2; methods are skipped; overflow sets the
size to `$FFFF`, records the failure, and reports E096 once at the class's
declaration line and column 1. The pass loops over name IDs and member rows,
so classes and fields are laid out in declaration order.
- `parser-test.s`: `dump_layout` emits `$FA`, then per class its name, size
lo/hi, field count, and each field's name and offset lo/hi. `count_fields`
counts non-method member rows owned by the class. `FIXTURE_COUNT` is 39.
- `verify-parser-test.ps1`: decodes `$FA` until `$FD`/`$FB` and compares the
layout lines against `layout.expect`; the member loop now also stops at
`$FA`, because `dump_layout` always emits its marker before `$FD`.
- `diagcat.inc`: appended `TYP_INSTANCE_TOO_LARGE, 96`; the catalog now has 68
entries and `docs/diagnostics.md` was regenerated.
- First build exposed four 6502 branch-range errors in `layout_classes` and
three in `dump_layout`; they are now short branches to nearby `jmp`
trampolines. The verifier edit had also joined `$p += 5` and `while` on one
line; fixed.

## Completion

- Tests run: `scripts/build-parser-test.ps1`,
`scripts/verify-parser-test.ps1 -Port 6530`,
`scripts/build-lexer-test.ps1`, `scripts/verify-lexer-test.ps1`,
`scripts/build-diag-test.ps1 -UpdateDocs`,
`scripts/verify-diag-test.ps1`, `scripts/demo-write-check.ps1`.
- Results: all 39 parser fixtures pass (lowest expression SP `$A7`);
`layout.n8` matches 13 layout lines and `too_big.n8` reports E096 at 1:1.
The lexer matches 10 fixtures / 6,733 dump bytes; the 68-entry diagnostic
catalog and its screen/ERR expectations match with docs in sync; the demo
saves `good.n8` and `bad.n8` byte-for-byte, `good.n8` reports no errors, and
`bad.n8` reports E151, E152, E120, and E061. `vim/work.d81` was not touched.
- Files changed: as listed under File area.
- Remaining risks: the `NAME.MAP` text writer is E05-S02, so the declaration
order and layout listing are verified through the harness record rather than
a real `.map` file. E096 reports the instance's saturated `$FFFF` size in the
table; consumers must treat that as "too large". Any future padding or
alignment rule would change `layout.expect` and the offsets.

+ 2
- 0
newLang/scripts/build-parser-test.ps1 Datei anzeigen

@@ -51,6 +51,8 @@ $script:ParserFixtures = [ordered]@{
"ops.n8" = @("$t\ops.n8", "exact", "$t\ops.expect")
"uses.n8" = @("$t\uses.n8", "exact", "$t\uses.expect")
"calls.n8" = @("$t\calls.n8", "exact", "$t\calls.expect")
"layout.n8" = @("$t\layout.n8", "layout", "$t\layout.expect")
"toobig.n8" = @("$t\too_big.n8", "rejected", "$t\too_big.expect")
}

$link = Invoke-Nova128Link -Name "parser-test" -BuildDir $out `


+ 26
- 5
newLang/scripts/verify-parser-test.ps1 Datei anzeigen

@@ -53,9 +53,9 @@ $records = @(); $script:p = 0
while ($dump[$p] -ne 0xFE) {
if ($dump[$p] -ne 0xFF) { throw "dump out of sync at $p" }
$r = [pscustomobject]@{ Index = $dump[$p + 1]; Load = $dump[$p + 2]; Count = $dump[$p + 3]
MinSp = $dump[$p + 4]; Types = @(); Members = @(); Trace = $null }
MinSp = $dump[$p + 4]; Types = @(); Members = @(); Layout = @(); Trace = $null }
$p += 5
while ($dump[$p] -ne 0xFD -and $dump[$p] -ne 0xFC) {
while ($dump[$p] -ne 0xFD -and $dump[$p] -ne 0xFC -and $dump[$p] -ne 0xFB -and $dump[$p] -ne 0xFA) {
$len = $dump[$p + 3]
$spell = ConvertFrom-Spelling $dump[($p + 4)..($p + 3 + $len)]
$r.Types += ("{0} {1} {2}" -f @("", "interface", "class", "program")[$dump[$p]], $spell, ($dump[$p + 1] + 256 * $dump[$p + 2]))
@@ -63,7 +63,7 @@ while ($dump[$p] -ne 0xFE) {
}
if ($dump[$p] -eq 0xFC) {
$p++
while ($dump[$p] -ne 0xFD -and $dump[$p] -ne 0xFB) {
while ($dump[$p] -ne 0xFD -and $dump[$p] -ne 0xFB -and $dump[$p] -ne 0xFA) {
$owner = Read-DumpName
$name = Read-DumpName
$flags = $dump[$p]; $p++
@@ -74,6 +74,20 @@ while ($dump[$p] -ne 0xFE) {
$(if ($flags -band 1) { "method" } else { "field" }),
$(if ($flags -band 2) { "private" } else { "public" }), $type, ($params -join ","))
}
if ($dump[$p] -eq 0xFA) {
$p++
while ($dump[$p] -ne 0xFD -and $dump[$p] -ne 0xFB) {
$owner = Read-DumpName
$size = $dump[$p] + 256 * $dump[$p + 1]; $p += 2
$count = $dump[$p]; $p++
$r.Layout += ("{0} size {1}" -f $owner, $size)
for ($k = 0; $k -lt $count; $k++) {
$fname = Read-DumpName
$off = $dump[$p] + 256 * $dump[$p + 1]; $p += 2
$r.Layout += ("{0}.{1} offset {2}" -f $owner, $fname, $off)
}
}
}
if ($dump[$p] -eq 0xFB) {
$n = $dump[$p + 1] + 256 * $dump[$p + 2]
$r.Trace = if ($n) { [byte[]]$dump[($p + 3)..($p + 2 + $n)] } else { [byte[]]@() }
@@ -181,7 +195,7 @@ foreach ($name in $ParserFixtures.Keys) {
$problems = @()
if ($r.Load -ne 0) { $problems += "src_load returned $($r.Load)" }
switch ($group) {
"accepted" {
{ $_ -eq "accepted" -or $_ -eq "layout" } {
if ($r.Count -ne 0) { $problems += "$($r.Count) diagnostic(s): $($errLines -join ' | ')" }
if ($null -ne $errLines) { $problems += "an ERR file exists" }
$want = @()
@@ -231,7 +245,7 @@ foreach ($name in $ParserFixtures.Keys) {
$detail = "{0} diagnostics" -f $got.Count
}
}
if ($group -eq "accepted" -or $memberChecked -contains $name) {
if ($group -in @("accepted", "layout") -or $memberChecked -contains $name) {
$wantMembers = Get-SourceMembers $src
if (($r.Members -join ';') -ne ($wantMembers -join ';')) {
$problems += "members [$($r.Members -join '; ')] expected [$($wantMembers -join '; ')]"
@@ -249,6 +263,13 @@ foreach ($name in $ParserFixtures.Keys) {
$detail += ", {0} traced statements" -f $got.Count
}
}
if ($group -eq "layout") {
$want = @(Get-Content -LiteralPath $expect | Where-Object { $_ -and -not $_.StartsWith("//") })
if (($r.Layout -join ';') -ne ($want -join ';')) {
$problems += "layout [$($r.Layout -join '; ')] expected [$($want -join '; ')]"
}
$detail += ", {0} layout lines" -f $r.Layout.Count
}
if ($r.MinSp -ne 0xFF -and $r.MinSp -lt $minSp) { $minSp = $r.MinSp }
$status = if ($problems) { "FAIL" } else { "ok" }
Write-Host (" {0,-13} {1,-9} {2} {3}" -f $name, $group, $status, $detail)


+ 1
- 0
newLang/src/common/diagcat.inc Datei anzeigen

@@ -74,6 +74,7 @@
DIAGNOSTIC TYP_NOT_CLASS, 93, "% IS NOT A CLASS"
DIAGNOSTIC TYP_ARRAY_SIGNATURE, 94, "ARRAYS CANNOT BE PARAMETERS OR RESULTS"
DIAGNOSTIC TYP_ARRAY_LENGTH, 95, "ARRAY LENGTH MUST NOT BE ZERO"
DIAGNOSTIC TYP_INSTANCE_TOO_LARGE, 96, "CLASS INSTANCE TOO LARGE"

; ----------------------------------------------------------------- access
DIAGNOSTIC ACC_PRIVATE_MEMBER, 120, "% IS PRIVATE"


+ 5
- 1
newLang/src/common/parser.inc Datei anzeigen

@@ -75,7 +75,11 @@ C_PAR_TNAME = 18
C_PAR_TLEN_LO = 19
C_PAR_TLEN_HI = 20
C_IMPL_IFACE = 21 ; implemented interface name ID
TABLE_COLUMNS = 22
C_TYPE_SIZE_LO = 22 ; class instance size (descriptor + fields)
C_TYPE_SIZE_HI = 23
C_MEM_OFFSET_LO = 24 ; field byte offset
C_MEM_OFFSET_HI = 25
TABLE_COLUMNS = 26
C_TYPE_LAST = C_TYPE_INIT ; type columns 0..this are cleared per run

.endif

+ 224
- 3
newLang/src/compiler/parser.s Datei anzeigen

@@ -1,5 +1,5 @@
; parser.s - declarations, members, scopes, statements, expressions, and
; type checking (E03-S01..E03-S04).
; type checking (E03-S01..E03-S05).
;
; parse_file runs two passes over the loaded source (call after src_load,
; diag_init, and names_init):
@@ -8,8 +8,8 @@
; the bank-1 type table and each field and method signature in the
; member and parameter tables; parses every statement; reports
; syntax, ordering, duplicate, init/destroy shape, and
; local-placement errors; records each class's implements list
; and init row.
; local-placement errors; records each class's implements list,
; init row, instance size, and field offsets (E03-S05).
; pass 2 replays the source, parsing everything again, and reports type
; references that do not name a declared interface or class
; (forward references are therefore legal), name, member, and
@@ -45,6 +45,7 @@
.import tok_kind, tok_line, tok_col, tok_len, tok_value, tok_text, tok_text_len, tok_err
.import src_line
.import name_intern, name_find, name_declare
.import names_count
.import diag_report, diag_line, diag_col, diag_arg1, diag_arg1_len
.import mmu_peek1, mmu_poke1
.importzp mmu_ptr
@@ -97,6 +98,7 @@ parse_file:
lda #$01
sta pass
jsr parse_pass
jsr layout_classes
lda #$02
sta pass
jsr parse_pass
@@ -544,6 +546,219 @@ no_array_sig:
jmp err1_col
@ok: rts

; ------------------------------------------------------------- layout
; Pass 1, after all declarations: instance sizes and field offsets. A class
; starts with its two-byte descriptor pointer; fields follow in declaration
; order with no padding. ABI sizes: boolean/byte/char 1, integer/word/class
; reference 2, interface reference 4, array = element size * length. E096 is
; reported at the class line when the total exceeds 65535.
layout_classes:
lda #$01
sta lk_id
@class: lda lk_id
cmp names_count
bcc :+
jmp @done
: ldy lk_id
lda #C_TYPE_KIND
jsr tb_get
cmp #TYPE_CLASS
beq :+
jmp @next
: lda #$02
sta cls_size
lda #$00
sta cls_size+1
sta cls_bad
sta lk_row
@row: lda lk_row
cmp mem_count
bcs @class_done
ldy lk_row
lda #C_MEM_OWNER
jsr tb_get
cmp lk_id
bne @rnext
ldy lk_row
lda #C_MEM_FLAGS
jsr tb_get
and #MF_METHOD
bne @rnext
lda cls_bad
bne @saturated
jsr field_size_mem
bcs @overflow
jsr store_field_offset
clc
lda cls_size
adc fsize
sta cls_size
lda cls_size+1
adc fsize+1
sta cls_size+1
bcc @rnext
@overflow:
jsr store_field_offset
lda #$01
sta cls_bad
lda #$FF
sta cls_size
sta cls_size+1
jmp @rnext
@saturated:
jsr store_field_offset
@rnext: inc lk_row
jmp @row
@class_done:
ldy lk_id
ldx cls_size
lda #C_TYPE_SIZE_LO
jsr tb_set
ldx cls_size+1
lda #C_TYPE_SIZE_HI
jsr tb_set
lda cls_bad
bne :+
jmp @next
: ldy lk_id
lda #C_TYPE_LINE_LO
jsr tb_get
sta diag_line
ldy lk_id
lda #C_TYPE_LINE_HI
jsr tb_get
sta diag_line+1
lda #$01
sta diag_col
lda #E_TYP_INSTANCE_TOO_LARGE
jsr diag_report
bcs :+
jmp @next
: jmp stop_parse
@next: inc lk_id
beq @done
jmp @class
@done: rts

; fsize = the type of member row lk_row; C=1 when it exceeds 65535.
field_size_mem:
ldy lk_row
lda #C_MEM_TBASE
jsr tb_get
sta ty_base
ldy lk_row
lda #C_MEM_TNAME
jsr tb_get
sta ty_name
ldy lk_row
lda #C_MEM_TLEN_LO
jsr tb_get
sta ty_len
ldy lk_row
lda #C_MEM_TLEN_HI
jsr tb_get
sta ty_len+1
jsr field_size
rts

; member row lk_row's offset = cls_size.
store_field_offset:
ldy lk_row
lda #C_MEM_OFFSET_LO
ldx cls_size
jsr tb_set
lda #C_MEM_OFFSET_HI
ldx cls_size+1
jsr tb_set
rts

; fsize = size of the type in ty_*; C=1 when the array is too large.
field_size:
lda ty_len
ora ty_len+1
beq @scalar
jsr elem_size
beq @zero
cmp #$01
beq @one
cmp #$02
beq @two
lda ty_len
sta fsize
lda ty_len+1
sta fsize+1
asl fsize
rol fsize+1
bcs @over
asl fsize
rol fsize+1
bcs @over
clc
rts
@one: lda ty_len
sta fsize
lda ty_len+1
sta fsize+1
clc
rts
@two: lda ty_len
sta fsize
lda ty_len+1
sta fsize+1
asl fsize
rol fsize+1
bcs @over
clc
rts
@zero: lda #$00
sta fsize
sta fsize+1
clc
rts
@scalar:
jsr elem_size
sta fsize
lda #$00
sta fsize+1
clc
rts
@over: lda #$FF
sta fsize
sta fsize+1
sec
rts

; A = bytes in one element of ty_*: 1, 2, 4, or 0 for an unknown type.
elem_size:
lda ty_base
cmp #TY_BOOLEAN
beq @one
cmp #TY_BYTE
beq @one
cmp #TY_CHAR
beq @one
cmp #TY_INTEGER
beq @two
cmp #TY_WORD
beq @two
cmp #TY_REF
bne @none
ldy ty_name
lda #C_TYPE_KIND
jsr tb_get
cmp #TYPE_INTERFACE
beq @four
lda #$02
rts
@one: lda #$01
rts
@two: lda #$02
rts
@four: lda #$04
rts
@none: lda #$00
rts

; Pass 1: a class's init records its member row (+1) for `new` checks.
note_init:
lda pass
@@ -2508,3 +2723,9 @@ ret_kind: .res 1 ; RET_*
ret_row: .res 1 ; member row of the method (RET_VALUE)
body_nm: .res 1 ; method or program name ID (E151)
end_col: .res 1 ; column of `end` (E150)
; class layout (E03-S05)
cls_size: .res 2 ; instance size being accumulated
cls_bad: .res 1 ; E096 reported for this class
fsize: .res 2 ; one field's size
lk_id: .res 1 ; layout: class name ID
lk_row: .res 1 ; layout: member row

+ 98
- 1
newLang/tests/parser/parser-test.s Datei anzeigen

@@ -141,6 +141,7 @@ test_entry:
lda #$FC
jsr emit
jsr dump_members
jsr dump_layout
lda fx_index
cmp #TRACE_INDEX
bne @advance
@@ -288,6 +289,97 @@ dump_members:
jmp @next
@done: rts

; Emit $FA, then each class: name, instance size lo/hi, field count, and
; every field's name and offset lo/hi in declaration order.
dump_layout:
lda #$FA
jsr emit
lda #$01
sta id
@next: lda id
cmp names_count
bcc :+
jmp @done
: ldy id
lda #C_TYPE_KIND
jsr tb_get
cmp #TYPE_CLASS
bne @not_class
lda id
jsr emit_name
ldy id
lda #C_TYPE_SIZE_LO
jsr tb_get
jsr emit
ldy id
lda #C_TYPE_SIZE_HI
jsr tb_get
jsr emit
lda id
jsr count_fields
jsr emit
lda #$00
sta lk_row
@field_loop:
lda lk_row
cmp mem_count
bcs @fields_done
ldy lk_row
lda #C_MEM_OWNER
jsr tb_get
cmp id
bne @fnext
ldy lk_row
lda #C_MEM_FLAGS
jsr tb_get
and #MF_METHOD
bne @fnext
ldy lk_row
lda #C_MEM_NAME
jsr tb_get
jsr emit_name
ldy lk_row
lda #C_MEM_OFFSET_LO
jsr tb_get
jsr emit
ldy lk_row
lda #C_MEM_OFFSET_HI
jsr tb_get
jsr emit
@fnext: inc lk_row
jmp @field_loop
@fields_done:
@not_class:
inc id
beq @done
jmp @next
@done: rts

; A = class name ID; A = number of field rows it owns.
count_fields:
sta lk_owner
lda #$00
sta lk_n
sta lk_row
@loop: lda lk_row
cmp mem_count
bcs @done
ldy lk_row
lda #C_MEM_OWNER
jsr tb_get
cmp lk_owner
bne @next
ldy lk_row
lda #C_MEM_FLAGS
jsr tb_get
and #MF_METHOD
bne @next
inc lk_n
@next: inc lk_row
jmp @loop
@done: lda lk_n
rts

; Emit $FB, the trace length, and the trace bytes.
dump_trace:
lda #$FB
@@ -425,7 +517,9 @@ fixtures:
FIXTURE "OPS.N8"
FIXTURE "USES.N8"
FIXTURE "CALLS.N8"
FIXTURE_COUNT = 37
FIXTURE "LAYOUT.N8"
FIXTURE "TOOBIG.N8"
FIXTURE_COUNT = 39
TRACE_INDEX = 28 ; PREC.N8

messages:
@@ -448,6 +542,9 @@ prow: .res 1
pleft: .res 1
col: .res 1
trow: .res 1
lk_owner: .res 1
lk_row: .res 1
lk_n: .res 1
trace_len: .res 2
trace_buf: .res 1024
dump: .res DUMP_SIZE

+ 17
- 0
newLang/tests/semantic/layout.expect Datei anzeigen

@@ -0,0 +1,17 @@
// E03-S05: instance size and field offsets. A class starts with its
// two-byte descriptor pointer; fields follow in declaration order with no
// padding. boolean/byte/char are 1 byte, integer/word/class reference 2,
// interface reference 4, and an array is element size times length.
box size 35
box.b offset 2
box.ok offset 3
box.c offset 4
box.w offset 5
box.i offset 7
box.nums offset 9
box.flags offset 15
box.s offset 17
box.next offset 21
box.many offset 23
box.kids offset 31
empty size 2

+ 27
- 0
newLang/tests/semantic/layout.n8 Datei anzeigen

@@ -0,0 +1,27 @@
interface Shape
method area() as word
end interface

class Box implements Shape
byte b
boolean ok
char c
word w
integer i
word[3] nums
byte[2] flags
Shape s
Box next
Shape[2] many
Box[2] kids

public method area() as word
return 0
end method
end class

class Empty
end class

program Main
end program

+ 4
- 0
newLang/tests/semantic/too_big.expect Datei anzeigen

@@ -0,0 +1,4 @@
diagnostic: TYP_INSTANCE_TOO_LARGE
line: 1
column: 1
reason: the field array makes the class instance exceed 65535 bytes

+ 6
- 0
newLang/tests/semantic/too_big.n8 Datei anzeigen

@@ -0,0 +1,6 @@
class Huge
word[40000] data
end class

program Main
end program

Laden…
Abbrechen
Speichern

Powered by TurnKey Linux.