Merge Phase 7e: polymorphic print
This commit is contained in:
commit
058cac88ec
23 changed files with 2947 additions and 2924 deletions
11
LANGUAGE.md
11
LANGUAGE.md
|
|
@ -403,9 +403,9 @@ handler Share phase Update {
|
|||
let a = new Tok
|
||||
let b = a # b and a are the SAME object
|
||||
b.kind = 9
|
||||
print_int(a.kind) # 9
|
||||
print(a.kind) # 9
|
||||
bump(a) # the mutation is visible to the caller
|
||||
print_int(a.kind) # 10
|
||||
print(a.kind) # 10
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -417,7 +417,7 @@ handler Walk phase Update {
|
|||
let a = new Tok
|
||||
let b = new Tok
|
||||
a.next = b
|
||||
print_int(a.next.kind)
|
||||
print(a.next.kind)
|
||||
a.next.kind = 42 # chains on the left of an assignment too
|
||||
}
|
||||
```
|
||||
|
|
@ -445,7 +445,7 @@ header never moves, an append is visible to everything holding that slice.
|
|||
handler Collect phase Update {
|
||||
let toks = new []Tok
|
||||
push(toks, new Tok)
|
||||
for i in 0 .. len(toks) { print_int(toks[i].kind) }
|
||||
for i in 0 .. len(toks) { print(toks[i].kind) }
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -626,7 +626,8 @@ literal; test any pointer/record/slice with `x == null` / `x != null` (an unset
|
|||
# state reg(i)->int set_reg(i,v) (64 integer resources shared by handlers)
|
||||
# entity self()->entity
|
||||
# save save() load()->bool (binary snapshot of the whole ECS World)
|
||||
# control quit() print_int(i)
|
||||
# control quit() print(x) (a value + newline)
|
||||
# convert str(x) -> str (int/bool/fixed -> text)
|
||||
# process os_argc()->int os_arg(i)->str (the command line; argv[0] included)
|
||||
# file_stderr()->ptr (a handle for file_write, off stdout)
|
||||
```
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ program RPG2D {
|
|||
}
|
||||
|
||||
handler Report phase Render {
|
||||
for (t, v) in query [Transform, Velocity] { print_int(t.x); print_int(v.speed2) }
|
||||
for (t, v) in query [Transform, Velocity] { print(t.x); print(v.speed2) }
|
||||
quit()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ program Hello {
|
|||
|
||||
handler Report phase Update {
|
||||
for (p) in query [Pos] {
|
||||
print_int(p.x)
|
||||
print_int(p.y)
|
||||
print(p.x)
|
||||
print(p.y)
|
||||
}
|
||||
quit()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@ program Arena {
|
|||
|
||||
handler Fight phase Update {
|
||||
for (f) in query [Fighter] {
|
||||
print_int(damage(f.attack, f.armour, 0))
|
||||
print_int(damage(f.attack, f.armour, 20))
|
||||
print_int(hits_to_kill(f.hp, f.attack, f.armour))
|
||||
print(damage(f.attack, f.armour, 0))
|
||||
print(damage(f.attack, f.armour, 20))
|
||||
print(hits_to_kill(f.hp, f.attack, f.armour))
|
||||
}
|
||||
print_int(xp_for(3, 4))
|
||||
print(xp_for(3, 4))
|
||||
quit()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,18 +10,18 @@ program Life {
|
|||
model Enemy { Health, Sprite }
|
||||
|
||||
# ---- program lifecycle -----------------------------------------------------
|
||||
@OnStart handler Boot { print_int(1) } # once, at boot
|
||||
@OnQuit handler Bye { print_int(2) } # once, at shutdown
|
||||
@OnStart handler Boot { print(1) } # once, at boot
|
||||
@OnQuit handler Bye { print(2) } # once, at shutdown
|
||||
|
||||
# ---- property / entity lifecycle -------------------------------------------
|
||||
@OnAttach(Sprite) handler Load { print_int(Sprite.id + 700) } # when a Sprite is attached
|
||||
@OnAttach(Sprite) handler Load { print(Sprite.id + 700) } # when a Sprite is attached
|
||||
@OnSpawn(Enemy) handler Init { Health.hp = Health.max } # constructor
|
||||
@OnDespawn(Enemy) handler Clean { print_int(Health.hp + 900) } # destructor (dispatched by kind)
|
||||
@OnDespawn(Enemy) handler Clean { print(Health.hp + 900) } # destructor (dispatched by kind)
|
||||
|
||||
handler Seed phase Start { spawn Enemy { Health { max: 50 } } }
|
||||
|
||||
handler Run phase Render {
|
||||
for (h) in query [Health] { print_int(h.hp) } # 50 — Init set hp to max
|
||||
for (h) in query [Health] { print(h.hp) } # 50 — Init set hp to max
|
||||
for (e) in query [Health] { despawn self() } # Clean fires: 50 + 900 = 950
|
||||
quit()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ program QueryDecl {
|
|||
# property; `on: Foe` adds the {Foe} kind filter.
|
||||
@Queries(these: [Battle{hp <= 0 and side == 1}, Pos], on: Foe)
|
||||
handler CleanBattle phase LateUpdate {
|
||||
print_int(Pos.x)
|
||||
print(Pos.x)
|
||||
despawn self()
|
||||
}
|
||||
|
||||
@Queries(these: [Battle])
|
||||
handler Census phase Render {
|
||||
print_int(Battle.hp)
|
||||
print(Battle.hp)
|
||||
}
|
||||
|
||||
handler Bye phase Render { quit() }
|
||||
|
|
|
|||
|
|
@ -7,32 +7,32 @@
|
|||
program SceneDemo {
|
||||
const R_N: int = 0
|
||||
|
||||
handler Boot phase Start { set_reg(R_N, 0); print_int(1000) }
|
||||
handler Boot phase Start { set_reg(R_N, 0); print(1000) }
|
||||
|
||||
scene Title start {
|
||||
on enter { print_int(1) }
|
||||
on exit { print_int(2) }
|
||||
on enter { print(1) }
|
||||
on exit { print(2) }
|
||||
layer Main {
|
||||
handler Tick phase Update {
|
||||
set_reg(R_N, reg(R_N) + 1)
|
||||
print_int(100 + reg(R_N))
|
||||
print(100 + reg(R_N))
|
||||
if reg(R_N) >= 2 { become Play }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scene Play {
|
||||
on enter { print_int(3); set_reg(R_N, 0) }
|
||||
on exit { print_int(4) }
|
||||
on enter { print(3); set_reg(R_N, 0) }
|
||||
on exit { print(4) }
|
||||
layer World {
|
||||
handler Step phase Update {
|
||||
set_reg(R_N, reg(R_N) + 1)
|
||||
print_int(200 + reg(R_N))
|
||||
print(200 + reg(R_N))
|
||||
if reg(R_N) >= 2 { quit() }
|
||||
}
|
||||
}
|
||||
layer Hud {
|
||||
handler Draw phase Render { print_int(900) }
|
||||
handler Draw phase Render { print(900) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,24 +3,24 @@
|
|||
program Strings {
|
||||
entry {
|
||||
let greeting = "hello"
|
||||
if greeting == "hello" { print_int(1) } # content comparison
|
||||
if greeting != "world" { print_int(2) }
|
||||
if greeting == "hello" { print(1) } # content comparison
|
||||
if greeting != "world" { print(2) }
|
||||
|
||||
let who = "Ludic"
|
||||
let msg = greeting + ", " + who + "!" # concatenation chains
|
||||
if msg == "hello, Ludic!" { print_int(3) }
|
||||
if msg == "hello, Ludic!" { print(3) }
|
||||
|
||||
# build up a string in a loop
|
||||
var line = ""
|
||||
var i = 0
|
||||
while i < 3 { line = line + "ab"; i = i + 1 }
|
||||
if line == "ababab" { print_int(4) }
|
||||
if line == "ababab" { print(4) }
|
||||
|
||||
if (greeting + who) != greeting { print_int(5) }
|
||||
if (greeting + who) != greeting { print(5) }
|
||||
|
||||
# interpolation: `{expr}` embeds any expression (numbers become text)
|
||||
let n = 42
|
||||
if `{greeting}, {who}!` == "hello, Ludic!" { print_int(6) }
|
||||
if `n={n}, next={n + 1}` == "n=42, next=43" { print_int(7) }
|
||||
if `{greeting}, {who}!` == "hello, Ludic!" { print(6) }
|
||||
if `n={n}, next={n + 1}` == "n=42, next=43" { print(7) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ program Toggles {
|
|||
model Player { Health, Shield }
|
||||
|
||||
# hooks run at the toggle point with the property's data bound by name
|
||||
@OnDisable(Shield) handler Down { print_int(Shield.amount + 1) } # 5 + 1
|
||||
@OnEnable(Shield) handler Up { print_int(Shield.amount + 2) } # 5 + 2
|
||||
@OnDisable(Shield) handler Down { print(Shield.amount + 1) } # 5 + 1
|
||||
@OnEnable(Shield) handler Up { print(Shield.amount + 2) } # 5 + 2
|
||||
|
||||
handler Seed phase Start { spawn Player { Health { max: 50 }, Shield { amount: 5 } } }
|
||||
|
||||
|
|
@ -21,17 +21,17 @@ program Toggles {
|
|||
for (e) in query [Player] { disable Shield on self() } # @OnDisable -> 6
|
||||
var n = 0
|
||||
for (s) in query [Shield] { n += 1 }
|
||||
print_int(n) # 0 — no live Shield now
|
||||
print(n) # 0 — no live Shield now
|
||||
|
||||
for (e) in query [Player] { enable Shield on self() } # @OnEnable -> 7, data intact
|
||||
n = 0
|
||||
for (s) in query [Shield] { n += 1 }
|
||||
print_int(n) # 1 — amount is still 5
|
||||
print(n) # 1 — amount is still 5
|
||||
|
||||
disable Player # whole model off
|
||||
n = 0
|
||||
for (p) in query [Player] { n += 1 }
|
||||
print_int(n) # 0 — model disabled
|
||||
print(n) # 0 — model disabled
|
||||
quit()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,9 +94,10 @@ fn emit_program() -> void {
|
|||
fn ir_flush(path: ptr) -> bool {
|
||||
let h = buf_str(head)
|
||||
let c = buf_str(code)
|
||||
if (path == null) {
|
||||
print_str(h)
|
||||
print_str(c)
|
||||
if (path == null) { # raw IR to stdout (no trailing newline)
|
||||
let out = file_stdout()
|
||||
file_write(out, h, slen(h))
|
||||
file_write(out, c, slen(c))
|
||||
return true
|
||||
}
|
||||
let f = file_open(path, "wb")
|
||||
|
|
|
|||
|
|
@ -132,6 +132,12 @@ fn emit_call(e: Node) -> Val {
|
|||
g_uses_intstr = true
|
||||
return val(emit_bind(("call ptr @fn_int_str(i32 " + (a.code + ")"))), "str")
|
||||
}
|
||||
if (name == "print") { # print(x): a value + newline (int or string)
|
||||
let a = emit_expr(e.kids[0])
|
||||
if (llty(a.ty) == "ptr") { emit(" call i32 (ptr, ...) @printf(ptr @.fmt_line, ptr " + (a.code + ")\n")) }
|
||||
else { emit(" call i32 (ptr, ...) @printf(ptr @.fmt_int, i32 " + (a.code + ")\n")) }
|
||||
return val("0", "void")
|
||||
}
|
||||
if (name == "fx") { let a = emit_expr(e.kids[0]); return val(emit_bind(("shl i32 " + (a.code + ", 16"))), "fixed") }
|
||||
if (name == "flr") { let a = emit_expr(e.kids[0]); return val(emit_bind(("ashr i32 " + (a.code + ", 16"))), "int") }
|
||||
if is_intrinsic(name) { return emit_intrinsic(name, e) }
|
||||
|
|
|
|||
|
|
@ -69,8 +69,9 @@ fn emit_header() -> void {
|
|||
emith("declare i32 @win_running()\n")
|
||||
emith("declare void @win_close()\n")
|
||||
emith("@__stderrp = external global ptr\n")
|
||||
emith("@.fmt_str = private unnamed_addr constant [3 x i8] c\"%s\\00\"\n")
|
||||
emith("@__stdoutp = external global ptr\n")
|
||||
emith("@.fmt_int = private unnamed_addr constant [4 x i8] c\"%d\\0A\\00\"\n")
|
||||
emith("@.fmt_line = private unnamed_addr constant [4 x i8] c\"%s\\0A\\00\"\n")
|
||||
emith("@L_argc = internal global i32 0\n")
|
||||
emith("@L_argv = internal global ptr null\n")
|
||||
emith("@.gametitle = private unnamed_addr constant [")
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ fn is_intrinsic(name: ptr) -> bool {
|
|||
if (name == "peek8") or (name == "poke8") { return true }
|
||||
if (name == "file_open") or (name == "file_read") or (name == "file_write") { return true }
|
||||
if (name == "file_seek") or (name == "file_tell") or (name == "file_close") { return true }
|
||||
if (name == "print_str") or (name == "print_int") { return true }
|
||||
if (name == "os_argc") or (name == "os_arg") or (name == "os_exit") or (name == "file_stderr") { return true }
|
||||
if (name == "file_stdout") { return true }
|
||||
if (name == "os_system") or (name == "os_getenv") { return true }
|
||||
if (name == "peek32") or (name == "poke32") { return true }
|
||||
return false
|
||||
|
|
@ -75,16 +75,7 @@ fn emit_intrinsic(name: ptr, e: Node) -> Val {
|
|||
emit(" call i32 @fclose(ptr "); emit(f); emit(")\n")
|
||||
return val("0", "void")
|
||||
}
|
||||
if (name == "print_str") {
|
||||
let s = arg_code(e, 0)
|
||||
emit(" call i32 (ptr, ...) @printf(ptr @.fmt_str, ptr "); emit(s); emit(")\n")
|
||||
return val("0", "void")
|
||||
}
|
||||
if (name == "print_int") {
|
||||
let n = arg_code(e, 0)
|
||||
emit(" call i32 (ptr, ...) @printf(ptr @.fmt_int, i32 "); emit(n); emit(")\n")
|
||||
return val("0", "void")
|
||||
}
|
||||
# print_str / print_int are the polymorphic `print(x)` builtin now (emit_call).
|
||||
if (name == "os_argc") { return val(emit_bind("load i32, ptr @L_argc"), "int") }
|
||||
if (name == "os_arg") {
|
||||
let i = arg_code(e, 0)
|
||||
|
|
@ -100,6 +91,7 @@ fn emit_intrinsic(name: ptr, e: Node) -> Val {
|
|||
return val("0", "void")
|
||||
}
|
||||
if (name == "file_stderr") { return val(emit_bind("load ptr, ptr @__stderrp"), "ptr") }
|
||||
if (name == "file_stdout") { return val(emit_bind("load ptr, ptr @__stdoutp"), "ptr") }
|
||||
if (name == "os_system") {
|
||||
let c = arg_code(e, 0)
|
||||
return val(emit_bind(("call i32 @system(ptr " + (c + ")"))), "int")
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,13 +1,13 @@
|
|||
program T {
|
||||
fn fib(n: int) -> int { if n < 2 { return n }; return fib(n-1) + fib(n-2) }
|
||||
entry {
|
||||
print_int(fib(10)) # 55
|
||||
print(fib(10)) # 55
|
||||
var s = 0
|
||||
for i in 0 .. 10 { if i == 5 { break }; if i % 2 == 0 { continue }; s = s + i }
|
||||
print_int(s) # 1+3 = 4
|
||||
print(s) # 1+3 = 4
|
||||
var i = 0; var t = 0
|
||||
while true { i = i + 1; if i > 5 { break }; t = t + i }
|
||||
print_int(t) # 15
|
||||
if false and (1/0 == 0) { print_int(999) } else { print_int(1) } # short-circuit: no div by zero
|
||||
print(t) # 15
|
||||
if false and (1/0 == 0) { print(999) } else { print(1) } # short-circuit: no div by zero
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ program T {
|
|||
entry {
|
||||
let half = 0.5
|
||||
let a = 1.5
|
||||
print_int(flr(a + half)) # flr(2.0) = 2
|
||||
print_int(flr(a * 2.0)) # flr(3.0) = 3
|
||||
print(flr(a + half)) # flr(2.0) = 2
|
||||
print(flr(a * 2.0)) # flr(3.0) = 3
|
||||
let third = 1.0 / 3.0
|
||||
print_int(flr(third * 3.0)) # ~flr(1.0) = 1 (may be 0 with rounding)
|
||||
print_int(flr(fx(5) + a)) # flr(6.5) = 6
|
||||
if a > half { print_int(1) } else { print_int(0) } # 1
|
||||
print(flr(third * 3.0)) # ~flr(1.0) = 1 (may be 0 with rounding)
|
||||
print(flr(fx(5) + a)) # flr(6.5) = 6
|
||||
if a > half { print(1) } else { print(0) } # 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ program T {
|
|||
return 0
|
||||
}
|
||||
entry {
|
||||
print_int(classify(65)) # 1
|
||||
print_int(classify(67)) # 2
|
||||
print_int(classify(90)) # 9
|
||||
print_int((1 << 4)) # 16
|
||||
print_int(((4 | 1) & 6)) # 4
|
||||
print(classify(65)) # 1
|
||||
print(classify(67)) # 2
|
||||
print(classify(90)) # 9
|
||||
print((1 << 4)) # 16
|
||||
print(((4 | 1) & 6)) # 4
|
||||
let p = mem_alloc(16)
|
||||
poke32(p, 1, 9999)
|
||||
print_int(peek32(p, 1)) # 9999
|
||||
print(peek32(p, 1)) # 9999
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
program T {
|
||||
entry {
|
||||
let xs = new []int
|
||||
print_int(len(xs)) # 0
|
||||
print(len(xs)) # 0
|
||||
for i in 0 .. 20 { push(xs, i * i) }
|
||||
print_int(len(xs)) # 20
|
||||
print_int(xs[19]) # 361
|
||||
print(len(xs)) # 20
|
||||
print(xs[19]) # 361
|
||||
xs[3] = 777
|
||||
print_int(xs[3]) # 777
|
||||
print(xs[3]) # 777
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,18 +3,18 @@ program T {
|
|||
fn bump(p: P) -> void { p.x = p.x + 100 }
|
||||
entry {
|
||||
let a = new P
|
||||
print_int(a.y) # 7 default
|
||||
print(a.y) # 7 default
|
||||
a.x = 5
|
||||
let b = a
|
||||
b.x = 9
|
||||
print_int(a.x) # 9 (reference)
|
||||
print(a.x) # 9 (reference)
|
||||
bump(a)
|
||||
print_int(a.x) # 109
|
||||
print(a.x) # 109
|
||||
let c = new P
|
||||
c.x = 2
|
||||
a.next = c
|
||||
print_int(a.next.x) # 2 chained
|
||||
print(a.next.x) # 2 chained
|
||||
a.next.x = 42
|
||||
print_int(c.x) # 42
|
||||
print(c.x) # 42
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,13 +64,13 @@ object LudicVocabulary {
|
|||
"sprites_load", "draw_sprite", "draw_sprite_scaled", "ui_build", "ui_open",
|
||||
"ui_tick", "ui_render", "ui_clicked", "ui_set_text", "ui_set_int", "ui_focus",
|
||||
"ui_focused", "ui_visible", "key", "reg", "set_reg", "self", "save", "load",
|
||||
"status", "print_int", "quit",
|
||||
"status", "print", "str", "quit",
|
||||
// compiler intrinsics: the floor the Ludic-written runtime stands on
|
||||
"mem_alloc", "mem_realloc", "mem_free", "mem_copy", "mem_set", "peek8", "poke8", "peek32",
|
||||
"os_argc", "os_arg", "file_stderr",
|
||||
"os_argc", "os_arg", "file_stderr", "file_stdout",
|
||||
"poke32", "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", "print_str",
|
||||
"file_seek", "file_tell", "file_close", "read_byte", "write_byte",
|
||||
"str_len", "os_exit", "os_time",
|
||||
"is_windowed", "game_title", "win_open", "win_poll", "win_present",
|
||||
"win_running", "win_close"
|
||||
|
|
|
|||
|
|
@ -204,12 +204,12 @@
|
|||
{
|
||||
"comment": "the runtime surface — every name here resolves to rt_<name> in runtime/native",
|
||||
"name": "support.function.builtin.ludic",
|
||||
"match": "\\b(min|max|abs|clamp|seed|rng_range|rng_chance|fx|flr|map_size|map_row|tile|clear|present|fill_rect|frame_rect|put_px|text|text_int|font_load|text_ttf|text_w|text_h|image_load|draw_image|draw_image_scaled|draw_9slice|png_load|sprites_load|draw_sprite|draw_sprite_scaled|ui_build|ui_open|ui_tick|ui_render|ui_clicked|ui_set_text|ui_set_int|ui_focus|ui_focused|ui_visible|key|reg|set_reg|self|save|load|status|print_int|quit)\\b(?=\\s*\\()"
|
||||
"match": "\\b(min|max|abs|clamp|seed|rng_range|rng_chance|fx|flr|map_size|map_row|tile|clear|present|fill_rect|frame_rect|put_px|text|text_int|font_load|text_ttf|text_w|text_h|image_load|draw_image|draw_image_scaled|draw_9slice|png_load|sprites_load|draw_sprite|draw_sprite_scaled|ui_build|ui_open|ui_tick|ui_render|ui_clicked|ui_set_text|ui_set_int|ui_focus|ui_focused|ui_visible|key|reg|set_reg|self|save|load|status|print|str|quit)\\b(?=\\s*\\()"
|
||||
},
|
||||
{
|
||||
"comment": "compiler intrinsics — these lower straight to libc or the OS",
|
||||
"name": "support.function.intrinsic.ludic",
|
||||
"match": "\\b(mem_alloc|mem_realloc|mem_free|mem_copy|mem_set|peek8|poke8|peek32|poke32|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|print_str|str_len|os_exit|os_time|os_argc|os_arg|file_stderr|is_windowed|game_title|win_open|win_poll|win_present|win_running|win_close)\\b(?=\\s*\\()"
|
||||
"match": "\\b(mem_alloc|mem_realloc|mem_free|mem_copy|mem_set|peek8|poke8|peek32|poke32|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*\\()"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -204,12 +204,12 @@
|
|||
{
|
||||
"comment": "the runtime surface — every name here resolves to rt_<name> in runtime/native",
|
||||
"name": "support.function.builtin.ludic",
|
||||
"match": "\\b(min|max|abs|clamp|seed|rng_range|rng_chance|fx|flr|map_size|map_row|tile|clear|present|fill_rect|frame_rect|put_px|text|text_int|font_load|text_ttf|text_w|text_h|image_load|draw_image|draw_image_scaled|draw_9slice|png_load|sprites_load|draw_sprite|draw_sprite_scaled|ui_build|ui_open|ui_tick|ui_render|ui_clicked|ui_set_text|ui_set_int|ui_focus|ui_focused|ui_visible|key|reg|set_reg|self|save|load|status|print_int|quit)\\b(?=\\s*\\()"
|
||||
"match": "\\b(min|max|abs|clamp|seed|rng_range|rng_chance|fx|flr|map_size|map_row|tile|clear|present|fill_rect|frame_rect|put_px|text|text_int|font_load|text_ttf|text_w|text_h|image_load|draw_image|draw_image_scaled|draw_9slice|png_load|sprites_load|draw_sprite|draw_sprite_scaled|ui_build|ui_open|ui_tick|ui_render|ui_clicked|ui_set_text|ui_set_int|ui_focus|ui_focused|ui_visible|key|reg|set_reg|self|save|load|status|print|str|quit)\\b(?=\\s*\\()"
|
||||
},
|
||||
{
|
||||
"comment": "compiler intrinsics — these lower straight to libc or the OS",
|
||||
"name": "support.function.intrinsic.ludic",
|
||||
"match": "\\b(mem_alloc|mem_realloc|mem_free|mem_copy|mem_set|peek8|poke8|peek32|poke32|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|print_str|str_len|os_exit|os_time|os_argc|os_arg|file_stderr|is_windowed|game_title|win_open|win_poll|win_present|win_running|win_close)\\b(?=\\s*\\()"
|
||||
"match": "\\b(mem_alloc|mem_realloc|mem_free|mem_copy|mem_set|peek8|poke8|peek32|poke32|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*\\()"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -138,7 +138,8 @@ static const LBuiltin LUDIC_BUILTINS[] = {
|
|||
{"save","save()","Write a binary snapshot of the whole ECS world."},
|
||||
{"load","load() -> bool","Restore the snapshot; false if there is none."},
|
||||
{"status","status(s: str)","Set the one-line status message."},
|
||||
{"print_int","print_int(i: int)","Print an integer to stdout."},
|
||||
{"print","print(x)","Print a value (int or string) and a newline to stdout."},
|
||||
{"str","str(x) -> str","Convert an int/bool/fixed to text (a string passes through)."},
|
||||
{"quit","quit()","Stop the frame loop and exit."},
|
||||
{0,0,0}
|
||||
};
|
||||
|
|
@ -149,6 +150,7 @@ static const LBuiltin LUDIC_INTRINSICS[] = {
|
|||
{"os_argc","os_argc() -> int","Number of command-line arguments, argv[0] included."},
|
||||
{"os_arg","os_arg(i: int) -> str","The i-th command-line argument."},
|
||||
{"file_stderr","file_stderr() -> ptr","The standard error stream, for file_write."},
|
||||
{"file_stdout","file_stdout() -> ptr","The standard output stream, for file_write."},
|
||||
{"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."},
|
||||
|
|
@ -171,7 +173,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."},
|
||||
{"print_str","print_str(s: str)","Write a string 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."},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue