Phase 8a: finish typed indexing — fixeds/ptrs buffers (retire peekf/pokef/peekp/pokep/str_len)
The last peek/poke pairs were the same "typed buffer access wearing a C name" as peek8/peek32, so they become indexing too: peekf(sc_x, i) -> sc_x[i] (a `fixeds` buffer -> a fixed) pokep(gc_bmp, s,b) -> gc_bmp[s] = b (a `ptrs` buffer -> a pointer) str_len(s) -> len(s) (len is polymorphic since 7f; str_len was dead) Two new element-typed buffers join words: `fixeds` (32-bit fixed) and `ptrs` (pointer, 8-byte stride). emit_index_addr dispatches on the base type; IR is byte-identical to the old intrinsics. The peekf/peekp buffers (ed_x0/ed_x1/ol_x/sc_x fixed coords; gc_bmp/img_px/ tt_data/ui_text pointer arrays) were retyped scope-aware, then the 33 sites migrated to indexing. Two bugs found via a menu golden diff / a link-time type error and fixed: the buffer-name regex truncated digit suffixes (ed_x0 -> ed_x), and the char-literal brace-miscount skipped a few module declarations (same class as 7j). Reseeded (22371 lines); C-free fixpoint holds; goldens byte-identical; 18/18; vocab (fixeds/ptrs types in, 5 intrinsics out) + doc-fences clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ae65acde33
commit
5a9e8cb2da
13 changed files with 2992 additions and 3206 deletions
|
|
@ -52,7 +52,7 @@ object LudicVocabulary {
|
|||
"enable", "disable", "match", "machine", "state", "become", "where",
|
||||
"and", "or", "not", "break", "continue", "new"
|
||||
)
|
||||
val PRIMITIVES = setOf("int", "fixed", "bool", "entity", "str", "ptr", "byte", "words", "void")
|
||||
val PRIMITIVES = setOf("int", "fixed", "bool", "entity", "str", "ptr", "byte", "words", "fixeds", "ptrs", "void")
|
||||
val PHASES = setOf("Start", "Input", "FixedUpdate", "Update", "LateUpdate", "Render")
|
||||
val WIDGETS = setOf("panel", "col", "row", "label", "button", "image", "spacer")
|
||||
|
||||
|
|
@ -67,10 +67,10 @@ object LudicVocabulary {
|
|||
"status", "print", "str", "quit",
|
||||
// compiler intrinsics: the floor the Ludic-written runtime stands on
|
||||
"bytes", "words", "mem_realloc", "mem_free", "mem_copy", "mem_set", "os_argc", "os_arg", "file_stderr", "file_stdout",
|
||||
"peekp", "pokep", "peekf", "pokef", "ptr_add",
|
||||
"ptr_add",
|
||||
"as_fixed", "as_int", "file_open", "file_read", "file_write",
|
||||
"file_seek", "file_tell", "file_close", "read_byte", "write_byte",
|
||||
"str_len", "os_exit", "os_time",
|
||||
"os_exit", "os_time",
|
||||
"is_windowed", "game_title", "win_open", "win_poll", "win_present",
|
||||
"win_running", "win_close"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@
|
|||
{ "name": "keyword.other.clause.ludic", "match": "\\b(phase|query|on)\\b" },
|
||||
{ "name": "keyword.other.ludic", "match": "\\b(import|extern)\\b" },
|
||||
{ "name": "storage.type.ludic", "match": "\\b(program|property|model|enum|ui|const|var|let|fn|handler|entry|state)\\b" },
|
||||
{ "name": "support.type.primitive.ludic", "match": "\\b(int|fixed|bool|entity|str|ptr|byte|words|void)\\b" },
|
||||
{ "name": "support.type.primitive.ludic", "match": "\\b(int|fixed|bool|entity|str|ptr|byte|words|fixeds|ptrs|void)\\b" },
|
||||
{ "name": "constant.language.boolean.ludic", "match": "\\b(true|false|null)\\b" },
|
||||
{ "name": "constant.language.phase.ludic", "match": "\\b(Start|Input|FixedUpdate|Update|LateUpdate|Render)\\b" }
|
||||
]
|
||||
|
|
@ -209,7 +209,7 @@
|
|||
{
|
||||
"comment": "compiler intrinsics — these lower straight to libc or the OS",
|
||||
"name": "support.function.intrinsic.ludic",
|
||||
"match": "\\b(bytes|words|mem_realloc|mem_free|mem_copy|mem_set|peekp|pokep|peekf|pokef|ptr_add|as_fixed|as_int|file_open|file_read|file_write|file_seek|file_tell|file_close|read_byte|write_byte|str_len|os_exit|os_time|os_argc|os_arg|file_stderr|file_stdout|is_windowed|game_title|win_open|win_poll|win_present|win_running|win_close)\\b(?=\\s*\\()"
|
||||
"match": "\\b(bytes|words|mem_realloc|mem_free|mem_copy|mem_set|ptr_add|as_fixed|as_int|file_open|file_read|file_write|file_seek|file_tell|file_close|read_byte|write_byte|os_exit|os_time|os_argc|os_arg|file_stderr|file_stdout|is_windowed|game_title|win_open|win_poll|win_present|win_running|win_close)\\b(?=\\s*\\()"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@
|
|||
{ "name": "keyword.other.clause.ludic", "match": "\\b(phase|query|on)\\b" },
|
||||
{ "name": "keyword.other.ludic", "match": "\\b(import|extern)\\b" },
|
||||
{ "name": "storage.type.ludic", "match": "\\b(program|property|model|enum|ui|const|var|let|fn|handler|entry|state)\\b" },
|
||||
{ "name": "support.type.primitive.ludic", "match": "\\b(int|fixed|bool|entity|str|ptr|byte|words|void)\\b" },
|
||||
{ "name": "support.type.primitive.ludic", "match": "\\b(int|fixed|bool|entity|str|ptr|byte|words|fixeds|ptrs|void)\\b" },
|
||||
{ "name": "constant.language.boolean.ludic", "match": "\\b(true|false|null)\\b" },
|
||||
{ "name": "constant.language.phase.ludic", "match": "\\b(Start|Input|FixedUpdate|Update|LateUpdate|Render)\\b" }
|
||||
]
|
||||
|
|
@ -209,7 +209,7 @@
|
|||
{
|
||||
"comment": "compiler intrinsics — these lower straight to libc or the OS",
|
||||
"name": "support.function.intrinsic.ludic",
|
||||
"match": "\\b(bytes|words|mem_realloc|mem_free|mem_copy|mem_set|peekp|pokep|peekf|pokef|ptr_add|as_fixed|as_int|file_open|file_read|file_write|file_seek|file_tell|file_close|read_byte|write_byte|str_len|os_exit|os_time|os_argc|os_arg|file_stderr|file_stdout|is_windowed|game_title|win_open|win_poll|win_present|win_running|win_close)\\b(?=\\s*\\()"
|
||||
"match": "\\b(bytes|words|mem_realloc|mem_free|mem_copy|mem_set|ptr_add|as_fixed|as_int|file_open|file_read|file_write|file_seek|file_tell|file_close|read_byte|write_byte|os_exit|os_time|os_argc|os_arg|file_stderr|file_stdout|is_windowed|game_title|win_open|win_poll|win_present|win_running|win_close)\\b(?=\\s*\\()"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ static const char* LUDIC_KW_STMT[] = {
|
|||
"and","or","not","break","continue","new", 0
|
||||
};
|
||||
static const char* LUDIC_TYPES[] = {
|
||||
"int","fixed","bool","entity","str","ptr","byte","words","void", 0
|
||||
"int","fixed","bool","entity","str","ptr","byte","words","fixeds","ptrs","void", 0
|
||||
};
|
||||
static const char* LUDIC_PHASES[] = {
|
||||
"Start","Input","FixedUpdate","Update","LateUpdate","Render", 0
|
||||
|
|
@ -155,10 +155,6 @@ static const LBuiltin LUDIC_INTRINSICS[] = {
|
|||
{"mem_free","mem_free(p: ptr)","Release an allocation."},
|
||||
{"mem_copy","mem_copy(dst: ptr, src: ptr, n: int)","memcpy."},
|
||||
{"mem_set","mem_set(p: ptr, byte: int, n: int)","memset."},
|
||||
{"peekp","peekp(p: ptr, off: int) -> ptr","Read a pointer-sized word."},
|
||||
{"pokep","pokep(p: ptr, off: int, v: ptr)","Write a pointer-sized word."},
|
||||
{"peekf","peekf(p: ptr, off: int) -> fixed","Read a fixed-point word."},
|
||||
{"pokef","pokef(p: ptr, off: int, v: fixed)","Write a fixed-point word."},
|
||||
{"ptr_add","ptr_add(p: ptr, off: int) -> ptr","Offset a pointer by bytes."},
|
||||
{"as_fixed","as_fixed(i: int) -> fixed","Reinterpret an int as fixed (no conversion)."},
|
||||
{"as_int","as_int(f: fixed) -> int","Reinterpret a fixed as int (no conversion)."},
|
||||
|
|
@ -170,7 +166,6 @@ static const LBuiltin LUDIC_INTRINSICS[] = {
|
|||
{"file_close","file_close(f: ptr)","fclose."},
|
||||
{"read_byte","read_byte() -> int","Read one byte from stdin, -1 at EOF."},
|
||||
{"write_byte","write_byte(b: int)","Write one byte to stdout."},
|
||||
{"str_len","str_len(s: str) -> int","Length of a string in bytes."},
|
||||
{"os_exit","os_exit(code: int)","Terminate the process."},
|
||||
{"os_time","os_time() -> int","Seconds since the epoch."},
|
||||
{"is_windowed","is_windowed() -> bool","True when the build has a window."},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue