From bca8f126fc714f1e32ac25aeaccff05c92dec189 Mon Sep 17 00:00:00 2001 From: Orkuncakilkaya Date: Sat, 29 Aug 2026 15:08:23 +0300 Subject: [PATCH] =?UTF-8?q?Networking=20N2=E2=80=93N6,=20and=20a=20fully?= =?UTF-8?q?=20C-free=20toolchain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement the rest of NETWORKING-DESIGN.md (N2–N6) and eliminate every `.c` file from the repo. clang remains only the LLVM-IR assembler; no C is compiled anywhere. Networking (selfhost/emit_net.ludic + parser/emit changes): - N2 @Sync: per-model serialize/apply + by-kind dispatchers; POD-scalar compile error and empty-participation warning; selective replication. - N3 @Owned: @L_owner array + owner/set_owner/is_owner; owners snapshot. - N4 @ToServer/@ToClients remote events: framed net_send + net_pump re-emit. - N5 @Server/@Predicted role guards + drivable sim (tick_fixed/tick_render, entry-owns-the-loop). - Built-in loopback transport so multiplayer runs with zero foreign code; extern fn net_send/net_poll still overrides it for a real socket. - N6 blessed runtime (examples/net_rt.ludic) + end-to-end demo (net_demo). - Fix: llty("entity") is now i32 (entities are i32 handles), so let e = self(). C elimination: - Networking + foreign-mod-ABI tests rewritten as self-contained pure-Ludic programs (examples/net_*, world_*, mod_events, scoped); tests/ removed. - Reflection ABI exposed to Ludic as world_* builtins (Ludic-to-Ludic modding). - Formatter rewritten C→Ludic: tools/ludic-tools/fmt.ludic. - Language server rewritten C→Ludic: tools/ludic-tools/lsp.ludic (lexer, index parser, cross-file workspace resolver, JSON, all LSP handlers). - Obsolete migrate_*.c codemods deleted; ludic_syntax.h kept as vocabulary data. Suites: ./test.sh 44/44, ./tools/test-tools.sh 28/28 (LSP 42/42), fixpoint holds. Co-Authored-By: Claude Opus 4.8 --- EVENTS-DESIGN.md | 670 + LANGUAGE.md | 158 +- LIFECYCLE-DESIGN.md | 348 + MOBILE-DESIGN.md | 338 + NETWORKING-DESIGN.md | 505 + SCENES-DESIGN.md | 354 + examples/cancel.ludic | 27 + examples/detach.ludic | 38 + examples/events.ludic | 25 + examples/layer_events.ludic | 27 + examples/mod_events.ludic | 16 + examples/net_demo.ludic | 45 + examples/net_echo.ludic | 24 + examples/net_owner.ludic | 25 + examples/net_roles.ludic | 33 + examples/net_rpc.ludic | 29 + examples/net_rt.ludic | 33 + examples/net_snapshot.ludic | 29 + examples/net_sync.ludic | 40 + examples/program_events.ludic | 18 + examples/promote.ludic | 32 + examples/prop_events.ludic | 26 + examples/reason.ludic | 38 + examples/recurse.ludic | 21 + examples/scene_events.ludic | 22 + examples/scenes.ludic | 22 +- examples/scoped.ludic | 21 + examples/world_dyn.ludic | 27 + examples/world_get.ludic | 22 + examples/world_mixed.ludic | 17 + examples/world_query.ludic | 26 + examples/world_scan.ludic | 30 + examples/world_spawn.ludic | 20 + selfhost/ast.ludic | 12 + selfhost/bootstrap-cfree.sh | 3 +- selfhost/build.sh | 1 + selfhost/emit_core.ludic | 107 +- selfhost/emit_decl.ludic | 15 +- selfhost/emit_ecs.ludic | 29 +- selfhost/emit_expr.ludic | 118 + selfhost/emit_game.ludic | 680 +- selfhost/emit_head.ludic | 21 + selfhost/emit_machine.ludic | 30 +- selfhost/emit_net.ludic | 373 + selfhost/emit_save.ludic | 70 +- selfhost/emit_spawn.ludic | 72 +- selfhost/emit_stmt.ludic | 70 +- selfhost/ludicc.seed.ll | 21758 ++++++++++++---- selfhost/parse.ludic | 115 +- selfhost/parse_game.ludic | 80 +- selfhost/reseed.sh | 3 +- test.sh | 135 + tools/build-tools.sh | 44 +- .../main/kotlin/io/ludic/ide/LudicTokens.kt | 6 +- tools/ludic-tools/fmt.ludic | 563 + tools/ludic-tools/lsp.ludic | 2409 ++ tools/ludic-tools/ludic_fmt.h | 339 - tools/ludic-tools/ludic_fmt_main.c | 118 - tools/ludic-tools/ludic_index.h | 672 - tools/ludic-tools/ludic_json.h | 191 - tools/ludic-tools/ludic_lsp.c | 1265 - tools/ludic-tools/ludic_syntax.h | 8 +- tools/ludic-tools/ludic_syntax.h.tmp | 327 - tools/ludic-tools/ludic_workspace.h | 405 - tools/ludic-tools/migrate_records.c | 59 - tools/ludic-tools/migrate_separators.c | 119 - tools/ludic-tools/migrate_ui.c | 52 - 67 files changed, 24066 insertions(+), 9309 deletions(-) create mode 100644 EVENTS-DESIGN.md create mode 100644 LIFECYCLE-DESIGN.md create mode 100644 MOBILE-DESIGN.md create mode 100644 NETWORKING-DESIGN.md create mode 100644 SCENES-DESIGN.md create mode 100644 examples/cancel.ludic create mode 100644 examples/detach.ludic create mode 100644 examples/events.ludic create mode 100644 examples/layer_events.ludic create mode 100644 examples/mod_events.ludic create mode 100644 examples/net_demo.ludic create mode 100644 examples/net_echo.ludic create mode 100644 examples/net_owner.ludic create mode 100644 examples/net_roles.ludic create mode 100644 examples/net_rpc.ludic create mode 100644 examples/net_rt.ludic create mode 100644 examples/net_snapshot.ludic create mode 100644 examples/net_sync.ludic create mode 100644 examples/program_events.ludic create mode 100644 examples/promote.ludic create mode 100644 examples/prop_events.ludic create mode 100644 examples/reason.ludic create mode 100644 examples/recurse.ludic create mode 100644 examples/scene_events.ludic create mode 100644 examples/scoped.ludic create mode 100644 examples/world_dyn.ludic create mode 100644 examples/world_get.ludic create mode 100644 examples/world_mixed.ludic create mode 100644 examples/world_query.ludic create mode 100644 examples/world_scan.ludic create mode 100644 examples/world_spawn.ludic create mode 100644 selfhost/emit_net.ludic create mode 100644 tools/ludic-tools/fmt.ludic create mode 100644 tools/ludic-tools/lsp.ludic delete mode 100644 tools/ludic-tools/ludic_fmt.h delete mode 100644 tools/ludic-tools/ludic_fmt_main.c delete mode 100644 tools/ludic-tools/ludic_index.h delete mode 100644 tools/ludic-tools/ludic_json.h delete mode 100644 tools/ludic-tools/ludic_lsp.c delete mode 100644 tools/ludic-tools/ludic_syntax.h.tmp delete mode 100644 tools/ludic-tools/ludic_workspace.h delete mode 100644 tools/ludic-tools/migrate_records.c delete mode 100644 tools/ludic-tools/migrate_separators.c delete mode 100644 tools/ludic-tools/migrate_ui.c diff --git a/EVENTS-DESIGN.md b/EVENTS-DESIGN.md new file mode 100644 index 00000000..2d5436c9 --- /dev/null +++ b/EVENTS-DESIGN.md @@ -0,0 +1,670 @@ +# Events & modding, expanded — a design doc + +> **Status: EV0 fully shipped; EV1 (spawn/despawn), EV2 (first cut) and EV3 +> shipped; EV4–EV7 are design.** Implemented, self-hosted to the C-free fixpoint, +> and each a `test.sh` check: +> - **EV0** — `event`/`@On`/`emit` lowered to `@ev_` dispatch (compile-time +> listeners), **plus the foreign C ABI** (`ludic_on_`, the `%Ev_` payload +> struct, a fixed-capacity listener array), proven by a C mod in +> [`tests/mod_c/mod.c`](tests/mod_c/mod.c) binding +> [`examples/mod_host.ludic`](examples/mod_host.ludic). Byte-identical when no +> event is declared. ([`examples/events.ludic`](examples/events.ludic)) +> - **EV1** — public events across the **whole architecture**, every scope shipped: +> **program** (`@Public @OnStart`/`@OnQuit` → `program_start`/`program_quit`, +> [`examples/program_events.ludic`](examples/program_events.ludic)); **models** +> (`@Public @OnSpawn`/`@OnDespawn` → `model__spawn`/`_despawn`, +> [`examples/promote.ludic`](examples/promote.ludic)); **properties** (`@Public +> @OnAttach`/`@OnDetach`/`@OnEnable`/`@OnDisable` → `prop_

_attach` etc., +> [`examples/prop_events.ludic`](examples/prop_events.ludic)); **scenes** (a +> `public` scene → `scene__enter`/`_exit`, +> [`examples/scene_events.ludic`](examples/scene_events.ludic)); and **layers** (a +> `public` layer + `enable/disable layer L` → `layer__show`/`_hide`, +> [`examples/layer_events.ludic`](examples/layer_events.ludic)) — which also +> landed **SCENES E2 layer toggle** (`@LE_` flag gating a layer's handlers). +> - **EV2 / EV2b** — the world table: the reflection ABI, generated from the +> compile-time schema, so a mod reads, writes, scans, identifies, **and creates** +> entity state **by name** without compiling against the game. `ludic_prop_id` / +> `ludic_field_id` / `ludic_get` / `ludic_set` / `ludic_has` (read/write — +> [`world_mod.c`](tests/mod_c/world_mod.c)); `ludic_entity_count` / `ludic_kind` / +> `ludic_model_id` (scan and identify — [`world_scan.c`](tests/mod_c/world_scan.c)); +> `ludic_spawn(model_id)` (create, reusing the compiler's own spawn lowering — +> [`world_spawn.c`](tests/mod_c/world_spawn.c)); `get`/`set` address each field by +> its real struct offset, correct for `int`/`fixed`/`byte`/`ptr` and mixed layouts +> ([`world_mixed.c`](tests/mod_c/world_mixed.c)); and iterate +> (`ludic_query_next`, [`world_query.c`](tests/mod_c/world_query.c)). Emitted only +> for an ECS program that declares events, so event-free games stay byte-exact. +> The world table is complete: read, write, scan, identify, create, iterate. +> - **EV3** — `cancellable` events, the `cancel` verb, and `emit E(…)` as an +> expression returning the veto flag. ([`examples/cancel.ludic`](examples/cancel.ludic)) +> - **EV5** — leak-proof scoped listeners: `ludic_off_(token)` (explicit +> unregister; dispatch skips tombstoned slots), `ludic_on_entity_(entity, cb)` +> (entity-scoped), and a generated `ludic_sweep_entity` called from `despawn` that +> nulls every listener the dying entity owned — a listener can't leak past its +> entity. Proven by [`tests/mod_c/scoped_mod.c`](tests/mod_c/scoped_mod.c). +> - **EV6** — re-entrant `emit` is depth-bounded (`@ev_depth` vs `EV_DEPTH_CAP`): a +> listener may emit another event, but an event cycle traps as an early return +> instead of hanging the frame. Dispatch order was already deterministic (array, +> registration order). Proven by [`examples/recurse.ludic`](examples/recurse.ludic). +> +> - **EV7 (schema opening)** — a mod defines a brand-new component at runtime: +> `ludic_register_prop(name, nfields)` mallocs flat `[MAX_ENT × nfields × i32]` +> storage + a has-flag array and returns a prop id past the compile-time range; +> `ludic_attach_dyn`/`ludic_detach_dyn` toggle it on an entity; `get`/`set`/`has`/ +> `prop_id` fall through to the dynamic registry for ids ≥ the compile-time count. +> A mod adds entirely new data to entities by name, with per-entity isolation. +> Proven by [`tests/mod_c/world_dyn.c`](tests/mod_c/world_dyn.c). (EV7's other +> half — networking's local/remote event split — has no substrate in Ludic yet.) +> +> Still design: EV4 (the scripting-shim bridge — deferred to keep the suite +> interpreter-free) and EV7 networking. This is a companion to +> [LIFECYCLE-DESIGN.md](LIFECYCLE-DESIGN.md) and [SCENES-DESIGN.md](SCENES-DESIGN.md). +> Where those docs extend Ludic's *internal, compile-time* lifecycle, this one +> proposes the *external, runtime* layer that turns those same lifecycle moments +> into a public event surface — the foundation a game can hand to mods written in +> Ludic, JS/TS, Lua, or anything with a C ABI. It distills a survey of modding and +> event systems (§3) into a phased roadmap (EV0–EV7, §12–§13). §14 lists the open +> decisions. + +--- + +## 1. Thesis + +Ludic already has a lifecycle. `@OnSpawn(Enemy)`, `@OnDetach(Sprite)`, scene +`on enter`, `@OnDespawn(M, reason: r)` — every one is a **compile-time, +closed-world, zero-cost** hook that desugars to a direct call at a fixed site. +That is the right design for the *game author*, who is compiled together with the +game. It is exactly the wrong design for a *mod author*, who is not. + +A modding event system is the mirror image of the lifecycle layer along three axes: + +| | Lifecycle hooks (today) | Modding events (this doc) | +|---|---|---| +| World | **closed** — all handlers known at compile time | **open** — mods add listeners after compilation | +| Binding | **static** — a checked symbol, a direct call | **dynamic** — registered at load, dispatched at runtime | +| Language | **in-language** — Ludic, compiled together | **cross-language** — JS/TS/Lua/native over an ABI | + +The instinct would be to build a second, parallel system. **The design that keeps +Ludic's discipline builds one system seen from two sides.** A lifecycle hook is a +*private* view of a moment; a public event is the *same moment* exposed across the +ABI. The author promotes a hook to an event; the compiler keeps its zero-cost +direct calls **and** emits one guarded `bus_emit` at the very same site. Nothing +exposed → nothing emitted → goldens stay byte-identical, exactly like `has_ecs` +and the `g_ondespawn` shutdown walk. + +**The Luanti dividend.** The gap analysis (`LUANTI-ROADMAP.md`) found that ~57k of +Luanti's lines exist only to bridge C++ and Lua, and that its mod predicates are +*runtime strings* it must re-interpret every call. Ludic pays neither tax. The +reflection surface a mod needs — "what properties exist, what fields, at what +offsets" — is a **compile-time fact**; the compiler can *generate* the bridge +instead of a human hand-writing 57k lines, and it is always in sync with the game +it describes. A mod itself written in Ludic and compiled to a shared library binds +that surface with **zero marshalling**; a Lua mod binds the same surface through +its FFI. One ABI, every language. + +--- + +## 2. What Ludic has today, and why it can't reach a mod + +The lifecycle table from [LIFECYCLE-DESIGN.md §2](LIFECYCLE-DESIGN.md), every cell +filled, every cell a zero-cost desugar: + +| Scope | Setup hook | Teardown hook | Fire site the compiler already owns | +|---|---|---|---| +| program | `@OnStart` | `@OnQuit` | boot / shutdown | +| entity | `@OnSpawn(M)` | `@OnDespawn(M, reason)` | `spawn` / `despawn` / shutdown-walk | +| property (structural) | `@OnAttach(P)` | `@OnDetach(P)` | `attach` / `detach` | +| property (toggle) | `@OnEnable(P)` | `@OnDisable(P)` | `enable` / `disable` | +| scene | `on enter` | `on exit` | `become` (and `push`/`pop`, SCENES E3) | + +Two more fire sites are proposed but unbuilt, and both are natural events: +`@OnChange(P)` (LC2 — a value-change hook the compiler can emit right after every +write site) and `@OnStartMatch`/`@OnStopMatch` (LC3 — query-membership edges). + +Every one of these is a place the compiler **already writes a call**. The problem +is purely that the call is *closed*: its targets are fixed at compile time, so a +mod loaded at runtime has no way to be one of them. The entire job of this doc is +to add, at each of these sites, an **opt-in second exit** to an open runtime list — +without touching the closed path's cost when no one opts in. + +What a mod additionally needs, that no hook provides: + +- a **stable name** for each event that survives recompilation (a mod compiled + against v1 must still bind in v1.1); +- a way to **read and write game state** it did not compile against (the world + table, §9); +- a way to **veto or rewrite** an action before it commits, not just observe it + after (cancellable events, §8); +- a **loader** — mods enable, disable, and unload, and their listeners must vanish + cleanly when they do (§10). + +--- + +## 3. Research digest — the one idea to steal from each + +The lifecycle doc surveyed engines for *internal* lifecycle. This surveys systems +for their *modding and event* surface — how untrusted, separately-authored code +plugs into a running game. + +| System | The transferable idea | +|---|---| +| **Bukkit / Spigot** (Minecraft) | The canonical **cancellable event**: `Cancellable.setCancelled(true)` vetoes the action; `EventPriority` orders listeners; `@EventHandler(ignoreCancelled=true)` opts out of already-vetoed events. Events are *classes*, checked at bind time — not strings. | +| **Fabric** (Minecraft) | `Event` backed by an **invoker over a plain array** of callbacks — deterministic registration order, no reflection at dispatch, phases for ordering. The closest existing design to what Ludic wants: fast, ordered, array-backed. | +| **Factorio** | **Deterministic** modded events for multiplayer lockstep: `script.on_event(defines.events.X)`, numeric event ids, `raise_event` for custom events, **filtered** subscriptions. Proof that a heavily-modded game can still replay bit-for-bit. | +| **Minetest / Luanti** | `register_on_*` + a string-keyed global (`minetest.*`) world API. The thing to beat: its predicates are runtime strings, and its C++↔Lua bridge is 57k hand-written lines. | +| **Godot** | **Signals as a first-class language construct**: `signal hurt(amount)`, `emit_signal`, `connect`. Decoupled, per-object, declared where the data lives. | +| **DOM events** | The **two-phase dispatch** vocabulary: capture → target → bubble, `preventDefault` (veto the default action) vs `stopPropagation` (halt the chain), and *passive* listeners that promise not to cancel (so dispatch can skip the veto check). | +| **Node `EventEmitter`** | The dead-simple baseline `on`/`emit` — and its footguns: untyped string names (a typo silently never fires) and **listener leaks** (a listener on a dead object keeps it alive). Design both out. | +| **flecs / Bevy observers** | **ECS-native reactive events**: an event *targeted at an entity*, observers that fire on component add/set/remove, deferred so mutation-during-iteration is safe. The correct shape for an ECS. | +| **Blender `bpy.app.handlers`** | Named application-level handler lists a script appends to, with a `persistent` flag controlling survival across file loads — the "engine lifecycle exposed to scripts" model, and the lesson that *survival scope* must be explicit. | +| **Roblox** | `BindableEvent` (local) vs `RemoteEvent` (across the network boundary) — the same event abstraction, one flag deciding whether it crosses a trust/latency boundary. Relevant the day Ludic has networking. | + +Five **footguns** the survey warns against, to design *out* of Ludic from the start: + +1. **Untyped string events.** Node/DOM let any string be an event; a typo never + fires and never errors. Ludic's core events are compiler-checked symbols; only + genuinely-dynamic *mod-defined* events use interned strings, and those must be + *registered* before use (§6), so an unknown name is a load-time error, not a + silent no-op. +2. **Listener leaks.** A listener bound to an entity that despawns must die with + it. Ludic ties listener lifetime to the scope it names (§10) — entity-scoped + listeners are swept by the same despawn walk that already runs. +3. **Nondeterministic dispatch order.** Hash-map iteration over listeners breaks + replay and save-load. Ludic dispatches in a **defined order** (priority, then + registration order) so a modded game stays deterministic — a hard constraint, + not a nicety, given Ludic's deterministic-by-design rng and byte-identical + goldens. +4. **Re-entrancy / mutate-during-dispatch.** A listener that emits another event, + or despawns the entity mid-dispatch, is the flecs "command during iteration" + hazard. Ludic defers structural changes made inside dispatch to the next sync + point (ties to LIFECYCLE LC5), and bounds re-entrant emit depth. +5. **Cancellation ambiguity.** If two listeners disagree, who wins? Ludic's rule + (§8): **one veto wins and is sticky**; later listeners see the cancelled state + and, unless they opted into `ignoreCancelled`, are skipped. + +--- + +## 4. The two layers, named + +To talk about this precisely the doc fixes two words: + +- A **hook** is the existing compile-time construct: an `@`-annotation or scene + clause that desugars to a direct call. Closed, zero-cost, author-only. Unchanged. +- An **event** is the new runtime construct: a named, ABI-visible moment that any + registered listener — in any language — may observe or (if cancellable) veto. + +An event is *fed by* a hook site. Promoting is additive: the hook keeps firing its +compile-time listeners as direct calls; the event is an extra, guarded emission at +the same site. **Author code never pays for the bus it doesn't expose, and mod +code never sees a hook it wasn't given.** + +--- + +## 5. EV0 — the event bus core + +The minimum viable layer: declare an event, emit it, and have both in-language and +foreign listeners receive it — with zero cost when a program declares no events. + +**Declaring a custom event.** A first-class declaration, mirroring `property`: + +```ludic +# doc-check: skip — sketch +event PlayerHurt { entity: int, amount: int } # a payload is a flat POD record +event WaveCleared { } # payloads may be empty +``` + +**Emitting.** A statement, mirroring `spawn`/`emit_signal`: + +```ludic +# doc-check: skip — sketch +emit PlayerHurt(entity: e, amount: dmg) +``` + +**Listening in-language** (author code, or a *native* Ludic mod) reuses the +annotation channel, mirroring `@OnSpawn`: + +```ludic +# doc-check: skip — sketch +@On(PlayerHurt) handler FlashRed { hud_flash(0xFF0000) } +``` + +**Listening across the ABI** (a JS/TS/Lua mod) goes through the stable C ABI: + +```c +/* the entire foreign-facing event ABI — four functions */ +uint32_t ludic_event_id(const char *name); /* intern → stable id */ +uint32_t ludic_on(uint32_t event, int32_t prio, ludic_cb cb, void *ctx); +void ludic_off(uint32_t token); +void ludic_emit(uint32_t event, void *payload); /* mod-raised events */ +/* cb: void (*)(void *ctx, void *payload) — payload is the flat POD record */ +``` + +**Lowering — the discipline holds.** An exposed event's emit site becomes: + +``` +; emit PlayerHurt(entity: e, amount: dmg) lowers to: + 1. build the payload record on the stack (POD, no heap) + 2. call each compile-time @On(PlayerHurt) handler directly ; zero-cost path + 3. if g_listeners[EV_PlayerHurt].count != 0: ; one branch + loop the runtime listener list, calling each cb(ctx, &payload) +``` + +- **A program that declares no `event` emits none of this.** A `has_events` flag + (exactly like `has_ecs`, `g_ondespawn`) gates the whole subsystem; a game with no + public events is byte-for-byte identical to today. This is the non-negotiable + invariant every phase preserves. +- The compile-time `@On` handlers are direct calls appended to the site — a native + listener costs the same as a lifecycle hook. Only *foreign* listeners walk the + runtime list, and an event with zero foreign listeners is a single count check. +- The runtime list is a **compiler-owned, fixed-capacity buffer** per event + (like the scene stack in SCENES E3) — not heap, not a hash map. `ludic_on` is an + index bump; `ludic_off` tombstones a slot. Deterministic order falls out of the + array (§7 of SCENES' "no dispatch tables" spirit, honestly bent — see §11). + +--- + +## 6. EV1 — promoting hooks to events (the taxonomy) + +Custom `event`s (EV0) cover author-raised signals. The **lifecycle** events — +spawn, despawn, attach, scene enter — should not require the author to hand-write +an `emit` in every `@OnSpawn`. Instead, a hook is promoted with one annotation: + +```ludic +# doc-check: skip — sketch +@Public @OnSpawn(Enemy) handler Init { Health.hp = Health.max } +# now firing this hook ALSO emits the public event model.Enemy.spawn +``` + +`@Public` on a lifecycle hook tells the compiler to add the guarded `bus_emit` at +that hook's existing site, with a **generated payload** built from what the hook +already binds (the entity id, the model/property fields, the `EndReason`). The +result is a uniform event namespace across the whole architecture — precisely the +"events for properties, models, scenes, layers, game" the request asks for: + +| Scope | Public event name | Payload | Fed by | +|---|---|---|---| +| program | `program.start` / `program.quit` | `{}` | `@OnStart` / `@OnQuit` | +| phase | `phase..pre` / `.post` | `{ frame }` | the phase scheduler | +| model | `model..spawn` / `.despawn` | `{ entity, reason? }` | `@OnSpawn` / `@OnDespawn` | +| property (structural) | `prop.

.attach` / `.detach` | `{ entity, }` | `@OnAttach` / `@OnDetach` | +| property (toggle) | `prop.

.enable` / `.disable` | `{ entity }` | `@OnEnable` / `@OnDisable` | +| property (value) | `prop.

.change` | `{ entity, field, old, new }` | `@OnChange` (LC2) | +| query (membership) | `query..enter` / `.exit` | `{ entity }` | `@OnStartMatch`/`@OnStopMatch` (LC3) | +| scene | `scene..enter` / `.exit` / `.push` / `.pop` | `{}` | `on enter`/`on exit`, `push`/`pop` | +| layer | `layer..show` / `.hide` | `{}` | layer toggle (SCENES E2) | + +- **Names are stable strings, ids are fast integers.** `model.Enemy.spawn` is the + public contract; the compiler assigns it a numeric id and registers the mapping + in a generated init. A mod compiled against the string binds by id at load — so + reordering declarations doesn't break a shipped mod (unlike raw + decl-order numbering, which is fine for the *closed* scene machine but wrong for + an *open* ABI). +- **Opt-in per hook, not global.** Only `@Public` hooks emit. A game exposes the + slice of its lifecycle it wants moddable and pays for nothing else. +- **`@Public` composes with everything.** A `@Public @OnDespawn(Enemy, reason: r)` + emits `model.Enemy.despawn` with the `EndReason` in the payload — mods can tell a + scene-exit death from a real one, the LC1 dividend extended to the mod boundary. + +--- + +## 7. EV2 — the world table (reflection for mods) + +The user's "game table": the stable, versioned surface a mod uses to **read and +write game state it never compiled against**. Minetest's `minetest.*`, Factorio's +`game.*`, but *generated* rather than hand-written. + +Because Ludic's data is packed POD in `@S_` arrays whose layout the compiler knows +exactly, the compiler can emit a **schema** (property id → field ids → offset + +type) plus a small accessor ABI over it: + +```c +/* the world table — reflection + mutation over the live ECS */ +uint32_t ludic_prop_id(const char *name); /* "Health" → id */ +uint32_t ludic_field_id(uint32_t prop, const char *name); /* ("Health","hp")→id */ +int64_t ludic_get(int32_t entity, uint32_t prop, uint32_t field); +void ludic_set(int32_t entity, uint32_t prop, uint32_t field, int64_t v); +bool ludic_has(int32_t entity, uint32_t prop); +int32_t ludic_spawn(uint32_t model); /* → entity */ +void ludic_despawn(int32_t entity); +uint32_t ludic_query(uint32_t *props, int n); /* → iterator handle */ +int32_t ludic_query_next(uint32_t iter); /* → entity or -1 */ +``` + +- **Generated from the compile-time schema, so it never drifts.** Add a field to + `Health`, recompile, and the schema updates; a mod that asked for + `("Health","hp")` still resolves. This is the entire Luanti bridge, minus the + hand-written 57k lines and minus the runtime-string re-interpretation. +- **`ludic_set` respects the semantic layer.** Writing a field routes through the + same path a native write does, so `@OnChange`/`prop.change` (LC2) fires for a + mod's write exactly as for the author's — mods can't silently corrupt invariants + that hooks are meant to maintain. +- **Mods can register content, within limits.** A mod may `ludic_on` existing + events and `ludic_emit` custom ones; **defining a new `property`/`model` is a + harder call** (it needs storage the closed `@S_` arrays didn't reserve). The + pragmatic first cut: models and properties are closed (author-defined), and mods + extend *behavior* (listeners, custom events, world reads/writes) but not the + *schema*. Opening the schema to mods is EV-late (§13, open decision 4). + +--- + +## 8. EV3 — cancellable and mutable events + +Observation alone (Node, Blender) can't stop a mod from turning damage off — the +modding headline is that a listener runs **before** the action and can veto or +rewrite it. Events split into two kinds, distinguished at declaration: + +- **notifications** — fired *after* the fact, observe-only, can't change anything. + Cheap, un-ordered-safe, the default. `model.Enemy.spawn` after the spawn. +- **decisions** — fired *before* the action, listeners may **cancel** it or + **mutate** the payload; the caller reads the verdict and branches. Marked + `cancellable` (Bukkit `Cancellable`, DOM `preventDefault`). + +```ludic +# doc-check: skip — sketch +event cancellable BeforeHurt { entity: int, amount: int } # a decision event + +# an author (or native mod) listener that halves fire damage and vetoes lethal hits: +@On(BeforeHurt, prio: 100) handler Armor { + BeforeHurt.amount = BeforeHurt.amount / 2 # mutate the payload… + if BeforeHurt.amount >= Health.hp { cancel } # …or veto the whole action +} + +# the fire site consults the verdict: +let dmg = emit? BeforeHurt(entity: e, amount: raw) # emit? returns the (maybe-mutated) payload +if !cancelled(dmg) { Health.hp -= dmg.amount } +``` + +Rules, chosen from the survey to remove the ambiguity footgun: + +- **Priority, then registration order.** `prio:` (default 0) orders listeners + high-to-low; ties break by registration order. Deterministic, replay-safe. +- **One veto wins and is sticky.** Once a listener calls `cancel`, the event is + cancelled for the rest of the chain; later listeners still run (so they can react + to the cancellation) unless declared `ignoreCancelled`, which skips them. +- **`stopPropagation` is separate from `cancel`.** DOM's distinction: `cancel` + vetoes the *action*, `halt` stops the *chain*. Keep both; they answer different + questions. +- **Passive listeners.** A listener declared `@On(E, passive)` promises not to + cancel or mutate — the dispatcher can call it after the decision is settled, and + a foreign listener that lies is a load-time capability error (§10), not a + mid-frame surprise. +- **Mutation is bounded to the payload.** A decision listener rewrites *the payload + record*, never arbitrary world state, so the caller's branch is the only place + the change takes effect — no spooky action at a distance. + +--- + +## 9. EV4 — the mod ABI & the language-agnostic bridge + +"Agnostic JS/TS/Lua or their own" resolves cleanly once EV0–EV3 exist, because the +contract is **the C ABI, not any one language.** Two mod tiers bind the *same* four +event functions (§5) and the same world table (§7): + +**Tier 1 — native mods (Ludic → shared library).** A mod is a `.ludic` file +compiled to a `.dylib`/`.so`/`.wasm` with `extern fn` bindings +([LANGUAGE.md §Functions & FFI](LANGUAGE.md)). It binds the ABI with **zero +marshalling** — payloads are the same POD records the host builds — and its `@On` +handlers can even be *inlined by the same compiler* if the mod is compiled with the +game. This is the tier Luanti can't offer and the one that makes Ludic's modding +fast: a compiled predicate where Luanti has a re-interpreted string. + +**Tier 2 — scripted mods (JS/TS/Lua/…).** The game embeds a scripting runtime +(QuickJS, Lua, Wasm) and registers a thin per-language shim that: + +1. calls `ludic_event_id("model.Enemy.spawn")` once at load to resolve the id; +2. calls `ludic_on(id, prio, trampoline, script_fn)` where `trampoline` is a + single C function that marshals the POD payload into the script runtime's values + and invokes `script_fn`; +3. exposes the world table (§7) as idiomatic bindings (`world.get(e, "Health", + "hp")` in Lua, `world.get(e, "Health", "hp")` in TS). + +The host writes **one trampoline per language**, not one per event — the schema +(§7) drives the marshalling generically. A Lua mod and a TS mod differ only in +their shim; the game core is identical. This is the structural win the Luanti gap +analysis pointed at: the bridge cost is *O(languages)*, not *O(events × languages)* +hand-written, because the schema is generated. + +``` + ┌─────────────── the stable C ABI ───────────────┐ + Ludic game core ──────┤ ludic_on / ludic_emit / ludic_get / ludic_set ├────── generated schema + (emits at hook sites) └────────────────────┬───────────────────────────┘ (prop→field→offset) + │ + ┌────────────────────────────────┼────────────────────────────────┐ + │ │ │ + Tier 1: native mod Tier 2: Lua shim Tier 2: JS/TS shim + (.dylib, zero marshalling) (one trampoline) (one trampoline) +``` + +--- + +## 10. EV5 — mod lifecycle, scoping & leak-proofing + +A mod is not eternal; it loads, enables, disables, and unloads, and its listeners +must vanish with it — the Node listener-leak footgun, solved structurally. + +- **Every registration returns a token** (`ludic_on → token`), and a mod's tokens + are tracked under its **mod handle**. Unloading a mod calls `ludic_off` on all of + them at once — a mod can't leak a listener past its own life. +- **Listeners may be scoped to a game object.** `ludic_on_entity(entity, …)` binds + a listener that the **existing despawn walk** sweeps when that entity dies — the + same `@L_despawn_all` loop LC1 already emits, extended to drop entity-scoped + listeners. An entity-scoped listener on a dead entity is impossible by + construction, not by discipline. +- **Scene-scoped listeners** ride SCENES E1: a listener registered while a scene is + active is dropped by that scene's synthesized `on exit`, alongside its owned + entities. Overlay push/pop (SCENES E3) scopes listeners to the overlay's life. +- **Survival is explicit** (Blender's `persistent` lesson): a listener is + program-, mod-, scene-, or entity-scoped, chosen at registration. There is no + implicit "lives forever" — the default is the narrowest scope that makes sense + (mod), and wider survival is opt-in and visible. +- **Capabilities gate what a scripted mod may touch** (§14, open decision 6). A mod + manifest declares the events and world-table properties it needs; the loader + grants ids only for those. A mod that never asked for `Health` cannot `ludic_set` + it — an untrusted-code boundary the closed lifecycle layer never needed but an + open mod ABI must have. + +--- + +## 11. EV6 — determinism, re-entrancy & the one honest compromise + +Ludic is deterministic by design — deterministic rng, byte-identical PPM goldens, +save-load of the whole World. A modding layer is the classic place that determinism +goes to die (hash-ordered listeners, mods reading wall-clock, emit storms). Holding +the line is a **feature**, and the same one that makes Factorio's modded multiplayer +lockstep-correct. + +- **Dispatch order is total and defined** — priority, then registration order, over + an *array*, never a hash map. Two mods loaded in the same order dispatch in the + same order on every machine. +- **Emit is synchronous by default, deferred on demand.** `emit E` runs listeners + now (push-at-the-site, Ludic's natural style — the LIFECYCLE footgun-1 fix). + Structural changes a listener requests (spawn/despawn/attach) **defer to the next + sync point** (LIFECYCLE LC5's `defer`), so mutate-during-dispatch is safe and + batched. Re-entrant `emit` inside a listener is allowed but **depth-bounded** (a + compile-time cap, trap on overflow) so an event cycle can't hang a frame. +- **Foreign listeners are the determinism boundary.** A native (Tier 1) listener is + as deterministic as any handler. A scripted (Tier 2) listener is only as + deterministic as the script — so the sandbox (§10) can **deny nondeterministic + capabilities** (wall-clock, unseeded rng, filesystem) to a mod that must stay in + a deterministic session (multiplayer, replays). Single-player mods can opt out. + +**The one honest compromise.** SCENES-DESIGN's principle is "no dispatch tables — +the active-scene path is a register read and a static branch." The runtime +listener list *is* a dispatch table, walked at runtime. This doc owns that: it is +the **deliberate, opt-in exception**, justified because open-world extension is the +entire point of a mod ABI and cannot be resolved at compile time by definition. +The mitigations keep it honest — it is (a) gated behind `has_events` so unused it +costs nothing, (b) an array not a hash map so it stays deterministic, (c) fed by +compile-time-checked names so the *closed* side stays typed, and (d) reached only +after the zero-cost direct calls to compile-time `@On` handlers. Ludic pays for a +dispatch table exactly when, and only when, a game chooses to be moddable. + +--- + +## 12. Lowering summary + +Everything above reduces to constructs Ludic already has or honestly-scoped +additions to them: + +| Construct | Lowers to | +|---|---| +| `event E { … }` | a generated payload record type + a reserved event id + a `has_events` bump | +| `emit E(…)` | build POD payload · direct-call each `@On(E)` handler · `if count: walk runtime list` | +| `@On(E)` handler | a compile-time listener: a direct call appended to `E`'s emit site (zero-cost) | +| `@Public @OnX(…)` | the existing hook's site, plus a guarded `bus_emit` of a payload built from the hook's bindings | +| public event name | a stable string interned to an integer id in a generated registry init | +| the runtime listener list | a compiler-owned fixed-capacity array per event; `ludic_on` = index bump, `ludic_off` = tombstone | +| the world table | a generated schema (prop→field→offset/type) + accessor ABI over the live `@S_` arrays | +| `cancellable` / `cancel` | a verdict field on the payload; the emit site branches on it | +| entity/scene-scoped listener | dropped by the existing despawn walk / synthesized `on exit` (LC1 / SCENES E1) | +| deferred structural change in a listener | LIFECYCLE LC5's `defer` queue, flushed at the sync point | + +No heap for native payloads, no hash map, no per-event hand-written bridge. The +active game path is unchanged unless it opts in; the opt-in cost is one branch per +exposed event plus the listeners a mod actually registers. + +--- + +## 13. Design principles distilled + +1. **One system, two sides.** A public event is a lifecycle hook seen from across + the ABI. Don't build a parallel event runtime; promote the sites you already + have. +2. **Opt-in or invisible.** No `event`, no `@Public` → byte-identical goldens. + `has_events` gates the world the way `has_ecs` gates the ECS. +3. **Closed stays typed; only the open edge is dynamic.** Core events are + compiler-checked symbols; string names exist only at the genuinely-runtime mod + boundary, and even there must be registered (no silent typos). +4. **Generated bridge, never hand-written.** The world table and payload marshalling + come from the compile-time schema, so they never drift and cost O(languages), + not O(events × languages). This is the Luanti dividend — spend it. +5. **Deterministic dispatch is a feature.** Array order, not hash order; deny + nondeterministic capabilities to mods in deterministic sessions. Modded replay + and modded multiplayer depend on it. +6. **Lifetime follows scope, explicitly.** Every listener names its scope + (program/mod/scene/entity); the existing teardown walks sweep it. No implicit + immortality, no leaks. +7. **One ABI, every language.** The C ABI is the contract. Native mods bind it with + zero marshalling; scripted mods bind it through one trampoline per language. + Ludic never blesses a single scripting language. +8. **Only the semantic layer, still.** Mods observe and decide; they do not get + ctor/dtor/move hooks Ludic doesn't have. POD in, POD out. + +--- + +## 14. Suggested implementation order + +Each phase is independently shippable and testable, matching how the repo phases +work (and how LIFECYCLE/SCENES sequence). + +- **EV0 — the bus core.** ✅ *Compile-time half shipped.* `event` / `emit` / `@On` + with the `g_events`-gated zero-cost lowering: an event compiles to a `@ev_` + function whose body is its listeners in declaration order (payload bound by + name as params), and `emit E(…)` is a direct call. Verified byte-identical for + event-free programs, self-hosted to the C-free fixpoint. Still open in EV0: the + foreign C ABI (`ludic_on`/`ludic_emit`) and its runtime listener array, so a + mod in another language can join the same dispatch. Implementation notes: AST + `N_EVENT`/`S_EMIT`; `parse_event` + `@On` annotation + `emit` statement (guarded + by an identifier-lookahead so a bare `emit(...)` call still parses); registries + `g_events`/`g_onlisten` (emit_core); `emit_event_fns` (emit_game); `emit_emit` + (emit_stmt). [`examples/events.ludic`](examples/events.ludic) is a `test.sh` check. +- **EV1 — `@Public` hook promotion.** ✅ *All scopes shipped.* `@Public` on a + lifecycle hook fires a public event at that hook's site (payload: entity, plus + `EndReason` for despawn); `find_event(name)` doubles as the "is this hook + public?" gate. Covered: program (`@OnStart`/`@OnQuit` → `program_start`/`_quit`), + models (`@OnSpawn`/`@OnDespawn`), properties + (`@OnAttach`/`@OnDetach`/`@OnEnable`/`@OnDisable` → `prop_

_…`). Scenes and + layers use a `public` block modifier instead of an annotation: + `scene__enter`/`_exit` at the synthesized scene functions, and + `layer__show`/`_hide` at the layer-toggle site. Building layer events also + delivered **SCENES E2 layer toggle**: `enable/disable layer L` flips an `@LE_` + flag that gates that layer's handlers, emitted only for toggled layers so + untouched scene programs stay byte-identical. +- **EV2 / EV2b — the world table.** ✅ *Read/write/scan/identify/create shipped.* + The generated reflection ABI (§7), dispatching a runtime prop/model id to the + right `@S_`/`@H_`/`@L_kind` storage: read/write (`prop_id`/`field_id`/`get`/`set`/ + `has`), scan/identify (`entity_count`/`kind`/`model_id`), and create + (`spawn(model_id)`, which reuses the compiler's own spawn lowering — defaults, + `@OnSpawn`, and the spawn event). `get`/`set` address each field by its real + struct offset (constant struct GEP), correct for `int`/`fixed`/`byte`/`ptr` + fields and mixed layouts alike. Emitted only for an ECS program that declares + events (gated on `has_ecs() && g_events`), so event-free games are byte-identical. + A `ludic_query_next(prop, from)` cursor iterates live entities that have a + property. The world table is complete: read, write, scan, identify, create, + iterate. +- **EV3 — cancellable events.** ✅ *Shipped.* `event cancellable E`, the `cancel` + verb, and `emit E(…)` as an expression yielding the veto flag; the flag is a + trailing field of `%Ev_`, so a foreign listener vetoes by setting it. Priority + ordering and `ignoreCancelled`/`halt` (§8) remain open. The modding headline — + observation becomes control. +- **EV4 — the scripting bridge.** One reference shim (Lua *or* QuickJS) over the + ABI, proving the O(languages) claim end to end. +- **EV5 — mod lifecycle & scoping.** ✅ *Shipped.* A parallel owner array `@evO_` + (-1 = program-scoped, ≥0 = owning entity); `ludic_on_` and + `ludic_on_entity_` register with the right owner; `ludic_off_(token)` + tombstones a slot to null and dispatch skips null slots; `ludic_sweep_entity`, + called from `emit_despawn` when the program has events, nulls every listener a + despawning entity owned. Scene-scoped listeners (drop on `on exit`) remain the + same shape applied at the scene teardown — a follow-on. +- **EV6 — determinism & re-entrancy.** ✅ *Depth bound shipped.* `@ev_depth` + increments on each `@ev_` entry and decrements on exit; past `EV_DEPTH_CAP` + (32) a dispatch returns immediately (a cancellable event returns "not + cancelled"), so an event cycle can't hang. Dispatch order was already + deterministic (array, registration order). Still design: deferred structural + changes at a sync point (LC5) and capability gating for deterministic sessions. +- **EV7 — schema-opening & networking.** ✅ *Schema-opening shipped.* A mod defines + a new component at runtime: `ludic_register_prop(name, nfields)` allocates flat + `[MAX_ENT × nfields × i32]` storage + a has-flag array (capacity 32 dynamic + components) and returns a prop id past the compile-time range; + `ludic_attach_dyn`/`ludic_detach_dyn` toggle presence; `get`/`set`/`has`/`prop_id` + fall through to the dynamic registry for a prop id ≥ the compile-time component + count. Per-entity storage is isolated (`world_dyn.c`). This is the first genuinely + *dynamic* `@S_` storage — a deliberate departure from the closed dense arrays, so + it lives entirely behind the ABI (the game's own components stay static and + byte-identical). Dynamic components use integer fields addressed by index (no + field-name schema). *Still design:* the local/remote event split (Roblox's + lesson) waits on Ludic having a networking substrate. + +EV0–EV1 deliver "the whole architecture emits public events." EV2–EV3 are where a +mod becomes able to *change the game*. EV4 proves the language-agnostic claim. +EV5–EV7 are hardening and reach. + +--- + +## 15. Open decisions + +1. **`emit` verb & payload identity.** Is `emit E(…)` the only spelling, or does a + `signal`-style per-property declaration (Godot) read better for the common case? + Are payloads always fresh POD records, or can an emit borrow an existing property + in place (cheaper, but aliases live storage)? +2. **`@Public` granularity.** Per-hook (proposed), per-model (`@Public model + Enemy`), or a program-level "expose all lifecycle" switch for prototyping? Does + `@Public` belong on the hook or on the `model`/`property`/`scene` it concerns? +3. **Name scheme stability.** Dotted strings (`model.Enemy.spawn`) interned to ids — + confirmed. Open: are ids stable across recompiles of the *same* source (needed + for save-compatibility of a listener table), and how does a renamed model + migrate a shipped mod? +4. **Schema opening (EV2/EV7).** Do mods stay behavior-only (listeners + custom + events + world reads/writes over author-defined schema), or can a mod define new + `property`/`model`? The latter needs dynamic `@S_` storage — a real departure + from the closed dense arrays (`LUDIC_MAX_ENT 1024`). Probably EV7. +5. **Cancellation surface.** Keep `cancel` (veto action) and `halt` (stop chain) + distinct (DOM), or collapse to one? Is `ignoreCancelled` per-listener or a + priority-band convention? +6. **Sandbox model.** Capability manifest per mod (proposed) — at what granularity + (per event? per property? per world-table verb)? What is denied by default in a + deterministic session, and who declares a session deterministic? +7. **Re-entrancy bound.** Compile-time constant emit-depth cap (trap on overflow), + or a runtime budget? What is the default depth, and is an event cycle a warning + or an error? +8. **Scripting runtime, in or out of scope.** Does Ludic *ship* an embedded runtime + (QuickJS/Lua) as a blessed default, or only the ABI and reference shims, leaving + the runtime to the game? (Bias: ship the ABI + one reference shim; bless no + language.) + +--- + +*Companion to [LIFECYCLE-DESIGN.md](LIFECYCLE-DESIGN.md) (the hook sites this layer +promotes) and [SCENES-DESIGN.md](SCENES-DESIGN.md) (scene/layer/overlay events and +scoped-listener teardown). Grounded in the Luanti gap analysis (`LUANTI-ROADMAP.md`): +the generated bridge is how Ludic avoids the 57k-line C++↔Lua tax. Supersedes +nothing until the compiler work in §12 lands.* diff --git a/LANGUAGE.md b/LANGUAGE.md index 76398912..d2362d9f 100644 --- a/LANGUAGE.md +++ b/LANGUAGE.md @@ -319,22 +319,34 @@ boot ── @OnStart ─▶ spawn ── @OnAttach(P), @OnSpawn(M) ─▶ … - **`@OnSpawn(Model)` / `@OnDespawn(Model)`** — an *entity*. Both bind the model's properties by name; `@OnSpawn` is a constructor, `@OnDespawn` a destructor. Despawn doesn't statically know an entity's model, so despawn hooks compile to - functions dispatched on the entity's kind. -- **`@OnAttach(Property)`** — a *property*, fired each time that property is - attached to an entity (once its fields are seeded), with the property bound by - name. + functions dispatched on the entity's kind. `@OnDespawn` may take an optional + **reason**: `@OnDespawn(Enemy, reason: r)` binds `r` to an `EndReason` the + compiler passes at each teardown site — `EndReason.Despawned` for an in-world + `despawn`, `EndReason.Quit` when the program exits. At shutdown every still-live + entity's `@OnDespawn` fires with `Quit` (no silent deaths), so teardown can + branch on *why* it is ending — save on `Quit`, drop loot otherwise. +- **`@OnAttach(Property)` / `@OnDetach(Property)`** — a *property* attached to or + removed from an entity, with the property bound by name. `@OnAttach` fires once + the fields are seeded (a per-property constructor); `@OnDetach` fires when the + property is removed, *before* its has-flag clears, so the body can read the + outgoing value (a per-property destructor). They pair with the `attach` / + `detach` statements below. ```ludic # doc-check: skip — lifecycle hooks @OnStart handler Boot { seed(1) } @OnSpawn(Enemy) handler Init { Health.hp = Health.max } # constructor @OnDespawn(Enemy) handler Clean { drop_loot(Health.hp) } # destructor +@OnDespawn(Enemy, reason: r) handler End { # destructor that knows why + match r { EndReason.Quit => save() ; _ => drop_loot(Health.hp) } +} @OnAttach(Sprite) handler Load { Sprite.id = image_load("goblin.png") } +@OnDetach(Sprite) handler Free { image_drop(Sprite.id) } # paired teardown @OnQuit handler Save { save() } # once, at shutdown ``` -**Enable / disable.** `enable` and `disable` are statements that flip something on -or off without destroying it. There are three scopes: +**Enable / disable — pause, don't destroy.** `enable` and `disable` are statements +that flip something on or off without destroying it. There are three scopes: - **`disable P on e` / `enable P on e`** — one *property* on one entity. Disabling clears the entity's has-flag, so queries stop matching it, but the field values @@ -349,20 +361,42 @@ or off without destroying it. There are three scopes: Each toggle is one global flag flip (or one has-flag store), so nothing is copied or freed — enable/disable is cheap and fully reversible. +**Attach / detach — add, don't just resume.** Where `enable`/`disable` *pause* a +property that already belongs to an entity, `attach`/`detach` change what the +entity *has*: + +- **`attach P on e` / `attach P on e { field: v, … }`** — add property `P` to a + live entity, seeding its fields from the defaults plus any overrides, and fire + `@OnAttach(P)`. It fires only on a real transition: attaching a property the + entity already has is a no-op. +- **`detach P on e`** — remove `P`, firing `@OnDetach(P)` (which still reads the + outgoing value) before the has-flag clears. Also a no-op if `P` is absent. + +The distinction mirrors DOTS's enableable components vs structural add/remove, or +Bevy's disable vs `Remove`: `disable` is a reversible pause that keeps the data; +`detach` is a structural removal (a following `attach` re-seeds fresh fields). + ```ludic -# doc-check: skip — enable/disable +# doc-check: skip — enable/disable + attach/detach @OnDisable(Shield) handler Down { play("shield_break.wav") } @OnEnable(Shield) handler Up { play("shield_up.wav") } +@OnAttach(Shield) handler Grab { play("shield_get.wav") } +@OnDetach(Shield) handler Drop { play("shield_drop.wav") } -disable Shield on self() # this entity loses its shield; data kept for later -enable Shield on self() # shield back, amount unchanged -disable Gravity # a whole model sits out every query -disable AiThink # a handler stops running each phase +disable Shield on self() # pause: this entity loses its shield; data kept +enable Shield on self() # resume: shield back, amount unchanged +attach Shield on self() { amount: 3 } # structural: give it a fresh shield +detach Shield on self() # structural: take the shield away entirely +disable Gravity # a whole model sits out every query +disable AiThink # a handler stops running each phase ``` -See [`examples/toggle.ludic`](examples/toggle.ludic) for all three scopes in one -frame. Still to come: **`@OnDetach`** (the paired hook for a property leaving, -needing the same per-property runtime dispatch as despawn). +See [`examples/toggle.ludic`](examples/toggle.ludic) for the three enable/disable +scopes, [`examples/detach.ludic`](examples/detach.ludic) for the structural +attach/detach pair, and [`examples/reason.ludic`](examples/reason.ludic) for +reason-carrying teardown. The rest of the lifecycle roadmap (value-change hooks, +query-membership edges, keyed effects) is in +[LIFECYCLE-DESIGN.md](LIFECYCLE-DESIGN.md). **`@Handles` — the handlers a program drives.** Written in front of the `program`, `@Handles(Move)` names the handlers it uses. It parses and reads as @@ -371,8 +405,71 @@ documentation; every declared handler still runs (registration is implicit). See [`examples/annotations.ludic`](examples/annotations.ludic) (queries, computed fields, one hook) and [`examples/lifecycle.ludic`](examples/lifecycle.ludic) (the whole timeline), plus [`examples/toggle.ludic`](examples/toggle.ludic) -(enable/disable). Still to come: **scene** hooks (`@OnEnter`/`@OnExit`), which -wait on `scene` support landing in the compiler. +(enable/disable). Scenes and their `on enter` / `on exit` lifecycle blocks are +implemented — see "Scenes & layers" below. (An annotation spelling, +`@OnEnter(Scene)` / `@OnExit(Scene)`, is a designed but not-yet-built convenience +— see [SCENES-DESIGN.md](SCENES-DESIGN.md); today the hooks are written as `on +enter { … }` inside the `scene`.) + +## Events & modding (`event`, `emit`, `@On`) + +Where lifecycle hooks are the *closed, in-language* reactions the game author +compiles in, **events are the open, runtime surface a game exposes to mods** — +code loaded after compilation, in any language with a C ABI. The two share their +fire sites; an event is a hook seen from across the ABI. A program that declares +no `event` is compiled byte-for-byte as before. + +- **`event E { field: T = default, … }`** declares a public event carrying a flat + POD payload (fields may be empty). **`@On(E) handler Name { … }`** registers an + in-language listener whose body reads the payload fields by name. **`emit + E(field: v, …)`** fires it — every listener runs, in declaration order, as a + direct call. It all desugars to a `@ev_` function; there is no interpreter. + +```ludic +# doc-check: skip — illustrative +event Hurt { entity: int, amount: int } +@On(Hurt) handler Flash { hud_flash(amount) } # payload bound by name +emit Hurt(entity: e, amount: 5) # fires every listener +``` + +- **The foreign ABI.** Each event also generates `int ludic_on_(void (*cb)(Ev*))` + and a payload struct `%Ev_`, so a mod in C / Lua / JS (over its FFI) registers + a callback and is dispatched to right after the native listeners — the closed and + open halves, one dispatch. Native listeners cost a direct call; foreign ones one + indirect call over a fixed-capacity array (registration order = dispatch order, + so a modded game stays deterministic). See [`examples/mod_host.ludic`](examples/mod_host.ludic) + and the C mod in [`tests/mod_c/mod.c`](tests/mod_c/mod.c). + +- **`@Public` promotes a lifecycle hook to an event, across the whole + architecture.** The game's own lifecycle becomes moddable with no hand-written + `emit`, at every scope: + - **program** — `@Public @OnStart`/`@OnQuit` → `program_start` / `program_quit` + (the top-level mod entry/exit points). See [`examples/program_events.ludic`](examples/program_events.ludic). + - **models** — `@Public @OnSpawn(Enemy)`/`@OnDespawn(Enemy)` → + `model_Enemy_spawn` / `model_Enemy_despawn` (entity, + `EndReason` on despawn). + See [`examples/promote.ludic`](examples/promote.ludic). + - **properties** — `@Public @OnAttach/@OnDetach/@OnEnable/@OnDisable(P)` → + `prop_

_attach` / `_detach` / `_enable` / `_disable`. See [`examples/prop_events.ludic`](examples/prop_events.ludic). + - **scenes** — a `public` scene → `scene__enter` / `scene__exit`. See [`examples/scene_events.ludic`](examples/scene_events.ludic). + - **layers** — a `public` layer, with `enable layer L` / `disable layer L` + flipping the layer on and off (its handlers stop while hidden) → + `layer__show` / `layer__hide`. See [`examples/layer_events.ludic`](examples/layer_events.ludic). + +- **`cancellable` events are decisions, not just notifications.** A listener on a + `cancellable` event may `cancel` it (a foreign listener sets the payload's + trailing `cancelled` flag); `emit E(…)` used as an *expression* yields that flag, + so the caller applies the action only when it wasn't vetoed — the Bukkit/DOM + `preventDefault` shape. See [`examples/cancel.ludic`](examples/cancel.ludic). + +```ludic +# doc-check: skip — illustrative +event cancellable BeforeHurt { amount: int } +@On(BeforeHurt) handler Armor { if amount > 10 { cancel } } +if emit BeforeHurt(amount: dmg) == 0 { hp = hp - dmg } # apply only if not vetoed +``` + +The full modding roadmap — the world-table reflection ABI, scoped/leak-proof +listeners, and the sandbox — is in [EVENTS-DESIGN.md](EVENTS-DESIGN.md). ## Records (`property`), arrays and slices @@ -478,7 +575,7 @@ another `.ludic` file (see `examples/lib/`). `if/else` (the `else` is optional) · `while cond { }` · `for i in a .. b { }` (numeric range) · `for (…) in query […] { }` · `break` · `continue` · `return` · `spawn` · `despawn` · `enable` / `disable` (a property `on e`, a model, or a -handler) · `match` · `machine`. +handler) · `attach` / `detach` (a property `on e`) · `match` · `machine`. ### Bindings: `let`, `var`, `const` @@ -712,8 +809,6 @@ Units on quantities (`9.8 m/s^2`), `with` record-update expressions, a bytecode VM + hot-reload, and the live agent bridge — these appear in the design docs but are future work. -- **`scene` / `layer` / `on enter` / `on exit`** — the state-machine-over-scenes - sugar is documented above but not parsed by the self-hosted compiler yet. - **`reads` / `writes` clauses** — parsed and reserved on the handler node, but no analysis pass consumes them. - **`[T; N]` fixed arrays** — documented above, but `ptype` parses only `[]T` @@ -730,13 +825,13 @@ self-hosting; their lowerings are in ## Scenes & layers -> ⚠️ **Not yet implemented in the current (self-hosted) compiler.** `scene`, -> `layer`, and the `on enter` / `on exit` hooks are a design target: the -> compiler has no `scene` declaration and [`examples/scenes.ludic`](examples/scenes.ludic) -> does not compile today. Games -> that need mutually-exclusive states use a mode register (`reg`/`set_reg`) with a -> `machine`, as `examples/chronorift` does. This section describes the intended -> syntax for when scene support lands. +> **Implemented (S0).** `scene`, `layer`, and the `on enter` / `on exit` hooks +> compile; [`examples/scenes.ludic`](examples/scenes.ludic) runs and is checked +> by `test.sh`. A scene lowers to a `machine` the compiler writes for you: one +> implicit active-scene register, states numbered by declaration order, and +> `become` as two direct calls plus a store. Richer scene features (the overlay +> stack, scene-owned entities, scene-local state, transition parameters) are +> designed in [SCENES-DESIGN.md](SCENES-DESIGN.md) and not built yet. A program is usually several mutually-exclusive states — a title screen, the overworld, a battle — and the usual way to write that is a mode register @@ -764,7 +859,8 @@ scene Overworld { ``` - Exactly **one scene is active**. The one marked `start` runs first (or the - first declared, if none is marked). + first declared, if none is marked); its `on enter` fires once at boot, right + after the `Start` phase. - A scene's handlers only run while it is active. Handlers declared outside any scene are global and run every frame regardless. - **Layers group handlers and declaration order is draw order**: within a phase, @@ -776,8 +872,14 @@ scene Overworld { becomes `Name`, and its `on enter` runs. Inside a layer handler the compiler knows which scene is leaving, so a transition costs two direct calls and a store — there is no dispatch table. +- **The active scene is snapshotted per phase.** A `become` mid-phase runs its + `on exit`/`on enter` immediately, but the switch of *which layers dispatch* + takes effect at the next phase boundary — so exactly one scene's layers run in + any single phase, and a `become` in `Update` is visible to that same frame's + `Render`. -`examples/scenes.ludic` sketches the ordering rules (it does not compile yet). +[`examples/scenes.ludic`](examples/scenes.ludic) is a runnable, tested example +of these rules. ## Queries in a handler signature diff --git a/LIFECYCLE-DESIGN.md b/LIFECYCLE-DESIGN.md new file mode 100644 index 00000000..21e920d9 --- /dev/null +++ b/LIFECYCLE-DESIGN.md @@ -0,0 +1,348 @@ +# Lifecycle events, expanded — a design doc + +> **Status: LC0–LC1 shipped; LC2–LC6 are design.** The structural attach/detach +> pair and `@OnDetach` (§4, LC0), and reason-carrying `@OnDespawn` (§5, LC1), are +> implemented and tested ([`examples/detach.ludic`](examples/detach.ludic), +> [`examples/reason.ludic`](examples/reason.ludic), `test.sh` checks). The +> extensions LC2–LC6 are research-informed proposals, not built. This document +> distills a survey of lifecycle models across seven systems (§3) into a roadmap +> for Ludic. §13 lists the open decisions. + +--- + +## 1. Thesis + +A game/ECS usually models lifetime as **create → destroy on a timeline**. A survey +of how other systems handle it — Unity (MonoBehaviour + DOTS), Unreal, Bevy, +flecs, EnTT, Godot, and non-game paradigms (actor model, declarative UI, RAII) — +shows that mature lifecycle designs model something richer than birth and death: + +- **a reaction to a *reason*** — teardown that knows *why* it is ending (Unreal + `EndPlay(reason)`, Erlang `terminate(Reason)`, Akka `preRestart(reason, msg)`); +- **paired setup/teardown *keyed on dependencies*** — an update is teardown-then- + setup on a value change (React `useEffect`, Compose `DisposableEffect`); +- **a deterministic consequence of *scope / ownership*** — guaranteed, ordered, + single-shot teardown (C++/Rust RAII, DI scoped lifetimes); +- **an edge on *query membership*** — fire when data starts/stops matching a + composite condition (DOTS `OnStartRunning`, flecs `Monitor`). + +Ludic's model is a good base: lifecycle hooks are `@`-annotations on handlers that +**desugar to ordinary code**, firing at fixed timeline moments, keeping the data +plain. This doc extends that base along the four axes above **without breaking the +desugars-to-code discipline** — every proposal lowers to plain branches and calls, +no hidden runtime. + +**One structural advantage worth stating up front.** flecs and EnTT each carry +*two* lifecycle layers: a **memory** layer (ctor/dtor/move/copy — because C++ +objects must be constructed and relocated as archetypes repack) and a **semantic** +layer (on_add/on_set/on_remove). Ludic's components are POD in packed `@S_` +arrays; there is nothing to construct, destruct, or move-relocate. **Ludic needs +only the semantic layer** — half the machinery, none of the "component isn't +movable" footguns. Keep it that way. + +--- + +## 2. What Ludic has today + +Seven hooks, each an annotation that desugars to a handler body at a timeline +moment ([LANGUAGE.md §Annotations](LANGUAGE.md)): + +``` +boot ─ @OnStart ─▶ spawn ─ @OnAttach(P), @OnSpawn(M) ─▶ … ─ @OnDetach(P)/@OnDespawn(M) ─▶ quit ─ @OnQuit +``` + +The lifecycle reads cleanest as a table of **paired setup/teardown** across five +scopes. Every cell is now filled — LC0 closed the one hole (`@OnDetach`): + +| Scope | Setup | Teardown | Driven by | +|---|---|---|---| +| program | `@OnStart` | `@OnQuit` | boot / quit | +| entity | `@OnSpawn(M)` | `@OnDespawn(M)` | `spawn` / `despawn` | +| property (structural) | `@OnAttach(P)` | `@OnDetach(P)` ✅ | `attach` / `detach` | +| property (toggle) | `@OnEnable(P)` | `@OnDisable(P)` | `enable` / `disable` | +| scene | `on enter` | `on exit` | `become` | + +Two things this table already gets right, which the survey flags as the frequent +mistakes to avoid: + +- **The toggle pair is distinct from the structural pair.** Unity's clearest + lesson is separating the *repeatable* enable/disable cycle (pooling, pausing, + data kept) from the *once* create/destroy (data gone). Ludic has both, as + distinct verbs: `disable` pauses and keeps data; `detach` structurally removes + (a later `attach` re-seeds). This is exactly DOTS enableable-components vs + structural add/remove, and Bevy `disabled` vs `Remove`. +- **Hooks are typed annotations, not magic-named methods.** MonoBehaviour matches + `Awake`/`Update` by *string name* via reflection — a typo silently never runs. + Ludic's `@OnSpawn(Enemy)` is a checked reference; a wrong name is a compile + error. Preserve this. + +What's missing is everything past "what happened": **why** it happened, **which +values changed**, **when composite conditions begin/end to hold**, and +**dependency-keyed** setup/teardown. That is the roadmap. + +--- + +## 3. Research digest — the one idea to steal from each + +| System | The transferable idea | +|---|---| +| **Unity MonoBehaviour** | Two-phase init with a global barrier (all `Awake` before any `Start`); repeatable enable-pair vs once create-pair. | +| **Unity DOTS** | *Data-driven activation*: `RequireForUpdate` + `OnStartRunning`/`OnStopRunning` — a system edge-triggers when its query starts/stops matching. Enableable components = cheap "logically off." | +| **Unreal** | *Reason-carrying teardown*: `EndPlay(EEndPlayReason)` — one teardown, branch on `Destroyed`/`LevelTransition`/`Quit`/…; forces enumerating every death path (no silent deaths). Provenance-tagged construction. | +| **Bevy** | Full structural event set Add/Insert/**Replace**/Remove/Despawn with strict order; **Replace exposes the old value before drop**. Hooks (type-level, singular, invariant) vs observers (plural, reactive). Declarative `before`/`after`/`chain` ordering. State `OnEnter`/`OnExit`/`OnTransition`. | +| **flecs** | `Monitor` observers fire on *composite query membership* start/stop. Events fire on **real transitions**, not every API call. Deferred-by-default with explicit sync points. | +| **EnTT** | `patch` as the *explicit mutation channel* that fires `on_update` (solves "raw writes are invisible"). Opt-in signals — zero cost when unused. | +| **Godot** | Tree membership *is* the lifecycle driver; enter top-down, **`_ready` bottom-up** (dependencies initialized first); `queue_free()` deferred safe-delete; `process_mode` pause inherited down the tree. | +| **Actor model (OTP/Akka)** | Lifecycle driven by *failure + supervision*: reason-carrying `terminate`, **restart as a state distinct from create/destroy** (stable identity, reset transient state), supervision trees, `code_change` = live state migration. | +| **Declarative UI (React/SwiftUI/Compose)** | *Paired setup/teardown keyed on a dependency list* — cleanup co-located with setup so it can't leak; an update **is** keyed teardown-then-setup; lifetime follows *identity*. | +| **RAII / Rust `Drop` / DI scopes** | *Scope = lifetime*: deterministic, reverse-construction-order, single-shot, no-resurrection teardown, guaranteed even on early exit; lifetime-mismatch checking (no long-lived thing holding a short-lived handle). | + +Two recurring **footguns** the whole survey warns against, to design *out* of Ludic: + +1. **Silent order-dependent reactivity.** Bevy's removal buffers are cleared at + end-of-frame, so a detector that runs before the mutator *misses removals + entirely*. If Ludic adds change/removal reactivity, make it either push-based + (fire at the mutation site — Ludic's natural style) or loudly order-checked. +2. **Invisible in-place writes.** flecs `on_set` and EnTT `on_update` don't fire + on a raw pointer write — you must call `modified()`/`patch`. Ludic can dodge + this entirely (see LC2): the compiler *sees* every write site. + +--- + +## 4. LC0 — structural attach/detach + `@OnDetach` ✅ *shipped* + +The one missing cell in §2's table. `attach P on e { overrides }` adds a property +to a **live** entity (seeding fields, firing `@OnAttach`); `detach P on e` removes +it (firing `@OnDetach`, which reads the outgoing value, before the has-flag +clears). Both fire only on a **real transition** (flecs/Bevy idempotent-add +semantics): re-attaching a present property or detaching an absent one is a no-op. + +Lowering: `attach` guards on the has-flag and, when absent, reuses the existing +`emit_init_component` (seed + `@OnAttach`); `detach` guards on presence, clears the +flag, and fires `@OnDetach` with the property bound by name — the same binding the +`@OnDisable` path already uses. No new runtime; POD data stays in `@S_` storage. +See [`examples/detach.ludic`](examples/detach.ludic). + +--- + +## 5. LC1 — reason-carrying teardown ✅ *shipped (`@OnDespawn`)* + +The highest-conviction idea in the survey: it appears independently in Unreal +(`EndPlay`), Erlang (`terminate`), and Akka (`preRestart`), and Bevy has an open +issue asking for it. **Teardown should know *why*.** A destructor frequently needs +to branch — save on `Quit` but not on a scene swap, skip network cleanup when the +whole program is exiting. + +`@OnDespawn` gains an optional bound **reason**: + +```ludic +# doc-check: skip +# EndReason { Despawned, SceneExit, Quit } — the compiler owns this enum + +@OnDespawn(Enemy, reason: r) handler Clean { + match r { + EndReason.Quit => {} # app closing — don't bother dropping loot + _ => drop_loot(Health.hp) + } +} +``` + +**What shipped.** The lowering is exactly the cheap desugars-to-code shape the +survey promises. The despawn hook compiles to `@on_despawn_(i32 %e, i32 +%reason)`; when the hook writes `reason: r`, `r` is bound as an int local reading +`%reason`. Each teardown *site* passes a constant `EndReason`: + +- `despawn e` passes `Despawned` (0) — an in-world death. +- **program shutdown** passes `Quit` (2): a generated `@L_despawn_all(reason)` + walks the live set at `done:` (before `@OnQuit`, matching the timeline) and + fires every survivor's `@OnDespawn`. This makes **"no silent deaths"** real — + an entity that outlives the run still gets its destructor, and can branch on + `Quit` to skip work that only matters mid-game. Emitted only when the program + has `@OnDespawn` hooks, so despawn-free programs are byte-for-byte unchanged. +- `SceneExit` (1) is reserved: a scene tearing down its owned entities + (SCENES-DESIGN E1) will pass it once scene-owned entities land. + +`EndReason` is compiler-owned (resolved in `enum_ordinal`), so `EndReason.Quit` +works without a user declaration; a user enum of the same name still shadows it. +Backward-compatible: the `reason:` binding is optional, and `@OnDespawn` without +it is unchanged. `@OnDetach` and scene `on exit` do **not** yet take reasons +(§13.1). See [`examples/reason.ludic`](examples/reason.ludic). + +--- + +## 6. LC2 — value-change hooks `@OnChange(P)` *(a compile-time win)* + +Every reactive ECS wants "fire when a component's value changes" (flecs `on_set`, +EnTT `on_update`, Bevy `Changed`), and every one hits the same footgun: a raw +in-place write is invisible, so you must route mutations through a special channel +(`modified()`, `patch`) or you miss changes. + +**Ludic can sidestep the footgun because it is an AOT compiler that sees every +write site.** A field store `Health.hp = …` is a statement the compiler lowers; if +`Health` carries an `@OnChange`, the compiler can emit the hook call *right after +the store*. No dirty bits, no end-of-frame flush, no missed-write class of bugs — +the thing that is a runtime hazard everywhere else is resolved at compile time. + +```ludic +# doc-check: skip +@OnChange(Health) handler Bar { hud_set_health(Health.hp) } # after any write to a Health field +``` + +Open question (§7): fire on *every* write (Bevy's `DerefMut` semantics — simple, +may over-fire) or guard with a value compare (fire only on actual change — needs +the old value, à la Bevy `Replace`). The compiler has the old value in hand at the +store site, so the value-compare form is feasible and is the more useful default. + +--- + +## 7. LC3 — query-membership edges `@OnStartMatch` / `@OnStopMatch` + +DOTS `OnStartRunning`/`OnStopRunning` and flecs `Monitor` fire when an entity +**starts or stops matching a composite query** — not a single component, but a +whole condition (`{Position, Velocity, moving}`). This is strictly more expressive +than per-property `@OnAttach`, which can't see "the entity now has *both* and is +alive." It's the natural ECS form of enter/exit. + +```ludic +# doc-check: skip +@OnStartMatch(these: [Position, Velocity{dx != 0 or dy != 0}], on: Actor) +handler BeginMoving { play("footstep_loop.wav") } + +@OnStopMatch(these: [Position, Velocity{dx != 0 or dy != 0}], on: Actor) +handler StopMoving { stop("footstep_loop.wav") } +``` + +Cost: unlike LC1/LC2 this needs runtime state — a per-entity shadow bit per +monitored query ("did it match last tick?"), checked once per frame, edge- +triggering the hook on a change. flecs does this by evaluating the query against +the entity's previous and current archetype. Ludic would keep a `@M_` bit +array parallel to `@H_`. Medium cost; a genuinely differentiated feature. + +--- + +## 8. LC4 — keyed effects (paired setup/teardown on a dependency list) + +The declarative-UI headline, and the biggest reach. React `useEffect`, Compose +`DisposableEffect`, and SwiftUI `.task` all express: *while this thing exists (or +while key K holds), set up a resource; when it leaves or K changes, tear it down* +— with cleanup **co-located** with setup so it can't leak, and an *update* defined +as keyed teardown-then-setup. This collapses create/update/destroy into one +primitive. + +```ludic +# doc-check: skip — sketch +@Effect(on: Enemy, keys: [Sprite.id]) handler Body { + let tex = image_load(Sprite.id) + dispose { image_drop(tex) } # runs on despawn OR when Sprite.id changes +} +``` + +Semantics: the setup runs on spawn (and whenever a listed key changes, after the +previous `dispose`), and `dispose` runs on despawn (and before each keyed re-run). +It unifies `@OnAttach`/`@OnDetach`/`@OnChange` into one leak-proof unit. Lowering +needs somewhere to stash the effect's captured teardown state and last key values +per entity — a per-effect side table, re-checked in a phase. Design only; the +syntax and storage model are open. This is where Ludic could feel genuinely modern +relative to every ECS surveyed (none of which have it). + +--- + +## 9. LC5 — deferred structural changes with commit points + +DOTS `EntityCommandBuffer`, flecs `defer_begin/end`, and Godot `queue_free()` all +make structural change **deferred with an explicit commit point**, so mutating +while iterating is safe and batched. Ludic's `spawn`/`despawn` are immediate today, +but *already* iteration-safe by a different route — matching is lazy per entity id +([LANGUAGE.md](LANGUAGE.md) "Matching is lazy, not snapshotted"), so despawning the +current entity is defined. A `defer { … }` block (or `despawn e at LateUpdate`) +that queues structural changes to a phase boundary would add batching and a single +predictable commit point, and is the prerequisite for safe parallel handlers +(the `reads`/`writes` scheduling in SCENES-DESIGN). Design only; lower priority +than LC1–LC3 because the immediate path is already safe. + +--- + +## 10. LC6 — supervision, restart-as-a-state, live migration + +The furthest-out cluster, from the actor model and OTP: lifecycle driven by +**failure**, not just create/destroy. Three ideas, all tied to Ludic's eventual +hot-reload / bytecode-VM roadmap rather than the near term: + +- **Restart as a distinct state** between create and destroy — preserve an + entity's identity, reset its transient components, re-run setup (respawn, + hot-reload). Akka's "stable external ref, replaced internal state." +- **Supervision / failure escalation** — a subsystem owner declares a policy for + child faults (restart one / restart the group / escalate to reload the scene) + instead of defensive inline checks. Ludic has no failure model yet, so this + waits on one. +- **Live state migration** (`code_change`) — a hook that transforms an entity's + persistent state across a code/schema version, so hot-reload evolves data + instead of destroying it. Directly relevant to a self-hosting language. + +--- + +## 11. Design principles distilled from the footguns + +1. **No silent deaths.** Enumerate every teardown reason (LC1). If the compiler + must name the reason at each site, it can't forget a path. +2. **Fire on real transitions, not API calls.** Idempotent add/remove — LC0 + already does this; keep it for every future hook. +3. **Keep "paused" and "gone" distinct.** `disable`/`enable` (data kept) vs + `detach`/`attach` (structural) — already true; don't let a future feature blur + them. +4. **Prefer compile-time resolution to runtime tracking.** LC2 turns the + universal "invisible write" footgun into a compile-time hook emission because + Ludic sees write sites. Reach for this wherever a runtime dirty-bit is the + obvious-but-worse option. +5. **If reactivity is order-dependent, make it loud.** Never silently drop events + at a frame boundary (Bevy's removal-buffer trap). Ludic's push-at-the-site + style avoids this by default. +6. **Deterministic teardown order.** When a scope tears down many things (a scene + unloading its owned entities — SCENES-DESIGN E1), define the order (reverse of + creation, RAII-style) rather than leaving it unspecified. +7. **Only the semantic layer.** POD components mean no ctor/dtor/move hooks. Don't + grow a memory-lifecycle layer Ludic doesn't need. + +--- + +## 12. Suggested implementation order + +- **LC0 — attach/detach + `@OnDetach`.** ✅ Done. Closes the structural pair. +- **LC1 — reason-carrying teardown.** ✅ Done for `@OnDespawn` (an `i32 %reason` + param + a constant at each site, plus a shutdown despawn-all for `Quit`). + `@OnDetach` / `on exit` reasons remain open (§13.1). +- **LC2 — `@OnChange(P)`.** Compile-time hook emission at write sites — a + Ludic-specific win over every ECS's invisible-write footgun. **Recommended next.** +- **LC3 — `@OnStartMatch`/`@OnStopMatch`.** First feature needing runtime shadow + state; the expressive ECS enter/exit. +- **LC4 — keyed effects.** The modern, leak-proof unification. Design first. +- **LC5 — deferred structural changes.** Batching + parallel-safety; the immediate + path is already iteration-safe, so lower urgency. +- **LC6 — supervision / restart / migration.** Waits on a failure model and the + hot-reload roadmap. + +--- + +## 13. Open decisions + +1. **Reason enum (LC1):** *resolved for `@OnDespawn`* — ships `Despawned`, + `SceneExit`, `Quit` as a compiler-owned `EndReason`, passed as an optional + `reason:` binding (not a separate annotation). Still open: `SceneExit` has no + firing site until scene-owned entities (SCENES-DESIGN E1); should `@OnDetach` + and scene `on exit` take reasons too, and if so with which reason values? +2. **`@OnChange` (LC2):** fire on every write (simple, over-fires) or only on an + actual value change (needs the old value at the store site)? Per-field or + whole-property granularity? +3. **Membership edges (LC3):** where do the shadow bits live, and is the check + per-frame or event-driven off attach/detach/spawn? Cost budget. +4. **Keyed effects (LC4):** syntax (`@Effect` annotation vs an `effect { … dispose + { … } }` statement), and where per-entity teardown/key state is stored. +5. **Ordering:** none of this addresses intra-phase handler ordering (Bevy + `before`/`after`, flecs `DependsOn`). Worth a separate proposal; declarative + relational ordering over priority integers, per the survey. + +--- + +*Companion to [LANGUAGE.md §Annotations](LANGUAGE.md) and +[SCENES-DESIGN.md](SCENES-DESIGN.md) (scene-owned entities and reasons intersect at +LC1/LC5). Supersedes nothing until the compiler work in §12 lands.* diff --git a/MOBILE-DESIGN.md b/MOBILE-DESIGN.md new file mode 100644 index 00000000..79064b39 --- /dev/null +++ b/MOBILE-DESIGN.md @@ -0,0 +1,338 @@ +# iOS & Android — a design doc + +> **Status: all design, nothing shipped.** Ludic builds windowed on macOS +> (`runtime/native/cocoa.ll`) and has a documented — but currently un-reimplemented +> — wasm32 web target. iOS and Android are not buildable today, and the +> cross-compile plumbing that would target them died with the C driver. This doc +> lays out the whole path so we can decide the shape before building any of it. The +> headline decision (§7): render on the **GPU via `extern fn` FFI**, not the CPU +> framebuffer. §11 lists the open decisions. + +--- + +## 1. Where we are + +A Ludic program compiles to LLVM IR, then clang assembles and links it. The +platform story has **two independent axes**, and it's essential not to conflate +them: + +| Axis | What it is | State today | +|---|---|---| +| **Target** (triple + toolchain) | how IR becomes a runnable binary for an OS/arch | barely plumbed — no `--target`, no emitted `target triple`, host-only | +| **Platform runtime** (window/input/present) | one file implementing the 5-function window protocol | well-factored — `cocoa.ll` is ~328 lines, swappable | + +**What exists:** + +- The window seam is exactly five functions — `win_open` / `win_poll` / + `win_present` / `win_running` / `win_close` — declared by the compiler + ([emit_head.ludic:58](selfhost/emit_head.ludic:58)) and lowered as intrinsics + ([emit_intrin2.ludic:39](selfhost/emit_intrin2.ludic:39)). The runtime calls them + through `rt_*` wrappers ([core.ludic:48](runtime/native/core.ludic:48), + [:103](runtime/native/core.ludic:103), [:217](runtime/native/core.ludic:217)). + `COMPILING.md` states the intent plainly: a new platform is "another `.ll` file + with the same five entry points and no compiler change." +- **`extern fn` FFI is real and live** — `extern fn c_hypot(a: fixed, b: fixed) -> + fixed = "hypot_fx"` ([LANGUAGE.md:565](LANGUAGE.md:565)), with a full pipeline: + parse ([parse_game.ludic:236](selfhost/parse_game.ludic:236)) → call lowering to a + direct `call @` ([emit_expr.ludic:168](selfhost/emit_expr.ludic:168)) → + `declare` emission ([emit_head.ludic:105](selfhost/emit_head.ludic:105)). Working + examples: [examples/net_echo.ludic:12](examples/net_echo.ludic:12), + [examples/lib/arena.ludic:14](examples/lib/arena.ludic:14). This is the single + most important fact in this document — see §7. + +**What's missing (all of it must be built):** + +| Gap | Why mobile needs it | +|---|---| +| `--target ` flag + emitted `target triple`/`datalayout` | iOS = `aarch64-apple-ios`, Android = `aarch64-linux-android`; both are cross-compiles | +| per-target `size_t` width (i32/i64) | already a known wasm trap; every allocation sizing depends on it | +| **OS-owned frame loop** (`ludic_boot`/`ludic_frame`/`ludic_alive`/`ludic_teardown`) | iOS (CADisplayLink) and Android (Choreographer) own the loop — you cannot `while(alive)` | +| per-platform window shim + touch input | UIKit/`CAMetalLayer`, Android `Surface`/NDK; input is touch, not a keycode | +| SDK sysroot + packaging + signing | `.app` bundle / `.apk`, not a bare executable | + +The frame-loop gap is shared with the web target — `tools/ludic-web/run.mjs` +already expects `ludic_boot`/`ludic_frame`, but the self-hosted emitter only +produces a monolithic `@main` ([emit_game.ludic:685](selfhost/emit_game.ludic:685)). +So the wasm path is half-broken for the same reason mobile can't exist yet. + +--- + +## 2. Design principles + +1. **Two axes, kept separate.** "Add a platform" = a cross-compile *target* plus a + platform *runtime*. Muddling them is why this looks bigger than it is. Most of + the compiler work (§4, §5) is target plumbing that serves web, iOS, and Android + at once; the per-OS work (§6) is genuinely small by design. +2. **The OS owns the loop — so we must too.** Mobile, like the browser, forbids an + inline frame loop. Rather than special-case mobile, adopt the frame-driven model + *everywhere* the OS demands it, from one emitter change. This is the keystone. +3. **The GPU is an ABI to call, not a program to compile.** `extern fn` already + binds C libraries; bind GL ES / Metal the same way. No IR-per-API (the `cocoa.ll` + route — 328 lines for *five* functions), no per-symbol intrinsics. The roadmap + reaches this conclusion independently ([LUANTI-ROADMAP.md:1083](LUANTI-ROADMAP.md:1083), + [:1375](LUANTI-ROADMAP.md:1375)). +4. **The 2D stack stays byte-identical.** The framebuffer graphics + (`rt_fb` + all `rt_*`/`image`/`truetype`/`ui` primitives) keep working + unchanged. GPU rendering is *additive*: 2D composites as one texture on top of + GPU 3D. Nothing above the window seam is rewritten. + +--- + +## 3. Core model + +Everything below reduces to plumbing one new flag through the compiler and swapping +two runtime files per OS. The mental model: + +``` +ludicc app.ludic --target aarch64-apple-ios -o app + │ + ├─ emit_head: target triple / datalayout / size_t width (§4) + ├─ emit_game: ludic_boot/frame/alive/teardown not @main (§5) + ├─ link: runtime/ios/uikit.ll + gfx3d.ldylib (§6, §7) + └─ package: .app bundle + codesign (§8) +``` + +The game source and the entire ECS/graphics/UI stack compile **unchanged** for +every target. Only the head declarations, the entry-point shape, the linked +platform file, and the packaging step vary. + +--- + +## 4. Extension M1 — the target axis: `--target`, triple, `size_t` + +Today [main.ludic:66](selfhost/main.ludic:66) parses `--windowed`/`--headless`/ +`--emit-llvm`/… and nothing selects an arch; the IR carries no `target triple`, so +native inherits clang's host default and the only explicit triple in the tree is +`wasm32-unknown-unknown` ([runtime/web/wasm.ll:23](runtime/web/wasm.ll:23)). + +Proposal: a `--target ` flag that drives three things. + +``` +ludicc app.ludic --target aarch64-apple-ios -o app +ludicc app.ludic --target aarch64-apple-ios-simulator -o app # x86_64 host → arm64 sim varies +ludicc app.ludic --target aarch64-linux-android -o libapp.so +``` + +- **Emit the triple + datalayout.** `emit_header` + ([emit_head.ludic:37](selfhost/emit_head.ludic:37)) gains a `target triple = …` + / `target datalayout = …` line, chosen from a small table keyed on `--target`. + Absent the flag, emit nothing (host default) — keeps existing native builds + byte-identical. +- **Per-target `size_t` width.** wasm32 already needs `i32` sizes; the same helper + discipline (`ll_size_t`/`ll_widen`/`ll_narrow`, per the web-backend notes) applies + to any 32-bit target. iOS/Android arm64 are LP64 like macOS, so `i64` — but the + flag must *select* the width, not assume the host's. +- **Toolchain construction.** The linker command + ([main.ludic:130](selfhost/main.ludic:130)) becomes target-conditional: an SDK + sysroot (`-isysroot`/`--sysroot`), the platform `.ll`, and target-specific link + flags (§8). `$LUDIC_CC` still overrides; add `$LUDIC_SYSROOT_` for the + SDK path so CI and local machines can differ. + +This axis is **shared with reviving wasm** — do it once, three targets benefit. + +--- + +## 5. Extension M2 — the OS-owned frame loop (the keystone) + +A native build emits `@main` with the frame loop inline — an `rt_init`, then a +`loop:`/`done:` block calling `rt_poll`/`rt_running` +([emit_game.ludic:685](selfhost/emit_game.ludic:685)). **iOS and Android cannot run +this.** UIKit calls back into your code once per display refresh (CADisplayLink); +Android's Choreographer does the same; the browser's `requestAnimationFrame` already +does. In all three the OS owns the loop and calls *you*. + +Proposal: emit four exported functions instead of an inline-loop `@main`, exactly +as `COMPILING.md` already describes and `run.mjs` already expects: + +``` +ludic_boot() → rt_init (once) +ludic_frame() → rt_poll · systems · rt_present (per OS callback) +ludic_alive() → i1 → rt_running (OS asks: keep going?) +ludic_teardown() → rt_shutdown (once) +``` + +- **`@main` becomes the composed default, not the only shape.** For host desktop + and headless, the compiler synthesizes an `@main` that *calls* the four in an + inline loop — so native/headless output is unchanged in behavior. For + OS-owned-loop targets (`--target` is wasm/ios/android, or a new + `--loop=external` mode), emit only the four exports and no driving `@main`. +- **One emitter change, three targets fixed.** This simultaneously un-breaks the + web target (whose runner already calls these) and unlocks both mobile OSes. It is + the highest-leverage change in this doc. +- **State stays where it is.** The four functions close over the same globals + `rt_init`/`rt_poll`/`rt_running`/`rt_shutdown` already touch + ([core.ludic:48](runtime/native/core.ludic:48)); no new runtime state, no heap. + +--- + +## 6. Extension M3 — the per-OS window shim + touch input + +Each OS gets one platform file implementing the five-function seam, modeled on +`cocoa.ll` but rewritten for its UI toolkit. This is the part the codebase is +explicitly built for. + +- **iOS — `runtime/ios/uikit.ll` (or a thin `.m` shim).** `win_open` creates a + `UIWindow` + a `UIViewController` whose view is a `CAMetalLayer`/`MTKView`; + `win_present` presents the current drawable; the loop is driven by M2's + `ludic_frame` from a `CADisplayLink`, so `win_poll`/`win_running` adapt to the + callback model rather than a spin. Hand-written IR against `objc_msgSend` is + possible (it's how `cocoa.ll` works) but a small compiled `.m` linked in is more + maintainable for UIKit's larger surface — an open decision (§11). +- **Android — `runtime/android/ndk.ll` + a Kotlin/Java `Activity` host.** The + native code is a `.so` loaded by an `Activity`; the window is an + `ANativeWindow`/`Surface` obtained via `GameActivity`/NDK, GPU via EGL + GL ES. + Frames are driven by Choreographer through JNI into `ludic_frame`. +- **Touch input changes the input seam.** `win_poll()` returns a single `int` + keycode today ([emit_intrin2.ludic:41](selfhost/emit_intrin2.ludic:41), + [core.ludic:217](runtime/native/core.ludic:217)) — insufficient for touch, which + needs `(x, y, phase, id)`. Options: (a) a parallel `win_poll_touch() -> ptr` + draining an event queue, or (b) widen the input model to a small event struct for + all platforms. This is the one place mobile forces a decision above the window + seam. Proposed: add touch as a **separate** seam so keyboard platforms stay + untouched and byte-identical. + +Everything above the seam — framebuffer, PNG sprites, TrueType, retained UI — is +portable Ludic and compiles unchanged. + +--- + +## 7. Extension M4 — GPU rendering via `extern fn` (the headline) + +Today **all** drawing writes into one CPU framebuffer: `rt_fb`, a +`words(320*240)` buffer of `0x00RRGGBB` i32 pixels +([core.ludic:23](runtime/native/core.ludic:23)), written by every primitive +(`rt_clear`/`rt_fill_rect`/glyphs/`rt_blend_px`/`tt_blit`/UI) and handed whole to +`win_present`. `cocoa.ll` blits it through CoreGraphics — +`CGBitmapContextCreate`→`CGImage`→`CGContextDrawImage` inside `@ludic_drawRect` +([cocoa.ll:94](runtime/native/cocoa.ll:94)). There is no GPU context anywhere. + +Because **`extern fn` already exists**, binding the GPU is ordinary runtime code — +no new language feature, no new intrinsic: + +```ludic +# doc-check: skip — runtime/native/gfx3d.ludic, illustrative +extern fn gl_gen_textures(n: int, out: ptr) -> void = "glGenTextures" +extern fn gl_tex_image_2d(t: int, w: int, h: int, px: ptr) -> void = "gl_tex_image_2d" +extern fn gl_draw_elements(mode: int, count: int, ty: int, idx: ptr) -> void = "glDrawElements" +``` + +Two phases, additive: + +1. **Framebuffer-as-texture (drop-in).** Keep the entire 2D stack. `rt_present` + ([core.ludic:103](runtime/native/core.ludic:103)) uploads `rt_fb` as one texture + and draws a full-screen quad. The `win_present(fb,w,h)` signature is unchanged; + only the pixel-delivery core of the platform file differs (texture upload instead + of CoreGraphics blit). This is the minimum viable GPU path and gets mobile on + screen with zero changes above the seam. +2. **True GPU 3D (additive).** Geometry goes straight to GL/Metal via `gfx3d.ludic` + `extern fn` calls; the CPU framebuffer is reused only for the 2D UI overlay, + composited as a texture on top. New GPU-draw entry points live in `gfx3d.ludic` + as `extern fn`s — the five-function window protocol does **not** widen. + +Language-level cost is narrow and already scoped by the roadmap: + +- **`f32`** (roadmap gate G-04) for vertex/matrix data — the *only* hard language + dependency ([LUANTI-ROADMAP.md:1087](LUANTI-ROADMAP.md:1087)). +- Optional vector operator overloading for `v3f`/`m4` ergonomics (G-29, + [:1107](LUANTI-ROADMAP.md:1107)) — a "nicer, not necessary." + +The roadmap's own decision is explicit: FFI over IR-per-API, because "`cocoa.ll` +is 327 lines for *five* window functions — OpenGL has hundreds of entry points" +([LUANTI-ROADMAP.md:1375](LUANTI-ROADMAP.md:1375)). + +--- + +## 8. Extension M5 — packaging, SDKs, and signing + +The current driver is one `clang` call ([main.ludic:130](selfhost/main.ludic:130)) +producing a bare binary. Mobile output is a bundle, and this is where most +real-world friction lives — it is deliberately the *last* phase. + +- **iOS.** Cross-compile with the iPhoneOS SDK sysroot → an executable, wrap in an + `App.app` bundle with an `Info.plist`, `codesign` with a development identity, + install to simulator/device. Simulator is the cheap inner loop + (`aarch64-apple-ios-simulator`); device needs a provisioning profile. ludicc + should emit the binary and shell a packaging step (or emit a manifest a small + script consumes), not learn Xcode's project format. +- **Android.** Cross-compile with the NDK → `libapp.so`, drop it into a minimal + Gradle/Kotlin `Activity` shell, build the `.apk`/`.aab`, sign with a keystore. + The `Activity` is fixed boilerplate that ships in the repo (`runtime/android/`), + parameterized by app name/id. +- **Keep the compiler out of it.** Both flows are "produce native code + assemble a + package around it." The compiler's job ends at the object/`.so`; a `--package` + step or an external `build-mobile.sh` owns the bundle. This mirrors how ludicc + already drives clang without becoming a build system. + +--- + +## 9. Lowering / build summary + +| Construct | Reduces to | +|---|---| +| `--target ` (M1) | a triple/datalayout line in `emit_header` + a `size_t`-width choice + target-conditional link command | +| OS-owned loop (M2) | emit `ludic_boot`/`ludic_frame`/`ludic_alive`/`ludic_teardown`; host/headless get a synthesized `@main` calling them | +| window shim (M3) | one `.ll`/shim per OS implementing the same five `win_*` intrinsics; no compiler change | +| touch input (M3) | a **new, separate** input seam (`win_poll_touch`), so keycode platforms stay byte-identical | +| framebuffer→texture (M4.1) | `rt_present` uploads `rt_fb` as a texture + full-screen quad; `win_present` signature unchanged | +| GPU 3D (M4.2) | `extern fn` calls in `runtime/native/gfx3d.ludic` — data in `prog`, zero compiler edits, needs only `f32` | +| packaging (M5) | binary/`.so` unchanged; an external `--package`/script builds `.app`/`.apk` and signs | + +No new allocator, no new dispatch, no per-API intrinsics. The game and the 2D +graphics stack compile identically for every target; only head declarations, the +entry-point shape, the linked platform file, and packaging vary. + +--- + +## 10. Suggested implementation phases + +Each is independently shippable and testable, matching how the repo phases work. + +- **M0 — target axis** (M1) + **revive the OS-owned loop** (M2). *Do these first + and together* — they're the shared compiler plumbing, they un-break the existing + web target (proving the frame-loop split against `run.mjs`/`test.sh` before any + mobile SDK is involved), and they need no mobile toolchain. This is the floor. +- **M1 — iOS simulator, framebuffer-as-texture** (M3 iOS shim + M4.1). First pixels + on a phone, GL/Metal binding proven, no signing/device friction yet. +- **M2 — iOS device** (M5 iOS packaging + signing). +- **M3 — Android** (M3 Android shim + M4.1 + M5 Android packaging), reusing every + M0 change. +- **M4 — `f32` + GPU 3D** (M4.2), gated on roadmap G-04; the additive 3D path over + `gfx3d.ludic`. +- **M5 (later) — touch-input model** hardening (M3), gesture/multitouch, once a real + app exercises it. + +M0 is the honest prerequisite and the highest-leverage work — it serves three +targets and revives a fourth. M1 is the first thing anyone can *see*. + +--- + +## 11. Open decisions + +1. **Loop selection:** does `--target ios/android/wasm` *imply* the external loop, + or is there an explicit `--loop=external` flag? (Proposed: implied by target, + with the flag as an override for headless testing.) +2. **iOS shim language:** hand-written `.ll` against `objc_msgSend` like `cocoa.ll`, + or a small compiled `.m`? (Proposed: `.m` — UIKit's surface is too large for + maintainable IR, and Metal setup is verbose.) +3. **Touch seam shape:** a separate `win_poll_touch` queue, or a unified event + struct replacing the keycode `win_poll` on all platforms? (Proposed: separate, + to keep desktop/web byte-identical.) +4. **GPU API baseline:** GL ES 3.0 everywhere (Android native, iOS via ANGLE/Metal + translation), or Metal on iOS + GL ES on Android from day one? (Proposed: GL ES + 3.0 first for a single codepath; Metal later.) +5. **Android host:** ship a fixed Kotlin `GameActivity` in `runtime/android/`, or + generate it per app? (Proposed: fixed boilerplate, parameterized by name/id.) +6. **Packaging home:** a `--package` step inside ludicc, or an external + `build-mobile.sh`? (Proposed: external script; keep the compiler out of bundle + formats.) +7. **`size_t` for arm64:** confirm iOS/Android arm64 are LP64 (`i64`) in the width + table, and that the `ll_size_t` discipline covers every new size-taking call. +8. **Simulator arch:** how to handle `aarch64-apple-ios-simulator` vs. x86_64 sim on + Intel hosts in the target table. + +--- + +*Companion to [COMPILING.md](COMPILING.md) (§ toolchain, the wasm frame-loop +split), [LANGUAGE.md §"Functions & FFI"](LANGUAGE.md:560) (`extern fn`), and +[LUANTI-ROADMAP.md](LUANTI-ROADMAP.md) (G-04 `f32`, G-28 GPU FFI, G-29 3D math). +Supersedes nothing until the M0 compiler work lands.* diff --git a/NETWORKING-DESIGN.md b/NETWORKING-DESIGN.md new file mode 100644 index 00000000..e04060e9 --- /dev/null +++ b/NETWORKING-DESIGN.md @@ -0,0 +1,505 @@ +# Networking, from primitives up — a design doc + +> **Status: N0–N6 all shipped.** The whole stack is implemented and self-hosted, +> and — unlike the original N0/N1 which linked C hosts — every phase now runs as a +> self-contained **pure-Ludic** program (no `.c`, no foreign host): a built-in +> loopback transport fills the seam, and each `examples/net_*.ludic` drives and +> asserts itself from its own `entry`. See `test.sh` (checks `net_echo` … `net_demo`) +> and `examples/net_demo.ludic` for a full RPC→authority→replicate→reconcile loop. +> clang remains only as the LLVM-IR assembler/linker (no C is compiled), the floor +> Rust and Swift stand on. +> +> _Historical note:_ **N0 + N1 shipped first; N2–N6 were design.** Two phases landed as `test.sh` +> checks. **N0 (transport seam):** `extern fn` now lowers end to end — a direct +> `@` call plus a `declare`, no networking logic in the compiler — so the whole +> transport is two externs (`net_send`/`net_poll`) a host fills. Proven by +> [`examples/net_echo.ludic`](examples/net_echo.ludic) sending four bytes through +> the loopback host in [`tests/net_c/loopback.c`](tests/net_c/loopback.c) and +> polling them back (`4 10 20 30 42`). **N1 (snapshot-to-buffer):** +> `world_size()`/`world_save(buf)`/`world_load(buf, len)` generalize `save()`/`load()` +> from a file to a caller-owned memory buffer — the same block layout via `memcpy` — +> so the whole ECS world round-trips through bytes. Proven by +> [`examples/net_snapshot.ludic`](examples/net_snapshot.ludic) + +> [`tests/net_c/snapshot_mod.c`](tests/net_c/snapshot_mod.c) (snapshot, mutate, +> restore → `50 7 50`). Both are byte-identical when unused, so the offline dividend +> (§8) holds. This is a companion to +> [EVENTS-DESIGN.md](EVENTS-DESIGN.md), [LIFECYCLE-DESIGN.md](LIFECYCLE-DESIGN.md), +> and [SCENES-DESIGN.md](SCENES-DESIGN.md). Where the events work made Ludic +> *moddable*, this proposes making it *networked* — and it deliberately does **not** +> ship a multiplayer framework. Ludic is a language: it exposes the low-level +> mechanism (transport seam, world snapshot, generated serializers, ownership, a +> drivable sim) and a thin high-level *declarative* layer that lowers onto that +> mechanism, and it leaves the netcode *policy* (authority, prediction, relevancy) +> to the developer or a library. §14 lists the open decisions. + +--- + +## 1. Thesis + +Every networking model dies on one of two problems: **determinism** or **state +serialization**. Ludic already solves both, almost by accident. + +- **Determinism** is designed in — seeded RNG, `fixed` (Q16.16) instead of floats, + byte-identical golden renders, and (as of [EVENTS-DESIGN EV6](EVENTS-DESIGN.md)) + bounded, array-ordered event dispatch. A modded, event-driven Ludic game still + replays identically. That is exactly the property lockstep multiplayer needs, and + the reason Factorio's heavily-modded multiplayer stays in sync. +- **State serialization** already exists — `save()`/`load()` snapshot the *entire* + ECS World to a byte buffer ([`selfhost/emit_save.ludic`](selfhost/emit_save.ludic)), + and the world-table schema built for [EVENTS-DESIGN EV2](EVENTS-DESIGN.md) (prop → + field → offset) is exactly the descriptor you serialize against. + +So networking is not a new subsystem. It is a **fourth lens on the event + world +layer** — the same layer modding used. And it obeys the same two-altitude rule as +everything else in Ludic: + +> **Low-level is freedom; high-level is developer experience; they are the same +> feature at two altitudes.** `@Queries` lowers to a query loop, `scene` lowers to a +> machine, `@Public @OnSpawn` lowers to `emit`. Networking's high-level annotations +> lower to a transport seam, generated serializers, and a drivable sim — and the +> primitives stay exposed underneath for anyone the sugar doesn't fit. + +The developer writes **one simulation**, declares *what* replicates, *who* owns +each entity, and *where* each handler runs — and never branches on `is_server()` +in ordinary code. The compiler lowers the declarations; a networking *runtime* +(the seam-filler, like `rt_*` for windowing) supplies the transport and the tick. + +--- + +## 2. Two altitudes, one system + +| Altitude | Who writes it | Surface | +|---|---|---| +| **High-level (DX)** | the developer, declaratively | `@Sync` (field/property/model), `@Owned`, `@Server`/`@Predicted`, directional remote events | +| **Lowering** | the compiler | per-model serializers, role-guarded dispatch, remote-event send/recv, ownership storage | +| **Runtime seam** | a networking library (blessed or custom) | binds the socket, sets `role`, drives the replication tick | +| **Low-level (freedom)** | power users, when the sugar doesn't fit | `net_send`/`net_poll`, `world_save`/`world_load`, generated `serialize_*`/`apply_*`, `owner()`, the drivable sim | + +Everyone lives at the top row for normal games; the bottom row stays open for +someone building something no framework could express. The split that keeps this a +*language* and not a *framework*: **annotations and their lowering are the language; +the replication driver and the transport are a library.** It is precisely the +events story — `@On`/`emit` are the language, the *modding system* is library code — +applied again. + +--- + +## 3. Research digest — the one idea to steal from each + +| System | The transferable idea | +|---|---| +| **Quake / QuakeWorld** | The founding pattern: **client-side prediction + server reconciliation**, and delta-compressed snapshots against the last acked baseline. Predict locally, correct from the authority. | +| **Source (Valve)** | **Entity interpolation** (render remote entities slightly in the past, smoothly) paired with **lag compensation** (the server rewinds to the shooter's view for hit detection). Interpolation and rewind are two halves of one clock discipline. | +| **Unity NGO** (GameObject) | `NetworkVariable` with **read/write permissions** + `OnValueChanged`; ownership as `OwnerClientId`. Also the **anti-pattern to avoid**: `IsServer`/`IsOwner` branching sprinkled through gameplay code. | +| **Unity Netcode for Entities** (ghosts) | The model Ludic is closest to: **replication is a compile-time property of components and fields** — `[GhostField]`, `[GhostComponent]`, `GhostOwner`, and `Predicted`/`Interpolated` ghost modes — with serializers *generated* from the ECS schema. | +| **Mirror / FishNet** | The community-ergonomic take: `SyncVar` with change **hooks**, and clean **directional RPCs** — `Command` (client→server) / `ClientRpc` (server→clients). | +| **GGPO / rollback** | Save state → predict → on misprediction **restore and re-simulate**. Its one hard requirement is *cheap, complete state snapshot/restore* — which Ludic already has in `save()`/`load()`. | +| **Factorio** | Fully **deterministic lockstep** for heavy mod multiplayer: only *inputs* cross the wire; the whole sim is reproduced. Proof that determinism (EV6) is the enabler, not a nicety. | +| **Photon Quantum** | A shipping product that *is* deterministic-ECS-rollback. Validates the exact combination — ECS + determinism + rollback — Ludic is already positioned for. | +| **Roblox** | The **local/remote split** (`BindableEvent` vs `RemoteEvent`), server-authority by default, and engine-replicated properties: "some state just replicates, and RPCs are directional events." | + +Six **footguns** the survey warns against, to design *out* from the start: + +1. **Role branching everywhere.** `if (IsServer)` scattered through gameplay is the + NGO readability tax. Fix: **role is a handler annotation** (`@Server`/`@Predicted`), + never a runtime branch in ordinary code. +2. **Float nondeterminism.** Lockstep breaks the instant the networked sim touches + `f32` across platforms. Fix: the determinism contract (§11) — the networked sim + stays `int`/`fixed`. +3. **Replicating pointers / heap refs.** A `ptr` field holds a machine-local + address; it cannot cross the wire. Fix: **the compiler rejects `@Sync` on a + non-POD-scalar field** — a checked guarantee, not a convention. +4. **Sending everything every tick.** Fix: `@Sync` is **opt-in at the field level** + (only marked fields replicate), plus change-driven dirty tracking (`@OnChange`, + [LIFECYCLE LC2](LIFECYCLE-DESIGN.md)) so an unchanged field costs nothing. +5. **Hidden authority.** Magic "the server decides" behavior is unclear and + unauditable. Fix: **explicit** `@Server`/`@Predicted`; unmarked code runs + everywhere by definition. +6. **Schema-less snapshots.** A raw state blob with no version desyncs silently on a + version mismatch. Fix: the **world-table schema is the versioned descriptor** the + serializer is generated against. + +--- + +## 4. What Ludic already has + +The substrate is unusually complete for an engine that has never networked: + +- **A deterministic simulation** — seeded RNG, `fixed` math, ordered ECS iteration, + EV6-bounded event dispatch. Lockstep's precondition. +- **World snapshot/restore** — `save()`/`load()` serialize the whole World + ([emit_save.ludic](selfhost/emit_save.ludic)); today to a file, trivially + retargetable to a memory buffer. Rollback's precondition. +- **A reflective world table** — `ludic_get`/`set`/`has`/`query`/`register_prop` + and the prop→field→offset schema (EV2/EV2b). The apply-and-serialize substrate. +- **An event bus with a foreign ABI and POD payloads** (EV0). Directional remote + events (RPCs) are one flag on this. +- **The `rt_*` seam pattern** — the compiler already emits calls to + `rt_init`/`rt_poll`/`rt_present` that a runtime library fills. Networking's + transport and role registers plug into the identical seam. + +What is missing is small and named: a transport seam, snapshot-to-*buffer*, +generated per-field serializers, ownership storage, role-guarded dispatch, and a +developer-drivable loop. Each is a phase in §13. + +--- + +## 5. The low-level primitives (the freedom layer) + +Unopinionated, composable, host- or developer-owned. A power user builds any model +directly from these; the high-level layer (§6) is sugar over them. + +| Primitive | Signature (sketch) | Enables | +|---|---|---| +| **Transport seam** | `extern fn net_send(peer: int, buf: ptr, len: int)` · `extern fn net_poll(buf: ptr, cap: int) -> int` | any model; host binds UDP (native) or WebRTC/WebSocket (wasm), or a loopback for tests | +| **World snapshot ↔ buffer** | `world_save(buf: ptr) -> int` · `world_load(buf: ptr, len: int)` | rollback, replication, join/resync — generalizes `save()`/`load()` off the filesystem | +| **Generated serializers** | `serialize_(e: entity, buf: ptr) -> int` · `apply_(e: entity, buf: ptr, len: int)` | per-model, touch only the `@Sync` fields; emitted from the schema | +| **Ownership** | `owner(e: entity) -> int` · `set_owner(e: entity, id: int)` | authority checks, per-entity owner metadata (an `@L_owner` array, like `@L_kind`) | +| **Role registers** | `is_server() -> bool` · `is_owner(e: entity) -> bool` · `local_id() -> int` | the runtime sets these; role-guarded dispatch reads them | +| **Drivable sim** | `tick_fixed()` · `tick_render()` · seed get/set | a developer-owned loop for prediction/rollback (also: replay, headless tests, AI) | +| **Remote-event serde** | `emit`-site serialize + `net_send`; inbound bytes rebuild + re-`emit` | RPCs | + +Transport is the one that needs *no* language work at all — a developer can already +`extern fn` a socket library and link it, exactly as the windowing layer is linked. +The language's genuine contributions are snapshot-to-buffer, the generated +serializers, ownership storage, and the drivable loop. + +```ludic +# doc-check: skip — the freedom layer, a hand-rolled replication tick +entry { + while running() { + if is_server() { + for (Transform) in query [Transform, Owned] { + let n = serialize_Player(self(), buf) # compiler-generated + net_send(ALL, buf, n) # developer's transport + } + } else { + let n = net_poll(buf, CAP) + if n > 0 { apply_Player(target_of(buf), buf, n) } + } + tick_render(); present() + } +} +``` + +This *works*, but it is deliberately not how most games should be written — it puts +serialization and role branching in the developer's face. That is what §6 fixes. + +--- + +## 6. The high-level DX layer (the default) + +The developer declares **what** replicates, **who** owns, and **where** handlers +run. No serialization, no transport, no `is_server()` in ordinary code. + +### 6.1 `@Sync` — what replicates, at three granularities + +Replication is **opt-in at the field level**: a field crosses the wire only when it +is explicitly marked. There is no `@NoSync` — the surface is purely additive. + +Two independent switches, and **both must be on** for a field to replicate: + +1. **A field is *replicable*** iff it is `@Sync`-marked — directly + (`@Sync hp: int`), or via `@Sync property P { … }` (a shorthand that marks + *every* field of `P` replicable). *Only marked fields — never all-by-default.* +2. **A component *participates* in a model** iff the model marks it `@Sync` + (`@Sync Transform` inside the `model`). Participation is decided **per model + use-site**, so the same property syncs in one model and not another. + +A field of an entity replicates **iff it is replicable AND its component +participates in that entity's model.** + +```ludic +# doc-check: skip — the three levels +@Sync property Position { x: int, y: int } # every field of Position is replicable +property Health { @Sync hp: int, max: int } # only hp is replicable; max never is +property Transform { @Sync x: int, @Sync y: int, angle: int } # x, y replicable; angle not + +@Owned model Player { # entities carry a network owner + @Sync Transform # participates → replicates x, y (not angle) + @Sync Health # participates → replicates hp (not max) + @Sync Position # participates → replicates x, y +} + +model Prop { # a non-owned decoration + Transform # not @Sync here → Transform does NOT replicate — the + # "non-synced Transform sometimes" case, for free +} +``` + +- **Checked, not silent.** `@Sync` on a `ptr`/non-POD-scalar field is a **compile + error** ("networked fields must be POD scalars" — footgun 3). A model that + `@Sync`es a component with *zero* replicable fields is a **compile warning** + (participation that replicates nothing). +- **Per-field direction** rides the same annotation as an argument, mirroring how + `@Queries(these:…, on:…)` takes args: `@Sync(to: owner) hp: int` replicates a + field only to the entity's owner (Unity's `SendToOwner`). Default is `to: all`. + +### 6.2 Roles — where a handler runs + +The role is a **declarative annotation on the handler**, never a runtime branch. +Unmarked code is the shared, deterministic simulation and runs everywhere. + +| Annotation | Runs where | Meaning | +|---|---|---| +| *(none)* | everywhere | shared, deterministic simulation | +| **`@Server`** | the authority only | server-authoritative logic; clients receive the result via `@Sync` | +| **`@Predicted`** | the owning client (speculatively) **and** the server (authoritatively) | responsive local control, auto-reconciled against the server | + +`@Predicted` is **explicit** — the developer opts an owned entity's control handlers +into prediction; the language does not silently predict. The name states the netcode +role (owner-predicts + server-authoritative + reconcile), not the machine, and +matches Unity's `GhostMode.Predicted` so the concept transfers. + +`@Interpolated` — how a *non-owned* synced component is smoothed between snapshots on +a remote client — is a **presentation** concern on the component, kept separate from +these sim-handler roles rather than muddying them. + +### 6.3 Ownership + +```ludic +# doc-check: skip +@Owned model Player { @Sync Transform; @Sync Health } # every Player entity has a network owner +``` + +`@Owned` gives the model an owner slot (the `@L_owner` array); `owner(e)` / +`set_owner(e, id)` read and assign it (the authority assigns). `is_owner(e)` and +`@Predicted` dispatch read it. Ownership gates who may write `@Sync(to: owner)` +fields and who runs `@Predicted` handlers. + +### 6.4 RPCs are directional remote events + +RPCs are the event bus with a direction flag — no new concept: + +```ludic +# doc-check: skip +@ToServer event Fire { dir: int } # client → server (a request) +@ToClients event Boom { x: int, y: int } # server → clients (a broadcast) + +@Server @On(Fire) handler DoFire { spawn Bullet { dir: Fire.dir } } # authority handles the request +@On(Boom) handler Vfx { spawn Explosion { x: Boom.x, y: Boom.y } } # every client reacts +``` + +`@ToServer`/`@ToClients` mark an `event` remote; the compiler serializes its POD +payload (already flat — [EVENTS-DESIGN EV0](EVENTS-DESIGN.md)) and routes it through +the transport seam in the declared direction, re-`emit`ting it on the far side into +the ordinary event dispatch. + +### 6.5 The whole game, high-level + +```ludic +# doc-check: skip — read top to bottom: you always know where each line runs +program Shooter { + @Sync property Position { x: int, y: int } + property Health { @Sync hp: int, max: int } + + @Owned model Player { @Sync Position; @Sync Health } + model Bullet { Position } + + handler Physics phase FixedUpdate { … } # no tag → shared, identical everywhere + @Predicted handler Move phase Input { … } # owner predicts, server authoritative + @Server handler Death phase Update { … } # authority only; clients get the result via @Sync + + @ToServer event Fire { dir: int } + @Server @On(Fire) handler DoFire { spawn Bullet { … } } +} +``` + +No `is_server()`, no `net_send`, no serializer — yet every line's role is legible, +and every replicated field is explicitly opted in. + +--- + +## 7. Lowering summary + +Everything above reduces to the §5 primitives, gated so an un-networked build is +unchanged: + +| High-level | Lowers to | +|---|---| +| `@Sync` field / `@Sync C` in a model | a per-model `serialize_` / `apply_` over the replicable-and-participating fields, + a `sync manifest` a runtime reads | +| `@Sync(to: owner)` | a field tag in the manifest; the serializer branches on `owner(e) == peer` | +| `@Owned` | an `@L_owner` array + `owner()`/`set_owner()`, like `@L_kind` | +| `@Server` / `@Predicted` handler | the handler's dispatch wrapped in a role guard the runtime's role register drives (the `rt_*` seam pattern) | +| `@ToServer` / `@ToClients event` | payload serialize + `net_send(direction, …)` at the `emit` site; inbound bytes rebuild + re-`emit` | +| `world_save`/`world_load` to buffer | the existing `save()`/`load()` snapshot machinery, retargeted from a file handle to a memory buffer | +| drivable `tick_fixed`/`tick_render` | the phase runners the compiler already generates for the frame loop, exposed as callables when a game owns its `entry` loop | + +No heap, no hidden runtime beyond the honestly-named transport/role seams a +networking library fills — the same relationship windowing already has. + +--- + +## 8. The offline dividend + +Because these are **opt-in-cost annotations** — serializers *generated*, nothing +*run* until a networking runtime is spliced — a build with no runtime is +**byte-identical to single-player**, and every role guard collapses to "run here." +You build the game offline, drop in a runtime, and the same annotated code starts +replicating. That is Unity's "offline mode adjustable," achieved by the same +opt-in-cost invariant the whole event system already holds. + +--- + +## 9. The one genuinely hard corner + +Determinism holds beautifully for `int`/`fixed` simulations, which makes lockstep +and rollback cheap. It **breaks for `f32` across platforms** — so **3D/voxel + +lockstep stays the hard corner** (3D wants floats; the Luanti analysis flagged that +`fixed` saturates at ±32768). No language sleight-of-hand fixes this; the +determinism contract (§11) states it plainly, and a developer choosing lockstep for +a 3D game has to accept it (or choose state replication, §10's other branch, where +per-frame determinism is not required). + +--- + +## 10. Two model families, both reachable — neither built in + +The language commits to **neither**; both are library policy over the §5 primitives. + +- **Deterministic lockstep / rollback** — exchange only inputs; reproduce the sim; + on misprediction, `world_load` a snapshot and re-`tick_fixed`. Plays to Ludic's + determinism, and GGPO-cheap because snapshot/restore already exists. Best for + 2D/integer/fixed games. +- **State replication** — the authority `world_save`s (or per-`@Sync` serializes), + delta-encodes against the last acked snapshot per peer, ships the diff; peers + `apply_*` it and interpolate/predict. Heavier, but needed when the sim can't be + deterministic (float physics, 3D). + +A **blessed reference runtime** (§13, N6) can ship one of these so `@Sync` games +work out of the box — the way [`tests/mod_c/mod.c`](tests/mod_c/mod.c) proved the +event ABI — while the seams stay open for others. + +--- + +## 11. The determinism contract (what the language must guarantee) + +For a developer to *trust* lockstep, the language must promise, document, and where +possible *enforce*: + +1. **`fixed`/`int` math is bit-identical across platforms.** The networked sim must + avoid `f32` (footgun 2). *(Enforcement: at least a documented rule; ideally a + `@Sync`/`@Server`-reachable-code float lint.)* +2. **ECS iteration order is stable** — query order is declaration/id order, and + EV6 already fixes event-dispatch order. No hash-map iteration in the sim path. +3. **RNG is deterministic from a shared seed** — `seed()` exists; the seed must be + synchronized at session start (library policy) and never re-seeded from + wall-clock mid-sim. +4. **Networked components are POD scalars** — no `ptr`/heap fields cross the wire + (footgun 3). *Enforced:* `@Sync` on a non-scalar field is a compile error. +5. **Entity ids agree across peers** — lockstep gets this free from determinism; + replication needs an id-mapping table (library policy). + +This contract is the language's real networking responsibility. Most of it is +*already true*; the work is stating and enforcing it, not inventing it. + +--- + +## 12. Design principles + +1. **Mechanism in the language, policy in the library.** Expose serializers, + transport seam, ownership, snapshot, drivable sim. Never bake in authority, + prediction, or matchmaking. +2. **Role is declared, not branched.** `@Server`/`@Predicted` on handlers; unmarked + code runs everywhere. No `is_server()` in ordinary gameplay. +3. **Replication is explicit and opt-in.** Only `@Sync`-marked fields cross the + wire; participation is decided per model. Nothing replicates by surprise. +4. **Opt-in cost.** Un-networked builds are byte-identical; the sim runs offline + with the same code. +5. **Determinism is a promise the language keeps.** Enforce the POD-scalar rule; + document the float/iteration/seed rules; keep the sim reproducible. +6. **Two altitudes, always.** The high-level lowers to primitives that stay + callable. The sugar is the default; the freedom layer is never removed. +7. **Reuse, don't reinvent.** Snapshot = generalized `save()`; RPC = directional + `event`; serializer = generated from the EV2 schema; role seam = the `rt_*` + pattern. Networking is the fourth lens, not a parallel stack. + +--- + +## 13. Suggested implementation order + +Each phase is independently shippable and testable, matching how the repo phases +work (and how EVENTS-DESIGN sequenced EV0–EV7). + +- **N0 — transport seam + loopback. ✅ SHIPPED.** The `net_send`/`net_poll` extern + seam and a loopback host stub; an echo test. The floor; needed almost no compiler + work — just finishing `extern fn`: a call lowers to a direct `@` call and the + header emits a matching `declare`, so any C/Rust/Zig library (a socket, here the + loopback) binds through the same seam windowing uses. `find_extern` (emit_core), + the extern branch in emit_expr's call path, `emit_extern_decls` (emit_head). + ([`examples/net_echo.ludic`](examples/net_echo.ludic), + [`tests/net_c/loopback.c`](tests/net_c/loopback.c) → `4 10 20 30 42`.) +- **N1 — snapshot-to-buffer. ✅ SHIPPED.** Generalized `save()`/`load()` to a memory + buffer: `world_size()` (exact snapshot bytes), `world_save(buf) -> int`, + `world_load(buf, len)`. The same fixed block list (entity count, freelist, alive, + kind, vars, per-component `@S_`/`@H_`) now feeds a file (fwrite/fread) *or* a buffer + (memcpy over a threaded i64 offset), chosen by `g_snap_mode` in emit_save.ludic; + no rt_ hook (the ECS world only). The rollback/replication substrate. + ([`examples/net_snapshot.ludic`](examples/net_snapshot.ludic), + [`tests/net_c/snapshot_mod.c`](tests/net_c/snapshot_mod.c) → `50 7 50`.) +- **N2 — `@Sync` codegen. ✅ SHIPPED.** The three-level annotations → generated + per-model `serialize_`/`apply_` + by-kind dispatchers (`ludic_serialize`/ + `apply`/`sync_size`, and the `serialize`/`apply`/`sync_size` builtins); the + POD-scalar compile error and the empty-participation warning. The declarative + core. ([`examples/net_sync.ludic`](examples/net_sync.ludic) → `12 3 4 50 999`, + emit in [`selfhost/emit_net.ludic`](selfhost/emit_net.ludic).) +- **N3 — ownership. ✅ SHIPPED.** `@Owned` + the `@L_owner_arr` array + + `owner()`/`set_owner()`/`is_owner()`; owners are part of the world snapshot. + ([`examples/net_owner.ludic`](examples/net_owner.ludic) → `-1 7 0 1`.) +- **N4 — remote events (RPCs). ✅ SHIPPED.** `@ToServer`/`@ToClients` on `event`s → + payload serialize (`[event id][fields]`) + directional `net_send` + `net_pump()` + far-side re-`emit`. ([`examples/net_rpc.ludic`](examples/net_rpc.ludic) → `0 8`.) +- **N5 — roles + drivable sim. ✅ SHIPPED.** `@Server`/`@Predicted` role-guarded + dispatch driven by the `@L_role` register (`set_role`/`is_server`/`local_id`); + the opt-in `entry`-owns-the-loop with `tick_fixed()`/`tick_render()`. Together + these let prediction/rollback be written in developer/library code. + ([`examples/net_roles.ludic`](examples/net_roles.ludic) → `1 102`.) +- **N6 — a blessed reference netcode runtime. ✅ SHIPPED.** A Ludic library + ([`examples/net_rt.ludic`](examples/net_rt.ludic)) — server-authoritative state + replication over the primitives — plus a full end-to-end demo, proving the seams + the way the C mod proved the event ABI, but in pure Ludic over the built-in + transport. Library policy, swappable for lockstep+rollback. + ([`examples/net_demo.ludic`](examples/net_demo.ludic) → `5 999 5`.) A built-in + loopback transport (N0) means all of this needs **no foreign code at all**. + +N0–N2 deliver "state can be declared, serialized, and moved." N3–N4 add ownership +and RPCs. N5 unlocks prediction. N6 is a batteries-included default that others can +replace. The **determinism contract (§11)** is cross-cutting — documented from N0, +enforced incrementally. + +--- + +## 14. Open decisions + +1. **Field direction vocabulary.** `@Sync(to: owner)` / `@Sync(to: all)` confirmed + in spirit; is `to:` the right key, and do we also want `to: server` (a field only + the authority reads)? How does per-field direction interact with `@Predicted`? +2. **Blessed runtime, or seams only?** Events chose "seams + reference mod, bless + nothing." Networking's DX may justify shipping one reference runtime (N6). One, + or none? +3. **Authority default.** Server-authoritative with `@Predicted` opt-in is the safe, + Unity-ish default. Confirm, or keep the language authority-neutral and leave even + that to the runtime? +4. **Drivable loop shape.** Whole-frame `tick()` vs the `tick_fixed()`/`tick_render()` + split; how a developer-owned `entry` loop coexists with scenes, the `rt_*` hooks, + and the auto-loop (opt-in via presence of an `entry` block?). +5. **Snapshot granularity.** Full `world_save` vs per-`@Sync` serialize vs a + generated delta between two snapshots — which does the language provide, and which + is library work? +6. **Float determinism enforcement.** A documented rule only, or a real lint that + flags `f32` reachable from `@Server`/`@Predicted`/`@Sync` code paths? +7. **Ownership at component granularity.** Unity's DOTS allows per-component owner + send-rules. Is `@Owned` per-*entity* enough, or do we need per-component owners + (a real complexity jump)? +8. **Networking substrate for the remote half of EVENTS EV7.** This doc's directional + remote events (N4) *are* the local/remote split EVENTS-DESIGN EV7 deferred for + "no networking substrate." N4 is that substrate — the two docs meet here. + +--- + +*Companion to [EVENTS-DESIGN.md](EVENTS-DESIGN.md) (remote events are directional +events; serializers reuse the EV2 world-table schema; EV7's deferred local/remote +split lands here as N4), [LIFECYCLE-DESIGN.md](LIFECYCLE-DESIGN.md) (`@OnChange`/LC2 +is the dirty-tracking primitive for delta replication), and +[SCENES-DESIGN.md](SCENES-DESIGN.md). Supersedes nothing until the compiler work in +§13 lands.* diff --git a/SCENES-DESIGN.md b/SCENES-DESIGN.md new file mode 100644 index 00000000..091cb413 --- /dev/null +++ b/SCENES-DESIGN.md @@ -0,0 +1,354 @@ +# Scenes, expanded — a design doc + +> **Status: S0 shipped; S1–S6 are design.** The base construct — `scene` / +> `layer` / `on enter` / `on exit` / `become`, lowered to the implicit machine of +> §3 and §9 — is implemented and tested ([`examples/scenes.ludic`](examples/scenes.ludic), +> a `test.sh` check). The extensions in §4–§8 (scene-owned entities, richer +> layers, the overlay stack, scene-local state, transition parameters) are still +> design targets. This document reaches deliberately past the thin sketch so we +> can decide the shape before building each one. §11 lists the open decisions. + +--- + +## 1. Where we are + +A Ludic program is almost always several mutually-exclusive states — a title +screen, the overworld, a battle, a pause menu. Two ways to write that exist in +the language today, and a third is sketched: + +| Approach | Status | Cost | +|---|---|---| +| Mode register consulted at the top of every handler (`if reg(R_MODE) == …`) | works | a guard re-read per handler per frame; state is a magic number; nothing scopes to it | +| `machine`/`state`/`become` over a register | works | dispatch on the register each frame; still one flat register, no per-state handlers or lifecycle | +| `scene`/`layer`/`on enter`/`on exit` | **sketch only** | — | + +The sketch ([`examples/scenes.ludic`](examples/scenes.ludic)) specs: + +- Exactly **one scene active**; the `start` scene runs first. +- A scene's handlers run only while it is active; handlers outside any scene are + global. +- **Layers group handlers; declaration order is draw order** — within a phase, + globals first, then the active scene's layers in written order. +- `on enter` / `on exit` are lifecycle hooks (not phases). +- `become Name` runs the old scene's `on exit`, switches, runs the new `on enter` + — two direct calls and a store, no dispatch table. + +That's a good spine. The problem is it's specced as **sugar over a mode +register**: it tidies the syntax but adds little the register didn't already +have. The compiler knows *much* more at a scene boundary than a register does, +and this doc is about spending that knowledge. + +--- + +## 2. Design principles + +1. **The scene boundary is a compile-time fact — use it.** The set of handlers, + layers, and owned state for each scene is known statically. Transitions should + be direct calls and a single store, never a table walk. (The sketch already + promises this; the extensions must preserve it.) +2. **Structure, not registers.** Anything you'd track with a hand-managed + register alongside the mode — which entities belong to this state, which layers + are drawn, what's paused — should be expressible *as* scene structure and + enforced by the compiler. +3. **Reuse the machinery we already have.** Layers pausing, scenes tearing down + their entities, and hooks firing are all expressible in terms of + `enable`/`disable` (cheap flag flips), `despawn`, and the lifecycle-hook + lowering. Scenes should *compose* those, not introduce a parallel runtime. +4. **One active-scene path stays hot; overlays are the exception, not the rule.** + The common case (one full-screen scene at a time) must lower to the cheapest + possible dispatch. Richer shapes (a pause menu over a frozen world) are opt-in + and pay only for what they use. + +--- + +## 3. Core model (firmed up from the sketch) + +```ludic +# doc-check: skip — illustrative +scene Title start { + on enter { ui_open(UI_Menu) } + on exit { ui_visible(UI_Menu, 0) } + + layer Main { + handler Choose phase Update { + if ui_clicked(UI_NewGame) { become Overworld } + } + } +} + +scene Overworld { + on enter { spawn_party() } + layer World { handler Move phase Update { … } } + layer Hud { handler Draw phase Render { … } } +} +``` + +Unchanged from the sketch, made precise: + +- **Scenes number themselves by declaration order**, exactly like `machine` + states — `Title` is `0`, `Overworld` is `1`. The active scene lives in one + implicit register (`__scene`). This makes `scene` a `machine` the compiler + writes for you, which is the right mental model and the right lowering. +- **A layer handler may not use phase `Start`.** `Start` runs once at boot, + before any scene is entered; scene setup goes in `on enter`. +- **Global handlers still run every frame**, before any scene's layers, in every + phase. A scene's layers run only while it is active. + +Everything below is new. + +--- + +## 4. Extension E1 — scene-owned entities (scoped lifetime) + +The single biggest thing a mode register cannot do: **own the entities that only +make sense in this state, and tear them down automatically on exit.** Today a +battle scene spawns combatants in `on enter` and must remember to despawn every +one in `on exit` — miss one and it leaks into the overworld. + +Proposal: entities spawned *by a scene's handlers or `on enter`* are tagged with +that scene, and `on exit` despawns them by default. + +```ludic +# doc-check: skip +scene Battle { + on enter { spawn Foe; spawn Foe; spawn Foe } # tagged @Battle + # on exit: implicit `despawn all @Battle` — no manual cleanup + layer World { handler Fight phase Update { … } } +} +``` + +- Implemented as an implicit **scene tag** (a `{Battle}`-style kind bit) added at + `spawn` time while a scene is active, plus a generated `despawn`-by-tag in the + synthesized `on exit`. Reuses the existing tag-filter and despawn-hook + machinery — no new runtime. +- **Opt out** for entities that should outlive the scene: `spawn Foe persist` (or + spawn it from a global handler). Persisted entities keep their data across the + transition, matching how `disable` keeps field data. +- Composes with `@OnDespawn(Model)`: the destructor hook fires for each + scene-owned entity as it's torn down, so `drop_loot`-style cleanup still runs. + +**Open:** does a re-`become Battle` get fresh entities (fresh tag generation) or +resume the old ones? Default: fresh. See §9. + +--- + +## 5. Extension E2 — layers are more than draw order + +The sketch uses layers only to order `Render`. Layers are the natural unit for +three more things, all built on the existing `enable`/`disable` flag flips: + +1. **Per-layer toggle.** `disable Hud` / `enable Hud` flips one flag; the layer's + handlers stop running and drawing. This is `disable Handler` generalized to a + named group — same one-flag-flip cost. + +2. **Pause vs. tear-down.** A layer can keep drawing while its *update* handlers + are suspended: + + ```ludic + # doc-check: skip + scene Overworld { + layer World { handler Move phase Update { … } handler Draw phase Render { … } } + layer Hud { handler DrawHud phase Render { … } } + } + ``` + + When a pause menu opens over the Overworld (see E3), `World`'s `Update` + handlers suspend but its `Render` handler still paints the frozen world behind + the menu. Today that requires a `if !paused` guard in every update handler; + with layers it's structural. + +3. **Layer lifecycle hooks.** `on show` / `on hide` per layer, mirroring scene + `on enter`/`on exit`, for the toggle points. (Naming TBD — could fold into the + `@OnEnable`/`@OnDisable` annotations, which already exist for properties.) + +--- + +## 6. Extension E3 — the scene *stack* (the headline) + +The sketch says "exactly one scene is active." That's the right default and the +wrong constraint. The states a mode register handles *worst* are the ones that +**overlay without replacing**: a pause menu over live gameplay, a dialog box, an +inventory screen, a confirmation prompt. With one register you either lose the +underlying state or hand-roll a "previous mode" variable and restore it. + +Proposal: keep "one *base* scene," but allow scenes to be **pushed as overlays**. + +```ludic +# doc-check: skip +scene Overworld { + layer World { handler Move phase Update { … } handler Draw phase Render { … } } + layer Hud { handler DrawHud phase Render { … } } + + on enter { … } + handler PauseKey phase Input { if pressed(KEY_ESC) { push Pause } } +} + +scene Pause overlay { # `overlay` = pushed, not swapped + on enter { dim_backdrop() } + layer Menu { + handler Nav phase Update { + if pressed(KEY_ESC) { pop } # back to Overworld, untouched + } + handler Draw phase Render { ui_render() } + } +} +``` + +- `push Name` runs `Name`'s `on enter` and makes it the top scene **without** + running the base scene's `on exit`. `pop` runs the overlay's `on exit` and + returns to whatever was beneath. +- **Update belongs to the top of the stack; render walks the whole stack bottom + to top.** So `Pause`'s `Menu` layer draws over `Overworld`'s frozen `World` and + `Hud`. This is the default that makes pause menus "just work." An overlay that + should let the layer beneath keep updating opts in with `push Name passthrough`. +- **The stack is a small fixed-capacity array of scene ids** (say 8) in a + compiler-owned buffer — not heap, not a linked structure. `push`/`pop` are an + index bump and an `on enter`/`on exit` call. Depth overflow is a compile-time + or trap decision (§9). +- `become` still exists and still means "swap the base scene" (full `on exit` → + `on enter`, stack cleared). `push`/`pop` are the overlay verbs. Keeping the two + distinct is what lets the common single-scene path stay a single register. + +This is the extension that turns `scene` from "nicer mode register" into +something with no clean equivalent in the register world. + +--- + +## 7. Extension E4 — scene-local state + +A scene almost always has state that exists only while it's active — a battle's +turn counter, a menu's cursor index. Today that's a global register that other +scenes could stomp. Proposal: **`var` / `const` declared inside a `scene` is +scoped to it**, storage shared across scenes that are never simultaneously active +(the compiler can overlap their storage since only one base scene runs at a +time — an arena-per-scene, or a union). + +```ludic +# doc-check: skip +scene Battle { + var turn = 0 # visible only inside Battle; reset by `on enter` if desired + layer World { handler Step phase Update { turn += 1 } } +} +``` + +- Reads/writes lower to a fixed offset in the scene's state block, no register + indirection. +- Overlay scenes (E3) that *can* be live simultaneously with their base cannot + share storage — the compiler keeps their blocks distinct. Base scenes that + never coexist share. + +--- + +## 8. Extension E5 — parameterized transitions, and the reserved annotations + +**Parameters on transitions.** `become`/`push` can carry arguments that the +target's `on enter` binds — so a battle knows which foes, a dialog knows which +line: + +```ludic +# doc-check: skip +scene Battle { + on enter (foe_kind: int, count: int) { for i in 0 .. count { spawn_foe(foe_kind) } } +} +# elsewhere: +become Battle(FOE_GOBLIN, 3) +``` + +Lowers to argument stores into the scene's state block (E4) immediately before +the `on enter` call. No variadic runtime; the arity is checked at compile time. + +**The already-reserved annotation form.** [LANGUAGE.md:374](LANGUAGE.md:374) +reserves `@OnEnter` / `@OnExit` as handler annotations "waiting on scene support." +This doc adopts them as the annotation spelling of `on enter` / `on exit`, +mirroring how `@OnStart` is the annotation form of `phase Start`: + +```ludic +# doc-check: skip +@OnEnter(Battle) handler Setup { … } # == Battle's `on enter` +@OnExit(Battle) handler Teardown { … } +``` + +Both spellings desugar to the same synthesized scene-lifecycle function; a scene +may use either, not both, for a given hook. + +**`reads`/`writes` + scenes (forward-looking).** The `reads`/`writes` clauses are +parsed but unconsumed ([LANGUAGE.md:717](LANGUAGE.md:717)). Once an analysis pass +exists, a scene's layers declare which state they touch, and the scheduler can run +independent layers of the active scene in parallel within a phase — the scene +boundary gives the pass a natural scope to reason about. Noted as a destination, +not part of the first cut. + +--- + +## 9. Lowering summary + +Everything above reduces to existing runtime concepts: + +| Construct | Lowers to | +|---|---| +| active base scene | one implicit register `__scene`, states numbered by decl order — literally a compiler-written `machine` | +| `become Name` | `on exit` call · `set __scene` · `on enter` call (two direct calls + store, as the sketch promises) | +| scene layers in a phase | the phase scheduler, after global handlers, dispatches on `__scene` to that scene's layer handlers in declaration order | +| `push`/`pop` (E3) | fixed-capacity scene-id array + index; render walks it, update reads its top | +| scene-owned entities (E1) | implicit kind tag at `spawn`; generated `despawn`-by-tag in synthesized `on exit`; reuses despawn hooks | +| layer toggle / pause (E2) | the same one-flag-flip as `disable Handler`, keyed per layer | +| scene-local `var` (E4) | fixed offsets in a per-scene state block; non-coexisting scenes share storage | +| transition args (E5) | arg stores into the state block before the `on enter` call | +| `@OnEnter`/`@OnExit` (E5) | the same synthesized lifecycle functions as `on enter`/`on exit` | + +No heap, no dispatch tables, no new allocator. The active-scene path is a +register read and a static branch; the stack adds a small array only for programs +that push overlays. + +--- + +## 10. Suggested implementation phases + +Each is independently shippable and testable, matching how the repo phases work. + +- **S0 — parse & lower the sketch.** ✅ **Done.** `scene`/`layer`/`on enter`/`on + exit`/`become` lowered to the implicit `machine`; the active scene is + snapshotted per phase so exactly one scene's layers dispatch in any phase. + [`examples/scenes.ludic`](examples/scenes.ludic) compiles, runs, and is checked + by `test.sh`. This is the floor everything else builds on. +- **S1 — `@OnEnter`/`@OnExit` annotation form** (E5, cheap once S0 exists). +- **S2 — layer toggle & pause** (E2) on top of the existing `enable`/`disable`. + ✅ *Toggle shipped* (via EVENTS-DESIGN EV1 layers): `enable layer L` / `disable + layer L` flips an `@LE_` flag that gates the layer's handlers (emitted only + for toggled layers, so untouched scene programs stay byte-identical), and a + `public` layer fires `layer__show`/`_hide` — see + [`examples/layer_events.ludic`](examples/layer_events.ludic). Still open: the + *pause* half (keep drawing while `Update` handlers suspend) and `on show`/`on + hide` blocks. +- **S3 — the scene stack** (E3): `push`/`pop`/`overlay`/`passthrough`. The big one. +- **S4 — scene-owned entities** (E1) and **scene-local state** (E4). +- **S5 — transition parameters** (E5). +- **S6 (later) — `reads`/`writes` scheduling** (E5), gated on the analysis pass. + +S0–S1 deliver the sketch as promised; S2–S3 are where the "great potential" +actually lands; S4–S5 are ergonomics; S6 is a performance destination. + +--- + +## 11. Open decisions + +1. **Re-entering a scene:** fresh entities/state, or resume? (Default proposed: + `become` = fresh, `push`/`pop` = the pushed scene is fresh each push, the base + underneath is untouched.) +2. **Stack depth:** compile-time cap with an error on overflow, or a runtime trap? + What capacity (8? configurable)? +3. **`passthrough` granularity:** does a passthrough overlay let *all* lower + layers update, or can it name which phases fall through? +4. **Layer hook naming:** `on show`/`on hide`, or reuse `@OnEnable`/`@OnDisable`? +5. **Scene-local storage sharing:** union non-coexisting scenes automatically, or + require an explicit opt-in so the sharing is visible in source? +6. **Global handlers and overlays:** do globals run once per frame regardless of + stack depth (proposed: yes), or per active scene? +7. **`become` from inside an overlay:** does it clear the stack (proposed: yes) or + is it an error while overlays are pushed? + +--- + +*Companion to [LANGUAGE.md §"Scenes & layers"](LANGUAGE.md) and the ordering +sketch in [`examples/scenes.ludic`](examples/scenes.ludic). Supersedes nothing +until the compiler work in §10 lands.* diff --git a/examples/cancel.ludic b/examples/cancel.ludic new file mode 100644 index 00000000..65e1f163 --- /dev/null +++ b/examples/cancel.ludic @@ -0,0 +1,27 @@ +# cancel.ludic — EV3: cancellable (decision) events. +# +# A `cancellable` event is fired BEFORE an action so a listener can veto it. The +# listener calls `cancel`; the caller reads the verdict back — `emit E(…)` used as +# an expression yields the cancelled flag (1 = vetoed, 0 = allowed). A foreign mod +# vetoes the same way, by setting the payload's trailing `cancelled` field over +# the ABI. This is the modding headline: observation becomes control. +# +# Running it prints: 0 1 92 +program Cancel { + event cancellable BeforeHurt { amount: int = 0 } + + @On(BeforeHurt) handler Armor { if amount > 10 { cancel } } # veto any hit over 10 + + entry { + let v1 = emit BeforeHurt(amount: 5) # 5 <= 10 -> allowed + print(v1) # 0 + let v2 = emit BeforeHurt(amount: 15) # 15 > 10 -> vetoed + print(v2) # 1 + + # the realistic shape: only apply the effect when the decision isn't vetoed + var hp = 100 + if emit BeforeHurt(amount: 8) == 0 { hp = hp - 8 } # allowed -> 92 + if emit BeforeHurt(amount: 50) == 0 { hp = hp - 50 } # vetoed -> unchanged + print(hp) # 92 + } +} diff --git a/examples/detach.ludic b/examples/detach.ludic new file mode 100644 index 00000000..3ce47358 --- /dev/null +++ b/examples/detach.ludic @@ -0,0 +1,38 @@ +# detach.ludic — the structural attach/detach pair and its @OnAttach / @OnDetach +# hooks. `attach P on e` adds a property to a LIVE entity (seeding its fields and +# firing @OnAttach); `detach P on e` removes it (firing @OnDetach, which still +# reads the outgoing value before the has-flag clears). This is the structural +# counterpart to enable/disable — attach/detach create and destroy the property's +# presence, whereas disable/enable only pause it while keeping the data. +# +# Running it prints: 15 1 25 0 +# 15 @OnAttach(Shield): amount seeded to 5, prints 5 + 10 +# 1 one live Shield now matches the query +# 25 @OnDetach(Shield): reads the outgoing amount 5, prints 5 + 20 +# 0 the Shield is gone — nothing matches +# +# ./selfhost/game-build.sh build/ludicc examples/detach.ludic /tmp/detach +# /tmp/detach 15 + var n = 0 + for (s) in query [Shield] { n += 1 } + print(n) # 1 + + for (s) in query [Shield] { detach Shield on self() } # @OnDetach -> 25 + n = 0 + for (s) in query [Shield] { n += 1 } + print(n) # 0 + quit() + } +} diff --git a/examples/events.ludic b/examples/events.ludic new file mode 100644 index 00000000..3a3d4316 --- /dev/null +++ b/examples/events.ludic @@ -0,0 +1,25 @@ +# events.ludic — EV0: the event bus core. +# +# `event E { fields }` declares a public event carrying a POD payload. `@On(E) +# handler …` registers a listener whose body reads the payload fields by name. +# `emit E(field: v, …)` fires the event: it calls every @On(E) listener, in +# declaration order, as a direct call — the whole thing desugars to code, with no +# runtime and no dispatch table. A program that declares no `event` is compiled +# byte-for-byte as before (the subsystem is gated on `g_events`). +# +# Running it prints: 5 8 20 30 999 42 42 +program Events { + event Hurt { entity: int = 0, amount: int = 0 } # a payload with fields + defaults + event Cleared { } # an empty payload is allowed + + @On(Hurt) handler Flash { print(amount) } # listeners bind payload fields by name + @On(Hurt) handler Guard { print(entity + amount) } # a second listener, run after the first + @On(Cleared) handler Cheer { print(999) } + + entry { + emit Hurt(entity: 3, amount: 5) # -> Flash 5, Guard 3+5=8 + emit Hurt(entity: 10, amount: 20) # -> Flash 20, Guard 10+20=30 + emit Cleared() # -> Cheer 999 + emit Hurt(amount: 42) # entity defaults to 0 -> Flash 42, Guard 0+42=42 + } +} diff --git a/examples/layer_events.ludic b/examples/layer_events.ludic new file mode 100644 index 00000000..61246356 --- /dev/null +++ b/examples/layer_events.ludic @@ -0,0 +1,27 @@ +# layer_events.ludic — EV1 for layers + SCENES E2 (layer toggle). A `public` layer +# promotes its show/hide to events; `enable layer L` / `disable layer L` flips the +# layer on and off (its handlers stop running while hidden) and fires +# layer__show / layer__hide. This closes the last scope of "events across the +# whole architecture" — properties, models, scenes, program, and now layers. +# +# Running it prints: 50 2 1 50 +program LayerEvents { + var step: int = 0 + + @On(layer_Hud_show) handler Shown { print(1) } # a mod reacts when the HUD returns + @On(layer_Hud_hide) handler Hidden { print(2) } # ...and when it's hidden + + scene Main start { + layer Hud public { + handler Draw phase Update { print(50) } # only runs while Hud is enabled + } + layer Ctrl { + handler Drive phase LateUpdate { + step = step + 1 + if step == 1 { disable layer Hud } # frame 1: hide -> Hidden 2, Draw stops + if step == 2 { enable layer Hud } # frame 2: show -> Shown 1, Draw resumes + if step == 3 { quit() } # frame 3: after Draw ran again + } + } + } +} diff --git a/examples/mod_events.ludic b/examples/mod_events.ludic new file mode 100644 index 00000000..92bd19e1 --- /dev/null +++ b/examples/mod_events.ludic @@ -0,0 +1,16 @@ +# mod_events.ludic — the event bus with two listeners on one event, driven from +# Ludic (replaces the former tests/mod_c/mod.c foreign-mod host). A public event +# `Damage` has two @On listeners: one prints the amount, one accumulates a total. +# Emitting it twice runs both listeners each time. Prints 10 / 32 / 42. +program ModEvents { + var total: int = 0 + event Damage { amount: int = 0 } + @On(Damage) handler Native { print(amount) } # prints each hit + @On(Damage) handler Accum { total = total + amount } # sums them + + entry { + emit Damage(amount: 10) # Native prints 10 + emit Damage(amount: 32) # Native prints 32 + print(total) # 42 + } +} diff --git a/examples/net_demo.ludic b/examples/net_demo.ludic new file mode 100644 index 00000000..10d6397f --- /dev/null +++ b/examples/net_demo.ludic @@ -0,0 +1,45 @@ +# net_demo.ludic — N6: a networked game end to end, in pure Ludic, no C at all +# (NETWORKING-DESIGN §13 N6). It exercises the whole stack the earlier phases +# built: an RPC carries client input to the authority (N4), the authority mutates +# authoritative state (N5 roles), and the blessed runtime replicates that state +# back to a peer that had diverged (N2 @Sync + N3 @Owned + net_rt.ludic). +# +# One process, one loopback transport, so the round-trips are observable. The +# sequence a real client/server splits across machines is played here in order: +# +# 1. client emits Move(dx:5) — an @ToServer RPC → serialized onto the wire +# 2. net_pump() — the authority drains it, @On(Move) applies +5 +# 3. rt_replicate(ship) — the authority ships the ship's synced state +# 4. Pos.x = 999 — the client diverges (mispredicts) +# 5. rt_receive() — the client reconciles to the authoritative x=5 +# +# Prints 5 / 999 / 5. Build & run with the Ludic toolchain only: +# ./build.sh examples/net_demo.ludic --headless && ./build/net_demo_headless +import "net_rt.ludic" + +program NetDemo { + @Sync property Pos { x: int = 0, y: int = 0 } + @Owned model Ship { @Sync Pos } + + @ToServer event Move { dx: int = 0 } # client → server RPC + @On(Move) handler DoMove { # the authority applies input + for (Pos) in query [Pos, {Ship}] { Pos.x = Pos.x + dx } + } + + entry { + spawn Ship { Pos { x: 0, y: 0 } } + + emit Move(dx: 5) # 1. client input → wire + net_pump() # 2. authority applies it + + for (Pos) in query [Pos, {Ship}] { + print(Pos.x) # 5 — server state advanced + rt_replicate(self()) # 3. authority replicates + Pos.x = 999 # 4. client diverges + print(Pos.x) # 999 + } + + rt_receive() # 5. client reconciles + for (Pos) in query [Pos, {Ship}] { print(Pos.x) } # 5 — back to authoritative + } +} diff --git a/examples/net_echo.ludic b/examples/net_echo.ludic new file mode 100644 index 00000000..952a948a --- /dev/null +++ b/examples/net_echo.ludic @@ -0,0 +1,24 @@ +# net_echo.ludic — N0: the transport seam (NETWORKING-DESIGN §5, §13 N0). +# +# The transport is two calls — net_send puts a datagram on the wire, net_poll +# takes the next one off. A production build binds them to a real socket with +# `extern fn net_send/net_poll` (UDP native, WebRTC/WebSocket wasm); absent that, +# the compiler supplies a built-in in-process loopback, so a program is networked +# end to end with NO foreign host — pure Ludic. This sends four bytes and polls +# them back through the loopback: prints 4, then 10 20 30 42. +program NetEcho { + entry { + let out = bytes(4) + out[0] = 10 + out[1] = 20 + out[2] = 30 + out[3] = 42 + net_send(0, out, 4) # onto the wire (the built-in loopback) + + let inb = bytes(64) + let n = net_poll(inb, 64) # take the next datagram back off + print(n) # 4 + var i = 0 + while i < n { print(inb[i]); i = i + 1 } # 10 20 30 42 + } +} diff --git a/examples/net_owner.ludic b/examples/net_owner.ludic new file mode 100644 index 00000000..027b1d72 --- /dev/null +++ b/examples/net_owner.ludic @@ -0,0 +1,25 @@ +# net_owner.ludic — N3: entity ownership (NETWORKING-DESIGN §6.3, §13 N3). +# +# `@Owned` gives a model an owner slot (the @L_owner array). owner(e) reads it, +# set_owner(e, id) assigns it (the authority does), is_owner(e) tests it against +# the local peer id. Ownership gates who may write @Sync(to: owner) fields and who +# runs @Predicted handlers; it is part of the world snapshot, so it round-trips +# through rollback/replication. A fresh entity is unowned (-1). This assigns and +# tests ownership against the default local id (0). Prints -1 / 7 / 0 / 1. +program NetOwner { + @Sync property Pos { x: int = 0, y: int = 0 } + @Owned model Unit { @Sync Pos } + + entry { + spawn Unit { Pos { x: 5, y: 6 } } + for (Pos) in query [Pos, {Unit}] { + let e = self() + print(owner(e)) # -1 — fresh entity is unowned + set_owner(e, 7) + print(owner(e)) # 7 — the authority assigned it + print(is_owner(e)) # 0 — local id 0 != 7 + set_owner(e, 0) + print(is_owner(e)) # 1 — now the local peer owns it + } + } +} diff --git a/examples/net_roles.ludic b/examples/net_roles.ludic new file mode 100644 index 00000000..9279de96 --- /dev/null +++ b/examples/net_roles.ludic @@ -0,0 +1,33 @@ +# net_roles.ludic — N5: handler roles + the drivable sim (NETWORKING-DESIGN §6.2, +# §5, §13 N5). +# +# A handler's network role is a declarative annotation, never a runtime branch in +# ordinary code: +# (unmarked) runs on every peer — the shared, deterministic simulation +# @Server runs only on the authority (clients get the result via @Sync) +# @Predicted runs on the owning client and the server (auto-reconciled) +# The runtime sets the peer's role register (set_role); offline it defaults to +# server, so guards collapse to "run here" and a non-networked build is unchanged. +# +# The per-frame phases are also exposed as callables — tick_fixed() runs the sim +# phases — so this game owns its own loop via `entry` (for prediction/rollback, +# replay, headless tests). Acting as a client then the server: 1, then 102. +program NetRoles { + property Score { n: int = 0 } + model Board { Score } + + handler Both phase Update { for (Score) in query [Score] { Score.n = Score.n + 1 } } # runs everywhere + @Server handler ServerOnly phase Update { for (Score) in query [Score] { Score.n = Score.n + 100 } } # authority only + + entry { + spawn Board { Score { n: 0 } } + + set_role(0) # act as a client + tick_fixed() # Both(+1); ServerOnly skipped + for (Score) in query [Score] { print(Score.n) } # 1 + + set_role(1) # act as the server + tick_fixed() # Both(+1) + ServerOnly(+100) + for (Score) in query [Score] { print(Score.n) } # 102 + } +} diff --git a/examples/net_rpc.ludic b/examples/net_rpc.ludic new file mode 100644 index 00000000..2bdbf442 --- /dev/null +++ b/examples/net_rpc.ludic @@ -0,0 +1,29 @@ +# net_rpc.ludic — N4: remote events / RPCs (NETWORKING-DESIGN §6.4, §13 N4). +# +# An `event` marked @ToServer (client→server) or @ToClients (server→clients) is a +# directional remote event — the event bus with a direction flag, no new concept. +# At an `emit` site the POD payload is serialized as [event id][fields] and +# net_send in its direction; net_pump() drains inbound frames and re-emits each +# into the ordinary @On dispatch on the far side. So `emit Fire(...)` is a remote +# call — it does not run locally; the receiver's pump runs the handler. +# +# Here two Fire RPCs are emitted (dir 5, dir 3). Before net_pump the handler has +# not run (hits still 0); after, both are drained and re-emitted (5 + 3 = 8). +program NetRpc { + property Log { hits: int = 0 } + model Sink { Log } + + @ToServer event Fire { dir: int = 0 } + @On(Fire) handler OnFire { + for (Log) in query [Log] { Log.hits = Log.hits + dir } + } + + entry { + spawn Sink { Log { hits: 0 } } + emit Fire(dir: 5) # serialized onto the wire (not run locally) + emit Fire(dir: 3) + for (Log) in query [Log] { print(Log.hits) } # 0 + net_pump() # drain + re-emit both RPCs + for (Log) in query [Log] { print(Log.hits) } # 8 + } +} diff --git a/examples/net_rt.ludic b/examples/net_rt.ludic new file mode 100644 index 00000000..fd9d74c9 --- /dev/null +++ b/examples/net_rt.ludic @@ -0,0 +1,33 @@ +# net_rt.ludic — a blessed, server-authoritative replication runtime (NETWORKING +# N6). It ties the language's networking primitives together into a batteries- +# included default, the way tests/mod_c/mod.c proved the event ABI — but written +# in Ludic, over the built-in transport, with no foreign code. +# +# This is LIBRARY POLICY, not the language (NETWORKING-DESIGN §10, §12): it picks +# server-authoritative state replication. The seams stay open — swap this for +# lockstep+rollback (world_save + tick_fixed on misprediction) or your own. +# +# Frame layout on the wire: [i32 entity id][synced field bytes]. The authority +# calls rt_replicate(e) per entity each tick; a peer calls rt_receive() to drain +# inbound snapshots and apply them. serialize/apply are the compiler-generated +# @Sync codecs; net_send/net_poll are the transport seam (built-in loopback here, +# a real socket when a program binds `extern fn net_send/net_poll`). + +# The authority ships one entity's authoritative synced state to peers. +fn rt_replicate(e: int) -> void { + let w = words(512) + w[0] = e # entity id in the first word + let n = serialize(e, offset(w, 4)) # synced fields after it + net_send(0, w, 4 + n) +} + +# A peer drains every inbound snapshot and applies it to the named entity. One +# datagram per poll (the transport is datagram-preserving), so loop until empty. +fn rt_receive() -> void { + let w = words(512) + var n = net_poll(w, 2048) + while n > 0 { + apply(w[0], offset(w, 4), n - 4) # w[0] = entity id; bytes follow + n = net_poll(w, 2048) + } +} diff --git a/examples/net_snapshot.ludic b/examples/net_snapshot.ludic new file mode 100644 index 00000000..3ed7bdbc --- /dev/null +++ b/examples/net_snapshot.ludic @@ -0,0 +1,29 @@ +# net_snapshot.ludic — N1: whole-world snapshot to a memory buffer +# (NETWORKING-DESIGN §5, §13 N1). The rollback/replication substrate. +# +# save()/load() snapshot the entire ECS world to a file; world_size/world_save/ +# world_load generalize the identical layout to a caller-owned memory buffer: +# world_size() -> exact snapshot byte count +# world_save(buf) -> bytes written (entities, components, vars) +# world_load(buf, len) -> restore the world from those bytes +# That is all rollback needs (save → predict → on misprediction restore and +# re-sim) and all state replication needs (snapshot → ship → apply). This program +# spawns a Unit (hp 50), snapshots the world, mutates hp to 7, then restores — hp +# reads back 50. Prints 50 / 7 / 50, driven entirely from Ludic (no C host). +program NetSnapshot { + property Health { hp: int = 0, max: int = 0 } + model Unit { Health } + + entry { + spawn Unit { Health { hp: 50, max: 100 } } + let buf = bytes(world_size()) + for (Health) in query [Health, {Unit}] { + print(Health.hp) # 50 + let n = world_save(buf) # snapshot the whole world + Health.hp = 7 + print(Health.hp) # 7 + world_load(buf, n) # roll the world back + print(Health.hp) # 50 — restored from bytes + } + } +} diff --git a/examples/net_sync.ludic b/examples/net_sync.ludic new file mode 100644 index 00000000..58b3e4e5 --- /dev/null +++ b/examples/net_sync.ludic @@ -0,0 +1,40 @@ +# net_sync.ludic — N2: @Sync replication codegen (NETWORKING-DESIGN §6.1, §13 N2). +# +# Replication is opt-in at the field level and per model use-site. All three +# granularities here: +# @Sync property Position — every field of Position is replicable +# Health { @Sync hp, max } — only hp is replicable; max never is +# @Sync Position in Player — Position participates → x, y replicate +# Position in Prop — not @Sync here → Prop's Position does NOT replicate +# +# The compiler generates per-model serialize/apply over exactly the replicable- +# and-participating fields, plus by-kind dispatchers: sync_size(e) / serialize(e, +# buf) / apply(e, buf, len). This snapshots a Player's synced fields, mutates all +# of them, then applies the snapshot: synced fields (x, y, hp) restore; the +# unsynced one (max) keeps its mutation. Prints 12 (bytes) / 3 4 50 999. +program NetSync { + @Sync property Position { x: int = 0, y: int = 0 } # all fields replicable + property Health { @Sync hp: int = 0, max: int = 0 } # only hp replicable + + @Owned model Player { @Sync Position, @Sync Health } + model Prop { Position } # Position not @Sync here → no replication + + entry { + spawn Player { Position { x: 3, y: 4 }, Health { hp: 50, max: 100 } } + for (Position, Health) in query [Position, Health, {Player}] { + let e = self() + let buf = bytes(64) + print(sync_size(e)) # 12 = Position(x,y)=8 + Health.hp=4 + let n = serialize(e, buf) # snapshot the synced fields + Position.x = 99 # mutate everything + Position.y = 88 + Health.hp = 7 + Health.max = 999 # max is NOT synced + apply(e, buf, n) # restore from the snapshot + print(Position.x) # 3 — restored + print(Position.y) # 4 — restored + print(Health.hp) # 50 — restored + print(Health.max) # 999 — kept (unsynced) + } + } +} diff --git a/examples/program_events.ludic b/examples/program_events.ludic new file mode 100644 index 00000000..4a7b49c2 --- /dev/null +++ b/examples/program_events.ludic @@ -0,0 +1,18 @@ +# program_events.ludic — EV1 for the program ("game") scope: @Public on @OnStart +# and @OnQuit promotes them to program_start / program_quit events, so a mod runs +# its own setup after the game boots and its own teardown as the game exits — the +# top-level modding entry points (Blender's app handlers, Minetest's on_shutdown). +# +# Running it prints: 1 100 2 200 +program ProgramEvents { + property Health { hp: int = 0 } + model Dummy { Health } + + @Public @OnStart handler Boot { print(1) } # -> program_start + @Public @OnQuit handler Bye { print(2) } # -> program_quit + + @On(program_start) handler ModInit { print(100) } # mod boots after the game + @On(program_quit) handler ModDone { print(200) } # mod tears down as the game exits + + handler Run phase Update { quit() } +} diff --git a/examples/promote.ludic b/examples/promote.ludic new file mode 100644 index 00000000..a338851c --- /dev/null +++ b/examples/promote.ludic @@ -0,0 +1,32 @@ +# promote.ludic — EV1: `@Public` promotes a lifecycle hook to a public event. +# +# Marking a lifecycle hook `@Public` makes its fire site ALSO emit an event named +# for the moment — `model__spawn`, `model__despawn` — carrying the entity +# (and, for despawn, the EndReason). Anything can then subscribe: a native +# listener with `@On(model_Enemy_spawn)`, or a foreign mod binding +# `ludic_on_model_Enemy_spawn` over the C ABI. The game's own lifecycle becomes +# the modding surface, with no hand-written `emit` in the hook body. +# +# Running it prints: 100 101 200 201 +program Promote { + property Health { hp: int = 0, max: int = 100 } + model Enemy { Health } + + @Public @OnSpawn(Enemy) handler Init { Health.hp = Health.max } # -> model_Enemy_spawn + @Public @OnDespawn(Enemy) handler Clean { } # -> model_Enemy_despawn + + # Listeners on the promoted events. These read the generated payload (entity, + # and reason for despawn) by name — exactly what a foreign mod receives. + @On(model_Enemy_spawn) handler Spawned { print(entity + 100) } + @On(model_Enemy_despawn) handler Died { print(entity + reason + 200) } + + handler Seed phase Start { + spawn Enemy { Health { max: 50 } } # entity 0 -> Spawned 100 + spawn Enemy { Health { max: 60 } } # entity 1 -> Spawned 101 + } + + handler Run phase Update { + for (h) in query [Health] { despawn self() } # despawn 0 -> Died 200, despawn 1 -> Died 201 + quit() + } +} diff --git a/examples/prop_events.ludic b/examples/prop_events.ludic new file mode 100644 index 00000000..13934a51 --- /dev/null +++ b/examples/prop_events.ludic @@ -0,0 +1,26 @@ +# prop_events.ludic — EV1 for properties: @Public promotes the structural +# attach/detach hooks to public events, so a mod sees a property appear or vanish +# on a live entity (the same shape works for @OnEnable/@OnDisable → enable/disable +# events). This extends the public-event surface past models to properties — +# "events for properties, models, scenes, layers" in the architecture. +# +# Running it prints: 300 400 +program PropEvents { + property Tag { v: int = 0 } + property Shield { amount: int = 0 } + model Unit { Tag } + + @Public @OnAttach(Shield) handler Up { } # -> prop_Shield_attach + @Public @OnDetach(Shield) handler Down { } # -> prop_Shield_detach + + @On(prop_Shield_attach) handler Gained { print(entity + 300) } # entity 0 -> 300 + @On(prop_Shield_detach) handler Lost { print(entity + 400) } # entity 0 -> 400 + + handler Seed phase Start { spawn Unit { Tag { v: 1 } } } # entity 0 + + handler Run phase Render { + for (u) in query [Unit] { attach Shield on self() { amount: 5 } } # -> prop_Shield_attach -> 300 + for (s) in query [Shield] { detach Shield on self() } # -> prop_Shield_detach -> 400 + quit() + } +} diff --git a/examples/reason.ludic b/examples/reason.ludic new file mode 100644 index 00000000..585f2721 --- /dev/null +++ b/examples/reason.ludic @@ -0,0 +1,38 @@ +# reason.ludic — LC1 reason-carrying teardown. One @OnDespawn hook, but it knows +# *why* the entity is ending: `reason: r` binds an EndReason the compiler passes +# at each teardown site. An in-world `despawn` passes EndReason.Despawned; program +# shutdown passes EndReason.Quit (every still-live entity's hook fires at exit — no +# silent deaths). The body branches on the reason, exactly as Unreal's +# EndPlay(reason) / Erlang's terminate(Reason) do. +# +# Running it prints: 503 1009 +# 503 Enemy A despawned in-world (Despawned): drop its loot, 3 + 500 +# 1009 Enemy B outlived the run; at quit (Quit) it skips loot, 9 + 1000 +# +# ./selfhost/game-build.sh build/ludicc examples/reason.ludic /tmp/reason +# /tmp/reason { print(Health.hp + 1000) } # app closing — don't bother dropping loot + _ => { print(Loot.gold + 500) } # died in-world — drop the loot + } + } + + handler Seed phase Start { + spawn Enemy { Health { hp: 7 }, Loot { gold: 3 } } # A + spawn Enemy { Health { hp: 9 }, Loot { gold: 4 } } # B + } + + handler Run phase Render { + var first = 0 + for (e) in query [Health] { + if first == 0 { despawn self(); first = 1 } # despawn A -> Despawned -> 3 + 500 = 503 + } + quit() # B survives -> Quit -> 9 + 1000 = 1009 + } +} diff --git a/examples/recurse.ludic b/examples/recurse.ludic new file mode 100644 index 00000000..45cb0295 --- /dev/null +++ b/examples/recurse.ludic @@ -0,0 +1,21 @@ +# recurse.ludic — EV6: re-entrant emit is bounded. Ping's listener emits Pong, +# Pong's listener emits Ping — an event cycle that would hang the frame forever. +# The depth bound (EV_DEPTH_CAP) makes the nesting trap as an early return, so the +# program terminates with a bounded count instead of spinning. This is the "no +# runaway event cycle" guarantee. +# +# Running it prints: 16 (the cycle bottoms out at the depth cap, deterministically) +program Recurse { + var n: int = 0 + + event Ping { } + event Pong { } + + @On(Ping) handler A { n = n + 1; emit Pong() } # each Ping deepens by one Pong + @On(Pong) handler B { emit Ping() } # ...and each Pong by one Ping + + entry { + emit Ping() + print(n) + } +} diff --git a/examples/scene_events.ludic b/examples/scene_events.ludic new file mode 100644 index 00000000..784a17a3 --- /dev/null +++ b/examples/scene_events.ludic @@ -0,0 +1,22 @@ +# scene_events.ludic — EV1 for scenes: a `public` scene promotes its on-enter / +# on-exit to public events scene__enter / scene__exit, extending the modding +# surface to the game's scene structure. A mod (native @On here, or foreign over +# the ABI) reacts as the game moves between scenes. +# +# Running it prints: 10 1 20 2 30 3 +program SceneEvents { + @On(scene_Menu_enter) handler Greet { print(1) } + @On(scene_Menu_exit) handler Bye { print(2) } + @On(scene_Game_enter) handler Begin { print(3) } + + scene Menu start public { + on enter { print(10) } # boot enters Menu: 10, then scene_Menu_enter -> 1 + on exit { print(20) } # become leaves Menu: 20, then scene_Menu_exit -> 2 + layer L { handler Go phase Update { become Game } } + } + + scene Game public { + on enter { print(30) } # become enters Game: 30, then scene_Game_enter -> 3 + layer M { handler Stop phase Update { quit() } } + } +} diff --git a/examples/scenes.ludic b/examples/scenes.ludic index e4043be9..b3a6e099 100644 --- a/examples/scenes.ludic +++ b/examples/scenes.ludic @@ -1,9 +1,19 @@ -# ⚠️ NOT YET IMPLEMENTED by the self-hosted compiler. `scene` / `layer` / -# `on enter` / `on exit` have no parser support today, so this file does NOT -# compile with build/ludicc — it is a design sketch of the intended syntax (see -# LANGUAGE.md §"Scenes & layers"). It is deliberately excluded from test.sh. -# Games that need scene-like states use a mode register + `machine` today, as -# examples/chronorift does. +# scenes — one active scene at a time, each grouping handlers into layers behind +# an implicit active-scene register (see LANGUAGE.md §"Scenes & layers"). +# +# Running it (feed a few keystrokes so the loop ticks) prints: +# 1000 1 101 102 2 3 900 201 900 202 900 +# 1000 Boot (a global handler) runs once at Start +# 1 Title is `start`; its `on enter` fires at boot +# 101 frame 1 Update: only Title.Main.Tick runs (Play is not active) +# 102 frame 2 Update: Tick reaches 2 -> `become Play`… +# 2 3 …which runs Title's `on exit` then Play's `on enter` +# 900 Play renders the same frame it is entered (Hud.Draw) +# 201 900 frame 3: Play.World.Step, then Hud.Draw +# 202 900 frame 4: Step reaches 2 -> quit(); Hud.Draw paints the last frame +# +# ./selfhost/game-build.sh build/ludicc examples/scenes.ludic /tmp/scenes +# printf 'aaaa' | /tmp/scenes program SceneDemo { const R_N: int = 0 diff --git a/examples/scoped.ludic b/examples/scoped.ludic new file mode 100644 index 00000000..c3a405ce --- /dev/null +++ b/examples/scoped.ludic @@ -0,0 +1,21 @@ +# scoped.ludic — a despawned entity drops out of subsequent event-driven work +# (replaces tests/mod_c/scoped_mod.c, which tested entity-scoped foreign callbacks +# swept on despawn). Here a @On(Tick) listener counts live Units each tick; after +# the Unit is despawned, a further tick finds none. Fires twice before the kill, +# not the third time. Prints 2. +program Scoped { + property Health { hp: int = 0 } + model Unit { Health } + var fires: int = 0 + event Tick { } + @On(Tick) handler OnTick { for (Health) in query [Health, {Unit}] { fires = fires + 1 } } + + entry { + spawn Unit { Health { hp: 1 } } + emit Tick() # 1 live Unit -> fires = 1 + emit Tick() # fires = 2 + for (Health) in query [Health, {Unit}] { despawn self() } # kill the Unit + emit Tick() # no live Units -> fires stays 2 + print(fires) # 2 + } +} diff --git a/examples/world_dyn.ludic b/examples/world_dyn.ludic new file mode 100644 index 00000000..179302b8 --- /dev/null +++ b/examples/world_dyn.ludic @@ -0,0 +1,27 @@ +# world_dyn.ludic — EV7 reflection: register a brand-new component at runtime +# (replaces tests/mod_c/world_dyn.c). world_register_prop declares a component the +# game never wrote; world_attach_dyn adds it to an entity; get/set/has then treat +# it exactly like a built-in, with per-entity isolation. Prints 0 1 30 100 1 30. +program WorldDyn { + property Health { hp: int = 0, max: int = 0 } + model Unit { Health } + @Public @OnSpawn(Unit) handler Init { } + + entry { + let Um = world_model_id("Unit") + let e = world_spawn(Um) + let e2 = world_spawn(Um) + let Mana = world_register_prop("Mana", 2) # a component never declared in source + print(world_has(e, Mana)) # 0 — not attached yet + world_attach_dyn(e, Mana) + print(world_has(e, Mana)) # 1 + world_set(e, Mana, 0, 30) # field 0 (current) + world_set(e, Mana, 1, 100) # field 1 (max) + print(world_get(e, Mana, 0)) # 30 + print(world_get(e, Mana, 1)) # 100 + if world_prop_id("Mana") == Mana { print(1) } else { print(0) } # 1 — name resolves + world_attach_dyn(e2, Mana) + world_set(e2, Mana, 0, 7) + print(world_get(e, Mana, 0)) # 30 — per-entity isolation + } +} diff --git a/examples/world_get.ludic b/examples/world_get.ludic new file mode 100644 index 00000000..64d10f88 --- /dev/null +++ b/examples/world_get.ludic @@ -0,0 +1,22 @@ +# world_get.ludic — EV2 reflection: read and write a component by NAME through the +# world table, driven from Ludic (replaces tests/mod_c/world_mod.c). world_prop_id +# / world_field_id resolve names to ids; world_get / world_set / world_has read and +# write by those ids — the same reflection ABI a foreign mod binds, now callable +# from Ludic. Spawns a Unit (Init sets hp=max=50), then reads/tests/writes hp. +# Prints 50 / 1 / 7. +program WorldGet { + property Health { hp: int = 0, max: int = 0 } + model Unit { Health } + @Public @OnSpawn(Unit) handler Init { Health.hp = Health.max } # -> emits the world table + + entry { + spawn Unit { Health { max: 50 } } + let H = world_prop_id("Health") + let hp = world_field_id(H, "hp") + let e = world_query_next(H, 0) + print(world_get(e, H, hp)) # 50 — read by name + print(world_has(e, H)) # 1 — entity has Health + world_set(e, H, hp, 7) # write by name + print(world_get(e, H, hp)) # 7 — the write stuck + } +} diff --git a/examples/world_mixed.ludic b/examples/world_mixed.ludic new file mode 100644 index 00000000..fc37f7d0 --- /dev/null +++ b/examples/world_mixed.ludic @@ -0,0 +1,17 @@ +# world_mixed.ludic — EV2b reflection: get/set use real struct offsets, not a +# field*4 assumption (replaces tests/mod_c/world_mixed.c). Slot's `qty` sits after +# a `ptr` field, so its byte offset is 8, not 4; writing qty=99 by name and reading +# it back proves the world table addresses fields by their true layout. Prints 99. +program WorldMixed { + property Slot { ref: ptr = null, qty: int = 0 } + model Item { Slot } + @Public @OnSpawn(Item) handler Born { } # makes it a modding program + + entry { + let e = world_spawn(world_model_id("Item")) + let S = world_prop_id("Slot") + let qty = world_field_id(S, "qty") # field index 1, after the ptr + world_set(e, S, qty, 99) + print(world_get(e, S, qty)) # 99 iff the offset is 8, not 4 + } +} diff --git a/examples/world_query.ludic b/examples/world_query.ludic new file mode 100644 index 00000000..33cf843b --- /dev/null +++ b/examples/world_query.ludic @@ -0,0 +1,26 @@ +# world_query.ludic — EV2b reflection: iterate the world by property (replaces +# tests/mod_c/world_query.c). world_query_next(prop, from) returns the next live +# entity (>= from) that has the property, or -1 — so a mod walks all bearers of a +# component without knowing the models. Two Units (hp 50, 60) → count 2, sum 110. +program WorldQuery { + property Health { hp: int = 0, max: int = 0 } + model Unit { Health } + @Public @OnSpawn(Unit) handler Init { Health.hp = Health.max } + + entry { + spawn Unit { Health { max: 50 } } + spawn Unit { Health { max: 60 } } + let H = world_prop_id("Health") + let hp = world_field_id(H, "hp") + var count = 0 + var sum = 0 + var e = world_query_next(H, 0) + while e >= 0 { + count = count + 1 + sum = sum + world_get(e, H, hp) + e = world_query_next(H, e + 1) + } + print(count) # 2 + print(sum) # 110 + } +} diff --git a/examples/world_scan.ludic b/examples/world_scan.ludic new file mode 100644 index 00000000..e82bde5c --- /dev/null +++ b/examples/world_scan.ludic @@ -0,0 +1,30 @@ +# world_scan.ludic — EV2b reflection: scan the world and identify each entity by +# MODEL, by name (replaces tests/mod_c/world_scan.c). world_count / world_kind / +# world_model_id let a mod walk every entity and pick out a model's instances, then +# read their fields with world_get. Two Units (hp 50, 60) → count 2, sum 110. +program WorldScan { + property Health { hp: int = 0, max: int = 0 } + model Unit { Health } + @Public @OnSpawn(Unit) handler Init { Health.hp = Health.max } + + entry { + spawn Unit { Health { max: 50 } } + spawn Unit { Health { max: 60 } } + let H = world_prop_id("Health") + let hp = world_field_id(H, "hp") + let Um = world_model_id("Unit") + let n = world_count() + var count = 0 + var sum = 0 + var e = 0 + while e < n { + if world_kind(e) == Um { + count = count + 1 + sum = sum + world_get(e, H, hp) + } + e = e + 1 + } + print(count) # 2 + print(sum) # 110 + } +} diff --git a/examples/world_spawn.ludic b/examples/world_spawn.ludic new file mode 100644 index 00000000..bbb39e9b --- /dev/null +++ b/examples/world_spawn.ludic @@ -0,0 +1,20 @@ +# world_spawn.ludic — EV2b reflection: a mod creates a fresh entity by model id +# (replaces tests/mod_c/world_spawn.c). world_spawn reuses the compiler's own +# spawn lowering (alloc, kind, component defaults, @OnSpawn), so a mod-spawned +# entity is indistinguishable from one born in source. Prints 1 / 42 / 1. +program WorldSpawn { + property Health { hp: int = 0, max: int = 0 } + model Unit { Health } + @Public @OnSpawn(Unit) handler Init { } # world table; leave defaults + + entry { + let Um = world_model_id("Unit") + let e = world_spawn(Um) # the mod creates an entity + let H = world_prop_id("Health") + let hp = world_field_id(H, "hp") + print(world_has(e, H)) # 1 — spawn attached Health with defaults + world_set(e, H, hp, 42) + print(world_get(e, H, hp)) # 42 + print(world_count()) # 1 — it is really in the world + } +} diff --git a/selfhost/ast.ludic b/selfhost/ast.ludic index 1bd816f4..48bd6351 100644 --- a/selfhost/ast.ludic +++ b/selfhost/ast.ludic @@ -17,6 +17,18 @@ const N_EXTERN: int = 11 const N_UI: int = 12 const N_ENUM: int = 27 # enum Name { A, B, ... } — named int constants const S_TOGGLE: int = 28 # enable/disable (ival: 1=enable 0=disable; s=target; a=entity or null) +const N_SCENE: int = 45 # scene Name [start] { on enter{} on exit{} layer L { handlers } } + # s=name ival=scene id a=on-enter block b=on-exit block +const S_ATTACH: int = 46 # attach P on e [{ overrides }] — add a property to a live entity + # s=property a=entity expr b=override record (E_REC) or null +const S_DETACH: int = 47 # detach P on e — remove a property from a live entity + # s=property a=entity expr +const N_EVENT: int = 48 # event Name { field: T = default, ... } — a public event payload + # s=name kids=payload fields (N_FIELD) +const S_EMIT: int = 49 # emit E(field: v, ...) — fire event E (calls its @On listeners) + # s=event name a=E_REC of named args; also usable as an + # expression (a cancellable event returns its cancelled flag) +const S_CANCEL: int = 50 # cancel — inside a listener, veto a `cancellable` event # statements const S_LET: int = 10 const S_ASSIGN: int = 11 diff --git a/selfhost/bootstrap-cfree.sh b/selfhost/bootstrap-cfree.sh index 2b23b48f..35fe0c66 100755 --- a/selfhost/bootstrap-cfree.sh +++ b/selfhost/bootstrap-cfree.sh @@ -23,7 +23,8 @@ echo " seed.ll --clang--> sh_seed (no C compiler used)" FRAGS="selfhost/str.ludic selfhost/buf.ludic selfhost/io.ludic selfhost/ast.ludic selfhost/lex.ludic selfhost/parse.ludic selfhost/parse_game.ludic selfhost/emit_core.ludic selfhost/emit_head.ludic selfhost/emit_addr.ludic selfhost/emit_intrin.ludic selfhost/emit_intrin2.ludic selfhost/emit_math.ludic selfhost/emit_new.ludic -selfhost/emit_expr.ludic selfhost/emit_stmt.ludic selfhost/emit_ecs.ludic selfhost/emit_query.ludic selfhost/emit_spawn.ludic selfhost/emit_game.ludic selfhost/emit_machine.ludic selfhost/emit_save.ludic selfhost/emit_ui.ludic selfhost/emit_decl.ludic selfhost/main.ludic" +selfhost/emit_expr.ludic selfhost/emit_stmt.ludic selfhost/emit_ecs.ludic selfhost/emit_query.ludic selfhost/emit_spawn.ludic selfhost/emit_game.ludic selfhost/emit_machine.ludic selfhost/emit_save.ludic +selfhost/emit_net.ludic selfhost/emit_ui.ludic selfhost/emit_decl.ludic selfhost/main.ludic" { echo "program SelfHost {"; for f in $FRAGS; do cat "$f"; echo; done; echo "}"; } > "$B/selfhost.ludic" # the seed-built compiler compiles its own source diff --git a/selfhost/build.sh b/selfhost/build.sh index b32c5374..4951b444 100755 --- a/selfhost/build.sh +++ b/selfhost/build.sh @@ -29,6 +29,7 @@ selfhost/emit_spawn.ludic selfhost/emit_game.ludic selfhost/emit_machine.ludic selfhost/emit_save.ludic +selfhost/emit_net.ludic selfhost/emit_ui.ludic selfhost/emit_decl.ludic selfhost/main.ludic" diff --git a/selfhost/emit_core.ludic b/selfhost/emit_core.ludic index bc97a61d..4e473ee4 100644 --- a/selfhost/emit_core.ludic +++ b/selfhost/emit_core.ludic @@ -34,6 +34,20 @@ var nself: int = 0 var mach_stk: []Node # enclosing `machine` nodes, so `become` finds its register var nmach: int = 0 +# scenes: one implicit active-scene register (@L_scene). A scene lowers to a +# machine the compiler writes for you — `become ` runs the source scene's +# on-exit, stores the target id, and runs its on-enter. +var g_scenes: []Node # every `scene` declaration, in source order (ival = id) +var g_scene_count: int = 0 # parse-time id counter +var g_start_scene: int = 0 # id of the scene marked `start` (else the first) +var g_cur_scene: Node = null # scene owning the handler being emitted, for `become` + +fn find_scene(name: ptr) -> Node { + var i = 0 + while i < len(g_scenes) { if (g_scenes[i].s == name) { return g_scenes[i] }; i = i + 1 } + return null +} + fn emit(s: ptr) -> void { buf_puts(code, s) } fn emith(s: ptr) -> void { buf_puts(head, s) } @@ -52,7 +66,7 @@ fn lbl(pfx: ptr) -> ptr { let r = (pfx + itoa(ll_lbl)); ll_lbl = ll_lbl + 1; r # Ludic type -> LLVM type. int/bool are i32; everything else (ptr/str/struct/ # slice) is a pointer; void is void. fn llty(t: ptr) -> ptr { - if (t == "int") or (t == "bool") or (t == "fixed") { return "i32" } + if (t == "int") or (t == "bool") or (t == "fixed") or (t == "entity") { return "i32" } # entity = an i32 handle (self()) if (t == "byte") { return "i8" } # a single byte (p[i] on a raw ptr) if (t == "words") or (t == "fixeds") or (t == "ptrs") { return "ptr" } # typed buffers if (t == "void") { return "void" } @@ -112,6 +126,13 @@ fn enum_ordinal(ename: ptr, vname: ptr) -> int { } i = i + 1 } + # LC1: the compiler owns `EndReason` — the reason bound by a reason-carrying + # teardown (`@OnDespawn(M, reason: r)`). Each despawn site passes one of these. + if (ename == "EndReason") { + if (vname == "Despawned") { return 0 } # explicit `despawn e` + if (vname == "SceneExit") { return 1 } # a scene tearing down its owned entities + if (vname == "Quit") { return 2 } # program shutdown + } return 0 - 1 } fn find_fn(name: ptr) -> Node { @@ -120,6 +141,17 @@ fn find_fn(name: ptr) -> Node { return null } +# `extern fn name(params) -> T = "sym"` binds a Ludic name to a link symbol. A +# call to `name` lowers to a direct `@` call (no @fn_ prefix — the string is +# the exact linked symbol), and emit_extern_decls emits a matching `declare`. This +# is the transport seam (net_send/net_poll), the windowing/socket FFI, and any +# C/Rust/Zig library binding — the same seam NETWORKING-DESIGN §5 names. +fn find_extern(name: ptr) -> Node { + var i = 0 + while i < len(prog) { let d = prog[i]; if d.kind == N_EXTERN and (d.s == name) { return d }; i = i + 1 } + return null +} + # @Computed derived fields: a per-property (Prop.field -> expression) registry. # These are NOT stored in the component layout; `x.field` expands inline to the # expression with its bare names read as fields of `x`. Populated at parse time. @@ -162,8 +194,11 @@ fn onspawn_body(model: ptr) -> Node { var g_ondespawn: []Node # each: s = Model name, a = hook body block var g_onattach: []Node # each: s = Property name, a = hook body block -fn register_ondespawn(model: ptr, body: Node) -> void { - let n = node(N_BLOCK); n.s = model; n.a = body; push(g_ondespawn, n) +# LC1: `.ty` carries the optional `reason:` binding name (null if the hook took +# no reason). The despawn hook function gains an `i32 %reason` parameter and each +# teardown site passes a constant EndReason (see emit_despawn_hooks / emit_despawn). +fn register_ondespawn(model: ptr, body: Node, reason: ptr) -> void { + let n = node(N_BLOCK); n.s = model; n.a = body; n.ty = reason; push(g_ondespawn, n) } fn ondespawn_body(model: ptr) -> Node { var i = 0 @@ -179,6 +214,19 @@ fn onattach_body(prop: ptr) -> Node { return null } +# @OnDetach(Property): the teardown paired with @OnAttach — fires when a property +# is removed from a live entity (`detach P on e`), with the property bound by name +# so the body can read its outgoing value before it is cleared. +var g_ondetach: []Node # each: s = Property name, a = hook body block +fn register_ondetach(prop: ptr, body: Node) -> void { + let n = node(N_BLOCK); n.s = prop; n.a = body; push(g_ondetach, n) +} +fn ondetach_body(prop: ptr) -> Node { + var i = 0 + while i < len(g_ondetach) { if (g_ondetach[i].s == prop) { return g_ondetach[i].a }; i = i + 1 } + return null +} + # @OnEnable(Property) / @OnDisable(Property): run when a property is toggled on an # entity, with the property bound by name. var g_onenable: []Node @@ -196,6 +244,59 @@ fn ondisable_body(prop: ptr) -> Node { return null } +# EV0 — the event bus core. `event E { fields }` declares a POD payload; `@On(E) +# handler …` registers a compile-time listener; `emit E(…)` fires it. An event +# lowers to a `@ev_(payload)` function whose body is the concatenation of its +# listeners in declaration order — a direct call at each `emit` site, no runtime. +# Gated on `len(g_events) > 0`, so a program with no events is byte-identical. +var g_events: []Node # each: an N_EVENT node (s = name, kids = payload fields, ival=1 if cancellable) +var g_onlisten: []Node # each: N_BLOCK, s = event name, a = listener body block +var g_cancel_addr: ptr = null # EV3: address of the current cancellable dispatch's flag (null outside one) + +fn register_event(n: Node) -> void { push(g_events, n) } +fn find_event(name: ptr) -> Node { + var i = 0 + while i < len(g_events) { if (g_events[i].s == name) { return g_events[i] }; i = i + 1 } + return null +} +fn register_onlisten(evt: ptr, body: Node) -> void { + let n = node(N_BLOCK); n.s = evt; n.a = body; push(g_onlisten, n) +} + +# EV1 — `@Public` promotes a lifecycle hook to a public event. A promoted event +# is synthesized here (payload = the entity, plus a reason for despawn); its +# presence in g_events is what makes each lifecycle fire site also `emit` it, so +# `find_event(name) != null` doubles as the "is this hook public?" test. Names are +# the stable ABI contract: `model__spawn`, `model__despawn`, etc. +fn ensure_event(name: ptr, with_reason: bool) -> void { + if (find_event(name) != null) { return } + let n = node(N_EVENT); n.s = name + let ent = node(N_FIELD); ent.s = "entity"; ent.ty = "int"; push(n.kids, ent) + if with_reason { let r = node(N_FIELD); r.s = "reason"; r.ty = "int"; push(n.kids, r) } + register_event(n) +} +# a promoted scene/program event has no per-entity payload +fn ensure_event_empty(name: ptr) -> void { + if (find_event(name) != null) { return } + let n = node(N_EVENT); n.s = name; register_event(n) +} + +# EV1/SCENES-E2 — layer toggle. A layer named in an `enable layer L`/`disable +# layer L` statement becomes "managed": it gets an @LE_ enabled flag and its +# handlers gate on it. Only managed layers pay for this, so a scene program that +# never toggles a layer is byte-identical. +var g_toggled_layers: []ptr +fn note_toggled_layer(name: ptr) -> void { + var i = 0 + while i < len(g_toggled_layers) { if (g_toggled_layers[i] == name) { return }; i = i + 1 } + push(g_toggled_layers, name) +} +fn is_toggled_layer(name: ptr) -> bool { + var i = 0 + while i < len(g_toggled_layers) { if (g_toggled_layers[i] == name) { return true }; i = i + 1 } + return false +} + # is `name` a model (archetype)? — chooses model-vs-handler for a bare enable/disable fn is_model(name: ptr) -> bool { return find_arch_id(name) > 0 } diff --git a/selfhost/emit_decl.ludic b/selfhost/emit_decl.ludic index 86bea6ad..0917db11 100644 --- a/selfhost/emit_decl.ludic +++ b/selfhost/emit_decl.ludic @@ -70,21 +70,32 @@ fn emit_program() -> void { g_uses_str = false g_uses_intstr = false g_uses_strslice = false + g_uses_loopback = false loc_name = new []ptr; loc_reg = new []ptr; loc_ty = new []ptr; loc_mut = new []int brk_lbl = new []ptr; cnt_lbl = new []ptr self_stk = new []ptr mach_stk = new []Node emit_header() + emit_extern_decls() if has_ecs() { emit_ecs_storage() } var i = 0 while i < len(prog) { if prog[i].kind == N_FN { emit_fn(prog[i]) }; i = i + 1 } + if len(g_events) > 0 { emit_event_fns() } # EV0: @ev_ event-dispatch functions + if has_ecs() and len(g_events) > 0 { emit_world_table() } # EV2: the mod reflection ABI if has_ecs() { emit_ecs_allocator(); emit_snapshot() } + if has_ecs() { emit_net() } # N2/N3: @Sync serializers + @Owned storage (gated internally) if has_ui() { emit_ui_build() } - if has_systems() { emit_game_main() } - else { + if has_systems() and has_entry() { # N5: game owns its loop via `entry` + emit_game_defs() # system fns, hooks, tick helpers i = 0 while i < len(prog) { if prog[i].kind == N_MAIN { emit_main(prog[i]) }; i = i + 1 } } + else { if has_systems() { emit_game_main() } # the auto frame loop + else { + i = 0 + while i < len(prog) { if prog[i].kind == N_MAIN { emit_main(prog[i]) }; i = i + 1 } + } } + if g_uses_loopback { emit_loopback() } # built-in transport, after all net_send/net_poll uses are seen if g_uses_str { emit_str_prelude() } # @fn_str_eq / @fn_str_concat, after all uses are seen if g_uses_intstr { emit_int_str() } # @fn_int_str, for str(int) in interpolation if g_uses_strslice { emit_str_slice() } # @fn_str_slice, for s[a..b] diff --git a/selfhost/emit_ecs.ludic b/selfhost/emit_ecs.ludic index fb091522..6a9878c3 100644 --- a/selfhost/emit_ecs.ludic +++ b/selfhost/emit_ecs.ludic @@ -15,6 +15,14 @@ fn has_models() -> bool { while i < len(prog) { if prog[i].kind == N_ARCH { return true }; i = i + 1 } return false } +# N5: does the program have an `entry` block? A game with both handlers and an +# `entry` drives its own loop (calling tick_fixed/tick_render), instead of the +# compiler's auto frame loop. A game with handlers and no entry uses the auto-loop. +fn has_entry() -> bool { + var i = 0 + while i < len(prog) { if prog[i].kind == N_MAIN { return true }; i = i + 1 } + return false +} # Does this program run the ECS? A property alone no longer answers that — the # same `property` keyword also declares plain `new`-allocated records (the merged # `struct`). A program uses the ECS when it has a handler or a model; a tool that @@ -25,12 +33,22 @@ fn has_ecs() -> bool { return has_systems() or has_models() } fn emit_ecs_storage() -> void { emith("@L_running = internal global i32 1\n") emith("@L_key = internal global i32 0\n") + if len(g_scenes) > 0 { emith("@L_scene = internal global i32 0\n") } # active base scene id emith("@L_entc = internal global i32 0\n") let me = itoa(MAX_ENT) emith(`@L_alive = internal global [{me} x i32] zeroinitializer\n`) emith(`@L_kind = internal global [{me} x i32] zeroinitializer\n`) emith(`@L_freelist = internal global [{me} x i32] zeroinitializer\n`) emith("@L_freen = internal global i32 0\n") + # NETWORKING role registers (N3/N5): a runtime sets these; offline they hold the + # single-player default — @L_role=1 (this peer is the authority), local id 0. + # Emitted only when a networking feature is used, so non-networked builds are + # byte-identical (§8). @L_owner_arr is the per-entity network owner (N3, @Owned). + if net_any() { + emith("@L_role = internal global i32 1\n") # 1 = server/authority (offline default) + emith("@L_localid = internal global i32 0\n") # this peer's id + } + if net_has_owned() { emith(`@L_owner_arr = internal global [{me} x i32] zeroinitializer\n`) } var i = 0 while i < len(prog) { let c = prog[i] @@ -46,6 +64,9 @@ fn emit_ecs_storage() -> void { if c.kind == N_SYS { emith(`@HE_{c.s} = internal global i32 1\n`) } i = i + 1 } + # one enabled-flag global per toggled layer (default shown) + var li = 0 + while li < len(g_toggled_layers) { emith(`@LE_{g_toggled_layers[li]} = internal global i32 1\n`); li = li + 1 } } # L_reset(e): clear every has-flag and the archetype kind for entity e @@ -62,7 +83,13 @@ fn emit_ecs_allocator() -> void { i = i + 1 } emit(" %k = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_kind, i32 0, i32 %e\n") - emit(" store i32 0, ptr %k\n ret void\n}\n\n") + emit(" store i32 0, ptr %k\n") + # N3: reset an @Owned entity's network owner to -1 (unowned) on alloc/free + if net_has_owned() { + emit(" %ow = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_owner_arr, i32 0, i32 %e\n") + emit(" store i32 -1, ptr %ow\n") + } + emit(" ret void\n}\n\n") emit("define i32 @L_alloc() {\nentry:\n") emit(" %fn = load i32, ptr @L_freen\n") diff --git a/selfhost/emit_expr.ludic b/selfhost/emit_expr.ludic index ce7f294b..52a2a2a4 100644 --- a/selfhost/emit_expr.ludic +++ b/selfhost/emit_expr.ludic @@ -123,7 +123,78 @@ fn emit_call(e: Node) -> Val { if (name == "save") { emit(" call void @L_save()\n"); return val("0", "void") } if (name == "ui_build") { emit(" call void @ui_build()\n"); return val("0", "void") } if (name == "load") { return val(emit_bind("call i32 @L_load()"), "bool") } + if (name == "world_size") { return val(emit_bind("call i32 @L_world_size()"), "int") } + if (name == "world_save") { # world_save(buf) -> bytes written + let b = emit_expr(e.kids[0]) + return val(emit_bind(`call i32 @L_world_save(ptr {b.code})`), "int") + } + if (name == "world_load") { # world_load(buf, len) + let b = emit_expr(e.kids[0]) + let l = emit_expr(e.kids[1]) + emit(" call void @L_world_load(ptr "); emit(b.code); emit(", i32 "); emit(l.code); emit(")\n") + return val("0", "void") + } if (name == "quit") { emit(" store i32 0, ptr @L_running\n"); return val("0", "void") } + # NETWORKING (NETWORKING-DESIGN §5) — the low-level freedom layer, callable from + # Ludic. serialize/apply/sync_size lower to the @Sync by-kind dispatchers (N2); + # owner/set_owner/is_owner to the @Owned storage (N3); is_server/local_id read + # the runtime-set role registers (N5). Offline these hold their single-player + # default (@L_role=1 → is_server()==true), so guards collapse to "run here" (§8). + if (name == "serialize") { # serialize(e, buf) -> bytes written + let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]) + return val(emit_bind(`call i32 @ludic_serialize(i32 {a.code}, ptr {b.code})`), "int") + } + if (name == "apply") { # apply(e, buf, len) + let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]); let c = emit_expr(e.kids[2]) + emit(" call void @ludic_apply(i32 "); emit(a.code); emit(", ptr "); emit(b.code); emit(", i32 "); emit(c.code); emit(")\n") + return val("0", "void") + } + if (name == "sync_size") { # sync_size(e) -> replicated byte count for e's model + let a = emit_expr(e.kids[0]) + return val(emit_bind(`call i32 @ludic_sync_size(i32 {a.code})`), "int") + } + if (name == "owner") { # owner(e) -> peer id (-1 = unowned) + let a = emit_expr(e.kids[0]) + return val(emit_bind(`call i32 @L_owner(i32 {a.code})`), "int") + } + if (name == "set_owner") { # set_owner(e, id) + let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]) + emit(" call void @L_set_owner(i32 "); emit(a.code); emit(", i32 "); emit(b.code); emit(")\n") + return val("0", "void") + } + if (name == "is_owner") { # is_owner(e) -> owner(e) == local_id() + let a = emit_expr(e.kids[0]) + return val(emit_bind(`call i32 @L_is_owner(i32 {a.code})`), "bool") + } + if (name == "is_server") { # is_server() -> the local peer is the authority + let r = emit_bind("load i32, ptr @L_role") + let c = emit_bind(`icmp eq i32 {r}, 1`) + return val(emit_bind(`zext i1 {c} to i32`), "bool") + } + if (name == "local_id") { return val(emit_bind("load i32, ptr @L_localid"), "int") } + if (name == "net_pump") { emit(" call void @L_net_pump()\n"); return val("0", "void") } # N4: drain + re-emit inbound RPCs + if (name == "tick_fixed") { emit(" call void @L_tick_fixed()\n"); return val("0", "void") } # N5: run the sim phases + if (name == "tick_render") { emit(" call void @L_tick_render()\n"); return val("0", "void") } # N5: run the Render phase + if (name == "set_role") { # N5: the runtime sets the peer's role (1=server, 0=client) + let a = emit_expr(e.kids[0]); emit(" store i32 "); emit(a.code); emit(", ptr @L_role\n"); return val("0", "void") + } + if (name == "set_local_id") { # N5: the runtime sets this peer's id + let a = emit_expr(e.kids[0]); emit(" store i32 "); emit(a.code); emit(", ptr @L_localid\n"); return val("0", "void") + } + # net_send(peer, buf, len) / net_poll(buf, cap): the transport seam. An + # `extern fn` of the same name (a real socket) wins; absent one, these lower to + # the compiler's built-in loopback so a game is networked with zero foreign code. + if (name == "net_send") and (find_extern("net_send") == null) { + g_uses_loopback = true + let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]); let c = emit_expr(e.kids[2]) + emit(" call void @L_net_send(i32 "); emit(a.code); emit(", ptr "); emit(b.code); emit(", i32 "); emit(c.code); emit(")\n") + return val("0", "void") + } + if (name == "net_poll") and (find_extern("net_poll") == null) { + g_uses_loopback = true + let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]) + return val(emit_bind(`call i32 @L_net_poll(ptr {a.code}, i32 {b.code})`), "int") + } if (name == "len") { return emit_len(e) } if (name == "push") { return emit_push(e) } if (name == "str") { # str(x): int/bool/fixed -> text, a string passes through @@ -151,9 +222,55 @@ fn emit_call(e: Node) -> Val { } 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") } + # The EV2 reflection ABI (the world table), exposed to Ludic so a Ludic mod can + # introspect the world by name — the same functions a foreign mod binds. Emitted + # only for a modding program (ECS + events), so a plain game is unchanged. + if (name == "world_prop_id") { let a = emit_expr(e.kids[0]); return val(emit_bind(`call i32 @ludic_prop_id(ptr {a.code})`), "int") } + if (name == "world_field_id") { let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]); return val(emit_bind(`call i32 @ludic_field_id(i32 {a.code}, ptr {b.code})`), "int") } + if (name == "world_get") { + let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]); let c = emit_expr(e.kids[2]) + let r = emit_bind(`call i64 @ludic_get(i32 {a.code}, i32 {b.code}, i32 {c.code})`) + return val(emit_bind(`trunc i64 {r} to i32`), "int") + } + if (name == "world_set") { + let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]); let c = emit_expr(e.kids[2]); let d = emit_expr(e.kids[3]) + let v64 = emit_bind(`sext i32 {d.code} to i64`) + emit(" call void @ludic_set(i32 "); emit(a.code); emit(", i32 "); emit(b.code); emit(", i32 "); emit(c.code); emit(", i64 "); emit(v64); emit(")\n") + return val("0", "void") + } + if (name == "world_has") { let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]); return val(emit_bind(`call i32 @ludic_has(i32 {a.code}, i32 {b.code})`), "int") } + if (name == "world_count") { return val(emit_bind("call i32 @ludic_entity_count()"), "int") } + if (name == "world_kind") { let a = emit_expr(e.kids[0]); return val(emit_bind(`call i32 @ludic_kind(i32 {a.code})`), "int") } + if (name == "world_model_id") { let a = emit_expr(e.kids[0]); return val(emit_bind(`call i32 @ludic_model_id(ptr {a.code})`), "int") } + if (name == "world_query_next") { let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]); return val(emit_bind(`call i32 @ludic_query_next(i32 {a.code}, i32 {b.code})`), "int") } + if (name == "world_register_prop") { let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]); return val(emit_bind(`call i32 @ludic_register_prop(ptr {a.code}, i32 {b.code})`), "int") } + if (name == "world_attach_dyn") { let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]); emit(" call void @ludic_attach_dyn(i32 "); emit(a.code); emit(", i32 "); emit(b.code); emit(")\n"); return val("0", "void") } + if (name == "world_detach_dyn") { let a = emit_expr(e.kids[0]); let b = emit_expr(e.kids[1]); emit(" call void @ludic_detach_dyn(i32 "); emit(a.code); emit(", i32 "); emit(b.code); emit(")\n"); return val("0", "void") } + if (name == "world_spawn") { let a = emit_expr(e.kids[0]); return val(emit_bind(`call i32 @ludic_spawn(i32 {a.code})`), "int") } if is_intrinsic(name) { return emit_intrinsic(name, e) } if is_intrinsic2(name) { return emit_intrinsic2(name, e) } if is_math_builtin(name) { return emit_math_builtin(name, e) } + # extern fn: a direct call to the declared link symbol (no @fn_ prefix) + let ext = find_extern(name) + if (ext != null) { + let eargs = new []ptr + let eatys = new []ptr + var ei = 0 + while ei < len(e.kids) { let v = emit_expr(e.kids[ei]); push(eargs, v.code); push(eatys, v.ty); ei = ei + 1 } + let erl = llty(ext.ty) + emit(" ") + var erreg = "0" + if not (erl == "void") { erreg = nreg(); emit(erreg); emit(" = ") } + emit("call "); emit(erl); emit(" @"); emit(ext.a.s); emit("(") + ei = 0 + while ei < len(eargs) { + if ei > 0 { emit(", ") } + emit(llty(eatys[ei])); emit(" "); emit(eargs[ei]) + ei = ei + 1 + } + emit(")\n") + return val(erreg, ext.ty) + } var fn2 = find_fn(name) var cname = name if (fn2 == null) { @@ -234,6 +351,7 @@ fn emit_expr(e: Node) -> Val { } return emit_load_at(a, g_addr_ty) } + if e.kind == S_EMIT { return emit_emit(e) } # emit as an expression -> cancelled flag if e.kind == E_CALL { return emit_call(e) } if e.kind == E_BIN { return emit_bin(e) } if e.kind == E_UN { diff --git a/selfhost/emit_game.ludic b/selfhost/emit_game.ludic index 679450c0..5145c16e 100644 --- a/selfhost/emit_game.ludic +++ b/selfhost/emit_game.ludic @@ -4,6 +4,7 @@ # called only when the runtime defines them. fn emit_system_fn(sys: Node) -> void { + g_cur_scene = sys.c # scene owning this handler (null if global) — for `become` ll_t = 0; ll_lbl = 0; g_term = false; loc_reset(); nloop = 0; nself = 0 ret_ty = "void" let fbody = buf_new() @@ -20,24 +21,101 @@ fn emit_system_fn(sys: Node) -> void { emit("}\n\n") } +# one enable-gated call to @sys_ (skipped while the handler is disabled). +fn emit_call_one(d: Node) -> void { + let he = emit_bind(`load i32, ptr @HE_{d.s}`) + var hc = emit_bind(`icmp ne i32 {he}, 0`) + # a handler in a toggled layer also gates on its layer's @LE_ flag (byte-identical + # for layers that are never enabled/disabled, since d.b is only read when managed) + if (d.b != null) and is_toggled_layer(d.b.s) { + let le = emit_bind(`load i32, ptr @LE_{d.b.s}`) + let lc = emit_bind(`icmp ne i32 {le}, 0`) + hc = emit_bind(`and i1 {hc}, {lc}`) + } + # N5: an @Server handler (d.ival==1) runs only on the authority (@L_role==1). + # Unmarked and @Predicted handlers run on every peer. Offline @L_role defaults to + # 1, so the guard collapses to "run here" and a non-networked build is unchanged. + if d.ival == 1 { + let rv = emit_bind("load i32, ptr @L_role") + let rc = emit_bind(`icmp eq i32 {rv}, 1`) + hc = emit_bind(`and i1 {hc}, {rc}`) + } + let run = lbl("hrun"); let skip = lbl("hskip") + emit(" br i1 "); emit(hc); emit(", label %"); emit(run); emit(", label %"); emit(skip); emit("\n") + emit(run); emit(":\n call void @sys_"); emit(d.s); emit("()\n") + emit(" br label %"); emit(skip); emit("\n"); emit(skip); emit(":\n") +} + +# Global handlers run first, then the active scene's layer handlers in +# declaration (draw) order. The active scene is snapshotted once per phase, so a +# `become` mid-phase takes effect at the next phase boundary — exactly one scene +# is active within any single phase. fn emit_calls_for_phase(phase: ptr) -> void { var i = 0 while i < len(prog) { let d = prog[i] - if d.kind == N_SYS and (d.ty == phase) { # skip a disabled handler - let he = emit_bind(`load i32, ptr @HE_{d.s}`) - let hc = emit_bind(`icmp ne i32 {he}, 0`) - let run = lbl("hrun"); let skip = lbl("hskip") - emit(" br i1 "); emit(hc); emit(", label %"); emit(run); emit(", label %"); emit(skip); emit("\n") - emit(run); emit(":\n call void @sys_"); emit(d.s); emit("()\n") + if d.kind == N_SYS and (d.ty == phase) and (d.c == null) { emit_call_one(d) } + i = i + 1 + } + # any scene-owned handlers in this phase? gate them on one @L_scene snapshot. + var has_sc = false + i = 0 + while i < len(prog) { let d = prog[i]; if d.kind == N_SYS and (d.ty == phase) and (d.c != null) { has_sc = true }; i = i + 1 } + if not has_sc { return } + let cs = emit_bind("load i32, ptr @L_scene") + i = 0 + while i < len(prog) { + let d = prog[i] + if d.kind == N_SYS and (d.ty == phase) and (d.c != null) { + let ce = emit_bind(`icmp eq i32 {cs}, {itoa(d.c.ival)}`) + let run = lbl("scrun"); let skip = lbl("scskip") + emit(" br i1 "); emit(ce); emit(", label %"); emit(run); emit(", label %"); emit(skip); emit("\n") + emit(run); emit(":\n") + emit_call_one(d) emit(" br label %"); emit(skip); emit("\n"); emit(skip); emit(":\n") } i = i + 1 } } -# @OnDespawn(Model) hooks compile to `@on_despawn_(entity)` functions that -# bind the model's properties and run the body — dispatched by kind at `despawn`. +# on enter / on exit compile to void functions @scene_enter_ / +# @scene_exit_, called at the transition point (and enter at boot for the +# start scene). Emitted for every scene, empty body when the hook is absent. +fn emit_scene_fn(name: ptr, kind: ptr, body: Node) -> void { + ll_t = 0; ll_lbl = 0; g_term = false; loc_reset(); nloop = 0; nself = 0 + ret_ty = "void" + let fbody = buf_new() + falloc = buf_new() + let saved = code + code = fbody + if (body != null) { emit_block(body) } + # EV1: a `public` scene fires scene__enter / scene__exit after its block + let sev = `scene_{name}_{kind}` + if (not g_term) and (find_event(sev) != null) { emit(" call void @ev_"); emit(sev); emit("()\n") } + if not g_term { emit(" br label %ret\n") } + emit("ret:\n ret void\n") + code = saved + emit("define void @scene_"); emit(kind); emit("_"); emit(name); emit("() {\nentry:\n") + emit(buf_str(falloc)) + emit(buf_str(fbody)) + emit("}\n\n") +} + +fn emit_scene_hooks() -> void { + var i = 0 + while i < len(g_scenes) { + let sc = g_scenes[i] + g_cur_scene = sc + emit_scene_fn(sc.s, "enter", sc.a) + emit_scene_fn(sc.s, "exit", sc.b) + i = i + 1 + } +} + +# @OnDespawn(Model) hooks compile to `@on_despawn_(entity, reason)` +# functions that bind the model's properties and run the body — dispatched by +# kind at `despawn`. LC1: the `i32 %reason` parameter carries an EndReason; when +# the hook declared `reason: r`, `r` is bound as an int local reading it. fn emit_despawn_hooks() -> void { var i = 0 while i < len(g_ondespawn) { @@ -49,30 +127,608 @@ fn emit_despawn_hooks() -> void { falloc = buf_new() let saved = code code = fbody + if (hk.ty != null) { # bind the reason: r name to %reason + let rslot = emit_alloca("i32") + emit(" store i32 %reason, ptr "); emit(rslot); emit("\n") + loc_push(hk.ty, rslot, "int") + } emit_bind_props(model, "%e") emit_block(hk.a) if not g_term { emit(" br label %ret\n") } emit("ret:\n ret void\n") code = saved - emit("define void @on_despawn_"); emit(hk.s); emit("(i32 %e) {\nentry:\n") + emit("define void @on_despawn_"); emit(hk.s); emit("(i32 %e, i32 %reason) {\nentry:\n") emit(buf_str(falloc)) emit(buf_str(fbody)) emit("}\n\n") i = i + 1 } + emit_despawn_all_fn() } -fn emit_game_main() -> void { - # every system becomes a function first +# LC1 "no silent deaths": at program shutdown every still-live entity's despawn +# hook fires with reason Quit, so teardown that must run on exit is not skipped. +# @L_despawn_all(reason) walks the live set and dispatches each entity by kind — +# the same per-model dispatch as `despawn`, but without freeing (the process is +# ending). Emitted only when the program has @OnDespawn hooks, so despawn-free +# programs are byte-for-byte unchanged. +fn emit_despawn_all_fn() -> void { + if len(g_ondespawn) == 0 { return } + let me = itoa(MAX_ENT) + emit("define void @L_despawn_all(i32 %reason) {\nentry:\n br label %loop\n") + emit("loop:\n %i = phi i32 [ 0, %entry ], [ %i1, %cont ]\n") + emit(" %n = load i32, ptr @L_entc\n %go = icmp slt i32 %i, %n\n") + emit(" br i1 %go, label %body, label %fin\n") + emit("body:\n %ap = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_alive, i32 0, i32 %i\n") + emit(" %al = load i32, ptr %ap\n %isa = icmp ne i32 %al, 0\n") + emit(" br i1 %isa, label %do, label %cont\n") + emit("do:\n %kp = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_kind, i32 0, i32 %i\n") + emit(" %k = load i32, ptr %kp\n") + var i = 0 + while i < len(g_ondespawn) { + let mname = g_ondespawn[i].s + let si = itoa(i) + emit(" %c"); emit(si); emit(" = icmp eq i32 %k, "); emit(itoa(find_arch_id(mname))); emit("\n") + emit(" br i1 %c"); emit(si); emit(", label %hit"); emit(si); emit(", label %next"); emit(si); emit("\n") + emit("hit"); emit(si); emit(":\n call void @on_despawn_"); emit(mname); emit("(i32 %i, i32 %reason)\n") + let dev = `model_{mname}_despawn` # EV1: @Public despawn event at shutdown + if (find_event(dev) != null) { emit(" call void @ev_"); emit(dev); emit("(i32 %i, i32 %reason)\n") } + emit(" br label %next"); emit(si); emit("\n") + emit("next"); emit(si); emit(":\n") + i = i + 1 + } + emit(" br label %cont\n") + emit("cont:\n %i1 = add i32 %i, 1\n br label %loop\n") + emit("fin:\n ret void\n}\n\n") +} + +# EV0: each declared `event E` compiles to a `@ev_(payload…)` function whose +# body is (1) its `@On(E)` listeners concatenated in declaration order — the +# closed, compile-time half — then (2) a loop over a runtime listener array, the +# open half a mod in another language joins through the C ABI. The payload fields +# arrive as params (%p0, %p1, …), bound by name so a listener body reads them bare +# (like a query/hook binding). Emitted only when g_events is non-empty, so an +# event-free program is byte-for-byte unchanged. +# +# The runtime half is the deliberate opt-in exception to "no dispatch tables": +# %Ev_ — the POD payload struct passed by pointer to foreign listeners +# @evL_ — a fixed-capacity [16 x ptr] array of foreign callbacks +# @evN_ — how many are registered (registration order = dispatch order) +# @ludic_on_(ptr cb) -> i32 — the C ABI: a mod appends its callback +# A native Ludic listener costs a direct call; a foreign one costs one indirect +# call. With no foreign listeners registered the loop runs zero times (one branch). +const EV_CAP: int = 16 +# EV6 — re-entrant emit is bounded: a listener may `emit` another event, but the +# nesting is capped so an event cycle traps as an early return instead of hanging +# the frame. @ev_depth counts the live dispatch nesting; past the cap a dispatch +# returns immediately (a cancellable event returns "not cancelled"). +const EV_DEPTH_CAP: int = 32 + +fn emit_event_fns() -> void { + emith("@ev_depth = global i32 0\n") # EV6 re-entrancy counter + var e = 0 + while e < len(g_events) { + let ev = g_events[e] + let en = ev.s + let cap = itoa(EV_CAP) + + # --- module-level: payload struct + the foreign listener registry (into head) + # A cancellable event's payload carries a trailing i32 `cancelled` flag that a + # listener (native or foreign) can set; the caller reads it back. + emith("%Ev_"); emith(en); emith(" = type { ") + var t = 0 + while t < len(ev.kids) { + if t > 0 { emith(", ") } + emith(llty(ev.kids[t].ty)) + t = t + 1 + } + if ev.ival == 1 { if len(ev.kids) > 0 { emith(", ") }; emith("i32") } + emith(" }\n") + emith("@evL_"); emith(en); emith(" = global ["); emith(cap); emith(" x ptr] zeroinitializer\n") + emith("@evN_"); emith(en); emith(" = global i32 0\n") + # EV5: a parallel owner array — -1 = program-scoped (never swept), >=0 = the + # entity that owns the listener (swept when that entity despawns). + emith("@evO_"); emith(en); emith(" = global ["); emith(cap); emith(" x i32] zeroinitializer\n") + + # --- @ludic_on_(cb): append a program-scoped callback, return a token + emit("define i32 @ludic_on_"); emit(en); emit("(ptr %cb) {\nentry:\n") + emit(" %n = load i32, ptr @evN_"); emit(en); emit("\n") + emit(" %full = icmp slt i32 %n, "); emit(cap); emit("\n") + emit(" br i1 %full, label %add, label %drop\n") + emit("add:\n %slot = getelementptr inbounds ["); emit(cap); emit(" x ptr], ptr @evL_"); emit(en); emit(", i32 0, i32 %n\n") + emit(" store ptr %cb, ptr %slot\n") + emit(" %oslot = getelementptr inbounds ["); emit(cap); emit(" x i32], ptr @evO_"); emit(en); emit(", i32 0, i32 %n\n") + emit(" store i32 -1, ptr %oslot\n") + emit(" %n1 = add i32 %n, 1\n store i32 %n1, ptr @evN_"); emit(en); emit("\n ret i32 %n\n") + emit("drop:\n ret i32 -1\n}\n\n") # registry full: reject (token -1) + + # --- @ludic_on_entity_(owner, cb): append an entity-scoped callback + emit("define i32 @ludic_on_entity_"); emit(en); emit("(i32 %owner, ptr %cb) {\nentry:\n") + emit(" %n = load i32, ptr @evN_"); emit(en); emit("\n") + emit(" %full = icmp slt i32 %n, "); emit(cap); emit("\n") + emit(" br i1 %full, label %add, label %drop\n") + emit("add:\n %slot = getelementptr inbounds ["); emit(cap); emit(" x ptr], ptr @evL_"); emit(en); emit(", i32 0, i32 %n\n") + emit(" store ptr %cb, ptr %slot\n") + emit(" %oslot = getelementptr inbounds ["); emit(cap); emit(" x i32], ptr @evO_"); emit(en); emit(", i32 0, i32 %n\n") + emit(" store i32 %owner, ptr %oslot\n") + emit(" %n1 = add i32 %n, 1\n store i32 %n1, ptr @evN_"); emit(en); emit("\n ret i32 %n\n") + emit("drop:\n ret i32 -1\n}\n\n") + + # --- @ludic_off_(token): remove a listener (tombstone the slot to null) + emit("define void @ludic_off_"); emit(en); emit("(i32 %tok) {\nentry:\n") + emit(" %n = load i32, ptr @evN_"); emit(en); emit("\n") + emit(" %lo = icmp sge i32 %tok, 0\n %hi = icmp slt i32 %tok, %n\n %ok = and i1 %lo, %hi\n") + emit(" br i1 %ok, label %do, label %skip\n") + emit("do:\n %slot = getelementptr inbounds ["); emit(cap); emit(" x ptr], ptr @evL_"); emit(en); emit(", i32 0, i32 %tok\n") + emit(" store ptr null, ptr %slot\n br label %skip\n") + emit("skip:\n ret void\n}\n\n") + + # --- @ev_(payload): fire compile-time listeners, then foreign ones + ll_t = 0; ll_lbl = 0; g_term = false; loc_reset(); nloop = 0; nself = 0 + ret_ty = "void" + let fbody = buf_new() + falloc = buf_new() + let saved = code + code = fbody + # EV6: bound re-entrant emit — past EV_DEPTH_CAP, return without dispatching + emit(" %evd = load i32, ptr @ev_depth\n") + emit(" %evover = icmp sge i32 %evd, "); emit(itoa(EV_DEPTH_CAP)); emit("\n") + emit(" br i1 %evover, label %evcap, label %evgo\n") + emit("evcap:\n") + if ev.ival == 1 { emit(" ret i32 0\n") } else { emit(" ret void\n") } + emit("evgo:\n") + emit(" %evd1 = add i32 %evd, 1\n store i32 %evd1, ptr @ev_depth\n") + # a stack copy of the payload, passed by pointer to every foreign listener + let pl = emit_alloca(`%Ev_{en}`) + # bind each field: store the param into the payload struct AND a name slot the + # compile-time listener bodies read bare. + var f = 0 + while f < len(ev.kids) { + let fd = ev.kids[f] + let lt = llty(fd.ty) + let pa = nreg(); emit(" "); emit(pa); emit(" = getelementptr inbounds %Ev_"); emit(en); emit(", ptr "); emit(pl); emit(", i32 0, i32 "); emit(itoa(f)); emit("\n") + emit(" store "); emit(lt); emit(" %p"); emit(itoa(f)); emit(", ptr "); emit(pa); emit("\n") + let slot = emit_alloca(lt) + emit(" store "); emit(lt); emit(" %p"); emit(itoa(f)); emit(", ptr "); emit(slot); emit("\n") + loc_push(fd.s, slot, fd.ty) + f = f + 1 + } + # cancellable: zero the flag and expose its address to `cancel` in the listeners + var caddr = null + if ev.ival == 1 { + caddr = nreg(); emit(" "); emit(caddr); emit(" = getelementptr inbounds %Ev_"); emit(en); emit(", ptr "); emit(pl); emit(", i32 0, i32 "); emit(itoa(len(ev.kids))); emit("\n") + emit(" store i32 0, ptr "); emit(caddr); emit("\n") + g_cancel_addr = caddr + } + let base = nloc # listeners share the params but not each other's locals + var i = 0 + while i < len(g_onlisten) { + if (g_onlisten[i].s == en) { nloc = base; g_term = false; emit_block(g_onlisten[i].a) } + i = i + 1 + } + # the open half: walk the foreign callback array in registration order + if not g_term { + let ci = emit_alloca("i32"); emit(" store i32 0, ptr "); emit(ci); emit("\n") + let L = lbl("evl"); let B = lbl("evb"); let D = lbl("evd") + emit(" br label %"); emit(L); emit("\n") + emit(L); emit(":\n") + let iv = emit_bind(`load i32, ptr {ci}`) + let nn = emit_bind(`load i32, ptr @evN_{en}`) + let go = emit_bind(`icmp slt i32 {iv}, {nn}`) + emit(" br i1 "); emit(go); emit(", label %"); emit(B); emit(", label %"); emit(D); emit("\n") + emit(B); emit(":\n") + let sp = nreg(); emit(" "); emit(sp); emit(" = getelementptr inbounds ["); emit(cap); emit(" x ptr], ptr @evL_"); emit(en); emit(", i32 0, i32 "); emit(iv); emit("\n") + let cb = emit_bind(`load ptr, ptr {sp}`) + let cbn = emit_bind(`icmp eq ptr {cb}, null`) # EV5: a removed (off) listener is null — skip it + let doc = lbl("evdo"); let skp = lbl("evsk") + emit(" br i1 "); emit(cbn); emit(", label %"); emit(skp); emit(", label %"); emit(doc); emit("\n") + emit(doc); emit(":\n") + emit(" call void "); emit(cb); emit("(ptr "); emit(pl); emit(")\n") + emit(" br label %"); emit(skp); emit("\n") + emit(skp); emit(":\n") + let i2 = emit_bind(`add i32 {iv}, 1`) + emit(" store i32 "); emit(i2); emit(", ptr "); emit(ci); emit("\n") + emit(" br label %"); emit(L); emit("\n") + emit(D); emit(":\n") + emit(" br label %ret\n") + } + emit("ret:\n") + emit(" %evdd = load i32, ptr @ev_depth\n %evdd1 = sub i32 %evdd, 1\n store i32 %evdd1, ptr @ev_depth\n") # EV6: leave one nesting level + if ev.ival == 1 { # return the (possibly set) cancelled flag + let cv = emit_bind(`load i32, ptr {caddr}`) + emit(" ret i32 "); emit(cv); emit("\n") + } else { emit(" ret void\n") } + g_cancel_addr = null # leaves listener scope + code = saved + var rt = "void"; if ev.ival == 1 { rt = "i32" } + emit("define "); emit(rt); emit(" @ev_"); emit(en); emit("(") + var g = 0 + while g < len(ev.kids) { + if g > 0 { emit(", ") } + emit(llty(ev.kids[g].ty)); emit(" %p"); emit(itoa(g)) + g = g + 1 + } + emit(") {\nentry:\n") + emit(buf_str(falloc)) + emit(buf_str(fbody)) + emit("}\n\n") + e = e + 1 + } + + # EV5: @ludic_sweep_entity(owner) — remove every entity-scoped listener owned by + # a despawning entity, across all events. Called from `despawn`, so a listener + # bound to an entity cannot outlive it (the Node listener-leak footgun, gone). + let capS = itoa(EV_CAP) + emit("define void @ludic_sweep_entity(i32 %owner) {\nentry:\n %ci = alloca i32\n store i32 0, ptr %ci\n br label %sw0\n") + var e2 = 0 + while e2 < len(g_events) { + let en2 = g_events[e2].s; let sk = itoa(e2) + emit("sw"); emit(sk); emit(":\n") + emit(" %swi"); emit(sk); emit(" = load i32, ptr %ci\n") + emit(" %swn"); emit(sk); emit(" = load i32, ptr @evN_"); emit(en2); emit("\n") + emit(" %swg"); emit(sk); emit(" = icmp slt i32 %swi"); emit(sk); emit(", %swn"); emit(sk); emit("\n") + emit(" br i1 %swg"); emit(sk); emit(", label %swb"); emit(sk); emit(", label %swd"); emit(sk); emit("\n") + emit("swb"); emit(sk); emit(":\n") + emit(" %swop"); emit(sk); emit(" = getelementptr inbounds ["); emit(capS); emit(" x i32], ptr @evO_"); emit(en2); emit(", i32 0, i32 %swi"); emit(sk); emit("\n") + emit(" %swov"); emit(sk); emit(" = load i32, ptr %swop"); emit(sk); emit("\n") + emit(" %swm"); emit(sk); emit(" = icmp eq i32 %swov"); emit(sk); emit(", %owner\n") + emit(" br i1 %swm"); emit(sk); emit(", label %swh"); emit(sk); emit(", label %swx"); emit(sk); emit("\n") + emit("swh"); emit(sk); emit(":\n") + emit(" %swlp"); emit(sk); emit(" = getelementptr inbounds ["); emit(capS); emit(" x ptr], ptr @evL_"); emit(en2); emit(", i32 0, i32 %swi"); emit(sk); emit("\n") + emit(" store ptr null, ptr %swlp"); emit(sk); emit("\n br label %swx"); emit(sk); emit("\n") + emit("swx"); emit(sk); emit(":\n") + emit(" %swi1"); emit(sk); emit(" = add i32 %swi"); emit(sk); emit(", 1\n store i32 %swi1"); emit(sk); emit(", ptr %ci\n br label %sw"); emit(sk); emit("\n") + emit("swd"); emit(sk); emit(":\n store i32 0, ptr %ci\n") + if (e2 + 1) < len(g_events) { emit(" br label %sw"); emit(itoa(e2 + 1)); emit("\n") } + else { emit(" ret void\n") } + e2 = e2 + 1 + } + emit("}\n\n") +} + +# EV2 — the world table: a generated reflection ABI so a mod reads and writes +# entity state *by name*, without having compiled against the game. This is the +# "game table" that lets a modding layer be ported in. Generated from the +# compile-time schema, so it never drifts. Emitted only for an ECS program that +# also declares events (a modding program), so event-free games stay byte-exact. +# +# i32 ludic_prop_id(name) property name -> stable id (-1 = none) +# i32 ludic_field_id(prop, name) field name within a property -> index +# i64 ludic_get(entity, prop, field) read a field (sign-extended to i64) +# void ludic_set(entity, prop, field, i64) write a field (truncated to i32) +# i32 ludic_has(entity, prop) does the entity have the property? +# +# First cut: integer component fields (the common case — hp, x, amount). Property +# ids are assignment order in the source; field ids are declaration order. +fn emit_world_table() -> void { + let me = itoa(MAX_ENT) + emith("declare i32 @strcmp(ptr, ptr)\n") + + # EV7 — schema opening: a mod can register a brand-new component at runtime. + # Compile-time components take prop ids 0..NC-1; mod-defined ones take NC.. and + # live in these parallel registries (fixed capacity 32). Storage is a flat + # malloc'd [MAX_ENT x nfields x i32] with a parallel has-flag array. get/set/has + # and prop_id fall through to this table for a prop id >= NC. + var ncomp = 0 + var ci0 = 0 + while ci0 < len(prog) { if prog[ci0].kind == N_COMP { ncomp = ncomp + 1 }; ci0 = ci0 + 1 } + let NC = itoa(ncomp) + emith("@dyn_count = global i32 0\n") + emith("@dynS = global [32 x ptr] zeroinitializer\n") # storage base per dyn component + emith("@dynH = global [32 x ptr] zeroinitializer\n") # has-flag array per dyn component + emith("@dynF = global [32 x i32] zeroinitializer\n") # field count per dyn component + emith("@dynName = global [32 x ptr] zeroinitializer\n") # name per dyn component + + # ludic_prop_id(name): strcmp against each property's name constant + emit("define i32 @ludic_prop_id(ptr %name) {\nentry:\n") + var k = 0 + var i = 0 + while i < len(prog) { + if prog[i].kind == N_COMP { + let sc = emit_str_const(prog[i].s); let sk = itoa(k) + emit(" %c"); emit(sk); emit(" = call i32 @strcmp(ptr %name, ptr "); emit(sc); emit(")\n") + emit(" %e"); emit(sk); emit(" = icmp eq i32 %c"); emit(sk); emit(", 0\n") + emit(" br i1 %e"); emit(sk); emit(", label %h"); emit(sk); emit(", label %n"); emit(sk); emit("\n") + emit("h"); emit(sk); emit(":\n ret i32 "); emit(sk); emit("\n") + emit("n"); emit(sk); emit(":\n") + k = k + 1 + } + i = i + 1 + } + # EV7: not a compile-time component — search the dynamic (mod-registered) names + emit(" %dpi = alloca i32\n store i32 0, ptr %dpi\n br label %dpl\n") + emit("dpl:\n %di = load i32, ptr %dpi\n %dn = load i32, ptr @dyn_count\n %dg = icmp slt i32 %di, %dn\n br i1 %dg, label %dpb, label %dpnone\n") + emit("dpb:\n %dnp = getelementptr inbounds [32 x ptr], ptr @dynName, i32 0, i32 %di\n %dname = load ptr, ptr %dnp\n %dcmp = call i32 @strcmp(ptr %name, ptr %dname)\n %deq = icmp eq i32 %dcmp, 0\n br i1 %deq, label %dphit, label %dpnext\n") + emit("dphit:\n %drid = add i32 %di, "); emit(NC); emit("\n ret i32 %drid\n") + emit("dpnext:\n %di1 = add i32 %di, 1\n store i32 %di1, ptr %dpi\n br label %dpl\n") + emit("dpnone:\n ret i32 -1\n}\n\n") + + # ludic_field_id(prop, name): within the matched property, strcmp each field name + emit("define i32 @ludic_field_id(i32 %p, ptr %name) {\nentry:\n") + k = 0; i = 0 + while i < len(prog) { + if prog[i].kind == N_COMP { + let c = prog[i]; let sk = itoa(k) + emit(" %pm"); emit(sk); emit(" = icmp eq i32 %p, "); emit(sk); emit("\n") + emit(" br i1 %pm"); emit(sk); emit(", label %pk"); emit(sk); emit(", label %pn"); emit(sk); emit("\n") + emit("pk"); emit(sk); emit(":\n") + var f = 0 + while f < len(c.kids) { + let fc = emit_str_const(c.kids[f].s); let fk = `{sk}_{itoa(f)}` + emit(" %fc"); emit(fk); emit(" = call i32 @strcmp(ptr %name, ptr "); emit(fc); emit(")\n") + emit(" %fe"); emit(fk); emit(" = icmp eq i32 %fc"); emit(fk); emit(", 0\n") + emit(" br i1 %fe"); emit(fk); emit(", label %fh"); emit(fk); emit(", label %fn"); emit(fk); emit("\n") + emit("fh"); emit(fk); emit(":\n ret i32 "); emit(itoa(f)); emit("\n") + emit("fn"); emit(fk); emit(":\n") + f = f + 1 + } + emit(" ret i32 -1\n") + emit("pn"); emit(sk); emit(":\n") + k = k + 1 + } + i = i + 1 + } + emit(" ret i32 -1\n}\n\n") + + # ludic_get / ludic_set / ludic_has dispatch prop -> @S_/@H_ storage; the field + # address is slot + field*4 (integer fields). + # ludic_get/ludic_set dispatch prop -> component storage, then the field id to a + # constant struct GEP (so mixed layouts and ptr/byte fields are addressed + # correctly, not assumed 4-byte). Values cross the ABI as i64: int/bool/fixed + # sign-extend, byte zero-extends, ptr round-trips through ptrtoint/inttoptr. + emit("define i64 @ludic_get(i32 %e, i32 %p, i32 %f) {\nentry:\n") + k = 0; i = 0 + while i < len(prog) { + if prog[i].kind == N_COMP { + let c = prog[i]; let cn = c.s; let sk = itoa(k) + emit(" %m"); emit(sk); emit(" = icmp eq i32 %p, "); emit(sk); emit("\n") + emit(" br i1 %m"); emit(sk); emit(", label %g"); emit(sk); emit(", label %gn"); emit(sk); emit("\n") + emit("g"); emit(sk); emit(":\n") + emit(" %s"); emit(sk); emit(" = getelementptr inbounds ["); emit(me); emit(" x %Cmp_"); emit(cn); emit("], ptr @S_"); emit(cn); emit(", i32 0, i32 %e\n") + var fj = 0 + while fj < len(c.kids) { + let ft = llty(c.kids[fj].ty); let fk = `{sk}_{itoa(fj)}` + emit(" %gm"); emit(fk); emit(" = icmp eq i32 %f, "); emit(itoa(fj)); emit("\n") + emit(" br i1 %gm"); emit(fk); emit(", label %gf"); emit(fk); emit(", label %gk"); emit(fk); emit("\n") + emit("gf"); emit(fk); emit(":\n") + emit(" %ga"); emit(fk); emit(" = getelementptr inbounds %Cmp_"); emit(cn); emit(", ptr %s"); emit(sk); emit(", i32 0, i32 "); emit(itoa(fj)); emit("\n") + if (ft == "ptr") { + emit(" %gl"); emit(fk); emit(" = load ptr, ptr %ga"); emit(fk); emit("\n") + emit(" %gr"); emit(fk); emit(" = ptrtoint ptr %gl"); emit(fk); emit(" to i64\n ret i64 %gr"); emit(fk); emit("\n") + } else { if (ft == "i8") { + emit(" %gl"); emit(fk); emit(" = load i8, ptr %ga"); emit(fk); emit("\n") + emit(" %gr"); emit(fk); emit(" = zext i8 %gl"); emit(fk); emit(" to i64\n ret i64 %gr"); emit(fk); emit("\n") + } else { + emit(" %gl"); emit(fk); emit(" = load i32, ptr %ga"); emit(fk); emit("\n") + emit(" %gr"); emit(fk); emit(" = sext i32 %gl"); emit(fk); emit(" to i64\n ret i64 %gr"); emit(fk); emit("\n") + } } + emit("gk"); emit(fk); emit(":\n") + fj = fj + 1 + } + emit(" ret i64 0\n") + emit("gn"); emit(sk); emit(":\n") + k = k + 1 + } + i = i + 1 + } + # EV7: prop id >= NC -> a mod-registered component; index its flat storage + emit(" %gdyn = sub i32 %p, "); emit(NC); emit("\n") + emit(" %gdlo = icmp sge i32 %gdyn, 0\n %gdc = load i32, ptr @dyn_count\n %gdhi = icmp slt i32 %gdyn, %gdc\n %gdok = and i1 %gdlo, %gdhi\n br i1 %gdok, label %gdyng, label %gdnone\n") + emit("gdyng:\n %gsp = getelementptr inbounds [32 x ptr], ptr @dynS, i32 0, i32 %gdyn\n %gbase = load ptr, ptr %gsp\n") + emit(" %gfp = getelementptr inbounds [32 x i32], ptr @dynF, i32 0, i32 %gdyn\n %gnf = load i32, ptr %gfp\n %grow = mul i32 %e, %gnf\n %gidx = add i32 %grow, %f\n") + emit(" %gaddr = getelementptr inbounds i32, ptr %gbase, i32 %gidx\n %gv = load i32, ptr %gaddr\n %gr = sext i32 %gv to i64\n ret i64 %gr\n") + emit("gdnone:\n ret i64 0\n}\n\n") + + emit("define void @ludic_set(i32 %e, i32 %p, i32 %f, i64 %val) {\nentry:\n") + k = 0; i = 0 + while i < len(prog) { + if prog[i].kind == N_COMP { + let c = prog[i]; let cn = c.s; let sk = itoa(k) + emit(" %m"); emit(sk); emit(" = icmp eq i32 %p, "); emit(sk); emit("\n") + emit(" br i1 %m"); emit(sk); emit(", label %g"); emit(sk); emit(", label %gn"); emit(sk); emit("\n") + emit("g"); emit(sk); emit(":\n") + emit(" %s"); emit(sk); emit(" = getelementptr inbounds ["); emit(me); emit(" x %Cmp_"); emit(cn); emit("], ptr @S_"); emit(cn); emit(", i32 0, i32 %e\n") + var fj = 0 + while fj < len(c.kids) { + let ft = llty(c.kids[fj].ty); let fk = `{sk}_{itoa(fj)}` + emit(" %sm"); emit(fk); emit(" = icmp eq i32 %f, "); emit(itoa(fj)); emit("\n") + emit(" br i1 %sm"); emit(fk); emit(", label %sf"); emit(fk); emit(", label %sk"); emit(fk); emit("\n") + emit("sf"); emit(fk); emit(":\n") + emit(" %sa"); emit(fk); emit(" = getelementptr inbounds %Cmp_"); emit(cn); emit(", ptr %s"); emit(sk); emit(", i32 0, i32 "); emit(itoa(fj)); emit("\n") + if (ft == "ptr") { + emit(" %sp"); emit(fk); emit(" = inttoptr i64 %val to ptr\n") + emit(" store ptr %sp"); emit(fk); emit(", ptr %sa"); emit(fk); emit("\n ret void\n") + } else { if (ft == "i8") { + emit(" %sb"); emit(fk); emit(" = trunc i64 %val to i8\n") + emit(" store i8 %sb"); emit(fk); emit(", ptr %sa"); emit(fk); emit("\n ret void\n") + } else { + emit(" %sw"); emit(fk); emit(" = trunc i64 %val to i32\n") + emit(" store i32 %sw"); emit(fk); emit(", ptr %sa"); emit(fk); emit("\n ret void\n") + } } + emit("sk"); emit(fk); emit(":\n") + fj = fj + 1 + } + emit(" ret void\n") + emit("gn"); emit(sk); emit(":\n") + k = k + 1 + } + i = i + 1 + } + # EV7: prop id >= NC -> a mod-registered component + emit(" %sdyn = sub i32 %p, "); emit(NC); emit("\n") + emit(" %sdlo = icmp sge i32 %sdyn, 0\n %sdc = load i32, ptr @dyn_count\n %sdhi = icmp slt i32 %sdyn, %sdc\n %sdok = and i1 %sdlo, %sdhi\n br i1 %sdok, label %sdyng, label %sdnone\n") + emit("sdyng:\n %ssp = getelementptr inbounds [32 x ptr], ptr @dynS, i32 0, i32 %sdyn\n %sbase = load ptr, ptr %ssp\n") + emit(" %sfp = getelementptr inbounds [32 x i32], ptr @dynF, i32 0, i32 %sdyn\n %snf = load i32, ptr %sfp\n %srow = mul i32 %e, %snf\n %sidx = add i32 %srow, %f\n") + emit(" %saddr = getelementptr inbounds i32, ptr %sbase, i32 %sidx\n %sv = trunc i64 %val to i32\n store i32 %sv, ptr %saddr\n ret void\n") + emit("sdnone:\n ret void\n}\n\n") + + emit("define i32 @ludic_has(i32 %e, i32 %p) {\nentry:\n") + k = 0; i = 0 + while i < len(prog) { + if prog[i].kind == N_COMP { + let cn = prog[i].s; let sk = itoa(k) + emit(" %m"); emit(sk); emit(" = icmp eq i32 %p, "); emit(sk); emit("\n") + emit(" br i1 %m"); emit(sk); emit(", label %g"); emit(sk); emit(", label %gn"); emit(sk); emit("\n") + emit("g"); emit(sk); emit(":\n") + emit(" %hp"); emit(sk); emit(" = getelementptr inbounds ["); emit(me); emit(" x i8], ptr @H_"); emit(cn); emit(", i32 0, i32 %e\n") + emit(" %hv"); emit(sk); emit(" = load i8, ptr %hp"); emit(sk); emit("\n") + emit(" %hr"); emit(sk); emit(" = zext i8 %hv"); emit(sk); emit(" to i32\n ret i32 %hr"); emit(sk); emit("\n") + emit("gn"); emit(sk); emit(":\n") + k = k + 1 + } + i = i + 1 + } + # EV7: prop id >= NC -> a mod-registered component's has-flag array + emit(" %hdyn = sub i32 %p, "); emit(NC); emit("\n") + emit(" %hdlo = icmp sge i32 %hdyn, 0\n %hdc = load i32, ptr @dyn_count\n %hdhi = icmp slt i32 %hdyn, %hdc\n %hdok = and i1 %hdlo, %hdhi\n br i1 %hdok, label %hdyng, label %hdnone\n") + emit("hdyng:\n %hhp = getelementptr inbounds [32 x ptr], ptr @dynH, i32 0, i32 %hdyn\n %hh = load ptr, ptr %hhp\n %hslot = getelementptr inbounds i8, ptr %hh, i32 %e\n %hval = load i8, ptr %hslot\n %hres = zext i8 %hval to i32\n ret i32 %hres\n") + emit("hdnone:\n ret i32 0\n}\n\n") + + # ludic_register_prop(name, nfields) -> prop id — a mod declares a NEW component. + # Allocates flat [MAX_ENT x nfields x i32] storage + a MAX_ENT has-flag array, + # zeroed. The returned id works with get/set/has/attach exactly like a built-in. + emit("define i32 @ludic_register_prop(ptr %name, i32 %nfields) {\nentry:\n") + emit(" %dc = load i32, ptr @dyn_count\n %full = icmp slt i32 %dc, 32\n br i1 %full, label %do, label %rej\n") + emit("do:\n %nf4 = mul i32 %nfields, 4\n %sz = mul i32 %nf4, "); emit(me); emit("\n %szl = sext i32 %sz to i64\n") + emit(" %buf = call ptr @malloc(i64 %szl)\n call ptr @memset(ptr %buf, i32 0, i64 %szl)\n") + emit(" %sp = getelementptr inbounds [32 x ptr], ptr @dynS, i32 0, i32 %dc\n store ptr %buf, ptr %sp\n") + emit(" %hbuf = call ptr @malloc(i64 "); emit(me); emit(")\n call ptr @memset(ptr %hbuf, i32 0, i64 "); emit(me); emit(")\n") + emit(" %hp = getelementptr inbounds [32 x ptr], ptr @dynH, i32 0, i32 %dc\n store ptr %hbuf, ptr %hp\n") + emit(" %fp = getelementptr inbounds [32 x i32], ptr @dynF, i32 0, i32 %dc\n store i32 %nfields, ptr %fp\n") + emit(" %np = getelementptr inbounds [32 x ptr], ptr @dynName, i32 0, i32 %dc\n store ptr %name, ptr %np\n") + emit(" %id = add i32 %dc, "); emit(NC); emit("\n %dc1 = add i32 %dc, 1\n store i32 %dc1, ptr @dyn_count\n ret i32 %id\n") + emit("rej:\n ret i32 -1\n}\n\n") + + # ludic_attach_dyn / ludic_detach_dyn(entity, prop) — set/clear a mod-registered + # component's has-flag on an entity (the dynamic analogue of attach/detach). + emit("define void @ludic_attach_dyn(i32 %e, i32 %p) {\nentry:\n") + emit(" %dyn = sub i32 %p, "); emit(NC); emit("\n %hp = getelementptr inbounds [32 x ptr], ptr @dynH, i32 0, i32 %dyn\n %h = load ptr, ptr %hp\n %slot = getelementptr inbounds i8, ptr %h, i32 %e\n store i8 1, ptr %slot\n ret void\n}\n\n") + emit("define void @ludic_detach_dyn(i32 %e, i32 %p) {\nentry:\n") + emit(" %dyn = sub i32 %p, "); emit(NC); emit("\n %hp = getelementptr inbounds [32 x ptr], ptr @dynH, i32 0, i32 %dyn\n %h = load ptr, ptr %hp\n %slot = getelementptr inbounds i8, ptr %h, i32 %e\n store i8 0, ptr %slot\n ret void\n}\n\n") + + # ludic_entity_count / ludic_kind / ludic_model_id — a mod scans the world and + # identifies each entity's model, then reads/writes it with get/set/has above. + emit("define i32 @ludic_entity_count() {\nentry:\n %n = load i32, ptr @L_entc\n ret i32 %n\n}\n\n") + emit("define i32 @ludic_kind(i32 %e) {\nentry:\n") + emit(" %kp = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_kind, i32 0, i32 %e\n") + emit(" %k = load i32, ptr %kp\n ret i32 %k\n}\n\n") + emit("define i32 @ludic_model_id(ptr %name) {\nentry:\n") + k = 0; i = 0 + while i < len(prog) { + if prog[i].kind == N_ARCH { + let sc = emit_str_const(prog[i].s); let sk = itoa(k) + emit(" %mdc"); emit(sk); emit(" = call i32 @strcmp(ptr %name, ptr "); emit(sc); emit(")\n") + emit(" %mde"); emit(sk); emit(" = icmp eq i32 %mdc"); emit(sk); emit(", 0\n") + emit(" br i1 %mde"); emit(sk); emit(", label %mdh"); emit(sk); emit(", label %mdn"); emit(sk); emit("\n") + emit("mdh"); emit(sk); emit(":\n ret i32 "); emit(itoa(find_arch_id(prog[i].s))); emit("\n") + emit("mdn"); emit(sk); emit(":\n") + k = k + 1 + } + i = i + 1 + } + emit(" ret i32 -1\n}\n\n") + + # ludic_spawn(model_id) -> entity — a mod creates a new entity. Each model gets a + # @ludic_spawn_ that reuses the compiler's own spawn lowering (alloc, kind, + # component defaults, @OnSpawn, and the model__spawn event), so a mod-spawned + # entity is indistinguishable from one born in source. A dispatcher routes the id. + i = 0 + while i < len(prog) { + if prog[i].kind == N_ARCH { + let m = prog[i].s + ll_t = 0; ll_lbl = 0; g_term = false; loc_reset(); nloop = 0; nself = 0 + ret_ty = "int" + let fbody = buf_new() + falloc = buf_new() + let saved = code + code = fbody + let syn = node(S_SPAWN); syn.s = m # a defaults-only spawn of model m + let se = emit_spawn(syn) + emit(" ret i32 "); emit(se); emit("\n") + code = saved + emit("define i32 @ludic_spawn_"); emit(m); emit("() {\nentry:\n") + emit(buf_str(falloc)) + emit(buf_str(fbody)) + emit("}\n\n") + } + i = i + 1 + } + emit("define i32 @ludic_spawn(i32 %m) {\nentry:\n") + k = 0; i = 0 + while i < len(prog) { + if prog[i].kind == N_ARCH { + let m = prog[i].s; let sk = itoa(k) + emit(" %sm"); emit(sk); emit(" = icmp eq i32 %m, "); emit(itoa(find_arch_id(m))); emit("\n") + emit(" br i1 %sm"); emit(sk); emit(", label %sh"); emit(sk); emit(", label %sn"); emit(sk); emit("\n") + emit("sh"); emit(sk); emit(":\n %sr"); emit(sk); emit(" = call i32 @ludic_spawn_"); emit(m); emit("()\n ret i32 %sr"); emit(sk); emit("\n") + emit("sn"); emit(sk); emit(":\n") + k = k + 1 + } + i = i + 1 + } + emit(" ret i32 -1\n}\n\n") + + # ludic_query_next(prop_id, from) -> the next live entity (>= from) that has the + # property, or -1. A mod iterates: for (e = query_next(p, 0); e >= 0; e = + # query_next(p, e+1)). Reuses ludic_has for the membership test. + emit("define i32 @ludic_query_next(i32 %p, i32 %from) {\nentry:\n") + emit(" %n = load i32, ptr @L_entc\n br label %loop\n") + emit("loop:\n %e = phi i32 [ %from, %entry ], [ %e1, %cont ]\n") + emit(" %go = icmp slt i32 %e, %n\n br i1 %go, label %body, label %none\n") + emit("body:\n %ap = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_alive, i32 0, i32 %e\n") + emit(" %al = load i32, ptr %ap\n %isa = icmp ne i32 %al, 0\n br i1 %isa, label %chk, label %cont\n") + emit("chk:\n %h = call i32 @ludic_has(i32 %e, i32 %p)\n %hit = icmp ne i32 %h, 0\n br i1 %hit, label %hitb, label %cont\n") + emit("hitb:\n ret i32 %e\n") + emit("cont:\n %e1 = add i32 %e, 1\n br label %loop\n") + emit("none:\n ret i32 -1\n}\n\n") +} + +# N5 — the drivable sim (NETWORKING-DESIGN §5). The per-frame phases the auto-loop +# runs are also exposed as callables, so a game that owns its `entry` loop can +# drive the simulation itself (for prediction/rollback, replay, headless tests, or +# AI). tick_fixed() runs the sim phases; tick_render() runs Render. +fn emit_tick_helpers() -> void { + emit("define void @L_tick_fixed() {\nentry:\n") + ll_t = 0; ll_lbl = 0 + emit_calls_for_phase("Input") + emit_calls_for_phase("FixedUpdate") + emit_calls_for_phase("Update") + emit_calls_for_phase("LateUpdate") + emit(" ret void\n}\n\n") + emit("define void @L_tick_render() {\nentry:\n") + ll_t = 0; ll_lbl = 0 + emit_calls_for_phase("Render") + emit(" ret void\n}\n\n") +} + +# system functions + lifecycle hooks + the drivable tick helpers — shared by the +# auto-loop game (emit_game_main) and an entry-driven game that owns its own loop. +fn emit_game_defs() -> void { var i = 0 while i < len(prog) { if prog[i].kind == N_SYS { emit_system_fn(prog[i]) }; i = i + 1 } emit_despawn_hooks() + emit_scene_hooks() + emit_tick_helpers() +} + +fn emit_game_main() -> void { + emit_game_defs() emit("define i32 @main(i32 %argc, ptr %argv) {\nentry:\n") emit(" store i32 %argc, ptr @L_argc\n") emit(" store ptr %argv, ptr @L_argv\n") if (find_fn("rt_init") != null) { emit(" call void @fn_rt_init()\n") } emit_calls_for_phase("Start") + # enter the start scene once, after boot: store its id and run its on-enter. + if len(g_scenes) > 0 { + emit(" store i32 "); emit(itoa(g_start_scene)); emit(", ptr @L_scene\n") + var si = 0 + while si < len(g_scenes) { + if (g_scenes[si].ival == g_start_scene) { emit(" call void @scene_enter_"); emit(g_scenes[si].s); emit("()\n") } + si = si + 1 + } + } + if (find_event("program_start") != null) { emit(" call void @ev_program_start()\n") } # EV1: @Public @OnStart emit(" br label %loop\n") emit("loop:\n") let r = emit_bind("load i32, ptr @L_running") @@ -97,7 +753,9 @@ fn emit_game_main() -> void { emit_calls_for_phase("Render") emit(" br label %loop\n") emit("done:\n") + if len(g_ondespawn) > 0 { emit(" call void @L_despawn_all(i32 2)\n") } # LC1: every survivor's @OnDespawn fires with reason Quit emit_calls_for_phase("OnQuit") # @OnQuit shutdown hooks run once, before teardown + if (find_event("program_quit") != null) { emit(" call void @ev_program_quit()\n") } # EV1: @Public @OnQuit if (find_fn("rt_shutdown") != null) { emit(" call void @fn_rt_shutdown()\n") } emit(" ret i32 0\n}\n") } diff --git a/selfhost/emit_head.ludic b/selfhost/emit_head.ludic index 19940710..4df2a220 100644 --- a/selfhost/emit_head.ludic +++ b/selfhost/emit_head.ludic @@ -102,6 +102,27 @@ fn emit_header() -> void { } } +# One `declare @()` per `extern fn`, so the linker resolves the +# call to the bound symbol. Emitted after the header; a program with no `extern fn` +# emits nothing here, so un-networked builds stay byte-identical. +fn emit_extern_decls() -> void { + var i = 0 + while i < len(prog) { + let d = prog[i] + if d.kind == N_EXTERN { + emith("declare "); emith(llty(d.ty)); emith(" @"); emith(d.a.s); emith("(") + var f = 0 + while f < len(d.kids) { + if f > 0 { emith(", ") } + emith(llty(d.kids[f].ty)) + f = f + 1 + } + emith(")\n") + } + i = i + 1 + } +} + # The string runtime, emitted (once) into any program that uses `+`/`==`/`!=` # on strings. Hand-written IR over NUL-terminated byte buffers: str_eq walks both # until a mismatch or a shared terminator; str_concat measures both, mallocs diff --git a/selfhost/emit_machine.ludic b/selfhost/emit_machine.ludic index cc722c88..96987f65 100644 --- a/selfhost/emit_machine.ludic +++ b/selfhost/emit_machine.ludic @@ -26,14 +26,26 @@ fn emit_machine(st: Node) -> void { nmach = nmach - 1 } +# `become Name` — a machine state transition when Name is a state of an +# enclosing `machine`, otherwise a scene transition. A scene transition runs the +# source scene's on-exit, stores the target scene id into @L_scene, and runs the +# target's on-enter (two direct calls and a store — no dispatch table). fn emit_become(st: Node) -> void { - if nmach == 0 { perr("'become' outside a machine") } - let m = mach_stk[nmach - 1] - var target: Node = null - var i = 0 - while i < len(m.kids) { if (m.kids[i].s == st.s) { target = m.kids[i] }; i = i + 1 } - if (target == null) { perr(`become: no state {st.s}`) } - let regv = emit_expr(m.a) - let sv = emit_expr(target.b) - emit(" call void @fn_rt_set_reg(i32 "); emit(regv.code); emit(", i32 "); emit(sv.code); emit(")\n") + if nmach > 0 { # inside a machine: try a state first + let m = mach_stk[nmach - 1] + var target: Node = null + var i = 0 + while i < len(m.kids) { if (m.kids[i].s == st.s) { target = m.kids[i] }; i = i + 1 } + if (target != null) { + let regv = emit_expr(m.a) + let sv = emit_expr(target.b) + emit(" call void @fn_rt_set_reg(i32 "); emit(regv.code); emit(", i32 "); emit(sv.code); emit(")\n") + return + } + } + let sc = find_scene(st.s) # else a scene transition + if (sc == null) { perr(`become: no state or scene {st.s}`) } + if (g_cur_scene != null) { emit(" call void @scene_exit_"); emit(g_cur_scene.s); emit("()\n") } + emit(" store i32 "); emit(itoa(sc.ival)); emit(", ptr @L_scene\n") + emit(" call void @scene_enter_"); emit(sc.s); emit("()\n") } diff --git a/selfhost/emit_net.ludic b/selfhost/emit_net.ludic new file mode 100644 index 00000000..a8d6358e --- /dev/null +++ b/selfhost/emit_net.ludic @@ -0,0 +1,373 @@ +# emit_net.ludic — NETWORKING N2–N6 codegen (NETWORKING-DESIGN.md). +# +# A program that calls net_send/net_poll with no `extern fn` override triggers the +# built-in loopback transport; this flag defers its emission to end-of-module. +var g_uses_loopback: bool = false + +# +# N2 (@Sync): per-model serialize/apply over the replicable-and-participating +# fields, by-kind dispatchers a replication runtime calls, and the POD-scalar +# compile error + empty-participation warning. +# N3 (@Owned): the @L_owner array + owner()/set_owner()/is_owner(). +# N5 (roles): the @L_role / @L_localid registers + is_server()/local_id(). +# +# Everything here is gated (net_has_sync / net_has_owned / len(g_events) etc.), +# so a program that uses none of it is byte-identical to single-player (§8). + +# ---- N2: what replicates ----------------------------------------------------- +# A field of an entity replicates iff the field is @Sync (field.ival==1) AND its +# component participates in the entity's model (the model member is @Sync, +# member.ival==1). Participation is decided per model use-site. + +fn net_field_ibytes(ty: ptr) -> int { if (llty(ty) == "i8") { return 1 }; return 4 } +fn net_field_bytes(ty: ptr) -> ptr { if (llty(ty) == "i8") { return "1" }; return "4" } + +# total replicated bytes for model m (compile-time constant) +fn net_model_bytes(m: Node) -> int { + var total = 0 + var ci = 0 + while ci < len(m.kids) { + if m.kids[ci].ival == 1 { + let c = find_comp(m.kids[ci].s) + if (c != null) { + var fj = 0 + while fj < len(c.kids) { if c.kids[fj].ival == 1 { total = total + net_field_ibytes(c.kids[fj].ty) }; fj = fj + 1 } + } + } + ci = ci + 1 + } + return total +} + +fn net_model_syncs(m: Node) -> bool { return net_model_bytes(m) > 0 } + +fn net_has_sync() -> bool { + var i = 0 + while i < len(prog) { if prog[i].kind == N_ARCH { if net_model_syncs(prog[i]) { return true } }; i = i + 1 } + return false +} + +# ---- N3: ownership ----------------------------------------------------------- +fn net_has_owned() -> bool { + var i = 0 + while i < len(prog) { if prog[i].kind == N_ARCH and (prog[i].ival == 1) { return true }; i = i + 1 } + return false +} + +# ---- N5: role-tagged handlers ------------------------------------------------ +# A handler tagged @Server (ival==1) or @Predicted (ival==2) has a network role. +fn net_has_role() -> bool { + var i = 0 + while i < len(prog) { if prog[i].kind == N_SYS and (prog[i].ival != 0) { return true }; i = i + 1 } + return false +} + +# Any networking feature in use → emit the shared role registers (@L_role / +# @L_localid). A runtime sets them; offline they keep their single-player default. +fn net_any() -> bool { return net_has_sync() or net_has_owned() or net_has_role() } + +# ---- diagnostics ------------------------------------------------------------- +fn net_warn(msg: ptr) -> void { + let e = file_stderr() + file_write(e, "ludicc(self): warning: ", 23) + file_write(e, msg, len(msg)) + file_write(e, "\n", 1) +} + +# Validate @Sync usage: a participating member whose component replicates nothing +# is a warning (participation that replicates nothing); a @Sync ptr field is a +# hard error (footgun 3 — networked fields must be POD scalars). +fn net_check() -> void { + var i = 0 + while i < len(prog) { + if prog[i].kind == N_ARCH { + let m = prog[i] + var ci = 0 + while ci < len(m.kids) { + if m.kids[ci].ival == 1 { + let cn = m.kids[ci].s + let c = find_comp(cn) + if (c != null) { + var any = false + var fj = 0 + while fj < len(c.kids) { + if c.kids[fj].ival == 1 { + any = true + if (llty(c.kids[fj].ty) == "ptr") { perr(`@Sync field {cn}.{c.kids[fj].s} is not a POD scalar (networked fields must be int/bool/fixed/byte)`) } + } + fj = fj + 1 + } + if not any { net_warn(`model {m.s} @Syncs {cn} but it has no @Sync fields — nothing replicates`) } + } + } + ci = ci + 1 + } + } + i = i + 1 + } +} + +# ---- N2: per-model serializer / applier -------------------------------------- +# serialize_(e, buf) -> bytes written. Copies each replicated field, tightly +# packed in member-then-field order, so apply reads the identical layout. +fn emit_net_serialize(m: Node) -> void { + ll_t = 0 + let me = itoa(MAX_ENT) + emit("define i32 @L_serialize_"); emit(m.s); emit("(i32 %e, ptr %buf) {\nentry:\n") + var off = 0 + var ci = 0 + while ci < len(m.kids) { + if m.kids[ci].ival == 1 { + let cn = m.kids[ci].s + let c = find_comp(cn) + if (c != null) { + let s = nreg(); emit(" "); emit(s); emit(" = getelementptr inbounds ["); emit(me); emit(" x %Cmp_"); emit(cn); emit("], ptr @S_"); emit(cn); emit(", i32 0, i32 %e\n") + var fj = 0 + while fj < len(c.kids) { + if c.kids[fj].ival == 1 { + let bytes = net_field_bytes(c.kids[fj].ty) + let fa = nreg(); emit(" "); emit(fa); emit(" = getelementptr inbounds %Cmp_"); emit(cn); emit(", ptr "); emit(s); emit(", i32 0, i32 "); emit(itoa(fj)); emit("\n") + let dst = nreg(); emit(" "); emit(dst); emit(" = getelementptr inbounds i8, ptr %buf, i32 "); emit(itoa(off)); emit("\n") + emit(" call ptr @memcpy(ptr "); emit(dst); emit(", ptr "); emit(fa); emit(", i64 "); emit(bytes); emit(")\n") + off = off + net_field_ibytes(c.kids[fj].ty) + } + fj = fj + 1 + } + } + } + ci = ci + 1 + } + emit(" ret i32 "); emit(itoa(off)); emit("\n}\n\n") +} + +# apply_(e, buf, len): the inverse — copy each replicated field back from the +# buffer into component storage. `len` is accepted for symmetry (the runtime's +# framing) but the layout is fixed, so it is not consulted. +fn emit_net_apply(m: Node) -> void { + ll_t = 0 + let me = itoa(MAX_ENT) + emit("define void @L_apply_"); emit(m.s); emit("(i32 %e, ptr %buf, i32 %len) {\nentry:\n") + var off = 0 + var ci = 0 + while ci < len(m.kids) { + if m.kids[ci].ival == 1 { + let cn = m.kids[ci].s + let c = find_comp(cn) + if (c != null) { + let s = nreg(); emit(" "); emit(s); emit(" = getelementptr inbounds ["); emit(me); emit(" x %Cmp_"); emit(cn); emit("], ptr @S_"); emit(cn); emit(", i32 0, i32 %e\n") + var fj = 0 + while fj < len(c.kids) { + if c.kids[fj].ival == 1 { + let bytes = net_field_bytes(c.kids[fj].ty) + let fa = nreg(); emit(" "); emit(fa); emit(" = getelementptr inbounds %Cmp_"); emit(cn); emit(", ptr "); emit(s); emit(", i32 0, i32 "); emit(itoa(fj)); emit("\n") + let src = nreg(); emit(" "); emit(src); emit(" = getelementptr inbounds i8, ptr %buf, i32 "); emit(itoa(off)); emit("\n") + emit(" call ptr @memcpy(ptr "); emit(fa); emit(", ptr "); emit(src); emit(", i64 "); emit(bytes); emit(")\n") + off = off + net_field_ibytes(c.kids[fj].ty) + } + fj = fj + 1 + } + } + } + ci = ci + 1 + } + emit(" ret void\n}\n\n") +} + +# ---- N2: by-kind dispatchers (the runtime ABI) ------------------------------- +# ludic_serialize(e, buf) -> bytes / ludic_apply(e, buf, len) / ludic_sync_size(e) +# route on the entity's model kind to the per-model function above, so a +# replication runtime replicates any entity without knowing its type. +fn emit_net_dispatch() -> void { + let me = itoa(MAX_ENT) + + emit("define i32 @ludic_serialize(i32 %e, ptr %buf) {\nentry:\n") + emit(" %kp = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_kind, i32 0, i32 %e\n %k = load i32, ptr %kp\n") + var k = 0 + var i = 0 + while i < len(prog) { + if prog[i].kind == N_ARCH and net_model_syncs(prog[i]) { + let mn = prog[i].s; let sk = itoa(k) + emit(" %c"); emit(sk); emit(" = icmp eq i32 %k, "); emit(itoa(find_arch_id(mn))); emit("\n") + emit(" br i1 %c"); emit(sk); emit(", label %h"); emit(sk); emit(", label %n"); emit(sk); emit("\n") + emit("h"); emit(sk); emit(":\n %r"); emit(sk); emit(" = call i32 @L_serialize_"); emit(mn); emit("(i32 %e, ptr %buf)\n ret i32 %r"); emit(sk); emit("\n") + emit("n"); emit(sk); emit(":\n") + k = k + 1 + } + i = i + 1 + } + emit(" ret i32 0\n}\n\n") + + emit("define void @ludic_apply(i32 %e, ptr %buf, i32 %len) {\nentry:\n") + emit(" %kp = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_kind, i32 0, i32 %e\n %k = load i32, ptr %kp\n") + k = 0; i = 0 + while i < len(prog) { + if prog[i].kind == N_ARCH and net_model_syncs(prog[i]) { + let mn = prog[i].s; let sk = itoa(k) + emit(" %c"); emit(sk); emit(" = icmp eq i32 %k, "); emit(itoa(find_arch_id(mn))); emit("\n") + emit(" br i1 %c"); emit(sk); emit(", label %h"); emit(sk); emit(", label %n"); emit(sk); emit("\n") + emit("h"); emit(sk); emit(":\n call void @L_apply_"); emit(mn); emit("(i32 %e, ptr %buf, i32 %len)\n ret void\n") + emit("n"); emit(sk); emit(":\n") + k = k + 1 + } + i = i + 1 + } + emit(" ret void\n}\n\n") + + # ludic_sync_size(e): the replicated byte count for the entity's model — a + # constant per kind, so a runtime can size a buffer before serialize. + emit("define i32 @ludic_sync_size(i32 %e) {\nentry:\n") + emit(" %kp = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_kind, i32 0, i32 %e\n %k = load i32, ptr %kp\n") + k = 0; i = 0 + while i < len(prog) { + if prog[i].kind == N_ARCH and net_model_syncs(prog[i]) { + let mn = prog[i].s; let sk = itoa(k) + emit(" %c"); emit(sk); emit(" = icmp eq i32 %k, "); emit(itoa(find_arch_id(mn))); emit("\n") + emit(" br i1 %c"); emit(sk); emit(", label %h"); emit(sk); emit(", label %n"); emit(sk); emit("\n") + emit("h"); emit(sk); emit(":\n ret i32 "); emit(itoa(net_model_bytes(prog[i]))); emit("\n") + emit("n"); emit(sk); emit(":\n") + k = k + 1 + } + i = i + 1 + } + emit(" ret i32 0\n}\n\n") +} + +# ---- N3: ownership storage + accessors --------------------------------------- +# @L_owner: one i32 owner id per entity, -1 = unowned. Only emitted when a model +# is @Owned, and L_reset clears it to -1 on alloc/free (see emit_ecs). owner()/ +# set_owner()/is_owner() read and write it; the authority assigns. +fn emit_net_owner() -> void { + let me = itoa(MAX_ENT) + emit("define i32 @L_owner(i32 %e) {\nentry:\n") + emit(" %p = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_owner_arr, i32 0, i32 %e\n %v = load i32, ptr %p\n ret i32 %v\n}\n\n") + emit("define void @L_set_owner(i32 %e, i32 %id) {\nentry:\n") + emit(" %p = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_owner_arr, i32 0, i32 %e\n store i32 %id, ptr %p\n ret void\n}\n\n") + # is_owner(e): does the local peer own e? owner(e) == local_id(). + emit("define i32 @L_is_owner(i32 %e) {\nentry:\n") + emit(" %p = getelementptr inbounds ["); emit(me); emit(" x i32], ptr @L_owner_arr, i32 0, i32 %e\n %o = load i32, ptr %p\n") + emit(" %lid = load i32, ptr @L_localid\n %eq = icmp eq i32 %o, %lid\n %r = zext i1 %eq to i32\n ret i32 %r\n}\n\n") +} + +# ---- built-in loopback transport (NETWORKING-DESIGN §5 N0) ------------------- +# The transport seam is net_send/net_poll. A production build binds them to a real +# socket via `extern fn` (UDP native, WebRTC/WebSocket wasm). Absent that, the +# compiler emits this in-process loopback — a single FIFO of datagrams, send +# enqueues a copy and poll dequeues the oldest — so a game is networked end to end +# with NO foreign host at all (the Ludic-native default). Datagram-preserving: +# one message per poll, matching how replication/RPC frame. Emitted only when a +# program actually calls net_send/net_poll without an extern override. +fn emit_loopback() -> void { + emith("@L_netq = internal global [64 x [2048 x i8]] zeroinitializer\n") + emith("@L_netlen = internal global [64 x i32] zeroinitializer\n") + emith("@L_nethead = internal global i32 0\n") + emith("@L_nettail = internal global i32 0\n") + + emit("define void @L_net_send(i32 %peer, ptr %buf, i32 %len) {\nentry:\n") + emit(" %l0 = icmp slt i32 %len, 0\n %len1 = select i1 %l0, i32 0, i32 %len\n") + emit(" %l1 = icmp sgt i32 %len1, 2048\n %n = select i1 %l1, i32 2048, i32 %len1\n") + emit(" %t = load i32, ptr @L_nettail\n %h = load i32, ptr @L_nethead\n") + emit(" %t1 = add i32 %t, 1\n %tn = srem i32 %t1, 64\n %full = icmp eq i32 %tn, %h\n") + emit(" br i1 %full, label %drop, label %go\n") + emit("go:\n") + emit(" %row = getelementptr inbounds [64 x [2048 x i8]], ptr @L_netq, i32 0, i32 %t\n") + emit(" %nz = zext i32 %n to i64\n call ptr @memcpy(ptr %row, ptr %buf, i64 %nz)\n") + emit(" %lp = getelementptr inbounds [64 x i32], ptr @L_netlen, i32 0, i32 %t\n store i32 %n, ptr %lp\n") + emit(" store i32 %tn, ptr @L_nettail\n br label %drop\n") + emit("drop:\n ret void\n}\n\n") + + emit("define i32 @L_net_poll(ptr %buf, i32 %cap) {\nentry:\n") + emit(" %h = load i32, ptr @L_nethead\n %t = load i32, ptr @L_nettail\n %empty = icmp eq i32 %h, %t\n") + emit(" br i1 %empty, label %none, label %go\n") + emit("go:\n") + emit(" %lp = getelementptr inbounds [64 x i32], ptr @L_netlen, i32 0, i32 %h\n %ln = load i32, ptr %lp\n") + emit(" %big = icmp sgt i32 %ln, %cap\n %n = select i1 %big, i32 %cap, i32 %ln\n") + emit(" %row = getelementptr inbounds [64 x [2048 x i8]], ptr @L_netq, i32 0, i32 %h\n") + emit(" %nz = zext i32 %n to i64\n call ptr @memcpy(ptr %buf, ptr %row, i64 %nz)\n") + emit(" %h1 = add i32 %h, 1\n %hn = srem i32 %h1, 64\n store i32 %hn, ptr @L_nethead\n ret i32 %n\n") + emit("none:\n ret i32 0\n}\n\n") +} + +# ---- N4: remote events (RPCs) ------------------------------------------------ +# An `event` marked @ToServer / @ToClients (ev.ty set) crosses the wire. At an +# `emit` site the POD payload is serialized as [i32 event_id][packed fields] and +# net_send in the declared direction; net_pump() drains inbound frames and +# re-emits each into the ordinary @ev_ dispatch on the far side. Reuses the +# EV0 payload (already flat) and the transport seam — no new concept. + +fn net_has_remote() -> bool { + var i = 0 + while i < len(g_events) { if (g_events[i].ty != null) { return true }; i = i + 1 } + return false +} +# stable wire id for an event = its index in g_events (same program both peers) +fn net_event_id(name: ptr) -> int { + var i = 0 + while i < len(g_events) { if (g_events[i].s == name) { return i }; i = i + 1 } + return 0 - 1 +} +# the transport symbols: an `extern fn` override, else the built-in loopback. +fn net_send_sym() -> ptr { let x = find_extern("net_send"); if (x != null) { return x.a.s }; return "L_net_send" } +fn net_poll_sym() -> ptr { let x = find_extern("net_poll"); if (x != null) { return x.a.s }; return "L_net_poll" } + +# net_pump(): poll every pending frame and re-emit it locally. The receive path +# of a remote event — the runtime/game calls this each tick. +fn emit_net_pump() -> void { + emith("@L_recvbuf = internal global [2048 x i8] zeroinitializer\n") + if (find_extern("net_poll") == null) { g_uses_loopback = true } + let psym = net_poll_sym() + emit("define void @L_net_pump() {\nentry:\n br label %loop\n") + emit("loop:\n %n = call i32 @"); emit(psym); emit("(ptr @L_recvbuf, i32 2048)\n") + emit(" %done = icmp eq i32 %n, 0\n br i1 %done, label %fin, label %body\n") + emit("body:\n %eid = load i32, ptr @L_recvbuf\n") + var e = 0 + while e < len(g_events) { + let ev = g_events[e] + if (ev.ty != null) { + let sk = itoa(e) + emit(" %c"); emit(sk); emit(" = icmp eq i32 %eid, "); emit(itoa(net_event_id(ev.s))); emit("\n") + emit(" br i1 %c"); emit(sk); emit(", label %h"); emit(sk); emit(", label %x"); emit(sk); emit("\n") + emit("h"); emit(sk); emit(":\n") + # decode each field from the frame (offset starts after the i32 event id) + var off = 4 + var f = 0 + let acc = buf_new() + while f < len(ev.kids) { + let ft = llty(ev.kids[f].ty) + let fk = `{sk}_{itoa(f)}` + emit(" %fa"); emit(fk); emit(" = getelementptr inbounds i8, ptr @L_recvbuf, i32 "); emit(itoa(off)); emit("\n") + emit(" %fv"); emit(fk); emit(" = load "); emit(ft); emit(", ptr %fa"); emit(fk); emit("\n") + if f > 0 { buf_puts(acc, ", ") } + buf_puts(acc, ft); buf_puts(acc, " %fv"); buf_puts(acc, fk) + off = off + net_field_ibytes(ev.kids[f].ty) + f = f + 1 + } + emit(" call void @ev_"); emit(ev.s); emit("("); emit(buf_str(acc)); emit(")\n") + emit(" br label %loop\n") + emit("x"); emit(sk); emit(":\n") + } + e = e + 1 + } + emit(" br label %loop\n") # unknown id: skip, keep draining + emit("fin:\n ret void\n}\n\n") +} + +# ---- driver ------------------------------------------------------------------ +fn emit_net() -> void { + if net_has_sync() { + net_check() + var i = 0 + while i < len(prog) { + if prog[i].kind == N_ARCH and net_model_syncs(prog[i]) { + emit_net_serialize(prog[i]) + emit_net_apply(prog[i]) + } + i = i + 1 + } + emit_net_dispatch() + } + if net_has_owned() { emit_net_owner() } + if net_has_remote() { + emith("@L_sendbuf = internal global [2048 x i8] zeroinitializer\n") # RPC send scratch + emit_net_pump() + } +} diff --git a/selfhost/emit_save.ludic b/selfhost/emit_save.ludic index 2bb597bc..9091ca41 100644 --- a/selfhost/emit_save.ludic +++ b/selfhost/emit_save.ludic @@ -5,13 +5,47 @@ var g_iok: int = 0 +# The snapshot is a fixed sequence of (region, byte-length) blocks; the same list +# feeds two targets — a file (save/load via fwrite/fread) and a memory buffer +# (world_save/world_load via memcpy, NETWORKING-DESIGN §5 N1). g_snap_mode picks +# which; buffer modes thread a running i64 offset (@g_off) so world_save returns +# the total byte count and world_load reads the identical layout back. +# NOTE: a string initializer on a module `ptr` var lowers to null (global_init), +# so these are seeded at runtime in emit_snapshot before first use — never read +# them uninitialized (a null string `==` would deref and crash the compiler). +var g_snap_mode: ptr = null # "file" | "save" | "load" | "size" +var g_off: ptr = null # current byte-offset register, buffer modes + fn emit_io(fn2: ptr, p: ptr, bytes: ptr) -> void { - let r = `%io{itoa(g_iok)}`; g_iok = g_iok + 1 - emit(" "); emit(r); emit(" = call i64 @"); emit(fn2); emit("(ptr "); emit(p); emit(", i64 1, i64 "); emit(bytes); emit(", ptr %f)\n") + if (g_snap_mode == "file") { + let r = `%io{itoa(g_iok)}`; g_iok = g_iok + 1 + emit(" "); emit(r); emit(" = call i64 @"); emit(fn2); emit("(ptr "); emit(p); emit(", i64 1, i64 "); emit(bytes); emit(", ptr %f)\n") + return + } + if (g_snap_mode == "size") { # accumulate the offset only, no copy + let noff = `%ioff{itoa(g_iok)}` + emit(" "); emit(noff); emit(" = add i64 "); emit(g_off); emit(", "); emit(bytes); emit("\n") + g_off = noff + g_iok = g_iok + 1 + return + } + # buffer mode: dst/src is %buf + g_off, copy `bytes`, then advance the cursor + let addr = `%ioa{itoa(g_iok)}` + emit(" "); emit(addr); emit(" = getelementptr inbounds i8, ptr %buf, i64 "); emit(g_off); emit("\n") + if (g_snap_mode == "save") { + emit(" call ptr @memcpy(ptr "); emit(addr); emit(", ptr "); emit(p); emit(", i64 "); emit(bytes); emit(")\n") + } else { + emit(" call ptr @memcpy(ptr "); emit(p); emit(", ptr "); emit(addr); emit(", i64 "); emit(bytes); emit(")\n") + } + let noff = `%ioff{itoa(g_iok)}` + emit(" "); emit(noff); emit(" = add i64 "); emit(g_off); emit(", "); emit(bytes); emit("\n") + g_off = noff + g_iok = g_iok + 1 } fn emit_snapshot_blocks(fn2: ptr) -> void { g_iok = 0 + g_off = "0" let me = itoa(MAX_ENT) emit_io(fn2, "@L_entc", "4") emit_io(fn2, "@L_freen", "4") @@ -19,6 +53,9 @@ fn emit_snapshot_blocks(fn2: ptr) -> void { emit_io(fn2, "@L_alive", "%nalive") emit_io(fn2, "@L_freelist", "%nalive") emit_io(fn2, "@L_kind", "%nalive") + # N3: an @Owned world snapshots its per-entity owners too, so rollback/replication + # round-trips ownership (like @L_kind). Gated, so non-@Owned snapshots are unchanged. + if net_has_owned() { emit_io(fn2, "@L_owner_arr", "%nalive") } var i = 0 while i < len(prog) { if prog[i].kind == N_VAR { emit_io(fn2, `@g_{prog[i].s}`, "4") }; i = i + 1 } var ci = 0 @@ -37,6 +74,7 @@ fn emit_snapshot_blocks(fn2: ptr) -> void { } fn emit_snapshot() -> void { + g_snap_mode = "file" # seed (module ptr inits are null) emith("@.sav_path = private unnamed_addr constant [10 x i8] c\"ludic.sav\\00\"\n") emith("@.sav_wb = private unnamed_addr constant [3 x i8] c\"wb\\00\"\n") emith("@.sav_rb = private unnamed_addr constant [3 x i8] c\"rb\\00\"\n") @@ -58,4 +96,32 @@ fn emit_snapshot() -> void { emit_snapshot_blocks("fread") if has_load { emit(" call void @fn_rt_load_state(ptr %f)\n") } emit(" %c = call i32 @fclose(ptr %f)\n ret i32 1\n}\n\n") + + # world_save(buf) -> int / world_load(buf, len): the same whole-world snapshot, + # to a caller-owned memory buffer instead of a file (NETWORKING-DESIGN §5 N1) — + # the rollback/replication substrate. No rt_ hook: this is the ECS world only + # (entities, components, vars), which is what a peer replicates or a rollback + # restores; the runtime's windowing state stays local. world_save returns the + # byte count written; the caller sizes the buffer with world_size(). + emit("define i32 @L_world_save(ptr %buf) {\nentry:\n") + g_snap_mode = "save" + emit_snapshot_blocks("") + let sret = `%wsn{itoa(g_iok)}` + emit(" "); emit(sret); emit(" = trunc i64 "); emit(g_off); emit(" to i32\n") + emit(" ret i32 "); emit(sret); emit("\n}\n\n") + + emit("define void @L_world_load(ptr %buf, i32 %len) {\nentry:\n") + g_snap_mode = "load" + emit_snapshot_blocks("") + emit(" ret void\n}\n\n") + + # world_size() -> int: the exact byte count a full snapshot needs, so a caller + # can size the buffer before world_save. Same block walk, offset-only. + emit("define i32 @L_world_size() {\nentry:\n") + g_snap_mode = "size" + emit_snapshot_blocks("") + let zret = `%wzn{itoa(g_iok)}` + emit(" "); emit(zret); emit(" = trunc i64 "); emit(g_off); emit(" to i32\n") + emit(" ret i32 "); emit(zret); emit("\n}\n\n") + g_snap_mode = "file" } diff --git a/selfhost/emit_spawn.ludic b/selfhost/emit_spawn.ludic index 8718a6eb..236ff736 100644 --- a/selfhost/emit_spawn.ludic +++ b/selfhost/emit_spawn.ludic @@ -47,6 +47,9 @@ fn emit_init_component(e: ptr, comp: ptr, rec: Node) -> void { emit_block(ab) nloc = save } + # EV1: a @Public attach hook fires prop_

_attach with the entity + let aev = `prop_{comp}_attach` + if (find_event(aev) != null) { emit(" call void @ev_"); emit(aev); emit("(i32 "); emit(e); emit(")\n") } } # bind each of a model's properties to entity `e`'s component storage, so an @@ -65,7 +68,7 @@ fn emit_bind_props(model: Node, e: ptr) -> void { } } -fn emit_spawn(st: Node) -> void { +fn emit_spawn(st: Node) -> ptr { let e = emit_bind("call i32 @L_alloc()") let ak = find_arch_id(st.s) if ak > 0 { @@ -89,10 +92,15 @@ fn emit_spawn(st: Node) -> void { emit_block(ob) nloc = save } + # EV1: a @Public spawn hook also fires the public event model__spawn, so + # mods (native or foreign, over the ABI) see the entity born. + let sev = `model_{st.s}_spawn` + if (find_event(sev) != null) { emit(" call void @ev_"); emit(sev); emit("(i32 "); emit(e); emit(")\n") } } else { var i = 0 while i < len(st.kids) { emit_init_component(e, st.kids[i].s, st.kids[i].a); i = i + 1 } } + return e # the new entity id (for ludic_spawn_) } fn emit_despawn(st: Node) -> void { @@ -108,19 +116,76 @@ fn emit_despawn(st: Node) -> void { let c = emit_bind(`icmp eq i32 {kind}, {itoa(find_arch_id(mname))}`) let yes = lbl("dh"); let no = lbl("dhn") emit(" br i1 "); emit(c); emit(", label %"); emit(yes); emit(", label %"); emit(no); emit("\n") - emit(yes); emit(":\n call void @on_despawn_"); emit(mname); emit("(i32 "); emit(v.code); emit(")\n") + emit(yes); emit(":\n call void @on_despawn_"); emit(mname); emit("(i32 "); emit(v.code); emit(", i32 0)\n") # reason = EndReason.Despawned + let dev = `model_{mname}_despawn` # EV1: @Public despawn event + if (find_event(dev) != null) { emit(" call void @ev_"); emit(dev); emit("(i32 "); emit(v.code); emit(", i32 0)\n") } emit(" br label %"); emit(no); emit("\n"); emit(no); emit(":\n") i = i + 1 } } + if len(g_events) > 0 { emit(" call void @ludic_sweep_entity(i32 "); emit(v.code); emit(")\n") } # EV5: drop entity-scoped listeners emit(" call void @L_free_entity(i32 "); emit(v.code); emit(")\n") } +# attach P on e [{ overrides }] — add a property to a live entity. Structural +# (not a toggle): seeds the property's fields and fires @OnAttach, but only on a +# real transition — if the entity already has the property it is a no-op, so the +# hook fires once per genuine attach (flecs/Bevy "real add" semantics). +fn emit_attach(st: Node) -> void { + let ev = emit_expr(st.a) + let me = itoa(MAX_ENT) + let hp = nreg(); emit(" "); emit(hp); emit(" = getelementptr inbounds ["); emit(me); emit(" x i8], ptr @H_"); emit(st.s); emit(", i32 0, i32 "); emit(ev.code); emit("\n") + let cur = emit_bind(`load i8, ptr {hp}`) + let isnew = emit_bind(`icmp eq i8 {cur}, 0`) + let doit = lbl("attach"); let done = lbl("attdone") + emit(" br i1 "); emit(isnew); emit(", label %"); emit(doit); emit(", label %"); emit(done); emit("\n") + emit(doit); emit(":\n"); g_term = false + emit_init_component(ev.code, st.s, st.b) # sets has=1, seeds defaults+overrides, fires @OnAttach + if not g_term { emit(" br label %"); emit(done); emit("\n") } + emit(done); emit(":\n"); g_term = false +} + +# detach P on e — remove a property from a live entity. Fires @OnDetach with the +# property bound by name (its data still lives in @S_ storage, so the teardown +# body reads the outgoing value), then clears the has-flag so queries skip it. +# Only fires on a real transition; detaching an absent property is a no-op. +fn emit_detach(st: Node) -> void { + let ev = emit_expr(st.a) + let me = itoa(MAX_ENT) + let hp = nreg(); emit(" "); emit(hp); emit(" = getelementptr inbounds ["); emit(me); emit(" x i8], ptr @H_"); emit(st.s); emit(", i32 0, i32 "); emit(ev.code); emit("\n") + let cur = emit_bind(`load i8, ptr {hp}`) + let here = emit_bind(`icmp ne i8 {cur}, 0`) + let doit = lbl("detach"); let done = lbl("detdone") + emit(" br i1 "); emit(here); emit(", label %"); emit(doit); emit(", label %"); emit(done); emit("\n") + emit(doit); emit(":\n"); g_term = false + emit(" store i8 0, ptr "); emit(hp); emit("\n") # clear has-flag (data persists in @S_) + let hb = ondetach_body(st.s) # @OnDetach reads the outgoing value + if (hb != null) { + let save = nloc + let slot = nreg(); emit(" "); emit(slot); emit(" = getelementptr inbounds ["); emit(me); emit(" x %Cmp_"); emit(st.s); emit("], ptr @S_"); emit(st.s); emit(", i32 0, i32 "); emit(ev.code); emit("\n") + let vslot = emit_alloca("ptr") + emit(" store ptr "); emit(slot); emit(", ptr "); emit(vslot); emit("\n") + loc_push(st.s, vslot, st.s) + emit_block(hb) + nloc = save + } + let dev = `prop_{st.s}_detach` # EV1: @Public detach event + if (find_event(dev) != null) { emit(" call void @ev_"); emit(dev); emit("(i32 "); emit(ev.code); emit(")\n") } + if not g_term { emit(" br label %"); emit(done); emit("\n") } + emit(done); emit(":\n"); g_term = false +} + # enable/disable. `

on ` toggles a property's has-flag on an entity (its # data persists, so re-enabling restores it, and queries already skip a cleared # flag). A bare `` / `` flips a global enabled flag. fn emit_toggle(st: Node) -> void { var val = "0"; if st.ival == 1 { val = "1" } + if (st.ty != null) and (st.ty == "layer") { # enable/disable layer L + emit(" store i32 "); emit(val); emit(", ptr @LE_"); emit(st.s); emit("\n") + var lev = `layer_{st.s}_hide`; if st.ival == 1 { lev = `layer_{st.s}_show` } # public layer -> event + if (find_event(lev) != null) { emit(" call void @ev_"); emit(lev); emit("()\n") } + return + } if (st.a != null) { let ev = emit_expr(st.a) let me = itoa(MAX_ENT) @@ -137,6 +202,9 @@ fn emit_toggle(st: Node) -> void { emit_block(hb) nloc = save } + # EV1: a @Public enable/disable hook fires prop_

_enable / prop_

_disable + var tev = `prop_{st.s}_disable`; if st.ival == 1 { tev = `prop_{st.s}_enable` } + if (find_event(tev) != null) { emit(" call void @ev_"); emit(tev); emit("(i32 "); emit(ev.code); emit(")\n") } } else { var g = "@HE_"; if is_model(st.s) { g = "@ME_" } # model vs handler emit(" store i32 "); emit(val); emit(", ptr "); emit(g); emit(st.s); emit("\n") diff --git a/selfhost/emit_stmt.ludic b/selfhost/emit_stmt.ludic index 11fd1ce7..0379ed48 100644 --- a/selfhost/emit_stmt.ludic +++ b/selfhost/emit_stmt.ludic @@ -160,6 +160,67 @@ fn emit_match(st: Node) -> void { emit(endl); emit(":\n"); g_term = false } +# emit E(field: v, ...) — evaluate the payload args in the event's declared field +# order (so call args line up with the `@ev_` signature), then a direct call. +# A missing arg falls back to the field's default; an unset scalar/ptr to 0/null. +fn emit_emit(st: Node) -> Val { + let ev = find_event(st.s) + if (ev == null) { perr(`emit: unknown event {st.s}`) } + # evaluate each payload field in declared order (default for a missing arg) + let fcodes = new []ptr + let ftys = new []ptr + var f = 0 + while f < len(ev.kids) { + let fd = ev.kids[f] + var av: Node = null # the caller's value for this field, if given + var j = 0 + while j < len(st.a.kids) { if (st.a.kids[j].s == fd.s) { av = st.a.kids[j].a }; j = j + 1 } + let lt = llty(fd.ty) + var code = "0" + if (lt == "ptr") { code = "null" } + if (av != null) { let v = emit_expr(av); code = v.code } + else { if (fd.a != null) { let dv = emit_expr(fd.a); code = dv.code } } # declared default + push(fcodes, code); push(ftys, lt) + f = f + 1 + } + # N4: a remote event (@ToServer/@ToClients) serializes its payload as + # [i32 event_id][packed fields] and net_send in its direction — the far side's + # net_pump() re-emits it. It is a remote call, so there is no local dispatch. + if (ev.ty != null) { + let idp = nreg(); emit(" "); emit(idp); emit(" = getelementptr inbounds i8, ptr @L_sendbuf, i32 0\n") + emit(" store i32 "); emit(itoa(net_event_id(st.s))); emit(", ptr "); emit(idp); emit("\n") + var off = 4 + var k = 0 + while k < len(ev.kids) { + let dp = nreg(); emit(" "); emit(dp); emit(" = getelementptr inbounds i8, ptr @L_sendbuf, i32 "); emit(itoa(off)); emit("\n") + emit(" store "); emit(ftys[k]); emit(" "); emit(fcodes[k]); emit(", ptr "); emit(dp); emit("\n") + off = off + net_field_ibytes(ev.kids[k].ty) + k = k + 1 + } + var peer = "0" + if (ev.ty == "toclients") { peer = "-1" } # broadcast (loopback ignores the peer id) + if (find_extern("net_send") == null) { g_uses_loopback = true } + emit(" call void @"); emit(net_send_sym()); emit("(i32 "); emit(peer); emit(", ptr @L_sendbuf, i32 "); emit(itoa(off)); emit(")\n") + return val("0", "int") + } + # a local event: build the call args and dispatch. A cancellable event returns + # its cancelled flag (i32); a plain event is void. + let args = buf_new() + var g = 0 + while g < len(fcodes) { + if g > 0 { buf_puts(args, ", ") } + buf_puts(args, ftys[g]); buf_puts(args, " "); buf_puts(args, fcodes[g]) + g = g + 1 + } + if ev.ival == 1 { + let r = nreg() + emit(" "); emit(r); emit(" = call i32 @ev_"); emit(st.s); emit("("); emit(buf_str(args)); emit(")\n") + return val(r, "int") + } + emit(" call void @ev_"); emit(st.s); emit("("); emit(buf_str(args)); emit(")\n") + return val("0", "int") +} + fn emit_stmt(st: Node) -> void { if st.kind == S_LET { var ty = st.ty @@ -184,9 +245,16 @@ fn emit_stmt(st: Node) -> void { if st.kind == S_CONTINUE { emit(" br label %"); emit(cnt_lbl[nloop - 1]); emit("\n"); g_term = true; return } if st.kind == S_MATCH { emit_match(st); return } if st.kind == S_QUERY { emit_query(st); return } - if st.kind == S_SPAWN { emit_spawn(st); return } + if st.kind == S_SPAWN { let se = emit_spawn(st); return } if st.kind == S_DESPAWN { emit_despawn(st); return } if st.kind == S_TOGGLE { emit_toggle(st); return } + if st.kind == S_ATTACH { emit_attach(st); return } + if st.kind == S_DETACH { emit_detach(st); return } + if st.kind == S_EMIT { let v = emit_emit(st); return } # statement form: discard the flag + if st.kind == S_CANCEL { # veto the enclosing cancellable event + if (g_cancel_addr == null) { perr("cancel outside a cancellable event listener") } + emit(" store i32 1, ptr "); emit(g_cancel_addr); emit("\n"); return + } if st.kind == S_MACHINE { emit_machine(st); return } if st.kind == S_BECOME { emit_become(st); return } if st.kind == S_EXPR { let v = emit_expr(st.a); return } diff --git a/selfhost/ludicc.seed.ll b/selfhost/ludicc.seed.ll index 810b4e90..40b36ef4 100644 --- a/selfhost/ludicc.seed.ll +++ b/selfhost/ludicc.seed.ll @@ -64,16 +64,28 @@ declare void @win_close() @g_nself = internal global i32 0 @g_mach_stk = internal global ptr null @g_nmach = internal global i32 0 +@g_g_scenes = internal global ptr null +@g_g_scene_count = internal global i32 0 +@g_g_start_scene = internal global i32 0 +@g_g_cur_scene = internal global ptr null @g_g_computed = internal global ptr null @g_g_onspawn = internal global ptr null @g_g_ondespawn = internal global ptr null @g_g_onattach = internal global ptr null +@g_g_ondetach = internal global ptr null @g_g_onenable = internal global ptr null @g_g_ondisable = internal global ptr null +@g_g_events = internal global ptr null +@g_g_onlisten = internal global ptr null +@g_g_cancel_addr = internal global ptr null +@g_g_toggled_layers = internal global ptr null @g_g_addr_ty = internal global ptr null @g_g_intrin_ok = internal global i32 0 @g_g_windowed = internal global i32 0 @g_g_iok = internal global i32 0 +@g_g_snap_mode = internal global ptr null +@g_g_off = internal global ptr null +@g_g_uses_loopback = internal global i32 0 @g_uiw = internal global ptr null @g_uiw_parent = internal global ptr null @g_ui_roots = internal global ptr null @@ -89,1569 +101,2805 @@ declare void @win_close() @.str9 = private unnamed_addr constant [2 x i8] c")\00" @.str10 = private unnamed_addr constant [2 x i8] c"+\00" @.str11 = private unnamed_addr constant [4 x i8] c"str\00" -@.str12 = private unnamed_addr constant [5 x i8] c"true\00" -@.str13 = private unnamed_addr constant [6 x i8] c"false\00" -@.str14 = private unnamed_addr constant [5 x i8] c"null\00" -@.str15 = private unnamed_addr constant [4 x i8] c"new\00" -@.str16 = private unnamed_addr constant [2 x i8] c"(\00" -@.str17 = private unnamed_addr constant [2 x i8] c")\00" -@.str18 = private unnamed_addr constant [20 x i8] c"expected expression\00" -@.str19 = private unnamed_addr constant [2 x i8] c".\00" -@.str20 = private unnamed_addr constant [2 x i8] c"[\00" -@.str21 = private unnamed_addr constant [3 x i8] c"..\00" -@.str22 = private unnamed_addr constant [2 x i8] c"]\00" -@.str23 = private unnamed_addr constant [2 x i8] c"]\00" -@.str24 = private unnamed_addr constant [2 x i8] c"(\00" -@.str25 = private unnamed_addr constant [2 x i8] c"-\00" -@.str26 = private unnamed_addr constant [2 x i8] c"-\00" -@.str27 = private unnamed_addr constant [2 x i8] c"~\00" -@.str28 = private unnamed_addr constant [2 x i8] c"~\00" -@.str29 = private unnamed_addr constant [4 x i8] c"not\00" -@.str30 = private unnamed_addr constant [4 x i8] c"not\00" -@.str31 = private unnamed_addr constant [2 x i8] c"*\00" -@.str32 = private unnamed_addr constant [2 x i8] c"/\00" -@.str33 = private unnamed_addr constant [2 x i8] c"%\00" -@.str34 = private unnamed_addr constant [3 x i8] c"<<\00" -@.str35 = private unnamed_addr constant [3 x i8] c">>\00" -@.str36 = private unnamed_addr constant [2 x i8] c"&\00" -@.str37 = private unnamed_addr constant [2 x i8] c"+\00" -@.str38 = private unnamed_addr constant [2 x i8] c"-\00" -@.str39 = private unnamed_addr constant [2 x i8] c"|\00" -@.str40 = private unnamed_addr constant [2 x i8] c"^\00" -@.str41 = private unnamed_addr constant [2 x i8] c"<\00" -@.str42 = private unnamed_addr constant [3 x i8] c"<=\00" -@.str43 = private unnamed_addr constant [2 x i8] c">\00" -@.str44 = private unnamed_addr constant [3 x i8] c">=\00" -@.str45 = private unnamed_addr constant [3 x i8] c"==\00" -@.str46 = private unnamed_addr constant [3 x i8] c"!=\00" -@.str47 = private unnamed_addr constant [4 x i8] c"and\00" -@.str48 = private unnamed_addr constant [4 x i8] c"and\00" -@.str49 = private unnamed_addr constant [3 x i8] c"or\00" -@.str50 = private unnamed_addr constant [3 x i8] c"or\00" -@.str51 = private unnamed_addr constant [2 x i8] c"{\00" -@.str52 = private unnamed_addr constant [2 x i8] c"}\00" -@.str53 = private unnamed_addr constant [2 x i8] c":\00" -@.str54 = private unnamed_addr constant [2 x i8] c",\00" -@.str55 = private unnamed_addr constant [2 x i8] c"}\00" -@.str56 = private unnamed_addr constant [2 x i8] c"{\00" -@.str57 = private unnamed_addr constant [2 x i8] c"}\00" +@.str12 = private unnamed_addr constant [2 x i8] c"(\00" +@.str13 = private unnamed_addr constant [2 x i8] c")\00" +@.str14 = private unnamed_addr constant [2 x i8] c":\00" +@.str15 = private unnamed_addr constant [2 x i8] c",\00" +@.str16 = private unnamed_addr constant [2 x i8] c")\00" +@.str17 = private unnamed_addr constant [5 x i8] c"emit\00" +@.str18 = private unnamed_addr constant [5 x i8] c"true\00" +@.str19 = private unnamed_addr constant [6 x i8] c"false\00" +@.str20 = private unnamed_addr constant [5 x i8] c"null\00" +@.str21 = private unnamed_addr constant [4 x i8] c"new\00" +@.str22 = private unnamed_addr constant [2 x i8] c"(\00" +@.str23 = private unnamed_addr constant [2 x i8] c")\00" +@.str24 = private unnamed_addr constant [20 x i8] c"expected expression\00" +@.str25 = private unnamed_addr constant [2 x i8] c".\00" +@.str26 = private unnamed_addr constant [2 x i8] c"[\00" +@.str27 = private unnamed_addr constant [3 x i8] c"..\00" +@.str28 = private unnamed_addr constant [2 x i8] c"]\00" +@.str29 = private unnamed_addr constant [2 x i8] c"]\00" +@.str30 = private unnamed_addr constant [2 x i8] c"(\00" +@.str31 = private unnamed_addr constant [2 x i8] c"-\00" +@.str32 = private unnamed_addr constant [2 x i8] c"-\00" +@.str33 = private unnamed_addr constant [2 x i8] c"~\00" +@.str34 = private unnamed_addr constant [2 x i8] c"~\00" +@.str35 = private unnamed_addr constant [4 x i8] c"not\00" +@.str36 = private unnamed_addr constant [4 x i8] c"not\00" +@.str37 = private unnamed_addr constant [2 x i8] c"*\00" +@.str38 = private unnamed_addr constant [2 x i8] c"/\00" +@.str39 = private unnamed_addr constant [2 x i8] c"%\00" +@.str40 = private unnamed_addr constant [3 x i8] c"<<\00" +@.str41 = private unnamed_addr constant [3 x i8] c">>\00" +@.str42 = private unnamed_addr constant [2 x i8] c"&\00" +@.str43 = private unnamed_addr constant [2 x i8] c"+\00" +@.str44 = private unnamed_addr constant [2 x i8] c"-\00" +@.str45 = private unnamed_addr constant [2 x i8] c"|\00" +@.str46 = private unnamed_addr constant [2 x i8] c"^\00" +@.str47 = private unnamed_addr constant [2 x i8] c"<\00" +@.str48 = private unnamed_addr constant [3 x i8] c"<=\00" +@.str49 = private unnamed_addr constant [2 x i8] c">\00" +@.str50 = private unnamed_addr constant [3 x i8] c">=\00" +@.str51 = private unnamed_addr constant [3 x i8] c"==\00" +@.str52 = private unnamed_addr constant [3 x i8] c"!=\00" +@.str53 = private unnamed_addr constant [4 x i8] c"and\00" +@.str54 = private unnamed_addr constant [4 x i8] c"and\00" +@.str55 = private unnamed_addr constant [3 x i8] c"or\00" +@.str56 = private unnamed_addr constant [3 x i8] c"or\00" +@.str57 = private unnamed_addr constant [2 x i8] c"{\00" @.str58 = private unnamed_addr constant [2 x i8] c"}\00" -@.str59 = private unnamed_addr constant [43 x i8] c"expected newline or ';' between statements\00" -@.str60 = private unnamed_addr constant [2 x i8] c"}\00" -@.str61 = private unnamed_addr constant [4 x i8] c"let\00" -@.str62 = private unnamed_addr constant [4 x i8] c"var\00" -@.str63 = private unnamed_addr constant [4 x i8] c"var\00" -@.str64 = private unnamed_addr constant [2 x i8] c":\00" -@.str65 = private unnamed_addr constant [2 x i8] c"=\00" -@.str66 = private unnamed_addr constant [7 x i8] c"return\00" -@.str67 = private unnamed_addr constant [2 x i8] c"}\00" -@.str68 = private unnamed_addr constant [3 x i8] c"if\00" -@.str69 = private unnamed_addr constant [5 x i8] c"else\00" -@.str70 = private unnamed_addr constant [3 x i8] c"if\00" -@.str71 = private unnamed_addr constant [6 x i8] c"while\00" -@.str72 = private unnamed_addr constant [4 x i8] c"for\00" -@.str73 = private unnamed_addr constant [2 x i8] c"(\00" -@.str74 = private unnamed_addr constant [3 x i8] c"..\00" -@.str75 = private unnamed_addr constant [6 x i8] c"spawn\00" -@.str76 = private unnamed_addr constant [8 x i8] c"machine\00" -@.str77 = private unnamed_addr constant [2 x i8] c"{\00" -@.str78 = private unnamed_addr constant [2 x i8] c"}\00" -@.str79 = private unnamed_addr constant [2 x i8] c"=\00" -@.str80 = private unnamed_addr constant [2 x i8] c"}\00" -@.str81 = private unnamed_addr constant [7 x i8] c"become\00" -@.str82 = private unnamed_addr constant [8 x i8] c"despawn\00" -@.str83 = private unnamed_addr constant [7 x i8] c"enable\00" -@.str84 = private unnamed_addr constant [8 x i8] c"disable\00" -@.str85 = private unnamed_addr constant [7 x i8] c"enable\00" -@.str86 = private unnamed_addr constant [3 x i8] c"on\00" -@.str87 = private unnamed_addr constant [6 x i8] c"break\00" -@.str88 = private unnamed_addr constant [9 x i8] c"continue\00" -@.str89 = private unnamed_addr constant [6 x i8] c"match\00" -@.str90 = private unnamed_addr constant [2 x i8] c"{\00" -@.str91 = private unnamed_addr constant [2 x i8] c"}\00" -@.str92 = private unnamed_addr constant [2 x i8] c",\00" -@.str93 = private unnamed_addr constant [3 x i8] c"=>\00" -@.str94 = private unnamed_addr constant [2 x i8] c"{\00" -@.str95 = private unnamed_addr constant [2 x i8] c"}\00" -@.str96 = private unnamed_addr constant [2 x i8] c"=\00" -@.str97 = private unnamed_addr constant [3 x i8] c"+=\00" -@.str98 = private unnamed_addr constant [3 x i8] c"-=\00" -@.str99 = private unnamed_addr constant [3 x i8] c"*=\00" -@.str100 = private unnamed_addr constant [3 x i8] c"/=\00" -@.str101 = private unnamed_addr constant [2 x i8] c":\00" -@.str102 = private unnamed_addr constant [2 x i8] c"=\00" -@.str103 = private unnamed_addr constant [2 x i8] c":\00" -@.str104 = private unnamed_addr constant [2 x i8] c"=\00" -@.str105 = private unnamed_addr constant [2 x i8] c"(\00" -@.str106 = private unnamed_addr constant [2 x i8] c")\00" -@.str107 = private unnamed_addr constant [2 x i8] c":\00" -@.str108 = private unnamed_addr constant [2 x i8] c",\00" -@.str109 = private unnamed_addr constant [2 x i8] c")\00" -@.str110 = private unnamed_addr constant [5 x i8] c"void\00" -@.str111 = private unnamed_addr constant [3 x i8] c"->\00" -@.str112 = private unnamed_addr constant [1 x i8] c"\00" -@.str113 = private unnamed_addr constant [2 x i8] c"@\00" -@.str114 = private unnamed_addr constant [7 x i8] c"export\00" -@.str115 = private unnamed_addr constant [8 x i8] c"Queries\00" -@.str116 = private unnamed_addr constant [8 x i8] c"OnSpawn\00" -@.str117 = private unnamed_addr constant [2 x i8] c"(\00" -@.str118 = private unnamed_addr constant [2 x i8] c")\00" -@.str119 = private unnamed_addr constant [10 x i8] c"OnDespawn\00" -@.str120 = private unnamed_addr constant [2 x i8] c"(\00" -@.str121 = private unnamed_addr constant [2 x i8] c")\00" -@.str122 = private unnamed_addr constant [9 x i8] c"OnAttach\00" -@.str123 = private unnamed_addr constant [2 x i8] c"(\00" -@.str124 = private unnamed_addr constant [2 x i8] c")\00" -@.str125 = private unnamed_addr constant [9 x i8] c"OnEnable\00" -@.str126 = private unnamed_addr constant [2 x i8] c"(\00" -@.str127 = private unnamed_addr constant [2 x i8] c")\00" -@.str128 = private unnamed_addr constant [10 x i8] c"OnDisable\00" -@.str129 = private unnamed_addr constant [2 x i8] c"(\00" -@.str130 = private unnamed_addr constant [2 x i8] c")\00" -@.str131 = private unnamed_addr constant [8 x i8] c"OnStart\00" -@.str132 = private unnamed_addr constant [6 x i8] c"Start\00" -@.str133 = private unnamed_addr constant [7 x i8] c"OnQuit\00" -@.str134 = private unnamed_addr constant [7 x i8] c"OnQuit\00" -@.str135 = private unnamed_addr constant [2 x i8] c"(\00" -@.str136 = private unnamed_addr constant [2 x i8] c"(\00" -@.str137 = private unnamed_addr constant [2 x i8] c")\00" -@.str138 = private unnamed_addr constant [7 x i8] c"import\00" -@.str139 = private unnamed_addr constant [29 x i8] c"expected \22path\22 after import\00" -@.str140 = private unnamed_addr constant [5 x i8] c"enum\00" -@.str141 = private unnamed_addr constant [9 x i8] c"property\00" -@.str142 = private unnamed_addr constant [6 x i8] c"model\00" -@.str143 = private unnamed_addr constant [8 x i8] c"handler\00" -@.str144 = private unnamed_addr constant [3 x i8] c"ui\00" -@.str145 = private unnamed_addr constant [4 x i8] c"var\00" -@.str146 = private unnamed_addr constant [6 x i8] c"const\00" -@.str147 = private unnamed_addr constant [3 x i8] c"fn\00" -@.str148 = private unnamed_addr constant [7 x i8] c"extern\00" -@.str149 = private unnamed_addr constant [6 x i8] c"entry\00" -@.str150 = private unnamed_addr constant [21 x i8] c"expected declaration\00" -@.str151 = private unnamed_addr constant [20 x i8] c"cannot open import \00" -@.str152 = private unnamed_addr constant [1 x i8] c"\00" -@.str153 = private unnamed_addr constant [26 x i8] c"runtime/native/core.ludic\00" -@.str154 = private unnamed_addr constant [6 x i8] c"Ludic\00" -@.str155 = private unnamed_addr constant [7 x i8] c"import\00" -@.str156 = private unnamed_addr constant [2 x i8] c"@\00" -@.str157 = private unnamed_addr constant [2 x i8] c"(\00" -@.str158 = private unnamed_addr constant [2 x i8] c"(\00" -@.str159 = private unnamed_addr constant [2 x i8] c")\00" -@.str160 = private unnamed_addr constant [8 x i8] c"program\00" -@.str161 = private unnamed_addr constant [2 x i8] c"{\00" -@.str162 = private unnamed_addr constant [2 x i8] c"}\00" -@.str163 = private unnamed_addr constant [2 x i8] c"{\00" -@.str164 = private unnamed_addr constant [2 x i8] c"}\00" -@.str165 = private unnamed_addr constant [2 x i8] c"@\00" -@.str166 = private unnamed_addr constant [9 x i8] c"Computed\00" -@.str167 = private unnamed_addr constant [2 x i8] c":\00" -@.str168 = private unnamed_addr constant [2 x i8] c"=\00" -@.str169 = private unnamed_addr constant [2 x i8] c",\00" -@.str170 = private unnamed_addr constant [2 x i8] c"}\00" -@.str171 = private unnamed_addr constant [7 x i8] c"Update\00" -@.str172 = private unnamed_addr constant [2 x i8] c"@\00" -@.str173 = private unnamed_addr constant [2 x i8] c"(\00" -@.str174 = private unnamed_addr constant [2 x i8] c"(\00" -@.str175 = private unnamed_addr constant [2 x i8] c")\00" -@.str176 = private unnamed_addr constant [6 x i8] c"phase\00" -@.str177 = private unnamed_addr constant [2 x i8] c"[\00" -@.str178 = private unnamed_addr constant [2 x i8] c"]\00" -@.str179 = private unnamed_addr constant [2 x i8] c"{\00" -@.str180 = private unnamed_addr constant [2 x i8] c"}\00" -@.str181 = private unnamed_addr constant [2 x i8] c",\00" -@.str182 = private unnamed_addr constant [2 x i8] c"]\00" -@.str183 = private unnamed_addr constant [6 x i8] c"where\00" -@.str184 = private unnamed_addr constant [2 x i8] c"(\00" -@.str185 = private unnamed_addr constant [2 x i8] c")\00" -@.str186 = private unnamed_addr constant [2 x i8] c",\00" -@.str187 = private unnamed_addr constant [2 x i8] c")\00" -@.str188 = private unnamed_addr constant [6 x i8] c"query\00" -@.str189 = private unnamed_addr constant [29 x i8] c"expected 'query' in for-loop\00" -@.str190 = private unnamed_addr constant [4 x i8] c"and\00" -@.str191 = private unnamed_addr constant [2 x i8] c"(\00" -@.str192 = private unnamed_addr constant [2 x i8] c")\00" -@.str193 = private unnamed_addr constant [2 x i8] c")\00" -@.str194 = private unnamed_addr constant [2 x i8] c":\00" -@.str195 = private unnamed_addr constant [6 x i8] c"these\00" -@.str196 = private unnamed_addr constant [2 x i8] c"[\00" -@.str197 = private unnamed_addr constant [2 x i8] c"]\00" -@.str198 = private unnamed_addr constant [2 x i8] c"{\00" -@.str199 = private unnamed_addr constant [2 x i8] c"}\00" -@.str200 = private unnamed_addr constant [2 x i8] c",\00" -@.str201 = private unnamed_addr constant [2 x i8] c"]\00" -@.str202 = private unnamed_addr constant [3 x i8] c"on\00" -@.str203 = private unnamed_addr constant [2 x i8] c",\00" -@.str204 = private unnamed_addr constant [2 x i8] c")\00" -@.str205 = private unnamed_addr constant [2 x i8] c"{\00" -@.str206 = private unnamed_addr constant [2 x i8] c"}\00" -@.str207 = private unnamed_addr constant [2 x i8] c",\00" -@.str208 = private unnamed_addr constant [2 x i8] c"}\00" -@.str209 = private unnamed_addr constant [2 x i8] c"{\00" -@.str210 = private unnamed_addr constant [2 x i8] c"}\00" -@.str211 = private unnamed_addr constant [2 x i8] c",\00" -@.str212 = private unnamed_addr constant [2 x i8] c"}\00" -@.str213 = private unnamed_addr constant [2 x i8] c"{\00" -@.str214 = private unnamed_addr constant [2 x i8] c"}\00" -@.str215 = private unnamed_addr constant [2 x i8] c",\00" +@.str59 = private unnamed_addr constant [2 x i8] c":\00" +@.str60 = private unnamed_addr constant [2 x i8] c",\00" +@.str61 = private unnamed_addr constant [2 x i8] c"}\00" +@.str62 = private unnamed_addr constant [2 x i8] c"{\00" +@.str63 = private unnamed_addr constant [2 x i8] c"}\00" +@.str64 = private unnamed_addr constant [2 x i8] c"}\00" +@.str65 = private unnamed_addr constant [43 x i8] c"expected newline or ';' between statements\00" +@.str66 = private unnamed_addr constant [2 x i8] c"}\00" +@.str67 = private unnamed_addr constant [4 x i8] c"let\00" +@.str68 = private unnamed_addr constant [4 x i8] c"var\00" +@.str69 = private unnamed_addr constant [4 x i8] c"var\00" +@.str70 = private unnamed_addr constant [2 x i8] c":\00" +@.str71 = private unnamed_addr constant [2 x i8] c"=\00" +@.str72 = private unnamed_addr constant [7 x i8] c"return\00" +@.str73 = private unnamed_addr constant [2 x i8] c"}\00" +@.str74 = private unnamed_addr constant [3 x i8] c"if\00" +@.str75 = private unnamed_addr constant [5 x i8] c"else\00" +@.str76 = private unnamed_addr constant [3 x i8] c"if\00" +@.str77 = private unnamed_addr constant [6 x i8] c"while\00" +@.str78 = private unnamed_addr constant [4 x i8] c"for\00" +@.str79 = private unnamed_addr constant [2 x i8] c"(\00" +@.str80 = private unnamed_addr constant [3 x i8] c"..\00" +@.str81 = private unnamed_addr constant [6 x i8] c"spawn\00" +@.str82 = private unnamed_addr constant [8 x i8] c"machine\00" +@.str83 = private unnamed_addr constant [2 x i8] c"{\00" +@.str84 = private unnamed_addr constant [2 x i8] c"}\00" +@.str85 = private unnamed_addr constant [2 x i8] c"=\00" +@.str86 = private unnamed_addr constant [2 x i8] c"}\00" +@.str87 = private unnamed_addr constant [5 x i8] c"emit\00" +@.str88 = private unnamed_addr constant [7 x i8] c"become\00" +@.str89 = private unnamed_addr constant [8 x i8] c"despawn\00" +@.str90 = private unnamed_addr constant [7 x i8] c"enable\00" +@.str91 = private unnamed_addr constant [8 x i8] c"disable\00" +@.str92 = private unnamed_addr constant [7 x i8] c"enable\00" +@.str93 = private unnamed_addr constant [6 x i8] c"layer\00" +@.str94 = private unnamed_addr constant [6 x i8] c"layer\00" +@.str95 = private unnamed_addr constant [3 x i8] c"on\00" +@.str96 = private unnamed_addr constant [7 x i8] c"attach\00" +@.str97 = private unnamed_addr constant [3 x i8] c"on\00" +@.str98 = private unnamed_addr constant [27 x i8] c"attach needs 'on '\00" +@.str99 = private unnamed_addr constant [2 x i8] c"{\00" +@.str100 = private unnamed_addr constant [7 x i8] c"detach\00" +@.str101 = private unnamed_addr constant [3 x i8] c"on\00" +@.str102 = private unnamed_addr constant [27 x i8] c"detach needs 'on '\00" +@.str103 = private unnamed_addr constant [6 x i8] c"break\00" +@.str104 = private unnamed_addr constant [9 x i8] c"continue\00" +@.str105 = private unnamed_addr constant [7 x i8] c"cancel\00" +@.str106 = private unnamed_addr constant [6 x i8] c"match\00" +@.str107 = private unnamed_addr constant [2 x i8] c"{\00" +@.str108 = private unnamed_addr constant [2 x i8] c"}\00" +@.str109 = private unnamed_addr constant [2 x i8] c",\00" +@.str110 = private unnamed_addr constant [3 x i8] c"=>\00" +@.str111 = private unnamed_addr constant [2 x i8] c"{\00" +@.str112 = private unnamed_addr constant [2 x i8] c"}\00" +@.str113 = private unnamed_addr constant [2 x i8] c"=\00" +@.str114 = private unnamed_addr constant [3 x i8] c"+=\00" +@.str115 = private unnamed_addr constant [3 x i8] c"-=\00" +@.str116 = private unnamed_addr constant [3 x i8] c"*=\00" +@.str117 = private unnamed_addr constant [3 x i8] c"/=\00" +@.str118 = private unnamed_addr constant [2 x i8] c":\00" +@.str119 = private unnamed_addr constant [2 x i8] c"=\00" +@.str120 = private unnamed_addr constant [2 x i8] c":\00" +@.str121 = private unnamed_addr constant [2 x i8] c"=\00" +@.str122 = private unnamed_addr constant [2 x i8] c"(\00" +@.str123 = private unnamed_addr constant [2 x i8] c")\00" +@.str124 = private unnamed_addr constant [2 x i8] c":\00" +@.str125 = private unnamed_addr constant [2 x i8] c",\00" +@.str126 = private unnamed_addr constant [2 x i8] c")\00" +@.str127 = private unnamed_addr constant [5 x i8] c"void\00" +@.str128 = private unnamed_addr constant [3 x i8] c"->\00" +@.str129 = private unnamed_addr constant [1 x i8] c"\00" +@.str130 = private unnamed_addr constant [2 x i8] c"@\00" +@.str131 = private unnamed_addr constant [7 x i8] c"export\00" +@.str132 = private unnamed_addr constant [7 x i8] c"Public\00" +@.str133 = private unnamed_addr constant [3 x i8] c"On\00" +@.str134 = private unnamed_addr constant [2 x i8] c"(\00" +@.str135 = private unnamed_addr constant [2 x i8] c")\00" +@.str136 = private unnamed_addr constant [8 x i8] c"Queries\00" +@.str137 = private unnamed_addr constant [8 x i8] c"OnSpawn\00" +@.str138 = private unnamed_addr constant [2 x i8] c"(\00" +@.str139 = private unnamed_addr constant [2 x i8] c")\00" +@.str140 = private unnamed_addr constant [10 x i8] c"OnDespawn\00" +@.str141 = private unnamed_addr constant [2 x i8] c"(\00" +@.str142 = private unnamed_addr constant [2 x i8] c",\00" +@.str143 = private unnamed_addr constant [2 x i8] c":\00" +@.str144 = private unnamed_addr constant [2 x i8] c")\00" +@.str145 = private unnamed_addr constant [9 x i8] c"OnAttach\00" +@.str146 = private unnamed_addr constant [2 x i8] c"(\00" +@.str147 = private unnamed_addr constant [2 x i8] c")\00" +@.str148 = private unnamed_addr constant [9 x i8] c"OnDetach\00" +@.str149 = private unnamed_addr constant [2 x i8] c"(\00" +@.str150 = private unnamed_addr constant [2 x i8] c")\00" +@.str151 = private unnamed_addr constant [9 x i8] c"OnEnable\00" +@.str152 = private unnamed_addr constant [2 x i8] c"(\00" +@.str153 = private unnamed_addr constant [2 x i8] c")\00" +@.str154 = private unnamed_addr constant [10 x i8] c"OnDisable\00" +@.str155 = private unnamed_addr constant [2 x i8] c"(\00" +@.str156 = private unnamed_addr constant [2 x i8] c")\00" +@.str157 = private unnamed_addr constant [8 x i8] c"OnStart\00" +@.str158 = private unnamed_addr constant [6 x i8] c"Start\00" +@.str159 = private unnamed_addr constant [7 x i8] c"OnQuit\00" +@.str160 = private unnamed_addr constant [7 x i8] c"OnQuit\00" +@.str161 = private unnamed_addr constant [5 x i8] c"Sync\00" +@.str162 = private unnamed_addr constant [6 x i8] c"Owned\00" +@.str163 = private unnamed_addr constant [7 x i8] c"Server\00" +@.str164 = private unnamed_addr constant [7 x i8] c"server\00" +@.str165 = private unnamed_addr constant [10 x i8] c"Predicted\00" +@.str166 = private unnamed_addr constant [10 x i8] c"predicted\00" +@.str167 = private unnamed_addr constant [9 x i8] c"ToServer\00" +@.str168 = private unnamed_addr constant [9 x i8] c"toserver\00" +@.str169 = private unnamed_addr constant [10 x i8] c"ToClients\00" +@.str170 = private unnamed_addr constant [10 x i8] c"toclients\00" +@.str171 = private unnamed_addr constant [2 x i8] c"(\00" +@.str172 = private unnamed_addr constant [2 x i8] c"(\00" +@.str173 = private unnamed_addr constant [2 x i8] c")\00" +@.str174 = private unnamed_addr constant [7 x i8] c"import\00" +@.str175 = private unnamed_addr constant [29 x i8] c"expected \22path\22 after import\00" +@.str176 = private unnamed_addr constant [5 x i8] c"enum\00" +@.str177 = private unnamed_addr constant [6 x i8] c"event\00" +@.str178 = private unnamed_addr constant [9 x i8] c"property\00" +@.str179 = private unnamed_addr constant [6 x i8] c"model\00" +@.str180 = private unnamed_addr constant [6 x i8] c"scene\00" +@.str181 = private unnamed_addr constant [8 x i8] c"handler\00" +@.str182 = private unnamed_addr constant [7 x i8] c"server\00" +@.str183 = private unnamed_addr constant [7 x i8] c"model_\00" +@.str184 = private unnamed_addr constant [7 x i8] c"_spawn\00" +@.str185 = private unnamed_addr constant [7 x i8] c"model_\00" +@.str186 = private unnamed_addr constant [9 x i8] c"_despawn\00" +@.str187 = private unnamed_addr constant [6 x i8] c"prop_\00" +@.str188 = private unnamed_addr constant [8 x i8] c"_attach\00" +@.str189 = private unnamed_addr constant [6 x i8] c"prop_\00" +@.str190 = private unnamed_addr constant [8 x i8] c"_detach\00" +@.str191 = private unnamed_addr constant [6 x i8] c"prop_\00" +@.str192 = private unnamed_addr constant [8 x i8] c"_enable\00" +@.str193 = private unnamed_addr constant [6 x i8] c"prop_\00" +@.str194 = private unnamed_addr constant [9 x i8] c"_disable\00" +@.str195 = private unnamed_addr constant [6 x i8] c"Start\00" +@.str196 = private unnamed_addr constant [14 x i8] c"program_start\00" +@.str197 = private unnamed_addr constant [13 x i8] c"program_quit\00" +@.str198 = private unnamed_addr constant [3 x i8] c"ui\00" +@.str199 = private unnamed_addr constant [4 x i8] c"var\00" +@.str200 = private unnamed_addr constant [6 x i8] c"const\00" +@.str201 = private unnamed_addr constant [3 x i8] c"fn\00" +@.str202 = private unnamed_addr constant [7 x i8] c"extern\00" +@.str203 = private unnamed_addr constant [6 x i8] c"entry\00" +@.str204 = private unnamed_addr constant [21 x i8] c"expected declaration\00" +@.str205 = private unnamed_addr constant [20 x i8] c"cannot open import \00" +@.str206 = private unnamed_addr constant [1 x i8] c"\00" +@.str207 = private unnamed_addr constant [26 x i8] c"runtime/native/core.ludic\00" +@.str208 = private unnamed_addr constant [6 x i8] c"Ludic\00" +@.str209 = private unnamed_addr constant [7 x i8] c"import\00" +@.str210 = private unnamed_addr constant [2 x i8] c"@\00" +@.str211 = private unnamed_addr constant [2 x i8] c"(\00" +@.str212 = private unnamed_addr constant [2 x i8] c"(\00" +@.str213 = private unnamed_addr constant [2 x i8] c")\00" +@.str214 = private unnamed_addr constant [8 x i8] c"program\00" +@.str215 = private unnamed_addr constant [2 x i8] c"{\00" @.str216 = private unnamed_addr constant [2 x i8] c"}\00" -@.str217 = private unnamed_addr constant [2 x i8] c"(\00" -@.str218 = private unnamed_addr constant [2 x i8] c")\00" -@.str219 = private unnamed_addr constant [2 x i8] c":\00" -@.str220 = private unnamed_addr constant [2 x i8] c",\00" -@.str221 = private unnamed_addr constant [2 x i8] c")\00" -@.str222 = private unnamed_addr constant [5 x i8] c"void\00" -@.str223 = private unnamed_addr constant [3 x i8] c"->\00" -@.str224 = private unnamed_addr constant [2 x i8] c"=\00" -@.str225 = private unnamed_addr constant [2 x i8] c":\00" -@.str226 = private unnamed_addr constant [2 x i8] c":\00" +@.str217 = private unnamed_addr constant [2 x i8] c"{\00" +@.str218 = private unnamed_addr constant [2 x i8] c"}\00" +@.str219 = private unnamed_addr constant [2 x i8] c"@\00" +@.str220 = private unnamed_addr constant [9 x i8] c"Computed\00" +@.str221 = private unnamed_addr constant [5 x i8] c"Sync\00" +@.str222 = private unnamed_addr constant [2 x i8] c":\00" +@.str223 = private unnamed_addr constant [2 x i8] c"=\00" +@.str224 = private unnamed_addr constant [2 x i8] c",\00" +@.str225 = private unnamed_addr constant [2 x i8] c"}\00" +@.str226 = private unnamed_addr constant [12 x i8] c"cancellable\00" @.str227 = private unnamed_addr constant [2 x i8] c"{\00" @.str228 = private unnamed_addr constant [2 x i8] c"}\00" -@.str229 = private unnamed_addr constant [2 x i8] c"}\00" -@.str230 = private unnamed_addr constant [2 x i8] c"{\00" -@.str231 = private unnamed_addr constant [2 x i8] c"}\00" -@.str232 = private unnamed_addr constant [3 x i8] c"%t\00" -@.str233 = private unnamed_addr constant [3 x i8] c" \00" -@.str234 = private unnamed_addr constant [11 x i8] c" = alloca \00" -@.str235 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str236 = private unnamed_addr constant [3 x i8] c"%t\00" -@.str237 = private unnamed_addr constant [4 x i8] c"int\00" -@.str238 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str239 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str240 = private unnamed_addr constant [4 x i8] c"i32\00" -@.str241 = private unnamed_addr constant [5 x i8] c"byte\00" -@.str242 = private unnamed_addr constant [3 x i8] c"i8\00" -@.str243 = private unnamed_addr constant [6 x i8] c"words\00" -@.str244 = private unnamed_addr constant [7 x i8] c"fixeds\00" -@.str245 = private unnamed_addr constant [5 x i8] c"ptrs\00" -@.str246 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str247 = private unnamed_addr constant [5 x i8] c"void\00" -@.str248 = private unnamed_addr constant [5 x i8] c"void\00" -@.str249 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str250 = private unnamed_addr constant [6 x i8] c"%Cmp_\00" -@.str251 = private unnamed_addr constant [4 x i8] c"int\00" -@.str252 = private unnamed_addr constant [2 x i8] c".\00" -@.str253 = private unnamed_addr constant [2 x i8] c".\00" -@.str254 = private unnamed_addr constant [6 x i8] c"@.str\00" -@.str255 = private unnamed_addr constant [35 x i8] c" = private unnamed_addr constant [\00" -@.str256 = private unnamed_addr constant [10 x i8] c" x i8] c\22\00" -@.str257 = private unnamed_addr constant [6 x i8] c"\5C00\22\0A\00" -@.str258 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str259 = private unnamed_addr constant [5 x i8] c"null\00" -@.str260 = private unnamed_addr constant [2 x i8] c"0\00" -@.str261 = private unnamed_addr constant [2 x i8] c"-\00" -@.str262 = private unnamed_addr constant [2 x i8] c"-\00" -@.str263 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str264 = private unnamed_addr constant [5 x i8] c"null\00" -@.str265 = private unnamed_addr constant [2 x i8] c"0\00" -@.str266 = private unnamed_addr constant [34 x i8] c"; Ludic (self-hosted) -> LLVM IR\0A\00" -@.str267 = private unnamed_addr constant [31 x i8] c"declare i32 @printf(ptr, ...)\0A\00" -@.str268 = private unnamed_addr constant [26 x i8] c"declare ptr @malloc(i64)\0A\00" -@.str269 = private unnamed_addr constant [32 x i8] c"declare ptr @realloc(ptr, i64)\0A\00" -@.str270 = private unnamed_addr constant [25 x i8] c"declare void @free(ptr)\0A\00" -@.str271 = private unnamed_addr constant [30 x i8] c"declare ptr @fopen(ptr, ptr)\0A\00" -@.str272 = private unnamed_addr constant [40 x i8] c"declare i64 @fread(ptr, i64, i64, ptr)\0A\00" -@.str273 = private unnamed_addr constant [41 x i8] c"declare i64 @fwrite(ptr, i64, i64, ptr)\0A\00" -@.str274 = private unnamed_addr constant [35 x i8] c"declare i32 @fseek(ptr, i64, i32)\0A\00" -@.str275 = private unnamed_addr constant [25 x i8] c"declare i64 @ftell(ptr)\0A\00" -@.str276 = private unnamed_addr constant [26 x i8] c"declare i32 @fclose(ptr)\0A\00" -@.str277 = private unnamed_addr constant [25 x i8] c"declare void @exit(i32)\0A\00" -@.str278 = private unnamed_addr constant [26 x i8] c"declare i32 @system(ptr)\0A\00" -@.str279 = private unnamed_addr constant [26 x i8] c"declare ptr @getenv(ptr)\0A\00" -@.str280 = private unnamed_addr constant [36 x i8] c"declare ptr @memcpy(ptr, ptr, i64)\0A\00" -@.str281 = private unnamed_addr constant [36 x i8] c"declare ptr @memset(ptr, i32, i64)\0A\00" -@.str282 = private unnamed_addr constant [26 x i8] c"declare i64 @strlen(ptr)\0A\00" -@.str283 = private unnamed_addr constant [24 x i8] c"declare i32 @getchar()\0A\00" -@.str284 = private unnamed_addr constant [27 x i8] c"declare i32 @putchar(i32)\0A\00" -@.str285 = private unnamed_addr constant [24 x i8] c"declare i64 @time(ptr)\0A\00" -@.str286 = private unnamed_addr constant [44 x i8] c"declare void @win_open(i32, i32, i32, ptr)\0A\00" -@.str287 = private unnamed_addr constant [25 x i8] c"declare i32 @win_poll()\0A\00" -@.str288 = private unnamed_addr constant [42 x i8] c"declare void @win_present(ptr, i32, i32)\0A\00" -@.str289 = private unnamed_addr constant [28 x i8] c"declare i32 @win_running()\0A\00" -@.str290 = private unnamed_addr constant [27 x i8] c"declare void @win_close()\0A\00" -@.str291 = private unnamed_addr constant [34 x i8] c"@__stderrp = external global ptr\0A\00" -@.str292 = private unnamed_addr constant [34 x i8] c"@__stdoutp = external global ptr\0A\00" -@.str293 = private unnamed_addr constant [64 x i8] c"@.fmt_int = private unnamed_addr constant [4 x i8] c\22%d\5C0A\5C00\22\0A\00" -@.str294 = private unnamed_addr constant [65 x i8] c"@.fmt_line = private unnamed_addr constant [4 x i8] c\22%s\5C0A\5C00\22\0A\00" -@.str295 = private unnamed_addr constant [33 x i8] c"@L_argc = internal global i32 0\0A\00" -@.str296 = private unnamed_addr constant [36 x i8] c"@L_argv = internal global ptr null\0A\00" -@.str297 = private unnamed_addr constant [46 x i8] c"@.gametitle = private unnamed_addr constant [\00" -@.str298 = private unnamed_addr constant [10 x i8] c" x i8] c\22\00" -@.str299 = private unnamed_addr constant [6 x i8] c"\5C00\22\0A\00" -@.str300 = private unnamed_addr constant [34 x i8] c"%LSlice = type { ptr, i32, i32 }\0A\00" -@.str301 = private unnamed_addr constant [11 x i8] c" = type { \00" -@.str302 = private unnamed_addr constant [4 x i8] c"i32\00" -@.str303 = private unnamed_addr constant [3 x i8] c", \00" -@.str304 = private unnamed_addr constant [4 x i8] c" }\0A\00" -@.str305 = private unnamed_addr constant [4 x i8] c"@g_\00" -@.str306 = private unnamed_addr constant [20 x i8] c" = internal global \00" -@.str307 = private unnamed_addr constant [2 x i8] c" \00" -@.str308 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str309 = private unnamed_addr constant [41 x i8] c"define i32 @fn_str_eq(ptr %a, ptr %b) {\0A\00" -@.str310 = private unnamed_addr constant [25 x i8] c"entry:\0A br label %loop\0A\00" -@.str311 = private unnamed_addr constant [52 x i8] c"loop:\0A %i = phi i32 [ 0, %entry ], [ %i1, %cont ]\0A\00" -@.str312 = private unnamed_addr constant [51 x i8] c" %pa = getelementptr inbounds i8, ptr %a, i32 %i\0A\00" -@.str313 = private unnamed_addr constant [51 x i8] c" %pb = getelementptr inbounds i8, ptr %b, i32 %i\0A\00" -@.str314 = private unnamed_addr constant [51 x i8] c" %ca = load i8, ptr %pa\0A %cb = load i8, ptr %pb\0A\00" -@.str315 = private unnamed_addr constant [66 x i8] c" %df = icmp ne i8 %ca, %cb\0A br i1 %df, label %ret0, label %chk\0A\00" -@.str316 = private unnamed_addr constant [70 x i8] c"chk:\0A %zt = icmp eq i8 %ca, 0\0A br i1 %zt, label %ret1, label %cont\0A\00" -@.str317 = private unnamed_addr constant [46 x i8] c"cont:\0A %i1 = add i32 %i, 1\0A br label %loop\0A\00" -@.str318 = private unnamed_addr constant [39 x i8] c"ret1:\0A ret i32 1\0Aret0:\0A ret i32 0\0A}\0A\00" -@.str319 = private unnamed_addr constant [45 x i8] c"define ptr @fn_str_concat(ptr %a, ptr %b) {\0A\00" -@.str320 = private unnamed_addr constant [23 x i8] c"entry:\0A br label %al\0A\00" -@.str321 = private unnamed_addr constant [51 x i8] c"al:\0A %ia = phi i32 [ 0, %entry ], [ %ia1, %alb ]\0A\00" -@.str322 = private unnamed_addr constant [78 x i8] c" %pa = getelementptr inbounds i8, ptr %a, i32 %ia\0A %cca = load i8, ptr %pa\0A\00" -@.str323 = private unnamed_addr constant [64 x i8] c" %za = icmp eq i8 %cca, 0\0A br i1 %za, label %bl0, label %alb\0A\00" -@.str324 = private unnamed_addr constant [45 x i8] c"alb:\0A %ia1 = add i32 %ia, 1\0A br label %al\0A\00" -@.str325 = private unnamed_addr constant [21 x i8] c"bl0:\0A br label %bl\0A\00" -@.str326 = private unnamed_addr constant [49 x i8] c"bl:\0A %ib = phi i32 [ 0, %bl0 ], [ %ib1, %blb ]\0A\00" -@.str327 = private unnamed_addr constant [78 x i8] c" %pb = getelementptr inbounds i8, ptr %b, i32 %ib\0A %ccb = load i8, ptr %pb\0A\00" -@.str328 = private unnamed_addr constant [66 x i8] c" %zb = icmp eq i8 %ccb, 0\0A br i1 %zb, label %alloc, label %blb\0A\00" -@.str329 = private unnamed_addr constant [45 x i8] c"blb:\0A %ib1 = add i32 %ib, 1\0A br label %bl\0A\00" -@.str330 = private unnamed_addr constant [58 x i8] c"alloc:\0A %sum = add i32 %ia, %ib\0A %sz = add i32 %sum, 1\0A\00" -@.str331 = private unnamed_addr constant [83 x i8] c" %sz64 = sext i32 %sz to i64\0A %out = call ptr @malloc(i64 %sz64)\0A br label %c1\0A\00" -@.str332 = private unnamed_addr constant [49 x i8] c"c1:\0A %i = phi i32 [ 0, %alloc ], [ %i1, %c1b ]\0A\00" -@.str333 = private unnamed_addr constant [66 x i8] c" %d1 = icmp slt i32 %i, %ia\0A br i1 %d1, label %c1b, label %c2i\0A\00" -@.str334 = private unnamed_addr constant [81 x i8] c"c1b:\0A %s1 = getelementptr inbounds i8, ptr %a, i32 %i\0A %v1 = load i8, ptr %s1\0A\00" -@.str335 = private unnamed_addr constant [77 x i8] c" %o1 = getelementptr inbounds i8, ptr %out, i32 %i\0A store i8 %v1, ptr %o1\0A\00" -@.str336 = private unnamed_addr constant [38 x i8] c" %i1 = add i32 %i, 1\0A br label %c1\0A\00" -@.str337 = private unnamed_addr constant [21 x i8] c"c2i:\0A br label %c2\0A\00" -@.str338 = private unnamed_addr constant [47 x i8] c"c2:\0A %j = phi i32 [ 0, %c2i ], [ %j1, %c2b ]\0A\00" -@.str339 = private unnamed_addr constant [66 x i8] c" %d2 = icmp slt i32 %j, %ib\0A br i1 %d2, label %c2b, label %fin\0A\00" -@.str340 = private unnamed_addr constant [81 x i8] c"c2b:\0A %s2 = getelementptr inbounds i8, ptr %b, i32 %j\0A %v2 = load i8, ptr %s2\0A\00" -@.str341 = private unnamed_addr constant [102 x i8] c" %oj = add i32 %ia, %j\0A %o2 = getelementptr inbounds i8, ptr %out, i32 %oj\0A store i8 %v2, ptr %o2\0A\00" -@.str342 = private unnamed_addr constant [38 x i8] c" %j1 = add i32 %j, 1\0A br label %c2\0A\00" -@.str343 = private unnamed_addr constant [99 x i8] c"fin:\0A %pe = getelementptr inbounds i8, ptr %out, i32 %sum\0A store i8 0, ptr %pe\0A ret ptr %out\0A}\0A\00" -@.str344 = private unnamed_addr constant [35 x i8] c"define ptr @fn_int_str(i32 %n0) {\0A\00" -@.str345 = private unnamed_addr constant [42 x i8] c"entry:\0A %buf = call ptr @malloc(i64 24)\0A\00" -@.str346 = private unnamed_addr constant [56 x i8] c" %isneg = icmp slt i32 %n0, 0\0A %neg = sub i32 0, %n0\0A\00" -@.str347 = private unnamed_addr constant [44 x i8] c" %n = select i1 %isneg, i32 %neg, i32 %n0\0A\00" -@.str348 = private unnamed_addr constant [79 x i8] c" %term = getelementptr inbounds i8, ptr %buf, i32 23\0A store i8 0, ptr %term\0A\00" -@.str349 = private unnamed_addr constant [70 x i8] c" %iszero = icmp eq i32 %n0, 0\0A br i1 %iszero, label %zc, label %dl\0A\00" -@.str350 = private unnamed_addr constant [94 x i8] c"zc:\0A %zp = getelementptr inbounds i8, ptr %buf, i32 22\0A store i8 48, ptr %zp\0A ret ptr %zp\0A\00" -@.str351 = private unnamed_addr constant [23 x i8] c"dl:\0A br label %dloop\0A\00" -@.str352 = private unnamed_addr constant [104 x i8] c"dloop:\0A %pos = phi i32 [ 22, %dl ], [ %pos2, %dbody ]\0A %cur = phi i32 [ %n, %dl ], [ %cur2, %dbody ]\0A\00" -@.str353 = private unnamed_addr constant [72 x i8] c" %done = icmp eq i32 %cur, 0\0A br i1 %done, label %sign, label %dbody\0A\00" -@.str354 = private unnamed_addr constant [85 x i8] c"dbody:\0A %d = urem i32 %cur, 10\0A %ch = add i32 %d, 48\0A %ch8 = trunc i32 %ch to i8\0A\00" -@.str355 = private unnamed_addr constant [80 x i8] c" %pp = getelementptr inbounds i8, ptr %buf, i32 %pos\0A store i8 %ch8, ptr %pp\0A\00" -@.str356 = private unnamed_addr constant [73 x i8] c" %cur2 = udiv i32 %cur, 10\0A %pos2 = sub i32 %pos, 1\0A br label %dloop\0A\00" -@.str357 = private unnamed_addr constant [49 x i8] c"sign:\0A br i1 %isneg, label %addneg, label %fin\0A\00" -@.str358 = private unnamed_addr constant [128 x i8] c"addneg:\0A %sp = getelementptr inbounds i8, ptr %buf, i32 %pos\0A store i8 45, ptr %sp\0A %posn = sub i32 %pos, 1\0A br label %fin\0A\00" -@.str359 = private unnamed_addr constant [60 x i8] c"fin:\0A %fpos = phi i32 [ %pos, %sign ], [ %posn, %addneg ]\0A\00" -@.str360 = private unnamed_addr constant [101 x i8] c" %rpos = add i32 %fpos, 1\0A %res = getelementptr inbounds i8, ptr %buf, i32 %rpos\0A ret ptr %res\0A}\0A\00" -@.str361 = private unnamed_addr constant [58 x i8] c"define ptr @fn_str_slice(ptr %s, i32 %start, i32 %end) {\0A\00" -@.str362 = private unnamed_addr constant [62 x i8] c"entry:\0A %len = sub i32 %end, %start\0A %sz = add i32 %len, 1\0A\00" -@.str363 = private unnamed_addr constant [85 x i8] c" %sz64 = sext i32 %sz to i64\0A %out = call ptr @malloc(i64 %sz64)\0A br label %loop\0A\00" -@.str364 = private unnamed_addr constant [52 x i8] c"loop:\0A %i = phi i32 [ 0, %entry ], [ %i1, %body ]\0A\00" -@.str365 = private unnamed_addr constant [66 x i8] c" %d = icmp slt i32 %i, %len\0A br i1 %d, label %body, label %fin\0A\00" -@.str366 = private unnamed_addr constant [109 x i8] c"body:\0A %si = add i32 %start, %i\0A %sp = getelementptr inbounds i8, ptr %s, i32 %si\0A %c = load i8, ptr %sp\0A\00" -@.str367 = private unnamed_addr constant [115 x i8] c" %op = getelementptr inbounds i8, ptr %out, i32 %i\0A store i8 %c, ptr %op\0A %i1 = add i32 %i, 1\0A br label %loop\0A\00" -@.str368 = private unnamed_addr constant [99 x i8] c"fin:\0A %tp = getelementptr inbounds i8, ptr %out, i32 %len\0A store i8 0, ptr %tp\0A ret ptr %out\0A}\0A\00" -@.str369 = private unnamed_addr constant [32 x i8] c"member access on non-aggregate \00" -@.str370 = private unnamed_addr constant [15 x i8] c"no such field \00" -@.str371 = private unnamed_addr constant [3 x i8] c" \00" -@.str372 = private unnamed_addr constant [27 x i8] c" = getelementptr inbounds \00" -@.str373 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str374 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str375 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str376 = private unnamed_addr constant [6 x i8] c"words\00" -@.str377 = private unnamed_addr constant [33 x i8] c"getelementptr inbounds i32, ptr \00" -@.str378 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str379 = private unnamed_addr constant [4 x i8] c"int\00" -@.str380 = private unnamed_addr constant [7 x i8] c"fixeds\00" -@.str381 = private unnamed_addr constant [33 x i8] c"getelementptr inbounds i32, ptr \00" -@.str382 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str383 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str384 = private unnamed_addr constant [5 x i8] c"ptrs\00" -@.str385 = private unnamed_addr constant [33 x i8] c"getelementptr inbounds ptr, ptr \00" -@.str386 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str387 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str388 = private unnamed_addr constant [32 x i8] c"getelementptr inbounds i8, ptr \00" -@.str389 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str390 = private unnamed_addr constant [5 x i8] c"byte\00" -@.str391 = private unnamed_addr constant [3 x i8] c" \00" -@.str392 = private unnamed_addr constant [40 x i8] c" = getelementptr inbounds %LSlice, ptr \00" -@.str393 = private unnamed_addr constant [16 x i8] c", i32 0, i32 0\0A\00" -@.str394 = private unnamed_addr constant [3 x i8] c" \00" -@.str395 = private unnamed_addr constant [18 x i8] c" = load ptr, ptr \00" -@.str396 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str397 = private unnamed_addr constant [3 x i8] c" \00" -@.str398 = private unnamed_addr constant [27 x i8] c" = getelementptr inbounds \00" -@.str399 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str400 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str401 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str402 = private unnamed_addr constant [7 x i8] c"resize\00" -@.str403 = private unnamed_addr constant [10 x i8] c"file_open\00" -@.str404 = private unnamed_addr constant [10 x i8] c"file_read\00" -@.str405 = private unnamed_addr constant [11 x i8] c"file_write\00" -@.str406 = private unnamed_addr constant [10 x i8] c"file_seek\00" -@.str407 = private unnamed_addr constant [10 x i8] c"file_tell\00" -@.str408 = private unnamed_addr constant [11 x i8] c"file_close\00" -@.str409 = private unnamed_addr constant [10 x i8] c"arg_count\00" -@.str410 = private unnamed_addr constant [4 x i8] c"arg\00" -@.str411 = private unnamed_addr constant [5 x i8] c"exit\00" -@.str412 = private unnamed_addr constant [12 x i8] c"file_stderr\00" -@.str413 = private unnamed_addr constant [12 x i8] c"file_stdout\00" -@.str414 = private unnamed_addr constant [4 x i8] c"run\00" -@.str415 = private unnamed_addr constant [7 x i8] c"getenv\00" -@.str416 = private unnamed_addr constant [3 x i8] c" \00" -@.str417 = private unnamed_addr constant [4 x i8] c" = \00" -@.str418 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str419 = private unnamed_addr constant [7 x i8] c"resize\00" -@.str420 = private unnamed_addr constant [10 x i8] c"zext i32 \00" -@.str421 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str422 = private unnamed_addr constant [23 x i8] c"call ptr @realloc(ptr \00" -@.str423 = private unnamed_addr constant [7 x i8] c", i64 \00" -@.str424 = private unnamed_addr constant [2 x i8] c")\00" -@.str425 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str426 = private unnamed_addr constant [10 x i8] c"file_open\00" -@.str427 = private unnamed_addr constant [21 x i8] c"call ptr @fopen(ptr \00" -@.str428 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str429 = private unnamed_addr constant [2 x i8] c")\00" -@.str430 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str431 = private unnamed_addr constant [10 x i8] c"file_read\00" -@.str432 = private unnamed_addr constant [11 x i8] c"file_write\00" -@.str433 = private unnamed_addr constant [10 x i8] c"zext i32 \00" -@.str434 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str435 = private unnamed_addr constant [7 x i8] c"@fread\00" -@.str436 = private unnamed_addr constant [11 x i8] c"file_write\00" -@.str437 = private unnamed_addr constant [8 x i8] c"@fwrite\00" -@.str438 = private unnamed_addr constant [10 x i8] c"call i64 \00" -@.str439 = private unnamed_addr constant [6 x i8] c"(ptr \00" -@.str440 = private unnamed_addr constant [14 x i8] c", i64 1, i64 \00" -@.str441 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str442 = private unnamed_addr constant [2 x i8] c")\00" -@.str443 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" -@.str444 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str445 = private unnamed_addr constant [4 x i8] c"int\00" -@.str446 = private unnamed_addr constant [10 x i8] c"file_seek\00" -@.str447 = private unnamed_addr constant [10 x i8] c"sext i32 \00" -@.str448 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str449 = private unnamed_addr constant [21 x i8] c"call i32 @fseek(ptr \00" -@.str450 = private unnamed_addr constant [7 x i8] c", i64 \00" -@.str451 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str452 = private unnamed_addr constant [2 x i8] c")\00" -@.str453 = private unnamed_addr constant [4 x i8] c"int\00" -@.str454 = private unnamed_addr constant [10 x i8] c"file_tell\00" -@.str455 = private unnamed_addr constant [21 x i8] c"call i64 @ftell(ptr \00" -@.str456 = private unnamed_addr constant [2 x i8] c")\00" -@.str457 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" -@.str458 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str459 = private unnamed_addr constant [4 x i8] c"int\00" -@.str460 = private unnamed_addr constant [11 x i8] c"file_close\00" -@.str461 = private unnamed_addr constant [24 x i8] c" call i32 @fclose(ptr \00" -@.str462 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str463 = private unnamed_addr constant [2 x i8] c"0\00" -@.str464 = private unnamed_addr constant [5 x i8] c"void\00" -@.str465 = private unnamed_addr constant [10 x i8] c"arg_count\00" -@.str466 = private unnamed_addr constant [22 x i8] c"load i32, ptr @L_argc\00" -@.str467 = private unnamed_addr constant [4 x i8] c"int\00" -@.str468 = private unnamed_addr constant [4 x i8] c"arg\00" -@.str469 = private unnamed_addr constant [22 x i8] c"load ptr, ptr @L_argv\00" -@.str470 = private unnamed_addr constant [24 x i8] c"getelementptr ptr, ptr \00" -@.str471 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str472 = private unnamed_addr constant [15 x i8] c"load ptr, ptr \00" -@.str473 = private unnamed_addr constant [4 x i8] c"str\00" -@.str474 = private unnamed_addr constant [5 x i8] c"exit\00" -@.str475 = private unnamed_addr constant [23 x i8] c" call void @exit(i32 \00" -@.str476 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str477 = private unnamed_addr constant [15 x i8] c" unreachable\0A\00" -@.str478 = private unnamed_addr constant [2 x i8] c"0\00" -@.str479 = private unnamed_addr constant [5 x i8] c"void\00" -@.str480 = private unnamed_addr constant [12 x i8] c"file_stderr\00" -@.str481 = private unnamed_addr constant [25 x i8] c"load ptr, ptr @__stderrp\00" -@.str482 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str483 = private unnamed_addr constant [12 x i8] c"file_stdout\00" -@.str484 = private unnamed_addr constant [25 x i8] c"load ptr, ptr @__stdoutp\00" -@.str485 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str486 = private unnamed_addr constant [4 x i8] c"run\00" -@.str487 = private unnamed_addr constant [22 x i8] c"call i32 @system(ptr \00" -@.str488 = private unnamed_addr constant [2 x i8] c")\00" -@.str489 = private unnamed_addr constant [4 x i8] c"int\00" -@.str490 = private unnamed_addr constant [7 x i8] c"getenv\00" -@.str491 = private unnamed_addr constant [22 x i8] c"call ptr @getenv(ptr \00" -@.str492 = private unnamed_addr constant [2 x i8] c")\00" -@.str493 = private unnamed_addr constant [4 x i8] c"str\00" -@.str494 = private unnamed_addr constant [2 x i8] c"0\00" -@.str495 = private unnamed_addr constant [5 x i8] c"void\00" -@.str496 = private unnamed_addr constant [5 x i8] c"free\00" -@.str497 = private unnamed_addr constant [5 x i8] c"fill\00" -@.str498 = private unnamed_addr constant [7 x i8] c"offset\00" -@.str499 = private unnamed_addr constant [10 x i8] c"read_char\00" -@.str500 = private unnamed_addr constant [9 x i8] c"as_fixed\00" -@.str501 = private unnamed_addr constant [7 x i8] c"as_int\00" -@.str502 = private unnamed_addr constant [12 x i8] c"is_windowed\00" -@.str503 = private unnamed_addr constant [11 x i8] c"game_title\00" -@.str504 = private unnamed_addr constant [9 x i8] c"win_open\00" -@.str505 = private unnamed_addr constant [9 x i8] c"win_poll\00" -@.str506 = private unnamed_addr constant [12 x i8] c"win_present\00" -@.str507 = private unnamed_addr constant [12 x i8] c"win_running\00" -@.str508 = private unnamed_addr constant [10 x i8] c"win_close\00" -@.str509 = private unnamed_addr constant [5 x i8] c"free\00" -@.str510 = private unnamed_addr constant [23 x i8] c" call void @free(ptr \00" -@.str511 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str512 = private unnamed_addr constant [2 x i8] c"0\00" -@.str513 = private unnamed_addr constant [5 x i8] c"void\00" -@.str514 = private unnamed_addr constant [5 x i8] c"fill\00" -@.str515 = private unnamed_addr constant [10 x i8] c"zext i32 \00" -@.str516 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str517 = private unnamed_addr constant [24 x i8] c" call ptr @memset(ptr \00" -@.str518 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str519 = private unnamed_addr constant [7 x i8] c", i64 \00" -@.str520 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str521 = private unnamed_addr constant [2 x i8] c"0\00" -@.str522 = private unnamed_addr constant [5 x i8] c"void\00" -@.str523 = private unnamed_addr constant [7 x i8] c"offset\00" -@.str524 = private unnamed_addr constant [3 x i8] c" \00" -@.str525 = private unnamed_addr constant [35 x i8] c" = getelementptr inbounds i8, ptr \00" -@.str526 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str527 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str528 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str529 = private unnamed_addr constant [10 x i8] c"read_char\00" -@.str530 = private unnamed_addr constant [20 x i8] c"call i32 @getchar()\00" -@.str531 = private unnamed_addr constant [4 x i8] c"int\00" -@.str532 = private unnamed_addr constant [9 x i8] c"as_fixed\00" -@.str533 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str534 = private unnamed_addr constant [7 x i8] c"as_int\00" -@.str535 = private unnamed_addr constant [4 x i8] c"int\00" -@.str536 = private unnamed_addr constant [12 x i8] c"is_windowed\00" -@.str537 = private unnamed_addr constant [2 x i8] c"1\00" -@.str538 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str539 = private unnamed_addr constant [2 x i8] c"0\00" -@.str540 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str541 = private unnamed_addr constant [11 x i8] c"game_title\00" -@.str542 = private unnamed_addr constant [12 x i8] c"@.gametitle\00" -@.str543 = private unnamed_addr constant [4 x i8] c"str\00" -@.str544 = private unnamed_addr constant [9 x i8] c"win_poll\00" -@.str545 = private unnamed_addr constant [21 x i8] c"call i32 @win_poll()\00" -@.str546 = private unnamed_addr constant [4 x i8] c"int\00" -@.str547 = private unnamed_addr constant [12 x i8] c"win_running\00" -@.str548 = private unnamed_addr constant [24 x i8] c"call i32 @win_running()\00" -@.str549 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str550 = private unnamed_addr constant [9 x i8] c"win_open\00" -@.str551 = private unnamed_addr constant [27 x i8] c" call void @win_open(i32 \00" -@.str552 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str553 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str554 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str555 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str556 = private unnamed_addr constant [2 x i8] c"0\00" -@.str557 = private unnamed_addr constant [5 x i8] c"void\00" -@.str558 = private unnamed_addr constant [12 x i8] c"win_present\00" -@.str559 = private unnamed_addr constant [30 x i8] c" call void @win_present(ptr \00" -@.str560 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str561 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str562 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str563 = private unnamed_addr constant [2 x i8] c"0\00" -@.str564 = private unnamed_addr constant [5 x i8] c"void\00" -@.str565 = private unnamed_addr constant [10 x i8] c"win_close\00" -@.str566 = private unnamed_addr constant [26 x i8] c" call void @win_close()\0A\00" +@.str229 = private unnamed_addr constant [2 x i8] c":\00" +@.str230 = private unnamed_addr constant [2 x i8] c"=\00" +@.str231 = private unnamed_addr constant [2 x i8] c",\00" +@.str232 = private unnamed_addr constant [2 x i8] c"}\00" +@.str233 = private unnamed_addr constant [7 x i8] c"Update\00" +@.str234 = private unnamed_addr constant [2 x i8] c"@\00" +@.str235 = private unnamed_addr constant [2 x i8] c"(\00" +@.str236 = private unnamed_addr constant [2 x i8] c"(\00" +@.str237 = private unnamed_addr constant [2 x i8] c")\00" +@.str238 = private unnamed_addr constant [6 x i8] c"phase\00" +@.str239 = private unnamed_addr constant [2 x i8] c"[\00" +@.str240 = private unnamed_addr constant [2 x i8] c"]\00" +@.str241 = private unnamed_addr constant [2 x i8] c"{\00" +@.str242 = private unnamed_addr constant [2 x i8] c"}\00" +@.str243 = private unnamed_addr constant [2 x i8] c",\00" +@.str244 = private unnamed_addr constant [2 x i8] c"]\00" +@.str245 = private unnamed_addr constant [6 x i8] c"where\00" +@.str246 = private unnamed_addr constant [2 x i8] c"(\00" +@.str247 = private unnamed_addr constant [2 x i8] c")\00" +@.str248 = private unnamed_addr constant [2 x i8] c",\00" +@.str249 = private unnamed_addr constant [2 x i8] c")\00" +@.str250 = private unnamed_addr constant [6 x i8] c"query\00" +@.str251 = private unnamed_addr constant [29 x i8] c"expected 'query' in for-loop\00" +@.str252 = private unnamed_addr constant [4 x i8] c"and\00" +@.str253 = private unnamed_addr constant [2 x i8] c"(\00" +@.str254 = private unnamed_addr constant [2 x i8] c")\00" +@.str255 = private unnamed_addr constant [2 x i8] c")\00" +@.str256 = private unnamed_addr constant [2 x i8] c":\00" +@.str257 = private unnamed_addr constant [6 x i8] c"these\00" +@.str258 = private unnamed_addr constant [2 x i8] c"[\00" +@.str259 = private unnamed_addr constant [2 x i8] c"]\00" +@.str260 = private unnamed_addr constant [2 x i8] c"{\00" +@.str261 = private unnamed_addr constant [2 x i8] c"}\00" +@.str262 = private unnamed_addr constant [2 x i8] c",\00" +@.str263 = private unnamed_addr constant [2 x i8] c"]\00" +@.str264 = private unnamed_addr constant [3 x i8] c"on\00" +@.str265 = private unnamed_addr constant [2 x i8] c",\00" +@.str266 = private unnamed_addr constant [2 x i8] c")\00" +@.str267 = private unnamed_addr constant [2 x i8] c"{\00" +@.str268 = private unnamed_addr constant [2 x i8] c"}\00" +@.str269 = private unnamed_addr constant [2 x i8] c",\00" +@.str270 = private unnamed_addr constant [2 x i8] c"}\00" +@.str271 = private unnamed_addr constant [6 x i8] c"start\00" +@.str272 = private unnamed_addr constant [7 x i8] c"public\00" +@.str273 = private unnamed_addr constant [6 x i8] c"start\00" +@.str274 = private unnamed_addr constant [7 x i8] c"scene_\00" +@.str275 = private unnamed_addr constant [7 x i8] c"_enter\00" +@.str276 = private unnamed_addr constant [7 x i8] c"scene_\00" +@.str277 = private unnamed_addr constant [6 x i8] c"_exit\00" +@.str278 = private unnamed_addr constant [2 x i8] c"{\00" +@.str279 = private unnamed_addr constant [2 x i8] c"}\00" +@.str280 = private unnamed_addr constant [3 x i8] c"on\00" +@.str281 = private unnamed_addr constant [6 x i8] c"enter\00" +@.str282 = private unnamed_addr constant [5 x i8] c"exit\00" +@.str283 = private unnamed_addr constant [38 x i8] c"expected 'enter' or 'exit' after 'on'\00" +@.str284 = private unnamed_addr constant [6 x i8] c"layer\00" +@.str285 = private unnamed_addr constant [7 x i8] c"public\00" +@.str286 = private unnamed_addr constant [7 x i8] c"layer_\00" +@.str287 = private unnamed_addr constant [6 x i8] c"_show\00" +@.str288 = private unnamed_addr constant [7 x i8] c"layer_\00" +@.str289 = private unnamed_addr constant [6 x i8] c"_hide\00" +@.str290 = private unnamed_addr constant [2 x i8] c"{\00" +@.str291 = private unnamed_addr constant [2 x i8] c"}\00" +@.str292 = private unnamed_addr constant [8 x i8] c"handler\00" +@.str293 = private unnamed_addr constant [28 x i8] c"expected 'handler' in layer\00" +@.str294 = private unnamed_addr constant [2 x i8] c"}\00" +@.str295 = private unnamed_addr constant [39 x i8] c"expected 'on', 'layer' or '}' in scene\00" +@.str296 = private unnamed_addr constant [2 x i8] c"}\00" +@.str297 = private unnamed_addr constant [2 x i8] c"{\00" +@.str298 = private unnamed_addr constant [2 x i8] c"}\00" +@.str299 = private unnamed_addr constant [2 x i8] c",\00" +@.str300 = private unnamed_addr constant [2 x i8] c"}\00" +@.str301 = private unnamed_addr constant [2 x i8] c"{\00" +@.str302 = private unnamed_addr constant [2 x i8] c"}\00" +@.str303 = private unnamed_addr constant [2 x i8] c"@\00" +@.str304 = private unnamed_addr constant [5 x i8] c"Sync\00" +@.str305 = private unnamed_addr constant [2 x i8] c",\00" +@.str306 = private unnamed_addr constant [2 x i8] c"}\00" +@.str307 = private unnamed_addr constant [2 x i8] c"(\00" +@.str308 = private unnamed_addr constant [2 x i8] c")\00" +@.str309 = private unnamed_addr constant [2 x i8] c":\00" +@.str310 = private unnamed_addr constant [2 x i8] c",\00" +@.str311 = private unnamed_addr constant [2 x i8] c")\00" +@.str312 = private unnamed_addr constant [5 x i8] c"void\00" +@.str313 = private unnamed_addr constant [3 x i8] c"->\00" +@.str314 = private unnamed_addr constant [2 x i8] c"=\00" +@.str315 = private unnamed_addr constant [2 x i8] c":\00" +@.str316 = private unnamed_addr constant [2 x i8] c":\00" +@.str317 = private unnamed_addr constant [2 x i8] c"{\00" +@.str318 = private unnamed_addr constant [2 x i8] c"}\00" +@.str319 = private unnamed_addr constant [2 x i8] c"}\00" +@.str320 = private unnamed_addr constant [2 x i8] c"{\00" +@.str321 = private unnamed_addr constant [2 x i8] c"}\00" +@.str322 = private unnamed_addr constant [3 x i8] c"%t\00" +@.str323 = private unnamed_addr constant [3 x i8] c" \00" +@.str324 = private unnamed_addr constant [11 x i8] c" = alloca \00" +@.str325 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str326 = private unnamed_addr constant [3 x i8] c"%t\00" +@.str327 = private unnamed_addr constant [4 x i8] c"int\00" +@.str328 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str329 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str330 = private unnamed_addr constant [7 x i8] c"entity\00" +@.str331 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str332 = private unnamed_addr constant [5 x i8] c"byte\00" +@.str333 = private unnamed_addr constant [3 x i8] c"i8\00" +@.str334 = private unnamed_addr constant [6 x i8] c"words\00" +@.str335 = private unnamed_addr constant [7 x i8] c"fixeds\00" +@.str336 = private unnamed_addr constant [5 x i8] c"ptrs\00" +@.str337 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str338 = private unnamed_addr constant [5 x i8] c"void\00" +@.str339 = private unnamed_addr constant [5 x i8] c"void\00" +@.str340 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str341 = private unnamed_addr constant [6 x i8] c"%Cmp_\00" +@.str342 = private unnamed_addr constant [4 x i8] c"int\00" +@.str343 = private unnamed_addr constant [10 x i8] c"EndReason\00" +@.str344 = private unnamed_addr constant [10 x i8] c"Despawned\00" +@.str345 = private unnamed_addr constant [10 x i8] c"SceneExit\00" +@.str346 = private unnamed_addr constant [5 x i8] c"Quit\00" +@.str347 = private unnamed_addr constant [2 x i8] c".\00" +@.str348 = private unnamed_addr constant [2 x i8] c".\00" +@.str349 = private unnamed_addr constant [7 x i8] c"entity\00" +@.str350 = private unnamed_addr constant [4 x i8] c"int\00" +@.str351 = private unnamed_addr constant [7 x i8] c"reason\00" +@.str352 = private unnamed_addr constant [4 x i8] c"int\00" +@.str353 = private unnamed_addr constant [6 x i8] c"@.str\00" +@.str354 = private unnamed_addr constant [35 x i8] c" = private unnamed_addr constant [\00" +@.str355 = private unnamed_addr constant [10 x i8] c" x i8] c\22\00" +@.str356 = private unnamed_addr constant [6 x i8] c"\5C00\22\0A\00" +@.str357 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str358 = private unnamed_addr constant [5 x i8] c"null\00" +@.str359 = private unnamed_addr constant [2 x i8] c"0\00" +@.str360 = private unnamed_addr constant [2 x i8] c"-\00" +@.str361 = private unnamed_addr constant [2 x i8] c"-\00" +@.str362 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str363 = private unnamed_addr constant [5 x i8] c"null\00" +@.str364 = private unnamed_addr constant [2 x i8] c"0\00" +@.str365 = private unnamed_addr constant [34 x i8] c"; Ludic (self-hosted) -> LLVM IR\0A\00" +@.str366 = private unnamed_addr constant [31 x i8] c"declare i32 @printf(ptr, ...)\0A\00" +@.str367 = private unnamed_addr constant [26 x i8] c"declare ptr @malloc(i64)\0A\00" +@.str368 = private unnamed_addr constant [32 x i8] c"declare ptr @realloc(ptr, i64)\0A\00" +@.str369 = private unnamed_addr constant [25 x i8] c"declare void @free(ptr)\0A\00" +@.str370 = private unnamed_addr constant [30 x i8] c"declare ptr @fopen(ptr, ptr)\0A\00" +@.str371 = private unnamed_addr constant [40 x i8] c"declare i64 @fread(ptr, i64, i64, ptr)\0A\00" +@.str372 = private unnamed_addr constant [41 x i8] c"declare i64 @fwrite(ptr, i64, i64, ptr)\0A\00" +@.str373 = private unnamed_addr constant [35 x i8] c"declare i32 @fseek(ptr, i64, i32)\0A\00" +@.str374 = private unnamed_addr constant [25 x i8] c"declare i64 @ftell(ptr)\0A\00" +@.str375 = private unnamed_addr constant [26 x i8] c"declare i32 @fclose(ptr)\0A\00" +@.str376 = private unnamed_addr constant [25 x i8] c"declare void @exit(i32)\0A\00" +@.str377 = private unnamed_addr constant [26 x i8] c"declare i32 @system(ptr)\0A\00" +@.str378 = private unnamed_addr constant [26 x i8] c"declare ptr @getenv(ptr)\0A\00" +@.str379 = private unnamed_addr constant [36 x i8] c"declare ptr @memcpy(ptr, ptr, i64)\0A\00" +@.str380 = private unnamed_addr constant [36 x i8] c"declare ptr @memset(ptr, i32, i64)\0A\00" +@.str381 = private unnamed_addr constant [26 x i8] c"declare i64 @strlen(ptr)\0A\00" +@.str382 = private unnamed_addr constant [24 x i8] c"declare i32 @getchar()\0A\00" +@.str383 = private unnamed_addr constant [27 x i8] c"declare i32 @putchar(i32)\0A\00" +@.str384 = private unnamed_addr constant [24 x i8] c"declare i64 @time(ptr)\0A\00" +@.str385 = private unnamed_addr constant [44 x i8] c"declare void @win_open(i32, i32, i32, ptr)\0A\00" +@.str386 = private unnamed_addr constant [25 x i8] c"declare i32 @win_poll()\0A\00" +@.str387 = private unnamed_addr constant [42 x i8] c"declare void @win_present(ptr, i32, i32)\0A\00" +@.str388 = private unnamed_addr constant [28 x i8] c"declare i32 @win_running()\0A\00" +@.str389 = private unnamed_addr constant [27 x i8] c"declare void @win_close()\0A\00" +@.str390 = private unnamed_addr constant [34 x i8] c"@__stderrp = external global ptr\0A\00" +@.str391 = private unnamed_addr constant [34 x i8] c"@__stdoutp = external global ptr\0A\00" +@.str392 = private unnamed_addr constant [64 x i8] c"@.fmt_int = private unnamed_addr constant [4 x i8] c\22%d\5C0A\5C00\22\0A\00" +@.str393 = private unnamed_addr constant [65 x i8] c"@.fmt_line = private unnamed_addr constant [4 x i8] c\22%s\5C0A\5C00\22\0A\00" +@.str394 = private unnamed_addr constant [33 x i8] c"@L_argc = internal global i32 0\0A\00" +@.str395 = private unnamed_addr constant [36 x i8] c"@L_argv = internal global ptr null\0A\00" +@.str396 = private unnamed_addr constant [46 x i8] c"@.gametitle = private unnamed_addr constant [\00" +@.str397 = private unnamed_addr constant [10 x i8] c" x i8] c\22\00" +@.str398 = private unnamed_addr constant [6 x i8] c"\5C00\22\0A\00" +@.str399 = private unnamed_addr constant [34 x i8] c"%LSlice = type { ptr, i32, i32 }\0A\00" +@.str400 = private unnamed_addr constant [11 x i8] c" = type { \00" +@.str401 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str402 = private unnamed_addr constant [3 x i8] c", \00" +@.str403 = private unnamed_addr constant [4 x i8] c" }\0A\00" +@.str404 = private unnamed_addr constant [4 x i8] c"@g_\00" +@.str405 = private unnamed_addr constant [20 x i8] c" = internal global \00" +@.str406 = private unnamed_addr constant [2 x i8] c" \00" +@.str407 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str408 = private unnamed_addr constant [9 x i8] c"declare \00" +@.str409 = private unnamed_addr constant [3 x i8] c" @\00" +@.str410 = private unnamed_addr constant [2 x i8] c"(\00" +@.str411 = private unnamed_addr constant [3 x i8] c", \00" +@.str412 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str413 = private unnamed_addr constant [41 x i8] c"define i32 @fn_str_eq(ptr %a, ptr %b) {\0A\00" +@.str414 = private unnamed_addr constant [25 x i8] c"entry:\0A br label %loop\0A\00" +@.str415 = private unnamed_addr constant [52 x i8] c"loop:\0A %i = phi i32 [ 0, %entry ], [ %i1, %cont ]\0A\00" +@.str416 = private unnamed_addr constant [51 x i8] c" %pa = getelementptr inbounds i8, ptr %a, i32 %i\0A\00" +@.str417 = private unnamed_addr constant [51 x i8] c" %pb = getelementptr inbounds i8, ptr %b, i32 %i\0A\00" +@.str418 = private unnamed_addr constant [51 x i8] c" %ca = load i8, ptr %pa\0A %cb = load i8, ptr %pb\0A\00" +@.str419 = private unnamed_addr constant [66 x i8] c" %df = icmp ne i8 %ca, %cb\0A br i1 %df, label %ret0, label %chk\0A\00" +@.str420 = private unnamed_addr constant [70 x i8] c"chk:\0A %zt = icmp eq i8 %ca, 0\0A br i1 %zt, label %ret1, label %cont\0A\00" +@.str421 = private unnamed_addr constant [46 x i8] c"cont:\0A %i1 = add i32 %i, 1\0A br label %loop\0A\00" +@.str422 = private unnamed_addr constant [39 x i8] c"ret1:\0A ret i32 1\0Aret0:\0A ret i32 0\0A}\0A\00" +@.str423 = private unnamed_addr constant [45 x i8] c"define ptr @fn_str_concat(ptr %a, ptr %b) {\0A\00" +@.str424 = private unnamed_addr constant [23 x i8] c"entry:\0A br label %al\0A\00" +@.str425 = private unnamed_addr constant [51 x i8] c"al:\0A %ia = phi i32 [ 0, %entry ], [ %ia1, %alb ]\0A\00" +@.str426 = private unnamed_addr constant [78 x i8] c" %pa = getelementptr inbounds i8, ptr %a, i32 %ia\0A %cca = load i8, ptr %pa\0A\00" +@.str427 = private unnamed_addr constant [64 x i8] c" %za = icmp eq i8 %cca, 0\0A br i1 %za, label %bl0, label %alb\0A\00" +@.str428 = private unnamed_addr constant [45 x i8] c"alb:\0A %ia1 = add i32 %ia, 1\0A br label %al\0A\00" +@.str429 = private unnamed_addr constant [21 x i8] c"bl0:\0A br label %bl\0A\00" +@.str430 = private unnamed_addr constant [49 x i8] c"bl:\0A %ib = phi i32 [ 0, %bl0 ], [ %ib1, %blb ]\0A\00" +@.str431 = private unnamed_addr constant [78 x i8] c" %pb = getelementptr inbounds i8, ptr %b, i32 %ib\0A %ccb = load i8, ptr %pb\0A\00" +@.str432 = private unnamed_addr constant [66 x i8] c" %zb = icmp eq i8 %ccb, 0\0A br i1 %zb, label %alloc, label %blb\0A\00" +@.str433 = private unnamed_addr constant [45 x i8] c"blb:\0A %ib1 = add i32 %ib, 1\0A br label %bl\0A\00" +@.str434 = private unnamed_addr constant [58 x i8] c"alloc:\0A %sum = add i32 %ia, %ib\0A %sz = add i32 %sum, 1\0A\00" +@.str435 = private unnamed_addr constant [83 x i8] c" %sz64 = sext i32 %sz to i64\0A %out = call ptr @malloc(i64 %sz64)\0A br label %c1\0A\00" +@.str436 = private unnamed_addr constant [49 x i8] c"c1:\0A %i = phi i32 [ 0, %alloc ], [ %i1, %c1b ]\0A\00" +@.str437 = private unnamed_addr constant [66 x i8] c" %d1 = icmp slt i32 %i, %ia\0A br i1 %d1, label %c1b, label %c2i\0A\00" +@.str438 = private unnamed_addr constant [81 x i8] c"c1b:\0A %s1 = getelementptr inbounds i8, ptr %a, i32 %i\0A %v1 = load i8, ptr %s1\0A\00" +@.str439 = private unnamed_addr constant [77 x i8] c" %o1 = getelementptr inbounds i8, ptr %out, i32 %i\0A store i8 %v1, ptr %o1\0A\00" +@.str440 = private unnamed_addr constant [38 x i8] c" %i1 = add i32 %i, 1\0A br label %c1\0A\00" +@.str441 = private unnamed_addr constant [21 x i8] c"c2i:\0A br label %c2\0A\00" +@.str442 = private unnamed_addr constant [47 x i8] c"c2:\0A %j = phi i32 [ 0, %c2i ], [ %j1, %c2b ]\0A\00" +@.str443 = private unnamed_addr constant [66 x i8] c" %d2 = icmp slt i32 %j, %ib\0A br i1 %d2, label %c2b, label %fin\0A\00" +@.str444 = private unnamed_addr constant [81 x i8] c"c2b:\0A %s2 = getelementptr inbounds i8, ptr %b, i32 %j\0A %v2 = load i8, ptr %s2\0A\00" +@.str445 = private unnamed_addr constant [102 x i8] c" %oj = add i32 %ia, %j\0A %o2 = getelementptr inbounds i8, ptr %out, i32 %oj\0A store i8 %v2, ptr %o2\0A\00" +@.str446 = private unnamed_addr constant [38 x i8] c" %j1 = add i32 %j, 1\0A br label %c2\0A\00" +@.str447 = private unnamed_addr constant [99 x i8] c"fin:\0A %pe = getelementptr inbounds i8, ptr %out, i32 %sum\0A store i8 0, ptr %pe\0A ret ptr %out\0A}\0A\00" +@.str448 = private unnamed_addr constant [35 x i8] c"define ptr @fn_int_str(i32 %n0) {\0A\00" +@.str449 = private unnamed_addr constant [42 x i8] c"entry:\0A %buf = call ptr @malloc(i64 24)\0A\00" +@.str450 = private unnamed_addr constant [56 x i8] c" %isneg = icmp slt i32 %n0, 0\0A %neg = sub i32 0, %n0\0A\00" +@.str451 = private unnamed_addr constant [44 x i8] c" %n = select i1 %isneg, i32 %neg, i32 %n0\0A\00" +@.str452 = private unnamed_addr constant [79 x i8] c" %term = getelementptr inbounds i8, ptr %buf, i32 23\0A store i8 0, ptr %term\0A\00" +@.str453 = private unnamed_addr constant [70 x i8] c" %iszero = icmp eq i32 %n0, 0\0A br i1 %iszero, label %zc, label %dl\0A\00" +@.str454 = private unnamed_addr constant [94 x i8] c"zc:\0A %zp = getelementptr inbounds i8, ptr %buf, i32 22\0A store i8 48, ptr %zp\0A ret ptr %zp\0A\00" +@.str455 = private unnamed_addr constant [23 x i8] c"dl:\0A br label %dloop\0A\00" +@.str456 = private unnamed_addr constant [104 x i8] c"dloop:\0A %pos = phi i32 [ 22, %dl ], [ %pos2, %dbody ]\0A %cur = phi i32 [ %n, %dl ], [ %cur2, %dbody ]\0A\00" +@.str457 = private unnamed_addr constant [72 x i8] c" %done = icmp eq i32 %cur, 0\0A br i1 %done, label %sign, label %dbody\0A\00" +@.str458 = private unnamed_addr constant [85 x i8] c"dbody:\0A %d = urem i32 %cur, 10\0A %ch = add i32 %d, 48\0A %ch8 = trunc i32 %ch to i8\0A\00" +@.str459 = private unnamed_addr constant [80 x i8] c" %pp = getelementptr inbounds i8, ptr %buf, i32 %pos\0A store i8 %ch8, ptr %pp\0A\00" +@.str460 = private unnamed_addr constant [73 x i8] c" %cur2 = udiv i32 %cur, 10\0A %pos2 = sub i32 %pos, 1\0A br label %dloop\0A\00" +@.str461 = private unnamed_addr constant [49 x i8] c"sign:\0A br i1 %isneg, label %addneg, label %fin\0A\00" +@.str462 = private unnamed_addr constant [128 x i8] c"addneg:\0A %sp = getelementptr inbounds i8, ptr %buf, i32 %pos\0A store i8 45, ptr %sp\0A %posn = sub i32 %pos, 1\0A br label %fin\0A\00" +@.str463 = private unnamed_addr constant [60 x i8] c"fin:\0A %fpos = phi i32 [ %pos, %sign ], [ %posn, %addneg ]\0A\00" +@.str464 = private unnamed_addr constant [101 x i8] c" %rpos = add i32 %fpos, 1\0A %res = getelementptr inbounds i8, ptr %buf, i32 %rpos\0A ret ptr %res\0A}\0A\00" +@.str465 = private unnamed_addr constant [58 x i8] c"define ptr @fn_str_slice(ptr %s, i32 %start, i32 %end) {\0A\00" +@.str466 = private unnamed_addr constant [62 x i8] c"entry:\0A %len = sub i32 %end, %start\0A %sz = add i32 %len, 1\0A\00" +@.str467 = private unnamed_addr constant [85 x i8] c" %sz64 = sext i32 %sz to i64\0A %out = call ptr @malloc(i64 %sz64)\0A br label %loop\0A\00" +@.str468 = private unnamed_addr constant [52 x i8] c"loop:\0A %i = phi i32 [ 0, %entry ], [ %i1, %body ]\0A\00" +@.str469 = private unnamed_addr constant [66 x i8] c" %d = icmp slt i32 %i, %len\0A br i1 %d, label %body, label %fin\0A\00" +@.str470 = private unnamed_addr constant [109 x i8] c"body:\0A %si = add i32 %start, %i\0A %sp = getelementptr inbounds i8, ptr %s, i32 %si\0A %c = load i8, ptr %sp\0A\00" +@.str471 = private unnamed_addr constant [115 x i8] c" %op = getelementptr inbounds i8, ptr %out, i32 %i\0A store i8 %c, ptr %op\0A %i1 = add i32 %i, 1\0A br label %loop\0A\00" +@.str472 = private unnamed_addr constant [99 x i8] c"fin:\0A %tp = getelementptr inbounds i8, ptr %out, i32 %len\0A store i8 0, ptr %tp\0A ret ptr %out\0A}\0A\00" +@.str473 = private unnamed_addr constant [32 x i8] c"member access on non-aggregate \00" +@.str474 = private unnamed_addr constant [15 x i8] c"no such field \00" +@.str475 = private unnamed_addr constant [3 x i8] c" \00" +@.str476 = private unnamed_addr constant [27 x i8] c" = getelementptr inbounds \00" +@.str477 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str478 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str479 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str480 = private unnamed_addr constant [6 x i8] c"words\00" +@.str481 = private unnamed_addr constant [33 x i8] c"getelementptr inbounds i32, ptr \00" +@.str482 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str483 = private unnamed_addr constant [4 x i8] c"int\00" +@.str484 = private unnamed_addr constant [7 x i8] c"fixeds\00" +@.str485 = private unnamed_addr constant [33 x i8] c"getelementptr inbounds i32, ptr \00" +@.str486 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str487 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str488 = private unnamed_addr constant [5 x i8] c"ptrs\00" +@.str489 = private unnamed_addr constant [33 x i8] c"getelementptr inbounds ptr, ptr \00" +@.str490 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str491 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str492 = private unnamed_addr constant [32 x i8] c"getelementptr inbounds i8, ptr \00" +@.str493 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str494 = private unnamed_addr constant [5 x i8] c"byte\00" +@.str495 = private unnamed_addr constant [3 x i8] c" \00" +@.str496 = private unnamed_addr constant [40 x i8] c" = getelementptr inbounds %LSlice, ptr \00" +@.str497 = private unnamed_addr constant [16 x i8] c", i32 0, i32 0\0A\00" +@.str498 = private unnamed_addr constant [3 x i8] c" \00" +@.str499 = private unnamed_addr constant [18 x i8] c" = load ptr, ptr \00" +@.str500 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str501 = private unnamed_addr constant [3 x i8] c" \00" +@.str502 = private unnamed_addr constant [27 x i8] c" = getelementptr inbounds \00" +@.str503 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str504 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str505 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str506 = private unnamed_addr constant [7 x i8] c"resize\00" +@.str507 = private unnamed_addr constant [10 x i8] c"file_open\00" +@.str508 = private unnamed_addr constant [10 x i8] c"file_read\00" +@.str509 = private unnamed_addr constant [11 x i8] c"file_write\00" +@.str510 = private unnamed_addr constant [10 x i8] c"file_seek\00" +@.str511 = private unnamed_addr constant [10 x i8] c"file_tell\00" +@.str512 = private unnamed_addr constant [11 x i8] c"file_close\00" +@.str513 = private unnamed_addr constant [10 x i8] c"arg_count\00" +@.str514 = private unnamed_addr constant [4 x i8] c"arg\00" +@.str515 = private unnamed_addr constant [5 x i8] c"exit\00" +@.str516 = private unnamed_addr constant [12 x i8] c"file_stderr\00" +@.str517 = private unnamed_addr constant [12 x i8] c"file_stdout\00" +@.str518 = private unnamed_addr constant [4 x i8] c"run\00" +@.str519 = private unnamed_addr constant [7 x i8] c"getenv\00" +@.str520 = private unnamed_addr constant [3 x i8] c" \00" +@.str521 = private unnamed_addr constant [4 x i8] c" = \00" +@.str522 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str523 = private unnamed_addr constant [7 x i8] c"resize\00" +@.str524 = private unnamed_addr constant [10 x i8] c"zext i32 \00" +@.str525 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str526 = private unnamed_addr constant [23 x i8] c"call ptr @realloc(ptr \00" +@.str527 = private unnamed_addr constant [7 x i8] c", i64 \00" +@.str528 = private unnamed_addr constant [2 x i8] c")\00" +@.str529 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str530 = private unnamed_addr constant [10 x i8] c"file_open\00" +@.str531 = private unnamed_addr constant [21 x i8] c"call ptr @fopen(ptr \00" +@.str532 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str533 = private unnamed_addr constant [2 x i8] c")\00" +@.str534 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str535 = private unnamed_addr constant [10 x i8] c"file_read\00" +@.str536 = private unnamed_addr constant [11 x i8] c"file_write\00" +@.str537 = private unnamed_addr constant [10 x i8] c"zext i32 \00" +@.str538 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str539 = private unnamed_addr constant [7 x i8] c"@fread\00" +@.str540 = private unnamed_addr constant [11 x i8] c"file_write\00" +@.str541 = private unnamed_addr constant [8 x i8] c"@fwrite\00" +@.str542 = private unnamed_addr constant [10 x i8] c"call i64 \00" +@.str543 = private unnamed_addr constant [6 x i8] c"(ptr \00" +@.str544 = private unnamed_addr constant [14 x i8] c", i64 1, i64 \00" +@.str545 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str546 = private unnamed_addr constant [2 x i8] c")\00" +@.str547 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" +@.str548 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str549 = private unnamed_addr constant [4 x i8] c"int\00" +@.str550 = private unnamed_addr constant [10 x i8] c"file_seek\00" +@.str551 = private unnamed_addr constant [10 x i8] c"sext i32 \00" +@.str552 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str553 = private unnamed_addr constant [21 x i8] c"call i32 @fseek(ptr \00" +@.str554 = private unnamed_addr constant [7 x i8] c", i64 \00" +@.str555 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str556 = private unnamed_addr constant [2 x i8] c")\00" +@.str557 = private unnamed_addr constant [4 x i8] c"int\00" +@.str558 = private unnamed_addr constant [10 x i8] c"file_tell\00" +@.str559 = private unnamed_addr constant [21 x i8] c"call i64 @ftell(ptr \00" +@.str560 = private unnamed_addr constant [2 x i8] c")\00" +@.str561 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" +@.str562 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str563 = private unnamed_addr constant [4 x i8] c"int\00" +@.str564 = private unnamed_addr constant [11 x i8] c"file_close\00" +@.str565 = private unnamed_addr constant [24 x i8] c" call i32 @fclose(ptr \00" +@.str566 = private unnamed_addr constant [3 x i8] c")\0A\00" @.str567 = private unnamed_addr constant [2 x i8] c"0\00" @.str568 = private unnamed_addr constant [5 x i8] c"void\00" -@.str569 = private unnamed_addr constant [2 x i8] c"0\00" -@.str570 = private unnamed_addr constant [5 x i8] c"void\00" -@.str571 = private unnamed_addr constant [4 x i8] c"min\00" -@.str572 = private unnamed_addr constant [4 x i8] c"max\00" -@.str573 = private unnamed_addr constant [4 x i8] c"abs\00" -@.str574 = private unnamed_addr constant [6 x i8] c"clamp\00" -@.str575 = private unnamed_addr constant [4 x i8] c"abs\00" -@.str576 = private unnamed_addr constant [14 x i8] c"icmp slt i32 \00" -@.str577 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str578 = private unnamed_addr constant [12 x i8] c"sub i32 0, \00" -@.str579 = private unnamed_addr constant [11 x i8] c"select i1 \00" -@.str580 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str581 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str582 = private unnamed_addr constant [4 x i8] c"int\00" -@.str583 = private unnamed_addr constant [4 x i8] c"min\00" -@.str584 = private unnamed_addr constant [4 x i8] c"max\00" -@.str585 = private unnamed_addr constant [4 x i8] c"slt\00" -@.str586 = private unnamed_addr constant [4 x i8] c"max\00" -@.str587 = private unnamed_addr constant [4 x i8] c"sgt\00" -@.str588 = private unnamed_addr constant [6 x i8] c"icmp \00" -@.str589 = private unnamed_addr constant [6 x i8] c" i32 \00" -@.str590 = private unnamed_addr constant [3 x i8] c", \00" -@.str591 = private unnamed_addr constant [11 x i8] c"select i1 \00" -@.str592 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str593 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str594 = private unnamed_addr constant [4 x i8] c"int\00" -@.str595 = private unnamed_addr constant [14 x i8] c"icmp slt i32 \00" -@.str596 = private unnamed_addr constant [3 x i8] c", \00" -@.str597 = private unnamed_addr constant [11 x i8] c"select i1 \00" -@.str598 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str599 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str600 = private unnamed_addr constant [14 x i8] c"icmp sgt i32 \00" -@.str601 = private unnamed_addr constant [3 x i8] c", \00" -@.str602 = private unnamed_addr constant [11 x i8] c"select i1 \00" -@.str603 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str604 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str605 = private unnamed_addr constant [4 x i8] c"int\00" -@.str606 = private unnamed_addr constant [15 x i8] c"getelementptr \00" -@.str607 = private unnamed_addr constant [18 x i8] c", ptr null, i32 1\00" -@.str608 = private unnamed_addr constant [14 x i8] c"ptrtoint ptr \00" -@.str609 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str610 = private unnamed_addr constant [27 x i8] c"unknown record type in new\00" -@.str611 = private unnamed_addr constant [22 x i8] c"call ptr @malloc(i64 \00" -@.str612 = private unnamed_addr constant [2 x i8] c")\00" -@.str613 = private unnamed_addr constant [3 x i8] c" \00" -@.str614 = private unnamed_addr constant [27 x i8] c" = getelementptr inbounds \00" -@.str615 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str616 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str617 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str618 = private unnamed_addr constant [2 x i8] c"0\00" -@.str619 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str620 = private unnamed_addr constant [5 x i8] c"null\00" -@.str621 = private unnamed_addr constant [9 x i8] c" store \00" -@.str622 = private unnamed_addr constant [2 x i8] c" \00" -@.str623 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str624 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str625 = private unnamed_addr constant [8 x i8] c"%LSlice\00" -@.str626 = private unnamed_addr constant [22 x i8] c"call ptr @malloc(i64 \00" -@.str627 = private unnamed_addr constant [2 x i8] c")\00" +@.str569 = private unnamed_addr constant [10 x i8] c"arg_count\00" +@.str570 = private unnamed_addr constant [22 x i8] c"load i32, ptr @L_argc\00" +@.str571 = private unnamed_addr constant [4 x i8] c"int\00" +@.str572 = private unnamed_addr constant [4 x i8] c"arg\00" +@.str573 = private unnamed_addr constant [22 x i8] c"load ptr, ptr @L_argv\00" +@.str574 = private unnamed_addr constant [24 x i8] c"getelementptr ptr, ptr \00" +@.str575 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str576 = private unnamed_addr constant [15 x i8] c"load ptr, ptr \00" +@.str577 = private unnamed_addr constant [4 x i8] c"str\00" +@.str578 = private unnamed_addr constant [5 x i8] c"exit\00" +@.str579 = private unnamed_addr constant [23 x i8] c" call void @exit(i32 \00" +@.str580 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str581 = private unnamed_addr constant [15 x i8] c" unreachable\0A\00" +@.str582 = private unnamed_addr constant [2 x i8] c"0\00" +@.str583 = private unnamed_addr constant [5 x i8] c"void\00" +@.str584 = private unnamed_addr constant [12 x i8] c"file_stderr\00" +@.str585 = private unnamed_addr constant [25 x i8] c"load ptr, ptr @__stderrp\00" +@.str586 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str587 = private unnamed_addr constant [12 x i8] c"file_stdout\00" +@.str588 = private unnamed_addr constant [25 x i8] c"load ptr, ptr @__stdoutp\00" +@.str589 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str590 = private unnamed_addr constant [4 x i8] c"run\00" +@.str591 = private unnamed_addr constant [22 x i8] c"call i32 @system(ptr \00" +@.str592 = private unnamed_addr constant [2 x i8] c")\00" +@.str593 = private unnamed_addr constant [4 x i8] c"int\00" +@.str594 = private unnamed_addr constant [7 x i8] c"getenv\00" +@.str595 = private unnamed_addr constant [22 x i8] c"call ptr @getenv(ptr \00" +@.str596 = private unnamed_addr constant [2 x i8] c")\00" +@.str597 = private unnamed_addr constant [4 x i8] c"str\00" +@.str598 = private unnamed_addr constant [2 x i8] c"0\00" +@.str599 = private unnamed_addr constant [5 x i8] c"void\00" +@.str600 = private unnamed_addr constant [5 x i8] c"free\00" +@.str601 = private unnamed_addr constant [5 x i8] c"fill\00" +@.str602 = private unnamed_addr constant [7 x i8] c"offset\00" +@.str603 = private unnamed_addr constant [10 x i8] c"read_char\00" +@.str604 = private unnamed_addr constant [9 x i8] c"as_fixed\00" +@.str605 = private unnamed_addr constant [7 x i8] c"as_int\00" +@.str606 = private unnamed_addr constant [12 x i8] c"is_windowed\00" +@.str607 = private unnamed_addr constant [11 x i8] c"game_title\00" +@.str608 = private unnamed_addr constant [9 x i8] c"win_open\00" +@.str609 = private unnamed_addr constant [9 x i8] c"win_poll\00" +@.str610 = private unnamed_addr constant [12 x i8] c"win_present\00" +@.str611 = private unnamed_addr constant [12 x i8] c"win_running\00" +@.str612 = private unnamed_addr constant [10 x i8] c"win_close\00" +@.str613 = private unnamed_addr constant [5 x i8] c"free\00" +@.str614 = private unnamed_addr constant [23 x i8] c" call void @free(ptr \00" +@.str615 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str616 = private unnamed_addr constant [2 x i8] c"0\00" +@.str617 = private unnamed_addr constant [5 x i8] c"void\00" +@.str618 = private unnamed_addr constant [5 x i8] c"fill\00" +@.str619 = private unnamed_addr constant [10 x i8] c"zext i32 \00" +@.str620 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str621 = private unnamed_addr constant [24 x i8] c" call ptr @memset(ptr \00" +@.str622 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str623 = private unnamed_addr constant [7 x i8] c", i64 \00" +@.str624 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str625 = private unnamed_addr constant [2 x i8] c"0\00" +@.str626 = private unnamed_addr constant [5 x i8] c"void\00" +@.str627 = private unnamed_addr constant [7 x i8] c"offset\00" @.str628 = private unnamed_addr constant [3 x i8] c" \00" -@.str629 = private unnamed_addr constant [40 x i8] c" = getelementptr inbounds %LSlice, ptr \00" -@.str630 = private unnamed_addr constant [16 x i8] c", i32 0, i32 0\0A\00" -@.str631 = private unnamed_addr constant [23 x i8] c" store ptr null, ptr \00" -@.str632 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str633 = private unnamed_addr constant [3 x i8] c" \00" -@.str634 = private unnamed_addr constant [40 x i8] c" = getelementptr inbounds %LSlice, ptr \00" -@.str635 = private unnamed_addr constant [16 x i8] c", i32 0, i32 1\0A\00" -@.str636 = private unnamed_addr constant [20 x i8] c" store i32 0, ptr \00" -@.str637 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str638 = private unnamed_addr constant [3 x i8] c" \00" -@.str639 = private unnamed_addr constant [40 x i8] c" = getelementptr inbounds %LSlice, ptr \00" -@.str640 = private unnamed_addr constant [16 x i8] c", i32 0, i32 2\0A\00" -@.str641 = private unnamed_addr constant [20 x i8] c" store i32 0, ptr \00" -@.str642 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str643 = private unnamed_addr constant [3 x i8] c" \00" -@.str644 = private unnamed_addr constant [40 x i8] c" = getelementptr inbounds %LSlice, ptr \00" -@.str645 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str646 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str647 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str648 = private unnamed_addr constant [4 x i8] c"int\00" -@.str649 = private unnamed_addr constant [22 x i8] c"call i64 @strlen(ptr \00" -@.str650 = private unnamed_addr constant [2 x i8] c")\00" -@.str651 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" -@.str652 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str653 = private unnamed_addr constant [4 x i8] c"int\00" -@.str654 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str655 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str656 = private unnamed_addr constant [14 x i8] c"icmp sge i32 \00" -@.str657 = private unnamed_addr constant [3 x i8] c", \00" -@.str658 = private unnamed_addr constant [5 x i8] c"grow\00" -@.str659 = private unnamed_addr constant [4 x i8] c"put\00" -@.str660 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str661 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str662 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str663 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str664 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str665 = private unnamed_addr constant [9 x i8] c"mul i32 \00" -@.str666 = private unnamed_addr constant [4 x i8] c", 2\00" -@.str667 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" -@.str668 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str669 = private unnamed_addr constant [11 x i8] c"select i1 \00" -@.str670 = private unnamed_addr constant [14 x i8] c", i32 8, i32 \00" -@.str671 = private unnamed_addr constant [10 x i8] c"zext i32 \00" -@.str672 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str673 = private unnamed_addr constant [9 x i8] c"mul i64 \00" -@.str674 = private unnamed_addr constant [3 x i8] c", \00" -@.str675 = private unnamed_addr constant [15 x i8] c"load ptr, ptr \00" -@.str676 = private unnamed_addr constant [23 x i8] c"call ptr @realloc(ptr \00" -@.str677 = private unnamed_addr constant [7 x i8] c", i64 \00" -@.str678 = private unnamed_addr constant [2 x i8] c")\00" -@.str679 = private unnamed_addr constant [13 x i8] c" store ptr \00" -@.str680 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str681 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str682 = private unnamed_addr constant [13 x i8] c" store i32 \00" -@.str683 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str684 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str685 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str686 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str687 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str688 = private unnamed_addr constant [15 x i8] c"load ptr, ptr \00" -@.str689 = private unnamed_addr constant [3 x i8] c" \00" -@.str690 = private unnamed_addr constant [27 x i8] c" = getelementptr inbounds \00" -@.str691 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str692 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str693 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str694 = private unnamed_addr constant [9 x i8] c" store \00" -@.str695 = private unnamed_addr constant [2 x i8] c" \00" -@.str696 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str697 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str698 = private unnamed_addr constant [9 x i8] c"add i32 \00" -@.str699 = private unnamed_addr constant [4 x i8] c", 1\00" -@.str700 = private unnamed_addr constant [13 x i8] c" store i32 \00" -@.str701 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str702 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str703 = private unnamed_addr constant [2 x i8] c"0\00" -@.str704 = private unnamed_addr constant [5 x i8] c"void\00" -@.str705 = private unnamed_addr constant [6 x i8] c"load \00" -@.str706 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str707 = private unnamed_addr constant [4 x i8] c"i32\00" -@.str708 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" -@.str709 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str710 = private unnamed_addr constant [9 x i8] c"zext i1 \00" -@.str711 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str712 = private unnamed_addr constant [13 x i8] c" store i32 \00" -@.str713 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str714 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str715 = private unnamed_addr constant [3 x i8] c"sc\00" -@.str716 = private unnamed_addr constant [6 x i8] c"scend\00" -@.str717 = private unnamed_addr constant [4 x i8] c"and\00" -@.str718 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str719 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str720 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str629 = private unnamed_addr constant [35 x i8] c" = getelementptr inbounds i8, ptr \00" +@.str630 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str631 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str632 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str633 = private unnamed_addr constant [10 x i8] c"read_char\00" +@.str634 = private unnamed_addr constant [20 x i8] c"call i32 @getchar()\00" +@.str635 = private unnamed_addr constant [4 x i8] c"int\00" +@.str636 = private unnamed_addr constant [9 x i8] c"as_fixed\00" +@.str637 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str638 = private unnamed_addr constant [7 x i8] c"as_int\00" +@.str639 = private unnamed_addr constant [4 x i8] c"int\00" +@.str640 = private unnamed_addr constant [12 x i8] c"is_windowed\00" +@.str641 = private unnamed_addr constant [2 x i8] c"1\00" +@.str642 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str643 = private unnamed_addr constant [2 x i8] c"0\00" +@.str644 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str645 = private unnamed_addr constant [11 x i8] c"game_title\00" +@.str646 = private unnamed_addr constant [12 x i8] c"@.gametitle\00" +@.str647 = private unnamed_addr constant [4 x i8] c"str\00" +@.str648 = private unnamed_addr constant [9 x i8] c"win_poll\00" +@.str649 = private unnamed_addr constant [21 x i8] c"call i32 @win_poll()\00" +@.str650 = private unnamed_addr constant [4 x i8] c"int\00" +@.str651 = private unnamed_addr constant [12 x i8] c"win_running\00" +@.str652 = private unnamed_addr constant [24 x i8] c"call i32 @win_running()\00" +@.str653 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str654 = private unnamed_addr constant [9 x i8] c"win_open\00" +@.str655 = private unnamed_addr constant [27 x i8] c" call void @win_open(i32 \00" +@.str656 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str657 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str658 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str659 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str660 = private unnamed_addr constant [2 x i8] c"0\00" +@.str661 = private unnamed_addr constant [5 x i8] c"void\00" +@.str662 = private unnamed_addr constant [12 x i8] c"win_present\00" +@.str663 = private unnamed_addr constant [30 x i8] c" call void @win_present(ptr \00" +@.str664 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str665 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str666 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str667 = private unnamed_addr constant [2 x i8] c"0\00" +@.str668 = private unnamed_addr constant [5 x i8] c"void\00" +@.str669 = private unnamed_addr constant [10 x i8] c"win_close\00" +@.str670 = private unnamed_addr constant [26 x i8] c" call void @win_close()\0A\00" +@.str671 = private unnamed_addr constant [2 x i8] c"0\00" +@.str672 = private unnamed_addr constant [5 x i8] c"void\00" +@.str673 = private unnamed_addr constant [2 x i8] c"0\00" +@.str674 = private unnamed_addr constant [5 x i8] c"void\00" +@.str675 = private unnamed_addr constant [4 x i8] c"min\00" +@.str676 = private unnamed_addr constant [4 x i8] c"max\00" +@.str677 = private unnamed_addr constant [4 x i8] c"abs\00" +@.str678 = private unnamed_addr constant [6 x i8] c"clamp\00" +@.str679 = private unnamed_addr constant [4 x i8] c"abs\00" +@.str680 = private unnamed_addr constant [14 x i8] c"icmp slt i32 \00" +@.str681 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str682 = private unnamed_addr constant [12 x i8] c"sub i32 0, \00" +@.str683 = private unnamed_addr constant [11 x i8] c"select i1 \00" +@.str684 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str685 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str686 = private unnamed_addr constant [4 x i8] c"int\00" +@.str687 = private unnamed_addr constant [4 x i8] c"min\00" +@.str688 = private unnamed_addr constant [4 x i8] c"max\00" +@.str689 = private unnamed_addr constant [4 x i8] c"slt\00" +@.str690 = private unnamed_addr constant [4 x i8] c"max\00" +@.str691 = private unnamed_addr constant [4 x i8] c"sgt\00" +@.str692 = private unnamed_addr constant [6 x i8] c"icmp \00" +@.str693 = private unnamed_addr constant [6 x i8] c" i32 \00" +@.str694 = private unnamed_addr constant [3 x i8] c", \00" +@.str695 = private unnamed_addr constant [11 x i8] c"select i1 \00" +@.str696 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str697 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str698 = private unnamed_addr constant [4 x i8] c"int\00" +@.str699 = private unnamed_addr constant [14 x i8] c"icmp slt i32 \00" +@.str700 = private unnamed_addr constant [3 x i8] c", \00" +@.str701 = private unnamed_addr constant [11 x i8] c"select i1 \00" +@.str702 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str703 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str704 = private unnamed_addr constant [14 x i8] c"icmp sgt i32 \00" +@.str705 = private unnamed_addr constant [3 x i8] c", \00" +@.str706 = private unnamed_addr constant [11 x i8] c"select i1 \00" +@.str707 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str708 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str709 = private unnamed_addr constant [4 x i8] c"int\00" +@.str710 = private unnamed_addr constant [15 x i8] c"getelementptr \00" +@.str711 = private unnamed_addr constant [18 x i8] c", ptr null, i32 1\00" +@.str712 = private unnamed_addr constant [14 x i8] c"ptrtoint ptr \00" +@.str713 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str714 = private unnamed_addr constant [27 x i8] c"unknown record type in new\00" +@.str715 = private unnamed_addr constant [22 x i8] c"call ptr @malloc(i64 \00" +@.str716 = private unnamed_addr constant [2 x i8] c")\00" +@.str717 = private unnamed_addr constant [3 x i8] c" \00" +@.str718 = private unnamed_addr constant [27 x i8] c" = getelementptr inbounds \00" +@.str719 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str720 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" @.str721 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str722 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str723 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str724 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str725 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str726 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str727 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" -@.str728 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str729 = private unnamed_addr constant [9 x i8] c"zext i1 \00" -@.str730 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str731 = private unnamed_addr constant [13 x i8] c" store i32 \00" -@.str732 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str733 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str734 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str735 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str736 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str737 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str738 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str739 = private unnamed_addr constant [2 x i8] c"<\00" -@.str740 = private unnamed_addr constant [4 x i8] c"slt\00" -@.str741 = private unnamed_addr constant [3 x i8] c"<=\00" -@.str742 = private unnamed_addr constant [4 x i8] c"sle\00" -@.str743 = private unnamed_addr constant [2 x i8] c">\00" -@.str744 = private unnamed_addr constant [4 x i8] c"sgt\00" -@.str745 = private unnamed_addr constant [3 x i8] c">=\00" -@.str746 = private unnamed_addr constant [4 x i8] c"sge\00" -@.str747 = private unnamed_addr constant [3 x i8] c"==\00" -@.str748 = private unnamed_addr constant [3 x i8] c"eq\00" -@.str749 = private unnamed_addr constant [3 x i8] c"ne\00" -@.str750 = private unnamed_addr constant [2 x i8] c"<\00" -@.str751 = private unnamed_addr constant [3 x i8] c"<=\00" -@.str752 = private unnamed_addr constant [2 x i8] c">\00" -@.str753 = private unnamed_addr constant [3 x i8] c">=\00" -@.str754 = private unnamed_addr constant [3 x i8] c"==\00" -@.str755 = private unnamed_addr constant [3 x i8] c"!=\00" -@.str756 = private unnamed_addr constant [2 x i8] c"+\00" -@.str757 = private unnamed_addr constant [4 x i8] c"add\00" -@.str758 = private unnamed_addr constant [2 x i8] c"-\00" -@.str759 = private unnamed_addr constant [4 x i8] c"sub\00" -@.str760 = private unnamed_addr constant [2 x i8] c"*\00" -@.str761 = private unnamed_addr constant [4 x i8] c"mul\00" -@.str762 = private unnamed_addr constant [2 x i8] c"/\00" -@.str763 = private unnamed_addr constant [5 x i8] c"sdiv\00" -@.str764 = private unnamed_addr constant [2 x i8] c"&\00" -@.str765 = private unnamed_addr constant [4 x i8] c"and\00" -@.str766 = private unnamed_addr constant [2 x i8] c"|\00" -@.str767 = private unnamed_addr constant [3 x i8] c"or\00" -@.str768 = private unnamed_addr constant [2 x i8] c"^\00" -@.str769 = private unnamed_addr constant [4 x i8] c"xor\00" -@.str770 = private unnamed_addr constant [3 x i8] c"<<\00" -@.str771 = private unnamed_addr constant [4 x i8] c"shl\00" -@.str772 = private unnamed_addr constant [3 x i8] c">>\00" -@.str773 = private unnamed_addr constant [5 x i8] c"lshr\00" -@.str774 = private unnamed_addr constant [5 x i8] c"srem\00" -@.str775 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str776 = private unnamed_addr constant [9 x i8] c"shl i32 \00" -@.str777 = private unnamed_addr constant [5 x i8] c", 16\00" -@.str778 = private unnamed_addr constant [2 x i8] c"+\00" -@.str779 = private unnamed_addr constant [29 x i8] c"call ptr @fn_str_concat(ptr \00" -@.str780 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str781 = private unnamed_addr constant [2 x i8] c")\00" -@.str782 = private unnamed_addr constant [4 x i8] c"str\00" -@.str783 = private unnamed_addr constant [25 x i8] c"call i32 @fn_str_eq(ptr \00" +@.str722 = private unnamed_addr constant [2 x i8] c"0\00" +@.str723 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str724 = private unnamed_addr constant [5 x i8] c"null\00" +@.str725 = private unnamed_addr constant [9 x i8] c" store \00" +@.str726 = private unnamed_addr constant [2 x i8] c" \00" +@.str727 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str728 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str729 = private unnamed_addr constant [8 x i8] c"%LSlice\00" +@.str730 = private unnamed_addr constant [22 x i8] c"call ptr @malloc(i64 \00" +@.str731 = private unnamed_addr constant [2 x i8] c")\00" +@.str732 = private unnamed_addr constant [3 x i8] c" \00" +@.str733 = private unnamed_addr constant [40 x i8] c" = getelementptr inbounds %LSlice, ptr \00" +@.str734 = private unnamed_addr constant [16 x i8] c", i32 0, i32 0\0A\00" +@.str735 = private unnamed_addr constant [23 x i8] c" store ptr null, ptr \00" +@.str736 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str737 = private unnamed_addr constant [3 x i8] c" \00" +@.str738 = private unnamed_addr constant [40 x i8] c" = getelementptr inbounds %LSlice, ptr \00" +@.str739 = private unnamed_addr constant [16 x i8] c", i32 0, i32 1\0A\00" +@.str740 = private unnamed_addr constant [20 x i8] c" store i32 0, ptr \00" +@.str741 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str742 = private unnamed_addr constant [3 x i8] c" \00" +@.str743 = private unnamed_addr constant [40 x i8] c" = getelementptr inbounds %LSlice, ptr \00" +@.str744 = private unnamed_addr constant [16 x i8] c", i32 0, i32 2\0A\00" +@.str745 = private unnamed_addr constant [20 x i8] c" store i32 0, ptr \00" +@.str746 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str747 = private unnamed_addr constant [3 x i8] c" \00" +@.str748 = private unnamed_addr constant [40 x i8] c" = getelementptr inbounds %LSlice, ptr \00" +@.str749 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str750 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str751 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str752 = private unnamed_addr constant [4 x i8] c"int\00" +@.str753 = private unnamed_addr constant [22 x i8] c"call i64 @strlen(ptr \00" +@.str754 = private unnamed_addr constant [2 x i8] c")\00" +@.str755 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" +@.str756 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str757 = private unnamed_addr constant [4 x i8] c"int\00" +@.str758 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str759 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str760 = private unnamed_addr constant [14 x i8] c"icmp sge i32 \00" +@.str761 = private unnamed_addr constant [3 x i8] c", \00" +@.str762 = private unnamed_addr constant [5 x i8] c"grow\00" +@.str763 = private unnamed_addr constant [4 x i8] c"put\00" +@.str764 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str765 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str766 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str767 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str768 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str769 = private unnamed_addr constant [9 x i8] c"mul i32 \00" +@.str770 = private unnamed_addr constant [4 x i8] c", 2\00" +@.str771 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" +@.str772 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str773 = private unnamed_addr constant [11 x i8] c"select i1 \00" +@.str774 = private unnamed_addr constant [14 x i8] c", i32 8, i32 \00" +@.str775 = private unnamed_addr constant [10 x i8] c"zext i32 \00" +@.str776 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str777 = private unnamed_addr constant [9 x i8] c"mul i64 \00" +@.str778 = private unnamed_addr constant [3 x i8] c", \00" +@.str779 = private unnamed_addr constant [15 x i8] c"load ptr, ptr \00" +@.str780 = private unnamed_addr constant [23 x i8] c"call ptr @realloc(ptr \00" +@.str781 = private unnamed_addr constant [7 x i8] c", i64 \00" +@.str782 = private unnamed_addr constant [2 x i8] c")\00" +@.str783 = private unnamed_addr constant [13 x i8] c" store ptr \00" @.str784 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str785 = private unnamed_addr constant [2 x i8] c")\00" -@.str786 = private unnamed_addr constant [3 x i8] c"!=\00" -@.str787 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" -@.str788 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str789 = private unnamed_addr constant [9 x i8] c"zext i1 \00" -@.str790 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str791 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str792 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str793 = private unnamed_addr constant [4 x i8] c"and\00" -@.str794 = private unnamed_addr constant [3 x i8] c"or\00" -@.str795 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str796 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str797 = private unnamed_addr constant [2 x i8] c"+\00" -@.str798 = private unnamed_addr constant [2 x i8] c"+\00" -@.str799 = private unnamed_addr constant [3 x i8] c"==\00" -@.str800 = private unnamed_addr constant [3 x i8] c"!=\00" -@.str801 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str802 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str803 = private unnamed_addr constant [4 x i8] c"i32\00" -@.str804 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str805 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str806 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str807 = private unnamed_addr constant [6 x i8] c"icmp \00" -@.str808 = private unnamed_addr constant [2 x i8] c" \00" -@.str809 = private unnamed_addr constant [2 x i8] c" \00" -@.str810 = private unnamed_addr constant [3 x i8] c", \00" -@.str811 = private unnamed_addr constant [9 x i8] c"zext i1 \00" -@.str812 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str813 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str814 = private unnamed_addr constant [2 x i8] c"*\00" -@.str815 = private unnamed_addr constant [10 x i8] c"sext i32 \00" -@.str816 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str817 = private unnamed_addr constant [10 x i8] c"sext i32 \00" -@.str818 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str819 = private unnamed_addr constant [9 x i8] c"mul i64 \00" -@.str820 = private unnamed_addr constant [3 x i8] c", \00" -@.str821 = private unnamed_addr constant [10 x i8] c"ashr i64 \00" -@.str822 = private unnamed_addr constant [5 x i8] c", 16\00" -@.str823 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" -@.str824 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str825 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str826 = private unnamed_addr constant [2 x i8] c"/\00" -@.str827 = private unnamed_addr constant [10 x i8] c"sext i32 \00" -@.str828 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str829 = private unnamed_addr constant [9 x i8] c"shl i64 \00" -@.str830 = private unnamed_addr constant [5 x i8] c", 16\00" -@.str831 = private unnamed_addr constant [10 x i8] c"sext i32 \00" -@.str832 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str833 = private unnamed_addr constant [10 x i8] c"sdiv i64 \00" -@.str834 = private unnamed_addr constant [3 x i8] c", \00" -@.str835 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" -@.str836 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str837 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str838 = private unnamed_addr constant [6 x i8] c" i32 \00" -@.str839 = private unnamed_addr constant [3 x i8] c", \00" -@.str840 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str841 = private unnamed_addr constant [6 x i8] c" i32 \00" -@.str842 = private unnamed_addr constant [3 x i8] c", \00" -@.str843 = private unnamed_addr constant [4 x i8] c"int\00" -@.str844 = private unnamed_addr constant [5 x i8] c"self\00" -@.str845 = private unnamed_addr constant [2 x i8] c"0\00" -@.str846 = private unnamed_addr constant [7 x i8] c"entity\00" -@.str847 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str848 = private unnamed_addr constant [7 x i8] c"entity\00" -@.str849 = private unnamed_addr constant [4 x i8] c"key\00" -@.str850 = private unnamed_addr constant [21 x i8] c"load i32, ptr @L_key\00" -@.str851 = private unnamed_addr constant [4 x i8] c"int\00" -@.str852 = private unnamed_addr constant [5 x i8] c"save\00" -@.str853 = private unnamed_addr constant [23 x i8] c" call void @L_save()\0A\00" -@.str854 = private unnamed_addr constant [2 x i8] c"0\00" -@.str855 = private unnamed_addr constant [5 x i8] c"void\00" -@.str856 = private unnamed_addr constant [9 x i8] c"ui_build\00" -@.str857 = private unnamed_addr constant [25 x i8] c" call void @ui_build()\0A\00" -@.str858 = private unnamed_addr constant [2 x i8] c"0\00" -@.str859 = private unnamed_addr constant [5 x i8] c"void\00" -@.str860 = private unnamed_addr constant [5 x i8] c"load\00" -@.str861 = private unnamed_addr constant [19 x i8] c"call i32 @L_load()\00" -@.str862 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str863 = private unnamed_addr constant [5 x i8] c"quit\00" -@.str864 = private unnamed_addr constant [31 x i8] c" store i32 0, ptr @L_running\0A\00" -@.str865 = private unnamed_addr constant [2 x i8] c"0\00" -@.str866 = private unnamed_addr constant [5 x i8] c"void\00" -@.str867 = private unnamed_addr constant [4 x i8] c"len\00" -@.str868 = private unnamed_addr constant [5 x i8] c"push\00" -@.str869 = private unnamed_addr constant [4 x i8] c"str\00" -@.str870 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str871 = private unnamed_addr constant [26 x i8] c"call ptr @fn_int_str(i32 \00" -@.str872 = private unnamed_addr constant [2 x i8] c")\00" -@.str873 = private unnamed_addr constant [4 x i8] c"str\00" -@.str874 = private unnamed_addr constant [6 x i8] c"print\00" -@.str875 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str876 = private unnamed_addr constant [51 x i8] c" call i32 (ptr, ...) @printf(ptr @.fmt_line, ptr \00" -@.str877 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str878 = private unnamed_addr constant [50 x i8] c" call i32 (ptr, ...) @printf(ptr @.fmt_int, i32 \00" -@.str879 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str880 = private unnamed_addr constant [2 x i8] c"0\00" -@.str881 = private unnamed_addr constant [5 x i8] c"void\00" -@.str882 = private unnamed_addr constant [6 x i8] c"bytes\00" -@.str883 = private unnamed_addr constant [10 x i8] c"zext i32 \00" -@.str884 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str885 = private unnamed_addr constant [22 x i8] c"call ptr @malloc(i64 \00" -@.str886 = private unnamed_addr constant [2 x i8] c")\00" -@.str887 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str888 = private unnamed_addr constant [6 x i8] c"words\00" -@.str889 = private unnamed_addr constant [9 x i8] c"mul i32 \00" -@.str890 = private unnamed_addr constant [4 x i8] c", 4\00" -@.str891 = private unnamed_addr constant [10 x i8] c"zext i32 \00" -@.str892 = private unnamed_addr constant [8 x i8] c" to i64\00" -@.str893 = private unnamed_addr constant [22 x i8] c"call ptr @malloc(i64 \00" -@.str894 = private unnamed_addr constant [2 x i8] c")\00" -@.str895 = private unnamed_addr constant [6 x i8] c"words\00" -@.str896 = private unnamed_addr constant [3 x i8] c"fx\00" -@.str897 = private unnamed_addr constant [9 x i8] c"shl i32 \00" -@.str898 = private unnamed_addr constant [5 x i8] c", 16\00" -@.str899 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str900 = private unnamed_addr constant [4 x i8] c"flr\00" -@.str901 = private unnamed_addr constant [10 x i8] c"ashr i32 \00" -@.str902 = private unnamed_addr constant [5 x i8] c", 16\00" -@.str903 = private unnamed_addr constant [4 x i8] c"int\00" -@.str904 = private unnamed_addr constant [4 x i8] c"rt_\00" -@.str905 = private unnamed_addr constant [18 x i8] c"unknown function \00" -@.str906 = private unnamed_addr constant [3 x i8] c" \00" -@.str907 = private unnamed_addr constant [2 x i8] c"0\00" -@.str908 = private unnamed_addr constant [5 x i8] c"void\00" -@.str909 = private unnamed_addr constant [4 x i8] c" = \00" -@.str910 = private unnamed_addr constant [6 x i8] c"call \00" -@.str911 = private unnamed_addr constant [6 x i8] c" @fn_\00" -@.str912 = private unnamed_addr constant [2 x i8] c"(\00" -@.str913 = private unnamed_addr constant [3 x i8] c", \00" -@.str914 = private unnamed_addr constant [2 x i8] c" \00" -@.str915 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str916 = private unnamed_addr constant [2 x i8] c"0\00" -@.str917 = private unnamed_addr constant [4 x i8] c"int\00" -@.str918 = private unnamed_addr constant [4 x i8] c"int\00" -@.str919 = private unnamed_addr constant [6 x i8] c"fixed\00" -@.str920 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str921 = private unnamed_addr constant [5 x i8] c"null\00" -@.str922 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str923 = private unnamed_addr constant [28 x i8] c"call ptr @fn_str_slice(ptr \00" -@.str924 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str925 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str926 = private unnamed_addr constant [2 x i8] c")\00" -@.str927 = private unnamed_addr constant [4 x i8] c"str\00" -@.str928 = private unnamed_addr constant [4 x i8] c"str\00" -@.str929 = private unnamed_addr constant [4 x i8] c"int\00" -@.str930 = private unnamed_addr constant [6 x i8] c"load \00" -@.str931 = private unnamed_addr constant [10 x i8] c", ptr @g_\00" -@.str932 = private unnamed_addr constant [4 x i8] c"int\00" -@.str933 = private unnamed_addr constant [20 x i8] c"unknown identifier \00" -@.str934 = private unnamed_addr constant [4 x i8] c"int\00" -@.str935 = private unnamed_addr constant [5 x i8] c"byte\00" -@.str936 = private unnamed_addr constant [14 x i8] c"load i8, ptr \00" -@.str937 = private unnamed_addr constant [9 x i8] c"zext i8 \00" -@.str938 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str939 = private unnamed_addr constant [4 x i8] c"int\00" -@.str940 = private unnamed_addr constant [2 x i8] c"-\00" -@.str941 = private unnamed_addr constant [12 x i8] c"sub i32 0, \00" -@.str942 = private unnamed_addr constant [4 x i8] c"int\00" -@.str943 = private unnamed_addr constant [2 x i8] c"~\00" -@.str944 = private unnamed_addr constant [9 x i8] c"xor i32 \00" -@.str945 = private unnamed_addr constant [5 x i8] c", -1\00" -@.str946 = private unnamed_addr constant [4 x i8] c"int\00" -@.str947 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" -@.str948 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str949 = private unnamed_addr constant [9 x i8] c"zext i1 \00" -@.str950 = private unnamed_addr constant [8 x i8] c" to i32\00" -@.str951 = private unnamed_addr constant [5 x i8] c"bool\00" -@.str952 = private unnamed_addr constant [23 x i8] c"cannot emit expression\00" -@.str953 = private unnamed_addr constant [2 x i8] c"0\00" -@.str954 = private unnamed_addr constant [4 x i8] c"int\00" -@.str955 = private unnamed_addr constant [9 x i8] c" store \00" -@.str956 = private unnamed_addr constant [2 x i8] c" \00" -@.str957 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str958 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str959 = private unnamed_addr constant [2 x i8] c"0\00" -@.str960 = private unnamed_addr constant [4 x i8] c"int\00" -@.str961 = private unnamed_addr constant [29 x i8] c"cannot assign to immutable '\00" -@.str962 = private unnamed_addr constant [41 x i8] c"' (declared with let; use var) \E2\80\94 line \00" -@.str963 = private unnamed_addr constant [19 x i8] c"assign to unknown \00" -@.str964 = private unnamed_addr constant [4 x i8] c"@g_\00" -@.str965 = private unnamed_addr constant [22 x i8] c"bad assignment target\00" -@.str966 = private unnamed_addr constant [2 x i8] c"=\00" -@.str967 = private unnamed_addr constant [6 x i8] c"load \00" -@.str968 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str969 = private unnamed_addr constant [4 x i8] c"add\00" -@.str970 = private unnamed_addr constant [3 x i8] c"-=\00" -@.str971 = private unnamed_addr constant [4 x i8] c"sub\00" -@.str972 = private unnamed_addr constant [3 x i8] c"*=\00" -@.str973 = private unnamed_addr constant [4 x i8] c"mul\00" -@.str974 = private unnamed_addr constant [3 x i8] c"/=\00" -@.str975 = private unnamed_addr constant [5 x i8] c"sdiv\00" -@.str976 = private unnamed_addr constant [6 x i8] c" i32 \00" -@.str977 = private unnamed_addr constant [3 x i8] c", \00" -@.str978 = private unnamed_addr constant [3 x i8] c"i8\00" -@.str979 = private unnamed_addr constant [11 x i8] c"trunc i32 \00" -@.str980 = private unnamed_addr constant [7 x i8] c" to i8\00" -@.str981 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" -@.str982 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str983 = private unnamed_addr constant [5 x i8] c"then\00" -@.str984 = private unnamed_addr constant [5 x i8] c"else\00" -@.str985 = private unnamed_addr constant [6 x i8] c"ifend\00" -@.str986 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str987 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str988 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str989 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str990 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str991 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str992 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str993 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str994 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str995 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str996 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str997 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str998 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str999 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1000 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1001 = private unnamed_addr constant [6 x i8] c"wcond\00" -@.str1002 = private unnamed_addr constant [6 x i8] c"wbody\00" -@.str1003 = private unnamed_addr constant [5 x i8] c"wend\00" -@.str1004 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1005 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1006 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1007 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" -@.str1008 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str1009 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1010 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1011 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1012 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1013 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1014 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1015 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1016 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1017 = private unnamed_addr constant [4 x i8] c"i32\00" -@.str1018 = private unnamed_addr constant [4 x i8] c"i32\00" -@.str1019 = private unnamed_addr constant [4 x i8] c"int\00" -@.str1020 = private unnamed_addr constant [6 x i8] c"fcond\00" -@.str1021 = private unnamed_addr constant [6 x i8] c"fbody\00" -@.str1022 = private unnamed_addr constant [6 x i8] c"fcont\00" -@.str1023 = private unnamed_addr constant [5 x i8] c"fend\00" -@.str1024 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1025 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1026 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1027 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str1028 = private unnamed_addr constant [14 x i8] c"icmp slt i32 \00" -@.str1029 = private unnamed_addr constant [3 x i8] c", \00" -@.str1030 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1031 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1032 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1033 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1034 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1035 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1036 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1037 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1038 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str1039 = private unnamed_addr constant [9 x i8] c"add i32 \00" -@.str1040 = private unnamed_addr constant [4 x i8] c", 1\00" -@.str1041 = private unnamed_addr constant [4 x i8] c"i32\00" -@.str1042 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1043 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1044 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1045 = private unnamed_addr constant [8 x i8] c"%retval\00" -@.str1046 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" -@.str1047 = private unnamed_addr constant [2 x i8] c"_\00" -@.str1048 = private unnamed_addr constant [5 x i8] c"mend\00" -@.str1049 = private unnamed_addr constant [2 x i8] c"0\00" -@.str1050 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" -@.str1051 = private unnamed_addr constant [3 x i8] c", \00" -@.str1052 = private unnamed_addr constant [7 x i8] c"or i1 \00" -@.str1053 = private unnamed_addr constant [3 x i8] c", \00" -@.str1054 = private unnamed_addr constant [6 x i8] c"mbody\00" -@.str1055 = private unnamed_addr constant [5 x i8] c"marm\00" -@.str1056 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1057 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1058 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1059 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1060 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1061 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1062 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1063 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1064 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1065 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1066 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1067 = private unnamed_addr constant [2 x i8] c"0\00" +@.str785 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str786 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str787 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str788 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str789 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str790 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str791 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str792 = private unnamed_addr constant [15 x i8] c"load ptr, ptr \00" +@.str793 = private unnamed_addr constant [3 x i8] c" \00" +@.str794 = private unnamed_addr constant [27 x i8] c" = getelementptr inbounds \00" +@.str795 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str796 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str797 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str798 = private unnamed_addr constant [9 x i8] c" store \00" +@.str799 = private unnamed_addr constant [2 x i8] c" \00" +@.str800 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str801 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str802 = private unnamed_addr constant [9 x i8] c"add i32 \00" +@.str803 = private unnamed_addr constant [4 x i8] c", 1\00" +@.str804 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str805 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str806 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str807 = private unnamed_addr constant [2 x i8] c"0\00" +@.str808 = private unnamed_addr constant [5 x i8] c"void\00" +@.str809 = private unnamed_addr constant [6 x i8] c"load \00" +@.str810 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str811 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str812 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str813 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str814 = private unnamed_addr constant [9 x i8] c"zext i1 \00" +@.str815 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str816 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str817 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str818 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str819 = private unnamed_addr constant [3 x i8] c"sc\00" +@.str820 = private unnamed_addr constant [6 x i8] c"scend\00" +@.str821 = private unnamed_addr constant [4 x i8] c"and\00" +@.str822 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str823 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str824 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str825 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str826 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str827 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str828 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str829 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str830 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str831 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str832 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str833 = private unnamed_addr constant [9 x i8] c"zext i1 \00" +@.str834 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str835 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str836 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str837 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str838 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str839 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str840 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str841 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str842 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str843 = private unnamed_addr constant [2 x i8] c"<\00" +@.str844 = private unnamed_addr constant [4 x i8] c"slt\00" +@.str845 = private unnamed_addr constant [3 x i8] c"<=\00" +@.str846 = private unnamed_addr constant [4 x i8] c"sle\00" +@.str847 = private unnamed_addr constant [2 x i8] c">\00" +@.str848 = private unnamed_addr constant [4 x i8] c"sgt\00" +@.str849 = private unnamed_addr constant [3 x i8] c">=\00" +@.str850 = private unnamed_addr constant [4 x i8] c"sge\00" +@.str851 = private unnamed_addr constant [3 x i8] c"==\00" +@.str852 = private unnamed_addr constant [3 x i8] c"eq\00" +@.str853 = private unnamed_addr constant [3 x i8] c"ne\00" +@.str854 = private unnamed_addr constant [2 x i8] c"<\00" +@.str855 = private unnamed_addr constant [3 x i8] c"<=\00" +@.str856 = private unnamed_addr constant [2 x i8] c">\00" +@.str857 = private unnamed_addr constant [3 x i8] c">=\00" +@.str858 = private unnamed_addr constant [3 x i8] c"==\00" +@.str859 = private unnamed_addr constant [3 x i8] c"!=\00" +@.str860 = private unnamed_addr constant [2 x i8] c"+\00" +@.str861 = private unnamed_addr constant [4 x i8] c"add\00" +@.str862 = private unnamed_addr constant [2 x i8] c"-\00" +@.str863 = private unnamed_addr constant [4 x i8] c"sub\00" +@.str864 = private unnamed_addr constant [2 x i8] c"*\00" +@.str865 = private unnamed_addr constant [4 x i8] c"mul\00" +@.str866 = private unnamed_addr constant [2 x i8] c"/\00" +@.str867 = private unnamed_addr constant [5 x i8] c"sdiv\00" +@.str868 = private unnamed_addr constant [2 x i8] c"&\00" +@.str869 = private unnamed_addr constant [4 x i8] c"and\00" +@.str870 = private unnamed_addr constant [2 x i8] c"|\00" +@.str871 = private unnamed_addr constant [3 x i8] c"or\00" +@.str872 = private unnamed_addr constant [2 x i8] c"^\00" +@.str873 = private unnamed_addr constant [4 x i8] c"xor\00" +@.str874 = private unnamed_addr constant [3 x i8] c"<<\00" +@.str875 = private unnamed_addr constant [4 x i8] c"shl\00" +@.str876 = private unnamed_addr constant [3 x i8] c">>\00" +@.str877 = private unnamed_addr constant [5 x i8] c"lshr\00" +@.str878 = private unnamed_addr constant [5 x i8] c"srem\00" +@.str879 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str880 = private unnamed_addr constant [9 x i8] c"shl i32 \00" +@.str881 = private unnamed_addr constant [5 x i8] c", 16\00" +@.str882 = private unnamed_addr constant [2 x i8] c"+\00" +@.str883 = private unnamed_addr constant [29 x i8] c"call ptr @fn_str_concat(ptr \00" +@.str884 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str885 = private unnamed_addr constant [2 x i8] c")\00" +@.str886 = private unnamed_addr constant [4 x i8] c"str\00" +@.str887 = private unnamed_addr constant [25 x i8] c"call i32 @fn_str_eq(ptr \00" +@.str888 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str889 = private unnamed_addr constant [2 x i8] c")\00" +@.str890 = private unnamed_addr constant [3 x i8] c"!=\00" +@.str891 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" +@.str892 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str893 = private unnamed_addr constant [9 x i8] c"zext i1 \00" +@.str894 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str895 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str896 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str897 = private unnamed_addr constant [4 x i8] c"and\00" +@.str898 = private unnamed_addr constant [3 x i8] c"or\00" +@.str899 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str900 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str901 = private unnamed_addr constant [2 x i8] c"+\00" +@.str902 = private unnamed_addr constant [2 x i8] c"+\00" +@.str903 = private unnamed_addr constant [3 x i8] c"==\00" +@.str904 = private unnamed_addr constant [3 x i8] c"!=\00" +@.str905 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str906 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str907 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str908 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str909 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str910 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str911 = private unnamed_addr constant [6 x i8] c"icmp \00" +@.str912 = private unnamed_addr constant [2 x i8] c" \00" +@.str913 = private unnamed_addr constant [2 x i8] c" \00" +@.str914 = private unnamed_addr constant [3 x i8] c", \00" +@.str915 = private unnamed_addr constant [9 x i8] c"zext i1 \00" +@.str916 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str917 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str918 = private unnamed_addr constant [2 x i8] c"*\00" +@.str919 = private unnamed_addr constant [10 x i8] c"sext i32 \00" +@.str920 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str921 = private unnamed_addr constant [10 x i8] c"sext i32 \00" +@.str922 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str923 = private unnamed_addr constant [9 x i8] c"mul i64 \00" +@.str924 = private unnamed_addr constant [3 x i8] c", \00" +@.str925 = private unnamed_addr constant [10 x i8] c"ashr i64 \00" +@.str926 = private unnamed_addr constant [5 x i8] c", 16\00" +@.str927 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" +@.str928 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str929 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str930 = private unnamed_addr constant [2 x i8] c"/\00" +@.str931 = private unnamed_addr constant [10 x i8] c"sext i32 \00" +@.str932 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str933 = private unnamed_addr constant [9 x i8] c"shl i64 \00" +@.str934 = private unnamed_addr constant [5 x i8] c", 16\00" +@.str935 = private unnamed_addr constant [10 x i8] c"sext i32 \00" +@.str936 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str937 = private unnamed_addr constant [10 x i8] c"sdiv i64 \00" +@.str938 = private unnamed_addr constant [3 x i8] c", \00" +@.str939 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" +@.str940 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str941 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str942 = private unnamed_addr constant [6 x i8] c" i32 \00" +@.str943 = private unnamed_addr constant [3 x i8] c", \00" +@.str944 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str945 = private unnamed_addr constant [6 x i8] c" i32 \00" +@.str946 = private unnamed_addr constant [3 x i8] c", \00" +@.str947 = private unnamed_addr constant [4 x i8] c"int\00" +@.str948 = private unnamed_addr constant [5 x i8] c"self\00" +@.str949 = private unnamed_addr constant [2 x i8] c"0\00" +@.str950 = private unnamed_addr constant [7 x i8] c"entity\00" +@.str951 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str952 = private unnamed_addr constant [7 x i8] c"entity\00" +@.str953 = private unnamed_addr constant [4 x i8] c"key\00" +@.str954 = private unnamed_addr constant [21 x i8] c"load i32, ptr @L_key\00" +@.str955 = private unnamed_addr constant [4 x i8] c"int\00" +@.str956 = private unnamed_addr constant [5 x i8] c"save\00" +@.str957 = private unnamed_addr constant [23 x i8] c" call void @L_save()\0A\00" +@.str958 = private unnamed_addr constant [2 x i8] c"0\00" +@.str959 = private unnamed_addr constant [5 x i8] c"void\00" +@.str960 = private unnamed_addr constant [9 x i8] c"ui_build\00" +@.str961 = private unnamed_addr constant [25 x i8] c" call void @ui_build()\0A\00" +@.str962 = private unnamed_addr constant [2 x i8] c"0\00" +@.str963 = private unnamed_addr constant [5 x i8] c"void\00" +@.str964 = private unnamed_addr constant [5 x i8] c"load\00" +@.str965 = private unnamed_addr constant [19 x i8] c"call i32 @L_load()\00" +@.str966 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str967 = private unnamed_addr constant [11 x i8] c"world_size\00" +@.str968 = private unnamed_addr constant [25 x i8] c"call i32 @L_world_size()\00" +@.str969 = private unnamed_addr constant [4 x i8] c"int\00" +@.str970 = private unnamed_addr constant [11 x i8] c"world_save\00" +@.str971 = private unnamed_addr constant [28 x i8] c"call i32 @L_world_save(ptr \00" +@.str972 = private unnamed_addr constant [2 x i8] c")\00" +@.str973 = private unnamed_addr constant [4 x i8] c"int\00" +@.str974 = private unnamed_addr constant [11 x i8] c"world_load\00" +@.str975 = private unnamed_addr constant [31 x i8] c" call void @L_world_load(ptr \00" +@.str976 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str977 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str978 = private unnamed_addr constant [2 x i8] c"0\00" +@.str979 = private unnamed_addr constant [5 x i8] c"void\00" +@.str980 = private unnamed_addr constant [5 x i8] c"quit\00" +@.str981 = private unnamed_addr constant [31 x i8] c" store i32 0, ptr @L_running\0A\00" +@.str982 = private unnamed_addr constant [2 x i8] c"0\00" +@.str983 = private unnamed_addr constant [5 x i8] c"void\00" +@.str984 = private unnamed_addr constant [10 x i8] c"serialize\00" +@.str985 = private unnamed_addr constant [31 x i8] c"call i32 @ludic_serialize(i32 \00" +@.str986 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str987 = private unnamed_addr constant [2 x i8] c")\00" +@.str988 = private unnamed_addr constant [4 x i8] c"int\00" +@.str989 = private unnamed_addr constant [6 x i8] c"apply\00" +@.str990 = private unnamed_addr constant [30 x i8] c" call void @ludic_apply(i32 \00" +@.str991 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str992 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str993 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str994 = private unnamed_addr constant [2 x i8] c"0\00" +@.str995 = private unnamed_addr constant [5 x i8] c"void\00" +@.str996 = private unnamed_addr constant [10 x i8] c"sync_size\00" +@.str997 = private unnamed_addr constant [31 x i8] c"call i32 @ludic_sync_size(i32 \00" +@.str998 = private unnamed_addr constant [2 x i8] c")\00" +@.str999 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1000 = private unnamed_addr constant [6 x i8] c"owner\00" +@.str1001 = private unnamed_addr constant [23 x i8] c"call i32 @L_owner(i32 \00" +@.str1002 = private unnamed_addr constant [2 x i8] c")\00" +@.str1003 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1004 = private unnamed_addr constant [10 x i8] c"set_owner\00" +@.str1005 = private unnamed_addr constant [30 x i8] c" call void @L_set_owner(i32 \00" +@.str1006 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1007 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1008 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1009 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1010 = private unnamed_addr constant [9 x i8] c"is_owner\00" +@.str1011 = private unnamed_addr constant [26 x i8] c"call i32 @L_is_owner(i32 \00" +@.str1012 = private unnamed_addr constant [2 x i8] c")\00" +@.str1013 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str1014 = private unnamed_addr constant [10 x i8] c"is_server\00" +@.str1015 = private unnamed_addr constant [22 x i8] c"load i32, ptr @L_role\00" +@.str1016 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" +@.str1017 = private unnamed_addr constant [4 x i8] c", 1\00" +@.str1018 = private unnamed_addr constant [9 x i8] c"zext i1 \00" +@.str1019 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str1020 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str1021 = private unnamed_addr constant [9 x i8] c"local_id\00" +@.str1022 = private unnamed_addr constant [25 x i8] c"load i32, ptr @L_localid\00" +@.str1023 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1024 = private unnamed_addr constant [9 x i8] c"net_pump\00" +@.str1025 = private unnamed_addr constant [27 x i8] c" call void @L_net_pump()\0A\00" +@.str1026 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1027 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1028 = private unnamed_addr constant [11 x i8] c"tick_fixed\00" +@.str1029 = private unnamed_addr constant [29 x i8] c" call void @L_tick_fixed()\0A\00" +@.str1030 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1031 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1032 = private unnamed_addr constant [12 x i8] c"tick_render\00" +@.str1033 = private unnamed_addr constant [30 x i8] c" call void @L_tick_render()\0A\00" +@.str1034 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1035 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1036 = private unnamed_addr constant [9 x i8] c"set_role\00" +@.str1037 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str1038 = private unnamed_addr constant [15 x i8] c", ptr @L_role\0A\00" +@.str1039 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1040 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1041 = private unnamed_addr constant [13 x i8] c"set_local_id\00" +@.str1042 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str1043 = private unnamed_addr constant [18 x i8] c", ptr @L_localid\0A\00" +@.str1044 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1045 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1046 = private unnamed_addr constant [9 x i8] c"net_send\00" +@.str1047 = private unnamed_addr constant [9 x i8] c"net_send\00" +@.str1048 = private unnamed_addr constant [29 x i8] c" call void @L_net_send(i32 \00" +@.str1049 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1050 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1051 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1052 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1053 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1054 = private unnamed_addr constant [9 x i8] c"net_poll\00" +@.str1055 = private unnamed_addr constant [9 x i8] c"net_poll\00" +@.str1056 = private unnamed_addr constant [26 x i8] c"call i32 @L_net_poll(ptr \00" +@.str1057 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1058 = private unnamed_addr constant [2 x i8] c")\00" +@.str1059 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1060 = private unnamed_addr constant [4 x i8] c"len\00" +@.str1061 = private unnamed_addr constant [5 x i8] c"push\00" +@.str1062 = private unnamed_addr constant [4 x i8] c"str\00" +@.str1063 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1064 = private unnamed_addr constant [26 x i8] c"call ptr @fn_int_str(i32 \00" +@.str1065 = private unnamed_addr constant [2 x i8] c")\00" +@.str1066 = private unnamed_addr constant [4 x i8] c"str\00" +@.str1067 = private unnamed_addr constant [6 x i8] c"print\00" @.str1068 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str1069 = private unnamed_addr constant [5 x i8] c"null\00" -@.str1070 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1071 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1072 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1073 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1074 = private unnamed_addr constant [22 x i8] c"cannot emit statement\00" -@.str1075 = private unnamed_addr constant [36 x i8] c"@L_running = internal global i32 1\0A\00" -@.str1076 = private unnamed_addr constant [32 x i8] c"@L_key = internal global i32 0\0A\00" -@.str1077 = private unnamed_addr constant [33 x i8] c"@L_entc = internal global i32 0\0A\00" -@.str1078 = private unnamed_addr constant [29 x i8] c"@L_alive = internal global [\00" -@.str1079 = private unnamed_addr constant [25 x i8] c" x i32] zeroinitializer\0A\00" -@.str1080 = private unnamed_addr constant [28 x i8] c"@L_kind = internal global [\00" -@.str1081 = private unnamed_addr constant [25 x i8] c" x i32] zeroinitializer\0A\00" -@.str1082 = private unnamed_addr constant [32 x i8] c"@L_freelist = internal global [\00" -@.str1083 = private unnamed_addr constant [25 x i8] c" x i32] zeroinitializer\0A\00" -@.str1084 = private unnamed_addr constant [34 x i8] c"@L_freen = internal global i32 0\0A\00" -@.str1085 = private unnamed_addr constant [4 x i8] c"@S_\00" -@.str1086 = private unnamed_addr constant [21 x i8] c" = internal global [\00" -@.str1087 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" -@.str1088 = private unnamed_addr constant [19 x i8] c"] zeroinitializer\0A\00" -@.str1089 = private unnamed_addr constant [4 x i8] c"@H_\00" -@.str1090 = private unnamed_addr constant [21 x i8] c" = internal global [\00" -@.str1091 = private unnamed_addr constant [24 x i8] c" x i8] zeroinitializer\0A\00" -@.str1092 = private unnamed_addr constant [5 x i8] c"@ME_\00" -@.str1093 = private unnamed_addr constant [26 x i8] c" = internal global i32 1\0A\00" -@.str1094 = private unnamed_addr constant [5 x i8] c"@HE_\00" -@.str1095 = private unnamed_addr constant [26 x i8] c" = internal global i32 1\0A\00" -@.str1096 = private unnamed_addr constant [39 x i8] c"define void @L_reset(i32 %e) {\0Aentry:\0A\00" -@.str1097 = private unnamed_addr constant [3 x i8] c"%h\00" -@.str1098 = private unnamed_addr constant [3 x i8] c" \00" -@.str1099 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1100 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" -@.str1101 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %e\0A\00" -@.str1102 = private unnamed_addr constant [19 x i8] c" store i8 0, ptr \00" -@.str1103 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1104 = private unnamed_addr constant [32 x i8] c" %k = getelementptr inbounds [\00" -@.str1105 = private unnamed_addr constant [37 x i8] c" x i32], ptr @L_kind, i32 0, i32 %e\0A\00" -@.str1106 = private unnamed_addr constant [37 x i8] c" store i32 0, ptr %k\0A ret void\0A}\0A\0A\00" -@.str1107 = private unnamed_addr constant [32 x i8] c"define i32 @L_alloc() {\0Aentry:\0A\00" -@.str1108 = private unnamed_addr constant [32 x i8] c" %fn = load i32, ptr @L_freen\0A\00" -@.str1109 = private unnamed_addr constant [30 x i8] c" %has = icmp sgt i32 %fn, 0\0A\00" -@.str1110 = private unnamed_addr constant [42 x i8] c" br i1 %has, label %reuse, label %fresh\0A\00" -@.str1111 = private unnamed_addr constant [8 x i8] c"reuse:\0A\00" -@.str1112 = private unnamed_addr constant [25 x i8] c" %fn1 = sub i32 %fn, 1\0A\00" -@.str1113 = private unnamed_addr constant [32 x i8] c" store i32 %fn1, ptr @L_freen\0A\00" -@.str1114 = private unnamed_addr constant [33 x i8] c" %fp = getelementptr inbounds [\00" -@.str1115 = private unnamed_addr constant [43 x i8] c" x i32], ptr @L_freelist, i32 0, i32 %fn1\0A\00" -@.str1116 = private unnamed_addr constant [27 x i8] c" %re = load i32, ptr %fp\0A\00" -@.str1117 = private unnamed_addr constant [18 x i8] c" br label %done\0A\00" -@.str1118 = private unnamed_addr constant [8 x i8] c"fresh:\0A\00" -@.str1119 = private unnamed_addr constant [31 x i8] c" %ec = load i32, ptr @L_entc\0A\00" -@.str1120 = private unnamed_addr constant [25 x i8] c" %ec1 = add i32 %ec, 1\0A\00" -@.str1121 = private unnamed_addr constant [31 x i8] c" store i32 %ec1, ptr @L_entc\0A\00" -@.str1122 = private unnamed_addr constant [18 x i8] c" br label %done\0A\00" -@.str1123 = private unnamed_addr constant [7 x i8] c"done:\0A\00" -@.str1124 = private unnamed_addr constant [49 x i8] c" %e = phi i32 [ %re, %reuse ], [ %ec, %fresh ]\0A\00" -@.str1125 = private unnamed_addr constant [30 x i8] c" call void @L_reset(i32 %e)\0A\00" -@.str1126 = private unnamed_addr constant [33 x i8] c" %ap = getelementptr inbounds [\00" -@.str1127 = private unnamed_addr constant [38 x i8] c" x i32], ptr @L_alive, i32 0, i32 %e\0A\00" -@.str1128 = private unnamed_addr constant [24 x i8] c" store i32 1, ptr %ap\0A\00" -@.str1129 = private unnamed_addr constant [17 x i8] c" ret i32 %e\0A}\0A\0A\00" -@.str1130 = private unnamed_addr constant [45 x i8] c"define void @L_free_entity(i32 %e) {\0Aentry:\0A\00" -@.str1131 = private unnamed_addr constant [33 x i8] c" %ap = getelementptr inbounds [\00" -@.str1132 = private unnamed_addr constant [38 x i8] c" x i32], ptr @L_alive, i32 0, i32 %e\0A\00" -@.str1133 = private unnamed_addr constant [24 x i8] c" store i32 0, ptr %ap\0A\00" -@.str1134 = private unnamed_addr constant [30 x i8] c" call void @L_reset(i32 %e)\0A\00" -@.str1135 = private unnamed_addr constant [32 x i8] c" %fn = load i32, ptr @L_freen\0A\00" -@.str1136 = private unnamed_addr constant [33 x i8] c" %fp = getelementptr inbounds [\00" -@.str1137 = private unnamed_addr constant [42 x i8] c" x i32], ptr @L_freelist, i32 0, i32 %fn\0A\00" -@.str1138 = private unnamed_addr constant [25 x i8] c" store i32 %e, ptr %fp\0A\00" -@.str1139 = private unnamed_addr constant [25 x i8] c" %fn1 = add i32 %fn, 1\0A\00" -@.str1140 = private unnamed_addr constant [32 x i8] c" store i32 %fn1, ptr @L_freen\0A\00" -@.str1141 = private unnamed_addr constant [15 x i8] c" ret void\0A}\0A\0A\00" -@.str1142 = private unnamed_addr constant [4 x i8] c"i32\00" -@.str1143 = private unnamed_addr constant [4 x i8] c"i32\00" -@.str1144 = private unnamed_addr constant [2 x i8] c"0\00" -@.str1145 = private unnamed_addr constant [6 x i8] c"qcond\00" -@.str1146 = private unnamed_addr constant [6 x i8] c"qbody\00" -@.str1147 = private unnamed_addr constant [6 x i8] c"qnext\00" -@.str1148 = private unnamed_addr constant [5 x i8] c"qend\00" -@.str1149 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1150 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1151 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1152 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str1153 = private unnamed_addr constant [22 x i8] c"load i32, ptr @L_entc\00" -@.str1154 = private unnamed_addr constant [14 x i8] c"icmp slt i32 \00" -@.str1155 = private unnamed_addr constant [3 x i8] c", \00" -@.str1156 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1157 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1158 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1159 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1160 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1161 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str1162 = private unnamed_addr constant [3 x i8] c" \00" -@.str1163 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1164 = private unnamed_addr constant [35 x i8] c" x i32], ptr @L_alive, i32 0, i32 \00" -@.str1165 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1166 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str1167 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" -@.str1168 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str1169 = private unnamed_addr constant [3 x i8] c"qa\00" -@.str1170 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1171 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1172 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1173 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1174 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1175 = private unnamed_addr constant [2 x i8] c"0\00" -@.str1176 = private unnamed_addr constant [3 x i8] c" \00" -@.str1177 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1178 = private unnamed_addr constant [34 x i8] c" x i32], ptr @L_kind, i32 0, i32 \00" -@.str1179 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1180 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str1181 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" -@.str1182 = private unnamed_addr constant [3 x i8] c", \00" -@.str1183 = private unnamed_addr constant [19 x i8] c"load i32, ptr @ME_\00" -@.str1184 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" -@.str1185 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str1186 = private unnamed_addr constant [8 x i8] c"and i1 \00" -@.str1187 = private unnamed_addr constant [3 x i8] c", \00" -@.str1188 = private unnamed_addr constant [3 x i8] c" \00" -@.str1189 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1190 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" -@.str1191 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str1192 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1193 = private unnamed_addr constant [14 x i8] c"load i8, ptr \00" -@.str1194 = private unnamed_addr constant [12 x i8] c"icmp ne i8 \00" -@.str1195 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str1196 = private unnamed_addr constant [3 x i8] c"qt\00" -@.str1197 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1198 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1199 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1200 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1201 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1202 = private unnamed_addr constant [3 x i8] c" \00" -@.str1203 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1204 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" -@.str1205 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" -@.str1206 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str1207 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1208 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str1209 = private unnamed_addr constant [13 x i8] c" store ptr \00" -@.str1210 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1211 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1212 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" -@.str1213 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str1214 = private unnamed_addr constant [3 x i8] c"qw\00" -@.str1215 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1216 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1217 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1218 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1219 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1220 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1221 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1222 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1223 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str1224 = private unnamed_addr constant [9 x i8] c"add i32 \00" -@.str1225 = private unnamed_addr constant [4 x i8] c", 1\00" -@.str1226 = private unnamed_addr constant [4 x i8] c"i32\00" -@.str1227 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1228 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1229 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1230 = private unnamed_addr constant [25 x i8] c"spawn: unknown property \00" -@.str1231 = private unnamed_addr constant [3 x i8] c" \00" -@.str1232 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1233 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" -@.str1234 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str1235 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1236 = private unnamed_addr constant [19 x i8] c" store i8 1, ptr \00" -@.str1237 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1238 = private unnamed_addr constant [3 x i8] c" \00" -@.str1239 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1240 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" -@.str1241 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" -@.str1242 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str1243 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1244 = private unnamed_addr constant [3 x i8] c" \00" -@.str1245 = private unnamed_addr constant [32 x i8] c" = getelementptr inbounds %Cmp_\00" -@.str1246 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1247 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str1248 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1249 = private unnamed_addr constant [2 x i8] c"0\00" -@.str1250 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str1251 = private unnamed_addr constant [5 x i8] c"null\00" -@.str1252 = private unnamed_addr constant [9 x i8] c" store \00" -@.str1253 = private unnamed_addr constant [2 x i8] c" \00" -@.str1254 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1255 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1256 = private unnamed_addr constant [3 x i8] c" \00" -@.str1257 = private unnamed_addr constant [32 x i8] c" = getelementptr inbounds %Cmp_\00" -@.str1258 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1259 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str1260 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1261 = private unnamed_addr constant [9 x i8] c" store \00" -@.str1262 = private unnamed_addr constant [2 x i8] c" \00" -@.str1263 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1264 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1265 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str1266 = private unnamed_addr constant [13 x i8] c" store ptr \00" -@.str1267 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1069 = private unnamed_addr constant [51 x i8] c" call i32 (ptr, ...) @printf(ptr @.fmt_line, ptr \00" +@.str1070 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1071 = private unnamed_addr constant [50 x i8] c" call i32 (ptr, ...) @printf(ptr @.fmt_int, i32 \00" +@.str1072 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1073 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1074 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1075 = private unnamed_addr constant [6 x i8] c"bytes\00" +@.str1076 = private unnamed_addr constant [10 x i8] c"zext i32 \00" +@.str1077 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str1078 = private unnamed_addr constant [22 x i8] c"call ptr @malloc(i64 \00" +@.str1079 = private unnamed_addr constant [2 x i8] c")\00" +@.str1080 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1081 = private unnamed_addr constant [6 x i8] c"words\00" +@.str1082 = private unnamed_addr constant [9 x i8] c"mul i32 \00" +@.str1083 = private unnamed_addr constant [4 x i8] c", 4\00" +@.str1084 = private unnamed_addr constant [10 x i8] c"zext i32 \00" +@.str1085 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str1086 = private unnamed_addr constant [22 x i8] c"call ptr @malloc(i64 \00" +@.str1087 = private unnamed_addr constant [2 x i8] c")\00" +@.str1088 = private unnamed_addr constant [6 x i8] c"words\00" +@.str1089 = private unnamed_addr constant [3 x i8] c"fx\00" +@.str1090 = private unnamed_addr constant [9 x i8] c"shl i32 \00" +@.str1091 = private unnamed_addr constant [5 x i8] c", 16\00" +@.str1092 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str1093 = private unnamed_addr constant [4 x i8] c"flr\00" +@.str1094 = private unnamed_addr constant [10 x i8] c"ashr i32 \00" +@.str1095 = private unnamed_addr constant [5 x i8] c", 16\00" +@.str1096 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1097 = private unnamed_addr constant [14 x i8] c"world_prop_id\00" +@.str1098 = private unnamed_addr constant [29 x i8] c"call i32 @ludic_prop_id(ptr \00" +@.str1099 = private unnamed_addr constant [2 x i8] c")\00" +@.str1100 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1101 = private unnamed_addr constant [15 x i8] c"world_field_id\00" +@.str1102 = private unnamed_addr constant [30 x i8] c"call i32 @ludic_field_id(i32 \00" +@.str1103 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1104 = private unnamed_addr constant [2 x i8] c")\00" +@.str1105 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1106 = private unnamed_addr constant [10 x i8] c"world_get\00" +@.str1107 = private unnamed_addr constant [25 x i8] c"call i64 @ludic_get(i32 \00" +@.str1108 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1109 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1110 = private unnamed_addr constant [2 x i8] c")\00" +@.str1111 = private unnamed_addr constant [11 x i8] c"trunc i64 \00" +@.str1112 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str1113 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1114 = private unnamed_addr constant [10 x i8] c"world_set\00" +@.str1115 = private unnamed_addr constant [10 x i8] c"sext i32 \00" +@.str1116 = private unnamed_addr constant [8 x i8] c" to i64\00" +@.str1117 = private unnamed_addr constant [28 x i8] c" call void @ludic_set(i32 \00" +@.str1118 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1119 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1120 = private unnamed_addr constant [7 x i8] c", i64 \00" +@.str1121 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1122 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1123 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1124 = private unnamed_addr constant [10 x i8] c"world_has\00" +@.str1125 = private unnamed_addr constant [25 x i8] c"call i32 @ludic_has(i32 \00" +@.str1126 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1127 = private unnamed_addr constant [2 x i8] c")\00" +@.str1128 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1129 = private unnamed_addr constant [12 x i8] c"world_count\00" +@.str1130 = private unnamed_addr constant [31 x i8] c"call i32 @ludic_entity_count()\00" +@.str1131 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1132 = private unnamed_addr constant [11 x i8] c"world_kind\00" +@.str1133 = private unnamed_addr constant [26 x i8] c"call i32 @ludic_kind(i32 \00" +@.str1134 = private unnamed_addr constant [2 x i8] c")\00" +@.str1135 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1136 = private unnamed_addr constant [15 x i8] c"world_model_id\00" +@.str1137 = private unnamed_addr constant [30 x i8] c"call i32 @ludic_model_id(ptr \00" +@.str1138 = private unnamed_addr constant [2 x i8] c")\00" +@.str1139 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1140 = private unnamed_addr constant [17 x i8] c"world_query_next\00" +@.str1141 = private unnamed_addr constant [32 x i8] c"call i32 @ludic_query_next(i32 \00" +@.str1142 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1143 = private unnamed_addr constant [2 x i8] c")\00" +@.str1144 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1145 = private unnamed_addr constant [20 x i8] c"world_register_prop\00" +@.str1146 = private unnamed_addr constant [35 x i8] c"call i32 @ludic_register_prop(ptr \00" +@.str1147 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1148 = private unnamed_addr constant [2 x i8] c")\00" +@.str1149 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1150 = private unnamed_addr constant [17 x i8] c"world_attach_dyn\00" +@.str1151 = private unnamed_addr constant [35 x i8] c" call void @ludic_attach_dyn(i32 \00" +@.str1152 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1153 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1154 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1155 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1156 = private unnamed_addr constant [17 x i8] c"world_detach_dyn\00" +@.str1157 = private unnamed_addr constant [35 x i8] c" call void @ludic_detach_dyn(i32 \00" +@.str1158 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1159 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1160 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1161 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1162 = private unnamed_addr constant [12 x i8] c"world_spawn\00" +@.str1163 = private unnamed_addr constant [27 x i8] c"call i32 @ludic_spawn(i32 \00" +@.str1164 = private unnamed_addr constant [2 x i8] c")\00" +@.str1165 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1166 = private unnamed_addr constant [3 x i8] c" \00" +@.str1167 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1168 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1169 = private unnamed_addr constant [4 x i8] c" = \00" +@.str1170 = private unnamed_addr constant [6 x i8] c"call \00" +@.str1171 = private unnamed_addr constant [3 x i8] c" @\00" +@.str1172 = private unnamed_addr constant [2 x i8] c"(\00" +@.str1173 = private unnamed_addr constant [3 x i8] c", \00" +@.str1174 = private unnamed_addr constant [2 x i8] c" \00" +@.str1175 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1176 = private unnamed_addr constant [4 x i8] c"rt_\00" +@.str1177 = private unnamed_addr constant [18 x i8] c"unknown function \00" +@.str1178 = private unnamed_addr constant [3 x i8] c" \00" +@.str1179 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1180 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1181 = private unnamed_addr constant [4 x i8] c" = \00" +@.str1182 = private unnamed_addr constant [6 x i8] c"call \00" +@.str1183 = private unnamed_addr constant [6 x i8] c" @fn_\00" +@.str1184 = private unnamed_addr constant [2 x i8] c"(\00" +@.str1185 = private unnamed_addr constant [3 x i8] c", \00" +@.str1186 = private unnamed_addr constant [2 x i8] c" \00" +@.str1187 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1188 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1189 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1190 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1191 = private unnamed_addr constant [6 x i8] c"fixed\00" +@.str1192 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str1193 = private unnamed_addr constant [5 x i8] c"null\00" +@.str1194 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1195 = private unnamed_addr constant [28 x i8] c"call ptr @fn_str_slice(ptr \00" +@.str1196 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1197 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str1198 = private unnamed_addr constant [2 x i8] c")\00" +@.str1199 = private unnamed_addr constant [4 x i8] c"str\00" +@.str1200 = private unnamed_addr constant [4 x i8] c"str\00" +@.str1201 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1202 = private unnamed_addr constant [6 x i8] c"load \00" +@.str1203 = private unnamed_addr constant [10 x i8] c", ptr @g_\00" +@.str1204 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1205 = private unnamed_addr constant [20 x i8] c"unknown identifier \00" +@.str1206 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1207 = private unnamed_addr constant [5 x i8] c"byte\00" +@.str1208 = private unnamed_addr constant [14 x i8] c"load i8, ptr \00" +@.str1209 = private unnamed_addr constant [9 x i8] c"zext i8 \00" +@.str1210 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str1211 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1212 = private unnamed_addr constant [2 x i8] c"-\00" +@.str1213 = private unnamed_addr constant [12 x i8] c"sub i32 0, \00" +@.str1214 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1215 = private unnamed_addr constant [2 x i8] c"~\00" +@.str1216 = private unnamed_addr constant [9 x i8] c"xor i32 \00" +@.str1217 = private unnamed_addr constant [5 x i8] c", -1\00" +@.str1218 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1219 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" +@.str1220 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1221 = private unnamed_addr constant [9 x i8] c"zext i1 \00" +@.str1222 = private unnamed_addr constant [8 x i8] c" to i32\00" +@.str1223 = private unnamed_addr constant [5 x i8] c"bool\00" +@.str1224 = private unnamed_addr constant [23 x i8] c"cannot emit expression\00" +@.str1225 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1226 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1227 = private unnamed_addr constant [9 x i8] c" store \00" +@.str1228 = private unnamed_addr constant [2 x i8] c" \00" +@.str1229 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1230 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1231 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1232 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1233 = private unnamed_addr constant [29 x i8] c"cannot assign to immutable '\00" +@.str1234 = private unnamed_addr constant [41 x i8] c"' (declared with let; use var) \E2\80\94 line \00" +@.str1235 = private unnamed_addr constant [19 x i8] c"assign to unknown \00" +@.str1236 = private unnamed_addr constant [4 x i8] c"@g_\00" +@.str1237 = private unnamed_addr constant [22 x i8] c"bad assignment target\00" +@.str1238 = private unnamed_addr constant [2 x i8] c"=\00" +@.str1239 = private unnamed_addr constant [6 x i8] c"load \00" +@.str1240 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1241 = private unnamed_addr constant [4 x i8] c"add\00" +@.str1242 = private unnamed_addr constant [3 x i8] c"-=\00" +@.str1243 = private unnamed_addr constant [4 x i8] c"sub\00" +@.str1244 = private unnamed_addr constant [3 x i8] c"*=\00" +@.str1245 = private unnamed_addr constant [4 x i8] c"mul\00" +@.str1246 = private unnamed_addr constant [3 x i8] c"/=\00" +@.str1247 = private unnamed_addr constant [5 x i8] c"sdiv\00" +@.str1248 = private unnamed_addr constant [6 x i8] c" i32 \00" +@.str1249 = private unnamed_addr constant [3 x i8] c", \00" +@.str1250 = private unnamed_addr constant [3 x i8] c"i8\00" +@.str1251 = private unnamed_addr constant [11 x i8] c"trunc i32 \00" +@.str1252 = private unnamed_addr constant [7 x i8] c" to i8\00" +@.str1253 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str1254 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1255 = private unnamed_addr constant [5 x i8] c"then\00" +@.str1256 = private unnamed_addr constant [5 x i8] c"else\00" +@.str1257 = private unnamed_addr constant [6 x i8] c"ifend\00" +@.str1258 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1259 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1260 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1261 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1262 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1263 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1264 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1265 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1266 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1267 = private unnamed_addr constant [13 x i8] c" br label %\00" @.str1268 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1269 = private unnamed_addr constant [3 x i8] c" \00" -@.str1270 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1271 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" -@.str1272 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" -@.str1273 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str1274 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1275 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str1276 = private unnamed_addr constant [13 x i8] c" store ptr \00" -@.str1277 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1278 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1279 = private unnamed_addr constant [20 x i8] c"call i32 @L_alloc()\00" -@.str1280 = private unnamed_addr constant [3 x i8] c" \00" -@.str1281 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1282 = private unnamed_addr constant [34 x i8] c" x i32], ptr @L_kind, i32 0, i32 \00" -@.str1283 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1284 = private unnamed_addr constant [13 x i8] c" store i32 \00" -@.str1285 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1286 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1287 = private unnamed_addr constant [3 x i8] c" \00" -@.str1288 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1289 = private unnamed_addr constant [34 x i8] c" x i32], ptr @L_kind, i32 0, i32 \00" -@.str1290 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1291 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" -@.str1292 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" -@.str1293 = private unnamed_addr constant [3 x i8] c", \00" -@.str1294 = private unnamed_addr constant [3 x i8] c"dh\00" -@.str1295 = private unnamed_addr constant [4 x i8] c"dhn\00" -@.str1296 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1297 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1298 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1299 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1300 = private unnamed_addr constant [27 x i8] c":\0A call void @on_despawn_\00" -@.str1301 = private unnamed_addr constant [6 x i8] c"(i32 \00" -@.str1302 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str1303 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1304 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1305 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1306 = private unnamed_addr constant [32 x i8] c" call void @L_free_entity(i32 \00" -@.str1307 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str1308 = private unnamed_addr constant [2 x i8] c"0\00" -@.str1309 = private unnamed_addr constant [2 x i8] c"1\00" -@.str1310 = private unnamed_addr constant [3 x i8] c" \00" -@.str1311 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1312 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" -@.str1313 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str1314 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1315 = private unnamed_addr constant [12 x i8] c" store i8 \00" -@.str1316 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1317 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1318 = private unnamed_addr constant [3 x i8] c" \00" -@.str1319 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" -@.str1320 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" -@.str1321 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" -@.str1322 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" -@.str1323 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1324 = private unnamed_addr constant [4 x i8] c"ptr\00" -@.str1325 = private unnamed_addr constant [13 x i8] c" store ptr \00" -@.str1326 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1327 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1328 = private unnamed_addr constant [5 x i8] c"@HE_\00" -@.str1329 = private unnamed_addr constant [5 x i8] c"@ME_\00" -@.str1330 = private unnamed_addr constant [13 x i8] c" store i32 \00" -@.str1331 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1332 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1333 = private unnamed_addr constant [5 x i8] c"void\00" -@.str1334 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" -@.str1335 = private unnamed_addr constant [17 x i8] c"ret:\0A ret void\0A\00" -@.str1336 = private unnamed_addr constant [18 x i8] c"define void @sys_\00" -@.str1337 = private unnamed_addr constant [13 x i8] c"() {\0Aentry:\0A\00" -@.str1338 = private unnamed_addr constant [4 x i8] c"}\0A\0A\00" -@.str1339 = private unnamed_addr constant [19 x i8] c"load i32, ptr @HE_\00" -@.str1340 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" -@.str1341 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str1342 = private unnamed_addr constant [5 x i8] c"hrun\00" -@.str1343 = private unnamed_addr constant [6 x i8] c"hskip\00" -@.str1344 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1345 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1346 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1269 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1270 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1271 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1272 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1273 = private unnamed_addr constant [6 x i8] c"wcond\00" +@.str1274 = private unnamed_addr constant [6 x i8] c"wbody\00" +@.str1275 = private unnamed_addr constant [5 x i8] c"wend\00" +@.str1276 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1277 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1278 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1279 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str1280 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1281 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1282 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1283 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1284 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1285 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1286 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1287 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1288 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1289 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str1290 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str1291 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1292 = private unnamed_addr constant [6 x i8] c"fcond\00" +@.str1293 = private unnamed_addr constant [6 x i8] c"fbody\00" +@.str1294 = private unnamed_addr constant [6 x i8] c"fcont\00" +@.str1295 = private unnamed_addr constant [5 x i8] c"fend\00" +@.str1296 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1297 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1298 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1299 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str1300 = private unnamed_addr constant [14 x i8] c"icmp slt i32 \00" +@.str1301 = private unnamed_addr constant [3 x i8] c", \00" +@.str1302 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1303 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1304 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1305 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1306 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1307 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1308 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1309 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1310 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str1311 = private unnamed_addr constant [9 x i8] c"add i32 \00" +@.str1312 = private unnamed_addr constant [4 x i8] c", 1\00" +@.str1313 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str1314 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1315 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1316 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1317 = private unnamed_addr constant [8 x i8] c"%retval\00" +@.str1318 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" +@.str1319 = private unnamed_addr constant [2 x i8] c"_\00" +@.str1320 = private unnamed_addr constant [5 x i8] c"mend\00" +@.str1321 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1322 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" +@.str1323 = private unnamed_addr constant [3 x i8] c", \00" +@.str1324 = private unnamed_addr constant [7 x i8] c"or i1 \00" +@.str1325 = private unnamed_addr constant [3 x i8] c", \00" +@.str1326 = private unnamed_addr constant [6 x i8] c"mbody\00" +@.str1327 = private unnamed_addr constant [5 x i8] c"marm\00" +@.str1328 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1329 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1330 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1331 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1332 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1333 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1334 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1335 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1336 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1337 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1338 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1339 = private unnamed_addr constant [21 x i8] c"emit: unknown event \00" +@.str1340 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1341 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1342 = private unnamed_addr constant [5 x i8] c"null\00" +@.str1343 = private unnamed_addr constant [3 x i8] c" \00" +@.str1344 = private unnamed_addr constant [53 x i8] c" = getelementptr inbounds i8, ptr @L_sendbuf, i32 0\0A\00" +@.str1345 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str1346 = private unnamed_addr constant [7 x i8] c", ptr \00" @.str1347 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1348 = private unnamed_addr constant [20 x i8] c":\0A call void @sys_\00" -@.str1349 = private unnamed_addr constant [4 x i8] c"()\0A\00" -@.str1350 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1351 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1352 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1353 = private unnamed_addr constant [5 x i8] c"void\00" -@.str1354 = private unnamed_addr constant [3 x i8] c"%e\00" -@.str1355 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" -@.str1356 = private unnamed_addr constant [17 x i8] c"ret:\0A ret void\0A\00" -@.str1357 = private unnamed_addr constant [25 x i8] c"define void @on_despawn_\00" -@.str1358 = private unnamed_addr constant [19 x i8] c"(i32 %e) {\0Aentry:\0A\00" -@.str1359 = private unnamed_addr constant [4 x i8] c"}\0A\0A\00" -@.str1360 = private unnamed_addr constant [49 x i8] c"define i32 @main(i32 %argc, ptr %argv) {\0Aentry:\0A\00" -@.str1361 = private unnamed_addr constant [32 x i8] c" store i32 %argc, ptr @L_argc\0A\00" -@.str1362 = private unnamed_addr constant [32 x i8] c" store ptr %argv, ptr @L_argv\0A\00" -@.str1363 = private unnamed_addr constant [8 x i8] c"rt_init\00" -@.str1364 = private unnamed_addr constant [27 x i8] c" call void @fn_rt_init()\0A\00" -@.str1365 = private unnamed_addr constant [6 x i8] c"Start\00" -@.str1366 = private unnamed_addr constant [18 x i8] c" br label %loop\0A\00" -@.str1367 = private unnamed_addr constant [7 x i8] c"loop:\0A\00" -@.str1368 = private unnamed_addr constant [25 x i8] c"load i32, ptr @L_running\00" -@.str1369 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" -@.str1370 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str1371 = private unnamed_addr constant [11 x i8] c"rt_running\00" -@.str1372 = private unnamed_addr constant [26 x i8] c"call i32 @fn_rt_running()\00" -@.str1373 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" -@.str1374 = private unnamed_addr constant [4 x i8] c", 0\00" -@.str1375 = private unnamed_addr constant [8 x i8] c"and i1 \00" -@.str1376 = private unnamed_addr constant [3 x i8] c", \00" -@.str1377 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1378 = private unnamed_addr constant [28 x i8] c", label %body, label %done\0A\00" -@.str1379 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1380 = private unnamed_addr constant [28 x i8] c", label %body, label %done\0A\00" -@.str1381 = private unnamed_addr constant [7 x i8] c"body:\0A\00" -@.str1382 = private unnamed_addr constant [8 x i8] c"rt_poll\00" -@.str1383 = private unnamed_addr constant [23 x i8] c"call i32 @fn_rt_poll()\00" -@.str1384 = private unnamed_addr constant [13 x i8] c" store i32 \00" -@.str1385 = private unnamed_addr constant [14 x i8] c", ptr @L_key\0A\00" -@.str1386 = private unnamed_addr constant [6 x i8] c"Input\00" -@.str1387 = private unnamed_addr constant [12 x i8] c"FixedUpdate\00" -@.str1388 = private unnamed_addr constant [7 x i8] c"Update\00" -@.str1389 = private unnamed_addr constant [11 x i8] c"LateUpdate\00" -@.str1390 = private unnamed_addr constant [7 x i8] c"Render\00" -@.str1391 = private unnamed_addr constant [18 x i8] c" br label %loop\0A\00" -@.str1392 = private unnamed_addr constant [7 x i8] c"done:\0A\00" -@.str1393 = private unnamed_addr constant [7 x i8] c"OnQuit\00" -@.str1394 = private unnamed_addr constant [12 x i8] c"rt_shutdown\00" -@.str1395 = private unnamed_addr constant [31 x i8] c" call void @fn_rt_shutdown()\0A\00" -@.str1396 = private unnamed_addr constant [15 x i8] c" ret i32 0\0A}\0A\00" -@.str1397 = private unnamed_addr constant [25 x i8] c"call i32 @fn_rt_reg(i32 \00" -@.str1398 = private unnamed_addr constant [2 x i8] c")\00" -@.str1399 = private unnamed_addr constant [6 x i8] c"smend\00" -@.str1400 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" -@.str1401 = private unnamed_addr constant [3 x i8] c", \00" -@.str1402 = private unnamed_addr constant [6 x i8] c"sbody\00" -@.str1403 = private unnamed_addr constant [5 x i8] c"sarm\00" -@.str1404 = private unnamed_addr constant [9 x i8] c" br i1 \00" -@.str1405 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1406 = private unnamed_addr constant [10 x i8] c", label %\00" -@.str1407 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1408 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1409 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1410 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1411 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1412 = private unnamed_addr constant [13 x i8] c" br label %\00" -@.str1413 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1414 = private unnamed_addr constant [3 x i8] c":\0A\00" -@.str1415 = private unnamed_addr constant [27 x i8] c"'become' outside a machine\00" -@.str1416 = private unnamed_addr constant [18 x i8] c"become: no state \00" -@.str1417 = private unnamed_addr constant [32 x i8] c" call void @fn_rt_set_reg(i32 \00" -@.str1418 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str1419 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str1420 = private unnamed_addr constant [4 x i8] c"%io\00" -@.str1421 = private unnamed_addr constant [3 x i8] c" \00" -@.str1422 = private unnamed_addr constant [14 x i8] c" = call i64 @\00" -@.str1423 = private unnamed_addr constant [6 x i8] c"(ptr \00" -@.str1424 = private unnamed_addr constant [14 x i8] c", i64 1, i64 \00" -@.str1425 = private unnamed_addr constant [11 x i8] c", ptr %f)\0A\00" -@.str1426 = private unnamed_addr constant [8 x i8] c"@L_entc\00" -@.str1427 = private unnamed_addr constant [2 x i8] c"4\00" -@.str1428 = private unnamed_addr constant [9 x i8] c"@L_freen\00" -@.str1429 = private unnamed_addr constant [2 x i8] c"4\00" -@.str1430 = private unnamed_addr constant [21 x i8] c" %nalive = mul i64 \00" -@.str1431 = private unnamed_addr constant [5 x i8] c", 4\0A\00" -@.str1432 = private unnamed_addr constant [9 x i8] c"@L_alive\00" -@.str1433 = private unnamed_addr constant [8 x i8] c"%nalive\00" -@.str1434 = private unnamed_addr constant [12 x i8] c"@L_freelist\00" -@.str1435 = private unnamed_addr constant [8 x i8] c"%nalive\00" -@.str1436 = private unnamed_addr constant [8 x i8] c"@L_kind\00" -@.str1437 = private unnamed_addr constant [8 x i8] c"%nalive\00" -@.str1438 = private unnamed_addr constant [4 x i8] c"@g_\00" -@.str1439 = private unnamed_addr constant [2 x i8] c"4\00" -@.str1440 = private unnamed_addr constant [5 x i8] c"%csz\00" -@.str1441 = private unnamed_addr constant [3 x i8] c" \00" -@.str1442 = private unnamed_addr constant [37 x i8] c" = ptrtoint ptr getelementptr (%Cmp_\00" -@.str1443 = private unnamed_addr constant [17 x i8] c", ptr null, i32 \00" -@.str1444 = private unnamed_addr constant [10 x i8] c") to i64\0A\00" -@.str1445 = private unnamed_addr constant [4 x i8] c"@S_\00" -@.str1446 = private unnamed_addr constant [4 x i8] c"@H_\00" -@.str1447 = private unnamed_addr constant [70 x i8] c"@.sav_path = private unnamed_addr constant [10 x i8] c\22ludic.sav\5C00\22\0A\00" -@.str1448 = private unnamed_addr constant [60 x i8] c"@.sav_wb = private unnamed_addr constant [3 x i8] c\22wb\5C00\22\0A\00" -@.str1449 = private unnamed_addr constant [60 x i8] c"@.sav_rb = private unnamed_addr constant [3 x i8] c\22rb\5C00\22\0A\00" -@.str1450 = private unnamed_addr constant [14 x i8] c"rt_save_state\00" -@.str1451 = private unnamed_addr constant [14 x i8] c"rt_load_state\00" -@.str1452 = private unnamed_addr constant [32 x i8] c"define void @L_save() {\0Aentry:\0A\00" -@.str1453 = private unnamed_addr constant [54 x i8] c" %f = call ptr @fopen(ptr @.sav_path, ptr @.sav_wb)\0A\00" -@.str1454 = private unnamed_addr constant [31 x i8] c" %bad = icmp eq ptr %f, null\0A\00" -@.str1455 = private unnamed_addr constant [41 x i8] c" br i1 %bad, label %out, label %go\0Ago:\0A\00" -@.str1456 = private unnamed_addr constant [7 x i8] c"fwrite\00" -@.str1457 = private unnamed_addr constant [39 x i8] c" call void @fn_rt_save_state(ptr %f)\0A\00" -@.str1458 = private unnamed_addr constant [68 x i8] c" %c = call i32 @fclose(ptr %f)\0A br label %out\0Aout:\0A ret void\0A}\0A\0A\00" -@.str1459 = private unnamed_addr constant [31 x i8] c"define i32 @L_load() {\0Aentry:\0A\00" -@.str1460 = private unnamed_addr constant [54 x i8] c" %f = call ptr @fopen(ptr @.sav_path, ptr @.sav_rb)\0A\00" -@.str1461 = private unnamed_addr constant [31 x i8] c" %bad = icmp eq ptr %f, null\0A\00" -@.str1462 = private unnamed_addr constant [60 x i8] c" br i1 %bad, label %miss, label %go\0Amiss:\0A ret i32 0\0Ago:\0A\00" -@.str1463 = private unnamed_addr constant [6 x i8] c"fread\00" -@.str1464 = private unnamed_addr constant [39 x i8] c" call void @fn_rt_load_state(ptr %f)\0A\00" -@.str1465 = private unnamed_addr constant [48 x i8] c" %c = call i32 @fclose(ptr %f)\0A ret i32 1\0A}\0A\0A\00" -@.str1466 = private unnamed_addr constant [6 x i8] c"panel\00" -@.str1467 = private unnamed_addr constant [4 x i8] c"col\00" -@.str1468 = private unnamed_addr constant [4 x i8] c"row\00" -@.str1469 = private unnamed_addr constant [6 x i8] c"label\00" -@.str1470 = private unnamed_addr constant [7 x i8] c"button\00" -@.str1471 = private unnamed_addr constant [6 x i8] c"image\00" -@.str1472 = private unnamed_addr constant [7 x i8] c"spacer\00" -@.str1473 = private unnamed_addr constant [3 x i8] c"id\00" -@.str1474 = private unnamed_addr constant [31 x i8] c" call void @fn_rt_ui_set(i32 \00" -@.str1475 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str1476 = private unnamed_addr constant [7 x i8] c", i32 \00" -@.str1477 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str1478 = private unnamed_addr constant [2 x i8] c"w\00" -@.str1479 = private unnamed_addr constant [2 x i8] c"h\00" -@.str1480 = private unnamed_addr constant [2 x i8] c"x\00" -@.str1481 = private unnamed_addr constant [2 x i8] c"y\00" -@.str1482 = private unnamed_addr constant [4 x i8] c"pad\00" -@.str1483 = private unnamed_addr constant [4 x i8] c"gap\00" -@.str1484 = private unnamed_addr constant [3 x i8] c"bg\00" -@.str1485 = private unnamed_addr constant [3 x i8] c"fg\00" -@.str1486 = private unnamed_addr constant [7 x i8] c"border\00" -@.str1487 = private unnamed_addr constant [5 x i8] c"grow\00" -@.str1488 = private unnamed_addr constant [5 x i8] c"font\00" -@.str1489 = private unnamed_addr constant [5 x i8] c"size\00" -@.str1490 = private unnamed_addr constant [6 x i8] c"inset\00" -@.str1491 = private unnamed_addr constant [6 x i8] c"focus\00" -@.str1492 = private unnamed_addr constant [33 x i8] c" call void @fn_rt_ui_reset(i32 \00" -@.str1493 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str1494 = private unnamed_addr constant [2 x i8] c"1\00" -@.str1495 = private unnamed_addr constant [3 x i8] c"id\00" -@.str1496 = private unnamed_addr constant [5 x i8] c"text\00" -@.str1497 = private unnamed_addr constant [39 x i8] c" call void @fn_rt_ui_static_text(i32 \00" -@.str1498 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1499 = private unnamed_addr constant [3 x i8] c")\0A\00" -@.str1500 = private unnamed_addr constant [5 x i8] c"skin\00" -@.str1501 = private unnamed_addr constant [6 x i8] c"image\00" -@.str1502 = private unnamed_addr constant [32 x i8] c"call i32 @fn_rt_image_load(ptr \00" -@.str1503 = private unnamed_addr constant [2 x i8] c")\00" -@.str1504 = private unnamed_addr constant [5 x i8] c"skin\00" -@.str1505 = private unnamed_addr constant [6 x i8] c"align\00" -@.str1506 = private unnamed_addr constant [7 x i8] c"center\00" -@.str1507 = private unnamed_addr constant [4 x i8] c"end\00" -@.str1508 = private unnamed_addr constant [2 x i8] c"1\00" -@.str1509 = private unnamed_addr constant [34 x i8] c"define void @ui_build() {\0Aentry:\0A\00" -@.str1510 = private unnamed_addr constant [15 x i8] c" ret void\0A}\0A\0A\00" +@.str1348 = private unnamed_addr constant [3 x i8] c" \00" +@.str1349 = private unnamed_addr constant [51 x i8] c" = getelementptr inbounds i8, ptr @L_sendbuf, i32 \00" +@.str1350 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1351 = private unnamed_addr constant [9 x i8] c" store \00" +@.str1352 = private unnamed_addr constant [2 x i8] c" \00" +@.str1353 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1354 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1355 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1356 = private unnamed_addr constant [10 x i8] c"toclients\00" +@.str1357 = private unnamed_addr constant [3 x i8] c"-1\00" +@.str1358 = private unnamed_addr constant [9 x i8] c"net_send\00" +@.str1359 = private unnamed_addr constant [14 x i8] c" call void @\00" +@.str1360 = private unnamed_addr constant [6 x i8] c"(i32 \00" +@.str1361 = private unnamed_addr constant [23 x i8] c", ptr @L_sendbuf, i32 \00" +@.str1362 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1363 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1364 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1365 = private unnamed_addr constant [3 x i8] c", \00" +@.str1366 = private unnamed_addr constant [2 x i8] c" \00" +@.str1367 = private unnamed_addr constant [3 x i8] c" \00" +@.str1368 = private unnamed_addr constant [17 x i8] c" = call i32 @ev_\00" +@.str1369 = private unnamed_addr constant [2 x i8] c"(\00" +@.str1370 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1371 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1372 = private unnamed_addr constant [17 x i8] c" call void @ev_\00" +@.str1373 = private unnamed_addr constant [2 x i8] c"(\00" +@.str1374 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1375 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1376 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1377 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1378 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1379 = private unnamed_addr constant [5 x i8] c"null\00" +@.str1380 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1381 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1382 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1383 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1384 = private unnamed_addr constant [44 x i8] c"cancel outside a cancellable event listener\00" +@.str1385 = private unnamed_addr constant [20 x i8] c" store i32 1, ptr \00" +@.str1386 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1387 = private unnamed_addr constant [22 x i8] c"cannot emit statement\00" +@.str1388 = private unnamed_addr constant [36 x i8] c"@L_running = internal global i32 1\0A\00" +@.str1389 = private unnamed_addr constant [32 x i8] c"@L_key = internal global i32 0\0A\00" +@.str1390 = private unnamed_addr constant [34 x i8] c"@L_scene = internal global i32 0\0A\00" +@.str1391 = private unnamed_addr constant [33 x i8] c"@L_entc = internal global i32 0\0A\00" +@.str1392 = private unnamed_addr constant [29 x i8] c"@L_alive = internal global [\00" +@.str1393 = private unnamed_addr constant [25 x i8] c" x i32] zeroinitializer\0A\00" +@.str1394 = private unnamed_addr constant [28 x i8] c"@L_kind = internal global [\00" +@.str1395 = private unnamed_addr constant [25 x i8] c" x i32] zeroinitializer\0A\00" +@.str1396 = private unnamed_addr constant [32 x i8] c"@L_freelist = internal global [\00" +@.str1397 = private unnamed_addr constant [25 x i8] c" x i32] zeroinitializer\0A\00" +@.str1398 = private unnamed_addr constant [34 x i8] c"@L_freen = internal global i32 0\0A\00" +@.str1399 = private unnamed_addr constant [33 x i8] c"@L_role = internal global i32 1\0A\00" +@.str1400 = private unnamed_addr constant [36 x i8] c"@L_localid = internal global i32 0\0A\00" +@.str1401 = private unnamed_addr constant [33 x i8] c"@L_owner_arr = internal global [\00" +@.str1402 = private unnamed_addr constant [25 x i8] c" x i32] zeroinitializer\0A\00" +@.str1403 = private unnamed_addr constant [4 x i8] c"@S_\00" +@.str1404 = private unnamed_addr constant [21 x i8] c" = internal global [\00" +@.str1405 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" +@.str1406 = private unnamed_addr constant [19 x i8] c"] zeroinitializer\0A\00" +@.str1407 = private unnamed_addr constant [4 x i8] c"@H_\00" +@.str1408 = private unnamed_addr constant [21 x i8] c" = internal global [\00" +@.str1409 = private unnamed_addr constant [24 x i8] c" x i8] zeroinitializer\0A\00" +@.str1410 = private unnamed_addr constant [5 x i8] c"@ME_\00" +@.str1411 = private unnamed_addr constant [26 x i8] c" = internal global i32 1\0A\00" +@.str1412 = private unnamed_addr constant [5 x i8] c"@HE_\00" +@.str1413 = private unnamed_addr constant [26 x i8] c" = internal global i32 1\0A\00" +@.str1414 = private unnamed_addr constant [5 x i8] c"@LE_\00" +@.str1415 = private unnamed_addr constant [26 x i8] c" = internal global i32 1\0A\00" +@.str1416 = private unnamed_addr constant [39 x i8] c"define void @L_reset(i32 %e) {\0Aentry:\0A\00" +@.str1417 = private unnamed_addr constant [3 x i8] c"%h\00" +@.str1418 = private unnamed_addr constant [3 x i8] c" \00" +@.str1419 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1420 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" +@.str1421 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %e\0A\00" +@.str1422 = private unnamed_addr constant [19 x i8] c" store i8 0, ptr \00" +@.str1423 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1424 = private unnamed_addr constant [32 x i8] c" %k = getelementptr inbounds [\00" +@.str1425 = private unnamed_addr constant [37 x i8] c" x i32], ptr @L_kind, i32 0, i32 %e\0A\00" +@.str1426 = private unnamed_addr constant [23 x i8] c" store i32 0, ptr %k\0A\00" +@.str1427 = private unnamed_addr constant [33 x i8] c" %ow = getelementptr inbounds [\00" +@.str1428 = private unnamed_addr constant [42 x i8] c" x i32], ptr @L_owner_arr, i32 0, i32 %e\0A\00" +@.str1429 = private unnamed_addr constant [25 x i8] c" store i32 -1, ptr %ow\0A\00" +@.str1430 = private unnamed_addr constant [15 x i8] c" ret void\0A}\0A\0A\00" +@.str1431 = private unnamed_addr constant [32 x i8] c"define i32 @L_alloc() {\0Aentry:\0A\00" +@.str1432 = private unnamed_addr constant [32 x i8] c" %fn = load i32, ptr @L_freen\0A\00" +@.str1433 = private unnamed_addr constant [30 x i8] c" %has = icmp sgt i32 %fn, 0\0A\00" +@.str1434 = private unnamed_addr constant [42 x i8] c" br i1 %has, label %reuse, label %fresh\0A\00" +@.str1435 = private unnamed_addr constant [8 x i8] c"reuse:\0A\00" +@.str1436 = private unnamed_addr constant [25 x i8] c" %fn1 = sub i32 %fn, 1\0A\00" +@.str1437 = private unnamed_addr constant [32 x i8] c" store i32 %fn1, ptr @L_freen\0A\00" +@.str1438 = private unnamed_addr constant [33 x i8] c" %fp = getelementptr inbounds [\00" +@.str1439 = private unnamed_addr constant [43 x i8] c" x i32], ptr @L_freelist, i32 0, i32 %fn1\0A\00" +@.str1440 = private unnamed_addr constant [27 x i8] c" %re = load i32, ptr %fp\0A\00" +@.str1441 = private unnamed_addr constant [18 x i8] c" br label %done\0A\00" +@.str1442 = private unnamed_addr constant [8 x i8] c"fresh:\0A\00" +@.str1443 = private unnamed_addr constant [31 x i8] c" %ec = load i32, ptr @L_entc\0A\00" +@.str1444 = private unnamed_addr constant [25 x i8] c" %ec1 = add i32 %ec, 1\0A\00" +@.str1445 = private unnamed_addr constant [31 x i8] c" store i32 %ec1, ptr @L_entc\0A\00" +@.str1446 = private unnamed_addr constant [18 x i8] c" br label %done\0A\00" +@.str1447 = private unnamed_addr constant [7 x i8] c"done:\0A\00" +@.str1448 = private unnamed_addr constant [49 x i8] c" %e = phi i32 [ %re, %reuse ], [ %ec, %fresh ]\0A\00" +@.str1449 = private unnamed_addr constant [30 x i8] c" call void @L_reset(i32 %e)\0A\00" +@.str1450 = private unnamed_addr constant [33 x i8] c" %ap = getelementptr inbounds [\00" +@.str1451 = private unnamed_addr constant [38 x i8] c" x i32], ptr @L_alive, i32 0, i32 %e\0A\00" +@.str1452 = private unnamed_addr constant [24 x i8] c" store i32 1, ptr %ap\0A\00" +@.str1453 = private unnamed_addr constant [17 x i8] c" ret i32 %e\0A}\0A\0A\00" +@.str1454 = private unnamed_addr constant [45 x i8] c"define void @L_free_entity(i32 %e) {\0Aentry:\0A\00" +@.str1455 = private unnamed_addr constant [33 x i8] c" %ap = getelementptr inbounds [\00" +@.str1456 = private unnamed_addr constant [38 x i8] c" x i32], ptr @L_alive, i32 0, i32 %e\0A\00" +@.str1457 = private unnamed_addr constant [24 x i8] c" store i32 0, ptr %ap\0A\00" +@.str1458 = private unnamed_addr constant [30 x i8] c" call void @L_reset(i32 %e)\0A\00" +@.str1459 = private unnamed_addr constant [32 x i8] c" %fn = load i32, ptr @L_freen\0A\00" +@.str1460 = private unnamed_addr constant [33 x i8] c" %fp = getelementptr inbounds [\00" +@.str1461 = private unnamed_addr constant [42 x i8] c" x i32], ptr @L_freelist, i32 0, i32 %fn\0A\00" +@.str1462 = private unnamed_addr constant [25 x i8] c" store i32 %e, ptr %fp\0A\00" +@.str1463 = private unnamed_addr constant [25 x i8] c" %fn1 = add i32 %fn, 1\0A\00" +@.str1464 = private unnamed_addr constant [32 x i8] c" store i32 %fn1, ptr @L_freen\0A\00" +@.str1465 = private unnamed_addr constant [15 x i8] c" ret void\0A}\0A\0A\00" +@.str1466 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str1467 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str1468 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1469 = private unnamed_addr constant [6 x i8] c"qcond\00" +@.str1470 = private unnamed_addr constant [6 x i8] c"qbody\00" +@.str1471 = private unnamed_addr constant [6 x i8] c"qnext\00" +@.str1472 = private unnamed_addr constant [5 x i8] c"qend\00" +@.str1473 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1474 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1475 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1476 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str1477 = private unnamed_addr constant [22 x i8] c"load i32, ptr @L_entc\00" +@.str1478 = private unnamed_addr constant [14 x i8] c"icmp slt i32 \00" +@.str1479 = private unnamed_addr constant [3 x i8] c", \00" +@.str1480 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1481 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1482 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1483 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1484 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1485 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str1486 = private unnamed_addr constant [3 x i8] c" \00" +@.str1487 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1488 = private unnamed_addr constant [35 x i8] c" x i32], ptr @L_alive, i32 0, i32 \00" +@.str1489 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1490 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str1491 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str1492 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1493 = private unnamed_addr constant [3 x i8] c"qa\00" +@.str1494 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1495 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1496 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1497 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1498 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1499 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1500 = private unnamed_addr constant [3 x i8] c" \00" +@.str1501 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1502 = private unnamed_addr constant [34 x i8] c" x i32], ptr @L_kind, i32 0, i32 \00" +@.str1503 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1504 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str1505 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" +@.str1506 = private unnamed_addr constant [3 x i8] c", \00" +@.str1507 = private unnamed_addr constant [19 x i8] c"load i32, ptr @ME_\00" +@.str1508 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str1509 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1510 = private unnamed_addr constant [8 x i8] c"and i1 \00" @.str1511 = private unnamed_addr constant [3 x i8] c", \00" -@.str1512 = private unnamed_addr constant [7 x i8] c" %arg_\00" -@.str1513 = private unnamed_addr constant [5 x i8] c"void\00" -@.str1514 = private unnamed_addr constant [20 x i8] c" %retval = alloca \00" -@.str1515 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1516 = private unnamed_addr constant [9 x i8] c" store \00" -@.str1517 = private unnamed_addr constant [7 x i8] c" %arg_\00" -@.str1518 = private unnamed_addr constant [7 x i8] c", ptr \00" -@.str1519 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1520 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" -@.str1521 = private unnamed_addr constant [6 x i8] c"ret:\0A\00" -@.str1522 = private unnamed_addr constant [5 x i8] c"void\00" -@.str1523 = private unnamed_addr constant [12 x i8] c" ret void\0A\00" -@.str1524 = private unnamed_addr constant [6 x i8] c"load \00" -@.str1525 = private unnamed_addr constant [14 x i8] c", ptr %retval\00" -@.str1526 = private unnamed_addr constant [7 x i8] c" ret \00" -@.str1527 = private unnamed_addr constant [2 x i8] c" \00" -@.str1528 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1529 = private unnamed_addr constant [8 x i8] c"define \00" -@.str1530 = private unnamed_addr constant [6 x i8] c" @fn_\00" -@.str1531 = private unnamed_addr constant [2 x i8] c"(\00" -@.str1532 = private unnamed_addr constant [12 x i8] c") {\0Aentry:\0A\00" -@.str1533 = private unnamed_addr constant [4 x i8] c"}\0A\0A\00" -@.str1534 = private unnamed_addr constant [4 x i8] c"int\00" -@.str1535 = private unnamed_addr constant [24 x i8] c" %retval = alloca i32\0A\00" -@.str1536 = private unnamed_addr constant [32 x i8] c" store i32 %argc, ptr @L_argc\0A\00" -@.str1537 = private unnamed_addr constant [32 x i8] c" store ptr %argv, ptr @L_argv\0A\00" -@.str1538 = private unnamed_addr constant [28 x i8] c" store i32 0, ptr %retval\0A\00" -@.str1539 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" -@.str1540 = private unnamed_addr constant [6 x i8] c"ret:\0A\00" -@.str1541 = private unnamed_addr constant [22 x i8] c"load i32, ptr %retval\00" -@.str1542 = private unnamed_addr constant [11 x i8] c" ret i32 \00" -@.str1543 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1544 = private unnamed_addr constant [49 x i8] c"define i32 @main(i32 %argc, ptr %argv) {\0Aentry:\0A\00" -@.str1545 = private unnamed_addr constant [3 x i8] c"}\0A\00" -@.str1546 = private unnamed_addr constant [3 x i8] c"wb\00" -@.str1547 = private unnamed_addr constant [7 x i8] c".ludic\00" -@.str1548 = private unnamed_addr constant [2 x i8] c"/\00" -@.str1549 = private unnamed_addr constant [6 x i8] c"ludic\00" -@.str1550 = private unnamed_addr constant [11 x i8] c"--windowed\00" -@.str1551 = private unnamed_addr constant [11 x i8] c"--headless\00" -@.str1552 = private unnamed_addr constant [12 x i8] c"--emit-llvm\00" -@.str1553 = private unnamed_addr constant [6 x i8] c"--fmt\00" -@.str1554 = private unnamed_addr constant [13 x i8] c"--save-temps\00" -@.str1555 = private unnamed_addr constant [6 x i8] c"--run\00" -@.str1556 = private unnamed_addr constant [3 x i8] c"-o\00" -@.str1557 = private unnamed_addr constant [31 x i8] c"ludicc: ignoring unknown flag \00" -@.str1558 = private unnamed_addr constant [2 x i8] c"\0A\00" -@.str1559 = private unnamed_addr constant [90 x i8] c"usage: ludicc [-o out] [--windowed|--headless] [--emit-llvm] [--save-temps]\0A\00" -@.str1560 = private unnamed_addr constant [27 x i8] c"ludicc: cannot open input\0A\00" -@.str1561 = private unnamed_addr constant [16 x i8] c"/tmp/ludic-run-\00" -@.str1562 = private unnamed_addr constant [10 x i8] c"mkdir -p \00" -@.str1563 = private unnamed_addr constant [4 x i8] c".ll\00" -@.str1564 = private unnamed_addr constant [25 x i8] c"ludicc: cannot write IR\0A\00" -@.str1565 = private unnamed_addr constant [9 x i8] c"LUDIC_CC\00" -@.str1566 = private unnamed_addr constant [6 x i8] c"clang\00" -@.str1567 = private unnamed_addr constant [11 x i8] c"LUDIC_HOME\00" -@.str1568 = private unnamed_addr constant [27 x i8] c" -O2 -Wno-override-module \00" -@.str1569 = private unnamed_addr constant [24 x i8] c"runtime/native/cocoa.ll\00" -@.str1570 = private unnamed_addr constant [2 x i8] c" \00" -@.str1571 = private unnamed_addr constant [42 x i8] c" -framework Cocoa -Wl,-rpath,@loader_path\00" -@.str1572 = private unnamed_addr constant [5 x i8] c" -o \00" -@.str1573 = private unnamed_addr constant [7 x i8] c"rm -f \00" -@.str1574 = private unnamed_addr constant [21 x i8] c"ludicc: link failed\0A\00" +@.str1512 = private unnamed_addr constant [3 x i8] c" \00" +@.str1513 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1514 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" +@.str1515 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1516 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1517 = private unnamed_addr constant [14 x i8] c"load i8, ptr \00" +@.str1518 = private unnamed_addr constant [12 x i8] c"icmp ne i8 \00" +@.str1519 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1520 = private unnamed_addr constant [3 x i8] c"qt\00" +@.str1521 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1522 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1523 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1524 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1525 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1526 = private unnamed_addr constant [3 x i8] c" \00" +@.str1527 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1528 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" +@.str1529 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" +@.str1530 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1531 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1532 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1533 = private unnamed_addr constant [13 x i8] c" store ptr \00" +@.str1534 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1535 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1536 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str1537 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1538 = private unnamed_addr constant [3 x i8] c"qw\00" +@.str1539 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1540 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1541 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1542 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1543 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1544 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1545 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1546 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1547 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str1548 = private unnamed_addr constant [9 x i8] c"add i32 \00" +@.str1549 = private unnamed_addr constant [4 x i8] c", 1\00" +@.str1550 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str1551 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1552 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1553 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1554 = private unnamed_addr constant [25 x i8] c"spawn: unknown property \00" +@.str1555 = private unnamed_addr constant [3 x i8] c" \00" +@.str1556 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1557 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" +@.str1558 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1559 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1560 = private unnamed_addr constant [19 x i8] c" store i8 1, ptr \00" +@.str1561 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1562 = private unnamed_addr constant [3 x i8] c" \00" +@.str1563 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1564 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" +@.str1565 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" +@.str1566 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1567 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1568 = private unnamed_addr constant [3 x i8] c" \00" +@.str1569 = private unnamed_addr constant [32 x i8] c" = getelementptr inbounds %Cmp_\00" +@.str1570 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1571 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1572 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1573 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1574 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1575 = private unnamed_addr constant [5 x i8] c"null\00" +@.str1576 = private unnamed_addr constant [9 x i8] c" store \00" +@.str1577 = private unnamed_addr constant [2 x i8] c" \00" +@.str1578 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1579 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1580 = private unnamed_addr constant [3 x i8] c" \00" +@.str1581 = private unnamed_addr constant [32 x i8] c" = getelementptr inbounds %Cmp_\00" +@.str1582 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1583 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1584 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1585 = private unnamed_addr constant [9 x i8] c" store \00" +@.str1586 = private unnamed_addr constant [2 x i8] c" \00" +@.str1587 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1588 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1589 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1590 = private unnamed_addr constant [13 x i8] c" store ptr \00" +@.str1591 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1592 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1593 = private unnamed_addr constant [6 x i8] c"prop_\00" +@.str1594 = private unnamed_addr constant [8 x i8] c"_attach\00" +@.str1595 = private unnamed_addr constant [17 x i8] c" call void @ev_\00" +@.str1596 = private unnamed_addr constant [6 x i8] c"(i32 \00" +@.str1597 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1598 = private unnamed_addr constant [3 x i8] c" \00" +@.str1599 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1600 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" +@.str1601 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" +@.str1602 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1603 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1604 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1605 = private unnamed_addr constant [13 x i8] c" store ptr \00" +@.str1606 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1607 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1608 = private unnamed_addr constant [20 x i8] c"call i32 @L_alloc()\00" +@.str1609 = private unnamed_addr constant [3 x i8] c" \00" +@.str1610 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1611 = private unnamed_addr constant [34 x i8] c" x i32], ptr @L_kind, i32 0, i32 \00" +@.str1612 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1613 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str1614 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1615 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1616 = private unnamed_addr constant [7 x i8] c"model_\00" +@.str1617 = private unnamed_addr constant [7 x i8] c"_spawn\00" +@.str1618 = private unnamed_addr constant [17 x i8] c" call void @ev_\00" +@.str1619 = private unnamed_addr constant [6 x i8] c"(i32 \00" +@.str1620 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1621 = private unnamed_addr constant [3 x i8] c" \00" +@.str1622 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1623 = private unnamed_addr constant [34 x i8] c" x i32], ptr @L_kind, i32 0, i32 \00" +@.str1624 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1625 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str1626 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" +@.str1627 = private unnamed_addr constant [3 x i8] c", \00" +@.str1628 = private unnamed_addr constant [3 x i8] c"dh\00" +@.str1629 = private unnamed_addr constant [4 x i8] c"dhn\00" +@.str1630 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1631 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1632 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1633 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1634 = private unnamed_addr constant [27 x i8] c":\0A call void @on_despawn_\00" +@.str1635 = private unnamed_addr constant [6 x i8] c"(i32 \00" +@.str1636 = private unnamed_addr constant [10 x i8] c", i32 0)\0A\00" +@.str1637 = private unnamed_addr constant [7 x i8] c"model_\00" +@.str1638 = private unnamed_addr constant [9 x i8] c"_despawn\00" +@.str1639 = private unnamed_addr constant [17 x i8] c" call void @ev_\00" +@.str1640 = private unnamed_addr constant [6 x i8] c"(i32 \00" +@.str1641 = private unnamed_addr constant [10 x i8] c", i32 0)\0A\00" +@.str1642 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1643 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1644 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1645 = private unnamed_addr constant [37 x i8] c" call void @ludic_sweep_entity(i32 \00" +@.str1646 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1647 = private unnamed_addr constant [32 x i8] c" call void @L_free_entity(i32 \00" +@.str1648 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1649 = private unnamed_addr constant [3 x i8] c" \00" +@.str1650 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1651 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" +@.str1652 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1653 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1654 = private unnamed_addr constant [14 x i8] c"load i8, ptr \00" +@.str1655 = private unnamed_addr constant [12 x i8] c"icmp eq i8 \00" +@.str1656 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1657 = private unnamed_addr constant [7 x i8] c"attach\00" +@.str1658 = private unnamed_addr constant [8 x i8] c"attdone\00" +@.str1659 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1660 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1661 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1662 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1663 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1664 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1665 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1666 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1667 = private unnamed_addr constant [3 x i8] c" \00" +@.str1668 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1669 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" +@.str1670 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1671 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1672 = private unnamed_addr constant [14 x i8] c"load i8, ptr \00" +@.str1673 = private unnamed_addr constant [12 x i8] c"icmp ne i8 \00" +@.str1674 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1675 = private unnamed_addr constant [7 x i8] c"detach\00" +@.str1676 = private unnamed_addr constant [8 x i8] c"detdone\00" +@.str1677 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1678 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1679 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1680 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1681 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1682 = private unnamed_addr constant [19 x i8] c" store i8 0, ptr \00" +@.str1683 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1684 = private unnamed_addr constant [3 x i8] c" \00" +@.str1685 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1686 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" +@.str1687 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" +@.str1688 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1689 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1690 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1691 = private unnamed_addr constant [13 x i8] c" store ptr \00" +@.str1692 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1693 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1694 = private unnamed_addr constant [6 x i8] c"prop_\00" +@.str1695 = private unnamed_addr constant [8 x i8] c"_detach\00" +@.str1696 = private unnamed_addr constant [17 x i8] c" call void @ev_\00" +@.str1697 = private unnamed_addr constant [6 x i8] c"(i32 \00" +@.str1698 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1699 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1700 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1701 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1702 = private unnamed_addr constant [2 x i8] c"0\00" +@.str1703 = private unnamed_addr constant [2 x i8] c"1\00" +@.str1704 = private unnamed_addr constant [6 x i8] c"layer\00" +@.str1705 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str1706 = private unnamed_addr constant [11 x i8] c", ptr @LE_\00" +@.str1707 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1708 = private unnamed_addr constant [7 x i8] c"layer_\00" +@.str1709 = private unnamed_addr constant [6 x i8] c"_hide\00" +@.str1710 = private unnamed_addr constant [7 x i8] c"layer_\00" +@.str1711 = private unnamed_addr constant [6 x i8] c"_show\00" +@.str1712 = private unnamed_addr constant [17 x i8] c" call void @ev_\00" +@.str1713 = private unnamed_addr constant [4 x i8] c"()\0A\00" +@.str1714 = private unnamed_addr constant [3 x i8] c" \00" +@.str1715 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1716 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" +@.str1717 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1718 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1719 = private unnamed_addr constant [12 x i8] c" store i8 \00" +@.str1720 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1721 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1722 = private unnamed_addr constant [3 x i8] c" \00" +@.str1723 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1724 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" +@.str1725 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" +@.str1726 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1727 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1728 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str1729 = private unnamed_addr constant [13 x i8] c" store ptr \00" +@.str1730 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1731 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1732 = private unnamed_addr constant [6 x i8] c"prop_\00" +@.str1733 = private unnamed_addr constant [9 x i8] c"_disable\00" +@.str1734 = private unnamed_addr constant [6 x i8] c"prop_\00" +@.str1735 = private unnamed_addr constant [8 x i8] c"_enable\00" +@.str1736 = private unnamed_addr constant [17 x i8] c" call void @ev_\00" +@.str1737 = private unnamed_addr constant [6 x i8] c"(i32 \00" +@.str1738 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1739 = private unnamed_addr constant [5 x i8] c"@HE_\00" +@.str1740 = private unnamed_addr constant [5 x i8] c"@ME_\00" +@.str1741 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str1742 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1743 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1744 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1745 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" +@.str1746 = private unnamed_addr constant [17 x i8] c"ret:\0A ret void\0A\00" +@.str1747 = private unnamed_addr constant [18 x i8] c"define void @sys_\00" +@.str1748 = private unnamed_addr constant [13 x i8] c"() {\0Aentry:\0A\00" +@.str1749 = private unnamed_addr constant [4 x i8] c"}\0A\0A\00" +@.str1750 = private unnamed_addr constant [19 x i8] c"load i32, ptr @HE_\00" +@.str1751 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str1752 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1753 = private unnamed_addr constant [19 x i8] c"load i32, ptr @LE_\00" +@.str1754 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str1755 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str1756 = private unnamed_addr constant [8 x i8] c"and i1 \00" +@.str1757 = private unnamed_addr constant [3 x i8] c", \00" +@.str1758 = private unnamed_addr constant [22 x i8] c"load i32, ptr @L_role\00" +@.str1759 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" +@.str1760 = private unnamed_addr constant [4 x i8] c", 1\00" +@.str1761 = private unnamed_addr constant [8 x i8] c"and i1 \00" +@.str1762 = private unnamed_addr constant [3 x i8] c", \00" +@.str1763 = private unnamed_addr constant [5 x i8] c"hrun\00" +@.str1764 = private unnamed_addr constant [6 x i8] c"hskip\00" +@.str1765 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1766 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1767 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1768 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1769 = private unnamed_addr constant [20 x i8] c":\0A call void @sys_\00" +@.str1770 = private unnamed_addr constant [4 x i8] c"()\0A\00" +@.str1771 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1772 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1773 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1774 = private unnamed_addr constant [23 x i8] c"load i32, ptr @L_scene\00" +@.str1775 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" +@.str1776 = private unnamed_addr constant [3 x i8] c", \00" +@.str1777 = private unnamed_addr constant [6 x i8] c"scrun\00" +@.str1778 = private unnamed_addr constant [7 x i8] c"scskip\00" +@.str1779 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1780 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1781 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1782 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1783 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1784 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1785 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1786 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1787 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1788 = private unnamed_addr constant [7 x i8] c"scene_\00" +@.str1789 = private unnamed_addr constant [2 x i8] c"_\00" +@.str1790 = private unnamed_addr constant [17 x i8] c" call void @ev_\00" +@.str1791 = private unnamed_addr constant [4 x i8] c"()\0A\00" +@.str1792 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" +@.str1793 = private unnamed_addr constant [17 x i8] c"ret:\0A ret void\0A\00" +@.str1794 = private unnamed_addr constant [20 x i8] c"define void @scene_\00" +@.str1795 = private unnamed_addr constant [2 x i8] c"_\00" +@.str1796 = private unnamed_addr constant [13 x i8] c"() {\0Aentry:\0A\00" +@.str1797 = private unnamed_addr constant [4 x i8] c"}\0A\0A\00" +@.str1798 = private unnamed_addr constant [6 x i8] c"enter\00" +@.str1799 = private unnamed_addr constant [5 x i8] c"exit\00" +@.str1800 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1801 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str1802 = private unnamed_addr constant [26 x i8] c" store i32 %reason, ptr \00" +@.str1803 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1804 = private unnamed_addr constant [4 x i8] c"int\00" +@.str1805 = private unnamed_addr constant [3 x i8] c"%e\00" +@.str1806 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" +@.str1807 = private unnamed_addr constant [17 x i8] c"ret:\0A ret void\0A\00" +@.str1808 = private unnamed_addr constant [25 x i8] c"define void @on_despawn_\00" +@.str1809 = private unnamed_addr constant [32 x i8] c"(i32 %e, i32 %reason) {\0Aentry:\0A\00" +@.str1810 = private unnamed_addr constant [4 x i8] c"}\0A\0A\00" +@.str1811 = private unnamed_addr constant [67 x i8] c"define void @L_despawn_all(i32 %reason) {\0Aentry:\0A br label %loop\0A\00" +@.str1812 = private unnamed_addr constant [52 x i8] c"loop:\0A %i = phi i32 [ 0, %entry ], [ %i1, %cont ]\0A\00" +@.str1813 = private unnamed_addr constant [58 x i8] c" %n = load i32, ptr @L_entc\0A %go = icmp slt i32 %i, %n\0A\00" +@.str1814 = private unnamed_addr constant [38 x i8] c" br i1 %go, label %body, label %fin\0A\00" +@.str1815 = private unnamed_addr constant [39 x i8] c"body:\0A %ap = getelementptr inbounds [\00" +@.str1816 = private unnamed_addr constant [38 x i8] c" x i32], ptr @L_alive, i32 0, i32 %i\0A\00" +@.str1817 = private unnamed_addr constant [55 x i8] c" %al = load i32, ptr %ap\0A %isa = icmp ne i32 %al, 0\0A\00" +@.str1818 = private unnamed_addr constant [38 x i8] c" br i1 %isa, label %do, label %cont\0A\00" +@.str1819 = private unnamed_addr constant [37 x i8] c"do:\0A %kp = getelementptr inbounds [\00" +@.str1820 = private unnamed_addr constant [37 x i8] c" x i32], ptr @L_kind, i32 0, i32 %i\0A\00" +@.str1821 = private unnamed_addr constant [26 x i8] c" %k = load i32, ptr %kp\0A\00" +@.str1822 = private unnamed_addr constant [5 x i8] c" %c\00" +@.str1823 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %k, \00" +@.str1824 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1825 = private unnamed_addr constant [11 x i8] c" br i1 %c\00" +@.str1826 = private unnamed_addr constant [13 x i8] c", label %hit\00" +@.str1827 = private unnamed_addr constant [14 x i8] c", label %next\00" +@.str1828 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1829 = private unnamed_addr constant [4 x i8] c"hit\00" +@.str1830 = private unnamed_addr constant [27 x i8] c":\0A call void @on_despawn_\00" +@.str1831 = private unnamed_addr constant [23 x i8] c"(i32 %i, i32 %reason)\0A\00" +@.str1832 = private unnamed_addr constant [7 x i8] c"model_\00" +@.str1833 = private unnamed_addr constant [9 x i8] c"_despawn\00" +@.str1834 = private unnamed_addr constant [17 x i8] c" call void @ev_\00" +@.str1835 = private unnamed_addr constant [23 x i8] c"(i32 %i, i32 %reason)\0A\00" +@.str1836 = private unnamed_addr constant [17 x i8] c" br label %next\00" +@.str1837 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1838 = private unnamed_addr constant [5 x i8] c"next\00" +@.str1839 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1840 = private unnamed_addr constant [18 x i8] c" br label %cont\0A\00" +@.str1841 = private unnamed_addr constant [46 x i8] c"cont:\0A %i1 = add i32 %i, 1\0A br label %loop\0A\00" +@.str1842 = private unnamed_addr constant [20 x i8] c"fin:\0A ret void\0A}\0A\0A\00" +@.str1843 = private unnamed_addr constant [26 x i8] c"@ev_depth = global i32 0\0A\00" +@.str1844 = private unnamed_addr constant [5 x i8] c"%Ev_\00" +@.str1845 = private unnamed_addr constant [11 x i8] c" = type { \00" +@.str1846 = private unnamed_addr constant [3 x i8] c", \00" +@.str1847 = private unnamed_addr constant [3 x i8] c", \00" +@.str1848 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str1849 = private unnamed_addr constant [4 x i8] c" }\0A\00" +@.str1850 = private unnamed_addr constant [6 x i8] c"@evL_\00" +@.str1851 = private unnamed_addr constant [12 x i8] c" = global [\00" +@.str1852 = private unnamed_addr constant [25 x i8] c" x ptr] zeroinitializer\0A\00" +@.str1853 = private unnamed_addr constant [6 x i8] c"@evN_\00" +@.str1854 = private unnamed_addr constant [17 x i8] c" = global i32 0\0A\00" +@.str1855 = private unnamed_addr constant [6 x i8] c"@evO_\00" +@.str1856 = private unnamed_addr constant [12 x i8] c" = global [\00" +@.str1857 = private unnamed_addr constant [25 x i8] c" x i32] zeroinitializer\0A\00" +@.str1858 = private unnamed_addr constant [22 x i8] c"define i32 @ludic_on_\00" +@.str1859 = private unnamed_addr constant [20 x i8] c"(ptr %cb) {\0Aentry:\0A\00" +@.str1860 = private unnamed_addr constant [27 x i8] c" %n = load i32, ptr @evN_\00" +@.str1861 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1862 = private unnamed_addr constant [28 x i8] c" %full = icmp slt i32 %n, \00" +@.str1863 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1864 = private unnamed_addr constant [40 x i8] c" br i1 %full, label %add, label %drop\0A\00" +@.str1865 = private unnamed_addr constant [40 x i8] c"add:\0A %slot = getelementptr inbounds [\00" +@.str1866 = private unnamed_addr constant [19 x i8] c" x ptr], ptr @evL_\00" +@.str1867 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %n\0A\00" +@.str1868 = private unnamed_addr constant [28 x i8] c" store ptr %cb, ptr %slot\0A\00" +@.str1869 = private unnamed_addr constant [36 x i8] c" %oslot = getelementptr inbounds [\00" +@.str1870 = private unnamed_addr constant [19 x i8] c" x i32], ptr @evO_\00" +@.str1871 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %n\0A\00" +@.str1872 = private unnamed_addr constant [28 x i8] c" store i32 -1, ptr %oslot\0A\00" +@.str1873 = private unnamed_addr constant [49 x i8] c" %n1 = add i32 %n, 1\0A store i32 %n1, ptr @evN_\00" +@.str1874 = private unnamed_addr constant [15 x i8] c"\0A ret i32 %n\0A\00" +@.str1875 = private unnamed_addr constant [23 x i8] c"drop:\0A ret i32 -1\0A}\0A\0A\00" +@.str1876 = private unnamed_addr constant [29 x i8] c"define i32 @ludic_on_entity_\00" +@.str1877 = private unnamed_addr constant [32 x i8] c"(i32 %owner, ptr %cb) {\0Aentry:\0A\00" +@.str1878 = private unnamed_addr constant [27 x i8] c" %n = load i32, ptr @evN_\00" +@.str1879 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1880 = private unnamed_addr constant [28 x i8] c" %full = icmp slt i32 %n, \00" +@.str1881 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1882 = private unnamed_addr constant [40 x i8] c" br i1 %full, label %add, label %drop\0A\00" +@.str1883 = private unnamed_addr constant [40 x i8] c"add:\0A %slot = getelementptr inbounds [\00" +@.str1884 = private unnamed_addr constant [19 x i8] c" x ptr], ptr @evL_\00" +@.str1885 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %n\0A\00" +@.str1886 = private unnamed_addr constant [28 x i8] c" store ptr %cb, ptr %slot\0A\00" +@.str1887 = private unnamed_addr constant [36 x i8] c" %oslot = getelementptr inbounds [\00" +@.str1888 = private unnamed_addr constant [19 x i8] c" x i32], ptr @evO_\00" +@.str1889 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %n\0A\00" +@.str1890 = private unnamed_addr constant [32 x i8] c" store i32 %owner, ptr %oslot\0A\00" +@.str1891 = private unnamed_addr constant [49 x i8] c" %n1 = add i32 %n, 1\0A store i32 %n1, ptr @evN_\00" +@.str1892 = private unnamed_addr constant [15 x i8] c"\0A ret i32 %n\0A\00" +@.str1893 = private unnamed_addr constant [23 x i8] c"drop:\0A ret i32 -1\0A}\0A\0A\00" +@.str1894 = private unnamed_addr constant [24 x i8] c"define void @ludic_off_\00" +@.str1895 = private unnamed_addr constant [21 x i8] c"(i32 %tok) {\0Aentry:\0A\00" +@.str1896 = private unnamed_addr constant [27 x i8] c" %n = load i32, ptr @evN_\00" +@.str1897 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1898 = private unnamed_addr constant [84 x i8] c" %lo = icmp sge i32 %tok, 0\0A %hi = icmp slt i32 %tok, %n\0A %ok = and i1 %lo, %hi\0A\00" +@.str1899 = private unnamed_addr constant [37 x i8] c" br i1 %ok, label %do, label %skip\0A\00" +@.str1900 = private unnamed_addr constant [39 x i8] c"do:\0A %slot = getelementptr inbounds [\00" +@.str1901 = private unnamed_addr constant [19 x i8] c" x ptr], ptr @evL_\00" +@.str1902 = private unnamed_addr constant [19 x i8] c", i32 0, i32 %tok\0A\00" +@.str1903 = private unnamed_addr constant [46 x i8] c" store ptr null, ptr %slot\0A br label %skip\0A\00" +@.str1904 = private unnamed_addr constant [21 x i8] c"skip:\0A ret void\0A}\0A\0A\00" +@.str1905 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1906 = private unnamed_addr constant [34 x i8] c" %evd = load i32, ptr @ev_depth\0A\00" +@.str1907 = private unnamed_addr constant [32 x i8] c" %evover = icmp sge i32 %evd, \00" +@.str1908 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1909 = private unnamed_addr constant [44 x i8] c" br i1 %evover, label %evcap, label %evgo\0A\00" +@.str1910 = private unnamed_addr constant [8 x i8] c"evcap:\0A\00" +@.str1911 = private unnamed_addr constant [13 x i8] c" ret i32 0\0A\00" +@.str1912 = private unnamed_addr constant [12 x i8] c" ret void\0A\00" +@.str1913 = private unnamed_addr constant [7 x i8] c"evgo:\0A\00" +@.str1914 = private unnamed_addr constant [60 x i8] c" %evd1 = add i32 %evd, 1\0A store i32 %evd1, ptr @ev_depth\0A\00" +@.str1915 = private unnamed_addr constant [5 x i8] c"%Ev_\00" +@.str1916 = private unnamed_addr constant [3 x i8] c" \00" +@.str1917 = private unnamed_addr constant [31 x i8] c" = getelementptr inbounds %Ev_\00" +@.str1918 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1919 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1920 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1921 = private unnamed_addr constant [9 x i8] c" store \00" +@.str1922 = private unnamed_addr constant [4 x i8] c" %p\00" +@.str1923 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1924 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1925 = private unnamed_addr constant [9 x i8] c" store \00" +@.str1926 = private unnamed_addr constant [4 x i8] c" %p\00" +@.str1927 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1928 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1929 = private unnamed_addr constant [3 x i8] c" \00" +@.str1930 = private unnamed_addr constant [31 x i8] c" = getelementptr inbounds %Ev_\00" +@.str1931 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1932 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1933 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1934 = private unnamed_addr constant [20 x i8] c" store i32 0, ptr \00" +@.str1935 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1936 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str1937 = private unnamed_addr constant [20 x i8] c" store i32 0, ptr \00" +@.str1938 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1939 = private unnamed_addr constant [4 x i8] c"evl\00" +@.str1940 = private unnamed_addr constant [4 x i8] c"evb\00" +@.str1941 = private unnamed_addr constant [4 x i8] c"evd\00" +@.str1942 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1943 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1944 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1945 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str1946 = private unnamed_addr constant [20 x i8] c"load i32, ptr @evN_\00" +@.str1947 = private unnamed_addr constant [14 x i8] c"icmp slt i32 \00" +@.str1948 = private unnamed_addr constant [3 x i8] c", \00" +@.str1949 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1950 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1951 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1952 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1953 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1954 = private unnamed_addr constant [3 x i8] c" \00" +@.str1955 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str1956 = private unnamed_addr constant [19 x i8] c" x ptr], ptr @evL_\00" +@.str1957 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str1958 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1959 = private unnamed_addr constant [15 x i8] c"load ptr, ptr \00" +@.str1960 = private unnamed_addr constant [13 x i8] c"icmp eq ptr \00" +@.str1961 = private unnamed_addr constant [7 x i8] c", null\00" +@.str1962 = private unnamed_addr constant [5 x i8] c"evdo\00" +@.str1963 = private unnamed_addr constant [5 x i8] c"evsk\00" +@.str1964 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str1965 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1966 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str1967 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1968 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1969 = private unnamed_addr constant [13 x i8] c" call void \00" +@.str1970 = private unnamed_addr constant [6 x i8] c"(ptr \00" +@.str1971 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str1972 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1973 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1974 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1975 = private unnamed_addr constant [9 x i8] c"add i32 \00" +@.str1976 = private unnamed_addr constant [4 x i8] c", 1\00" +@.str1977 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str1978 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str1979 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1980 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str1981 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1982 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str1983 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" +@.str1984 = private unnamed_addr constant [6 x i8] c"ret:\0A\00" +@.str1985 = private unnamed_addr constant [97 x i8] c" %evdd = load i32, ptr @ev_depth\0A %evdd1 = sub i32 %evdd, 1\0A store i32 %evdd1, ptr @ev_depth\0A\00" +@.str1986 = private unnamed_addr constant [15 x i8] c"load i32, ptr \00" +@.str1987 = private unnamed_addr constant [11 x i8] c" ret i32 \00" +@.str1988 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str1989 = private unnamed_addr constant [12 x i8] c" ret void\0A\00" +@.str1990 = private unnamed_addr constant [5 x i8] c"void\00" +@.str1991 = private unnamed_addr constant [4 x i8] c"i32\00" +@.str1992 = private unnamed_addr constant [8 x i8] c"define \00" +@.str1993 = private unnamed_addr constant [6 x i8] c" @ev_\00" +@.str1994 = private unnamed_addr constant [2 x i8] c"(\00" +@.str1995 = private unnamed_addr constant [3 x i8] c", \00" +@.str1996 = private unnamed_addr constant [4 x i8] c" %p\00" +@.str1997 = private unnamed_addr constant [12 x i8] c") {\0Aentry:\0A\00" +@.str1998 = private unnamed_addr constant [4 x i8] c"}\0A\0A\00" +@.str1999 = private unnamed_addr constant [112 x i8] c"define void @ludic_sweep_entity(i32 %owner) {\0Aentry:\0A %ci = alloca i32\0A store i32 0, ptr %ci\0A br label %sw0\0A\00" +@.str2000 = private unnamed_addr constant [3 x i8] c"sw\00" +@.str2001 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2002 = private unnamed_addr constant [7 x i8] c" %swi\00" +@.str2003 = private unnamed_addr constant [22 x i8] c" = load i32, ptr %ci\0A\00" +@.str2004 = private unnamed_addr constant [7 x i8] c" %swn\00" +@.str2005 = private unnamed_addr constant [23 x i8] c" = load i32, ptr @evN_\00" +@.str2006 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2007 = private unnamed_addr constant [7 x i8] c" %swg\00" +@.str2008 = private unnamed_addr constant [21 x i8] c" = icmp slt i32 %swi\00" +@.str2009 = private unnamed_addr constant [7 x i8] c", %swn\00" +@.str2010 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2011 = private unnamed_addr constant [13 x i8] c" br i1 %swg\00" +@.str2012 = private unnamed_addr constant [13 x i8] c", label %swb\00" +@.str2013 = private unnamed_addr constant [13 x i8] c", label %swd\00" +@.str2014 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2015 = private unnamed_addr constant [4 x i8] c"swb\00" +@.str2016 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2017 = private unnamed_addr constant [8 x i8] c" %swop\00" +@.str2018 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str2019 = private unnamed_addr constant [19 x i8] c" x i32], ptr @evO_\00" +@.str2020 = private unnamed_addr constant [18 x i8] c", i32 0, i32 %swi\00" +@.str2021 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2022 = private unnamed_addr constant [8 x i8] c" %swov\00" +@.str2023 = private unnamed_addr constant [23 x i8] c" = load i32, ptr %swop\00" +@.str2024 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2025 = private unnamed_addr constant [7 x i8] c" %swm\00" +@.str2026 = private unnamed_addr constant [21 x i8] c" = icmp eq i32 %swov\00" +@.str2027 = private unnamed_addr constant [10 x i8] c", %owner\0A\00" +@.str2028 = private unnamed_addr constant [13 x i8] c" br i1 %swm\00" +@.str2029 = private unnamed_addr constant [13 x i8] c", label %swh\00" +@.str2030 = private unnamed_addr constant [13 x i8] c", label %swx\00" +@.str2031 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2032 = private unnamed_addr constant [4 x i8] c"swh\00" +@.str2033 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2034 = private unnamed_addr constant [8 x i8] c" %swlp\00" +@.str2035 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str2036 = private unnamed_addr constant [19 x i8] c" x ptr], ptr @evL_\00" +@.str2037 = private unnamed_addr constant [18 x i8] c", i32 0, i32 %swi\00" +@.str2038 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2039 = private unnamed_addr constant [28 x i8] c" store ptr null, ptr %swlp\00" +@.str2040 = private unnamed_addr constant [17 x i8] c"\0A br label %swx\00" +@.str2041 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2042 = private unnamed_addr constant [4 x i8] c"swx\00" +@.str2043 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2044 = private unnamed_addr constant [8 x i8] c" %swi1\00" +@.str2045 = private unnamed_addr constant [16 x i8] c" = add i32 %swi\00" +@.str2046 = private unnamed_addr constant [22 x i8] c", 1\0A store i32 %swi1\00" +@.str2047 = private unnamed_addr constant [25 x i8] c", ptr %ci\0A br label %sw\00" +@.str2048 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2049 = private unnamed_addr constant [4 x i8] c"swd\00" +@.str2050 = private unnamed_addr constant [26 x i8] c":\0A store i32 0, ptr %ci\0A\00" +@.str2051 = private unnamed_addr constant [15 x i8] c" br label %sw\00" +@.str2052 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2053 = private unnamed_addr constant [12 x i8] c" ret void\0A\00" +@.str2054 = private unnamed_addr constant [4 x i8] c"}\0A\0A\00" +@.str2055 = private unnamed_addr constant [31 x i8] c"declare i32 @strcmp(ptr, ptr)\0A\00" +@.str2056 = private unnamed_addr constant [27 x i8] c"@dyn_count = global i32 0\0A\00" +@.str2057 = private unnamed_addr constant [43 x i8] c"@dynS = global [32 x ptr] zeroinitializer\0A\00" +@.str2058 = private unnamed_addr constant [43 x i8] c"@dynH = global [32 x ptr] zeroinitializer\0A\00" +@.str2059 = private unnamed_addr constant [43 x i8] c"@dynF = global [32 x i32] zeroinitializer\0A\00" +@.str2060 = private unnamed_addr constant [46 x i8] c"@dynName = global [32 x ptr] zeroinitializer\0A\00" +@.str2061 = private unnamed_addr constant [47 x i8] c"define i32 @ludic_prop_id(ptr %name) {\0Aentry:\0A\00" +@.str2062 = private unnamed_addr constant [5 x i8] c" %c\00" +@.str2063 = private unnamed_addr constant [36 x i8] c" = call i32 @strcmp(ptr %name, ptr \00" +@.str2064 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2065 = private unnamed_addr constant [5 x i8] c" %e\00" +@.str2066 = private unnamed_addr constant [18 x i8] c" = icmp eq i32 %c\00" +@.str2067 = private unnamed_addr constant [5 x i8] c", 0\0A\00" +@.str2068 = private unnamed_addr constant [11 x i8] c" br i1 %e\00" +@.str2069 = private unnamed_addr constant [11 x i8] c", label %h\00" +@.str2070 = private unnamed_addr constant [11 x i8] c", label %n\00" +@.str2071 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2072 = private unnamed_addr constant [2 x i8] c"h\00" +@.str2073 = private unnamed_addr constant [13 x i8] c":\0A ret i32 \00" +@.str2074 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2075 = private unnamed_addr constant [2 x i8] c"n\00" +@.str2076 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2077 = private unnamed_addr constant [61 x i8] c" %dpi = alloca i32\0A store i32 0, ptr %dpi\0A br label %dpl\0A\00" +@.str2078 = private unnamed_addr constant [135 x i8] c"dpl:\0A %di = load i32, ptr %dpi\0A %dn = load i32, ptr @dyn_count\0A %dg = icmp slt i32 %di, %dn\0A br i1 %dg, label %dpb, label %dpnone\0A\00" +@.str2079 = private unnamed_addr constant [231 x i8] c"dpb:\0A %dnp = getelementptr inbounds [32 x ptr], ptr @dynName, i32 0, i32 %di\0A %dname = load ptr, ptr %dnp\0A %dcmp = call i32 @strcmp(ptr %name, ptr %dname)\0A %deq = icmp eq i32 %dcmp, 0\0A br i1 %deq, label %dphit, label %dpnext\0A\00" +@.str2080 = private unnamed_addr constant [31 x i8] c"dphit:\0A %drid = add i32 %di, \00" +@.str2081 = private unnamed_addr constant [18 x i8] c"\0A ret i32 %drid\0A\00" +@.str2082 = private unnamed_addr constant [76 x i8] c"dpnext:\0A %di1 = add i32 %di, 1\0A store i32 %di1, ptr %dpi\0A br label %dpl\0A\00" +@.str2083 = private unnamed_addr constant [25 x i8] c"dpnone:\0A ret i32 -1\0A}\0A\0A\00" +@.str2084 = private unnamed_addr constant [56 x i8] c"define i32 @ludic_field_id(i32 %p, ptr %name) {\0Aentry:\0A\00" +@.str2085 = private unnamed_addr constant [6 x i8] c" %pm\00" +@.str2086 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %p, \00" +@.str2087 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2088 = private unnamed_addr constant [12 x i8] c" br i1 %pm\00" +@.str2089 = private unnamed_addr constant [12 x i8] c", label %pk\00" +@.str2090 = private unnamed_addr constant [12 x i8] c", label %pn\00" +@.str2091 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2092 = private unnamed_addr constant [3 x i8] c"pk\00" +@.str2093 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2094 = private unnamed_addr constant [2 x i8] c"_\00" +@.str2095 = private unnamed_addr constant [6 x i8] c" %fc\00" +@.str2096 = private unnamed_addr constant [36 x i8] c" = call i32 @strcmp(ptr %name, ptr \00" +@.str2097 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2098 = private unnamed_addr constant [6 x i8] c" %fe\00" +@.str2099 = private unnamed_addr constant [19 x i8] c" = icmp eq i32 %fc\00" +@.str2100 = private unnamed_addr constant [5 x i8] c", 0\0A\00" +@.str2101 = private unnamed_addr constant [12 x i8] c" br i1 %fe\00" +@.str2102 = private unnamed_addr constant [12 x i8] c", label %fh\00" +@.str2103 = private unnamed_addr constant [12 x i8] c", label %fn\00" +@.str2104 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2105 = private unnamed_addr constant [3 x i8] c"fh\00" +@.str2106 = private unnamed_addr constant [13 x i8] c":\0A ret i32 \00" +@.str2107 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2108 = private unnamed_addr constant [3 x i8] c"fn\00" +@.str2109 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2110 = private unnamed_addr constant [14 x i8] c" ret i32 -1\0A\00" +@.str2111 = private unnamed_addr constant [3 x i8] c"pn\00" +@.str2112 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2113 = private unnamed_addr constant [17 x i8] c" ret i32 -1\0A}\0A\0A\00" +@.str2114 = private unnamed_addr constant [56 x i8] c"define i64 @ludic_get(i32 %e, i32 %p, i32 %f) {\0Aentry:\0A\00" +@.str2115 = private unnamed_addr constant [5 x i8] c" %m\00" +@.str2116 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %p, \00" +@.str2117 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2118 = private unnamed_addr constant [11 x i8] c" br i1 %m\00" +@.str2119 = private unnamed_addr constant [11 x i8] c", label %g\00" +@.str2120 = private unnamed_addr constant [12 x i8] c", label %gn\00" +@.str2121 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2122 = private unnamed_addr constant [2 x i8] c"g\00" +@.str2123 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2124 = private unnamed_addr constant [5 x i8] c" %s\00" +@.str2125 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str2126 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" +@.str2127 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" +@.str2128 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %e\0A\00" +@.str2129 = private unnamed_addr constant [2 x i8] c"_\00" +@.str2130 = private unnamed_addr constant [6 x i8] c" %gm\00" +@.str2131 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %f, \00" +@.str2132 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2133 = private unnamed_addr constant [12 x i8] c" br i1 %gm\00" +@.str2134 = private unnamed_addr constant [12 x i8] c", label %gf\00" +@.str2135 = private unnamed_addr constant [12 x i8] c", label %gk\00" +@.str2136 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2137 = private unnamed_addr constant [3 x i8] c"gf\00" +@.str2138 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2139 = private unnamed_addr constant [6 x i8] c" %ga\00" +@.str2140 = private unnamed_addr constant [32 x i8] c" = getelementptr inbounds %Cmp_\00" +@.str2141 = private unnamed_addr constant [9 x i8] c", ptr %s\00" +@.str2142 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str2143 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2144 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str2145 = private unnamed_addr constant [6 x i8] c" %gl\00" +@.str2146 = private unnamed_addr constant [21 x i8] c" = load ptr, ptr %ga\00" +@.str2147 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2148 = private unnamed_addr constant [6 x i8] c" %gr\00" +@.str2149 = private unnamed_addr constant [20 x i8] c" = ptrtoint ptr %gl\00" +@.str2150 = private unnamed_addr constant [22 x i8] c" to i64\0A ret i64 %gr\00" +@.str2151 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2152 = private unnamed_addr constant [3 x i8] c"i8\00" +@.str2153 = private unnamed_addr constant [6 x i8] c" %gl\00" +@.str2154 = private unnamed_addr constant [20 x i8] c" = load i8, ptr %ga\00" +@.str2155 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2156 = private unnamed_addr constant [6 x i8] c" %gr\00" +@.str2157 = private unnamed_addr constant [15 x i8] c" = zext i8 %gl\00" +@.str2158 = private unnamed_addr constant [22 x i8] c" to i64\0A ret i64 %gr\00" +@.str2159 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2160 = private unnamed_addr constant [6 x i8] c" %gl\00" +@.str2161 = private unnamed_addr constant [21 x i8] c" = load i32, ptr %ga\00" +@.str2162 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2163 = private unnamed_addr constant [6 x i8] c" %gr\00" +@.str2164 = private unnamed_addr constant [16 x i8] c" = sext i32 %gl\00" +@.str2165 = private unnamed_addr constant [22 x i8] c" to i64\0A ret i64 %gr\00" +@.str2166 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2167 = private unnamed_addr constant [3 x i8] c"gk\00" +@.str2168 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2169 = private unnamed_addr constant [13 x i8] c" ret i64 0\0A\00" +@.str2170 = private unnamed_addr constant [3 x i8] c"gn\00" +@.str2171 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2172 = private unnamed_addr constant [23 x i8] c" %gdyn = sub i32 %p, \00" +@.str2173 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2174 = private unnamed_addr constant [175 x i8] c" %gdlo = icmp sge i32 %gdyn, 0\0A %gdc = load i32, ptr @dyn_count\0A %gdhi = icmp slt i32 %gdyn, %gdc\0A %gdok = and i1 %gdlo, %gdhi\0A br i1 %gdok, label %gdyng, label %gdnone\0A\00" +@.str2175 = private unnamed_addr constant [110 x i8] c"gdyng:\0A %gsp = getelementptr inbounds [32 x ptr], ptr @dynS, i32 0, i32 %gdyn\0A %gbase = load ptr, ptr %gsp\0A\00" +@.str2176 = private unnamed_addr constant [156 x i8] c" %gfp = getelementptr inbounds [32 x i32], ptr @dynF, i32 0, i32 %gdyn\0A %gnf = load i32, ptr %gfp\0A %grow = mul i32 %e, %gnf\0A %gidx = add i32 %grow, %f\0A\00" +@.str2177 = private unnamed_addr constant [133 x i8] c" %gaddr = getelementptr inbounds i32, ptr %gbase, i32 %gidx\0A %gv = load i32, ptr %gaddr\0A %gr = sext i32 %gv to i64\0A ret i64 %gr\0A\00" +@.str2178 = private unnamed_addr constant [24 x i8] c"gdnone:\0A ret i64 0\0A}\0A\0A\00" +@.str2179 = private unnamed_addr constant [67 x i8] c"define void @ludic_set(i32 %e, i32 %p, i32 %f, i64 %val) {\0Aentry:\0A\00" +@.str2180 = private unnamed_addr constant [5 x i8] c" %m\00" +@.str2181 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %p, \00" +@.str2182 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2183 = private unnamed_addr constant [11 x i8] c" br i1 %m\00" +@.str2184 = private unnamed_addr constant [11 x i8] c", label %g\00" +@.str2185 = private unnamed_addr constant [12 x i8] c", label %gn\00" +@.str2186 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2187 = private unnamed_addr constant [2 x i8] c"g\00" +@.str2188 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2189 = private unnamed_addr constant [5 x i8] c" %s\00" +@.str2190 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str2191 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" +@.str2192 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" +@.str2193 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %e\0A\00" +@.str2194 = private unnamed_addr constant [2 x i8] c"_\00" +@.str2195 = private unnamed_addr constant [6 x i8] c" %sm\00" +@.str2196 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %f, \00" +@.str2197 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2198 = private unnamed_addr constant [12 x i8] c" br i1 %sm\00" +@.str2199 = private unnamed_addr constant [12 x i8] c", label %sf\00" +@.str2200 = private unnamed_addr constant [12 x i8] c", label %sk\00" +@.str2201 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2202 = private unnamed_addr constant [3 x i8] c"sf\00" +@.str2203 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2204 = private unnamed_addr constant [6 x i8] c" %sa\00" +@.str2205 = private unnamed_addr constant [32 x i8] c" = getelementptr inbounds %Cmp_\00" +@.str2206 = private unnamed_addr constant [9 x i8] c", ptr %s\00" +@.str2207 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str2208 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2209 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str2210 = private unnamed_addr constant [6 x i8] c" %sp\00" +@.str2211 = private unnamed_addr constant [29 x i8] c" = inttoptr i64 %val to ptr\0A\00" +@.str2212 = private unnamed_addr constant [16 x i8] c" store ptr %sp\00" +@.str2213 = private unnamed_addr constant [10 x i8] c", ptr %sa\00" +@.str2214 = private unnamed_addr constant [13 x i8] c"\0A ret void\0A\00" +@.str2215 = private unnamed_addr constant [3 x i8] c"i8\00" +@.str2216 = private unnamed_addr constant [6 x i8] c" %sb\00" +@.str2217 = private unnamed_addr constant [25 x i8] c" = trunc i64 %val to i8\0A\00" +@.str2218 = private unnamed_addr constant [15 x i8] c" store i8 %sb\00" +@.str2219 = private unnamed_addr constant [10 x i8] c", ptr %sa\00" +@.str2220 = private unnamed_addr constant [13 x i8] c"\0A ret void\0A\00" +@.str2221 = private unnamed_addr constant [6 x i8] c" %sw\00" +@.str2222 = private unnamed_addr constant [26 x i8] c" = trunc i64 %val to i32\0A\00" +@.str2223 = private unnamed_addr constant [16 x i8] c" store i32 %sw\00" +@.str2224 = private unnamed_addr constant [10 x i8] c", ptr %sa\00" +@.str2225 = private unnamed_addr constant [13 x i8] c"\0A ret void\0A\00" +@.str2226 = private unnamed_addr constant [3 x i8] c"sk\00" +@.str2227 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2228 = private unnamed_addr constant [12 x i8] c" ret void\0A\00" +@.str2229 = private unnamed_addr constant [3 x i8] c"gn\00" +@.str2230 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2231 = private unnamed_addr constant [23 x i8] c" %sdyn = sub i32 %p, \00" +@.str2232 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2233 = private unnamed_addr constant [175 x i8] c" %sdlo = icmp sge i32 %sdyn, 0\0A %sdc = load i32, ptr @dyn_count\0A %sdhi = icmp slt i32 %sdyn, %sdc\0A %sdok = and i1 %sdlo, %sdhi\0A br i1 %sdok, label %sdyng, label %sdnone\0A\00" +@.str2234 = private unnamed_addr constant [110 x i8] c"sdyng:\0A %ssp = getelementptr inbounds [32 x ptr], ptr @dynS, i32 0, i32 %sdyn\0A %sbase = load ptr, ptr %ssp\0A\00" +@.str2235 = private unnamed_addr constant [156 x i8] c" %sfp = getelementptr inbounds [32 x i32], ptr @dynF, i32 0, i32 %sdyn\0A %snf = load i32, ptr %sfp\0A %srow = mul i32 %e, %snf\0A %sidx = add i32 %srow, %f\0A\00" +@.str2236 = private unnamed_addr constant [131 x i8] c" %saddr = getelementptr inbounds i32, ptr %sbase, i32 %sidx\0A %sv = trunc i64 %val to i32\0A store i32 %sv, ptr %saddr\0A ret void\0A\00" +@.str2237 = private unnamed_addr constant [23 x i8] c"sdnone:\0A ret void\0A}\0A\0A\00" +@.str2238 = private unnamed_addr constant [48 x i8] c"define i32 @ludic_has(i32 %e, i32 %p) {\0Aentry:\0A\00" +@.str2239 = private unnamed_addr constant [5 x i8] c" %m\00" +@.str2240 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %p, \00" +@.str2241 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2242 = private unnamed_addr constant [11 x i8] c" br i1 %m\00" +@.str2243 = private unnamed_addr constant [11 x i8] c", label %g\00" +@.str2244 = private unnamed_addr constant [12 x i8] c", label %gn\00" +@.str2245 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2246 = private unnamed_addr constant [2 x i8] c"g\00" +@.str2247 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2248 = private unnamed_addr constant [6 x i8] c" %hp\00" +@.str2249 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str2250 = private unnamed_addr constant [16 x i8] c" x i8], ptr @H_\00" +@.str2251 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %e\0A\00" +@.str2252 = private unnamed_addr constant [6 x i8] c" %hv\00" +@.str2253 = private unnamed_addr constant [20 x i8] c" = load i8, ptr %hp\00" +@.str2254 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2255 = private unnamed_addr constant [6 x i8] c" %hr\00" +@.str2256 = private unnamed_addr constant [15 x i8] c" = zext i8 %hv\00" +@.str2257 = private unnamed_addr constant [22 x i8] c" to i32\0A ret i32 %hr\00" +@.str2258 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2259 = private unnamed_addr constant [3 x i8] c"gn\00" +@.str2260 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2261 = private unnamed_addr constant [23 x i8] c" %hdyn = sub i32 %p, \00" +@.str2262 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2263 = private unnamed_addr constant [175 x i8] c" %hdlo = icmp sge i32 %hdyn, 0\0A %hdc = load i32, ptr @dyn_count\0A %hdhi = icmp slt i32 %hdyn, %hdc\0A %hdok = and i1 %hdlo, %hdhi\0A br i1 %hdok, label %hdyng, label %hdnone\0A\00" +@.str2264 = private unnamed_addr constant [238 x i8] c"hdyng:\0A %hhp = getelementptr inbounds [32 x ptr], ptr @dynH, i32 0, i32 %hdyn\0A %hh = load ptr, ptr %hhp\0A %hslot = getelementptr inbounds i8, ptr %hh, i32 %e\0A %hval = load i8, ptr %hslot\0A %hres = zext i8 %hval to i32\0A ret i32 %hres\0A\00" +@.str2265 = private unnamed_addr constant [24 x i8] c"hdnone:\0A ret i32 0\0A}\0A\0A\00" +@.str2266 = private unnamed_addr constant [67 x i8] c"define i32 @ludic_register_prop(ptr %name, i32 %nfields) {\0Aentry:\0A\00" +@.str2267 = private unnamed_addr constant [102 x i8] c" %dc = load i32, ptr @dyn_count\0A %full = icmp slt i32 %dc, 32\0A br i1 %full, label %do, label %rej\0A\00" +@.str2268 = private unnamed_addr constant [56 x i8] c"do:\0A %nf4 = mul i32 %nfields, 4\0A %sz = mul i32 %nf4, \00" +@.str2269 = private unnamed_addr constant [31 x i8] c"\0A %szl = sext i32 %sz to i64\0A\00" +@.str2270 = private unnamed_addr constant [83 x i8] c" %buf = call ptr @malloc(i64 %szl)\0A call ptr @memset(ptr %buf, i32 0, i64 %szl)\0A\00" +@.str2271 = private unnamed_addr constant [96 x i8] c" %sp = getelementptr inbounds [32 x ptr], ptr @dynS, i32 0, i32 %dc\0A store ptr %buf, ptr %sp\0A\00" +@.str2272 = private unnamed_addr constant [32 x i8] c" %hbuf = call ptr @malloc(i64 \00" +@.str2273 = private unnamed_addr constant [44 x i8] c")\0A call ptr @memset(ptr %hbuf, i32 0, i64 \00" +@.str2274 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2275 = private unnamed_addr constant [97 x i8] c" %hp = getelementptr inbounds [32 x ptr], ptr @dynH, i32 0, i32 %dc\0A store ptr %hbuf, ptr %hp\0A\00" +@.str2276 = private unnamed_addr constant [100 x i8] c" %fp = getelementptr inbounds [32 x i32], ptr @dynF, i32 0, i32 %dc\0A store i32 %nfields, ptr %fp\0A\00" +@.str2277 = private unnamed_addr constant [100 x i8] c" %np = getelementptr inbounds [32 x ptr], ptr @dynName, i32 0, i32 %dc\0A store ptr %name, ptr %np\0A\00" +@.str2278 = private unnamed_addr constant [22 x i8] c" %id = add i32 %dc, \00" +@.str2279 = private unnamed_addr constant [73 x i8] c"\0A %dc1 = add i32 %dc, 1\0A store i32 %dc1, ptr @dyn_count\0A ret i32 %id\0A\00" +@.str2280 = private unnamed_addr constant [22 x i8] c"rej:\0A ret i32 -1\0A}\0A\0A\00" +@.str2281 = private unnamed_addr constant [56 x i8] c"define void @ludic_attach_dyn(i32 %e, i32 %p) {\0Aentry:\0A\00" +@.str2282 = private unnamed_addr constant [22 x i8] c" %dyn = sub i32 %p, \00" +@.str2283 = private unnamed_addr constant [187 x i8] c"\0A %hp = getelementptr inbounds [32 x ptr], ptr @dynH, i32 0, i32 %dyn\0A %h = load ptr, ptr %hp\0A %slot = getelementptr inbounds i8, ptr %h, i32 %e\0A store i8 1, ptr %slot\0A ret void\0A}\0A\0A\00" +@.str2284 = private unnamed_addr constant [56 x i8] c"define void @ludic_detach_dyn(i32 %e, i32 %p) {\0Aentry:\0A\00" +@.str2285 = private unnamed_addr constant [22 x i8] c" %dyn = sub i32 %p, \00" +@.str2286 = private unnamed_addr constant [187 x i8] c"\0A %hp = getelementptr inbounds [32 x ptr], ptr @dynH, i32 0, i32 %dyn\0A %h = load ptr, ptr %hp\0A %slot = getelementptr inbounds i8, ptr %h, i32 %e\0A store i8 0, ptr %slot\0A ret void\0A}\0A\0A\00" +@.str2287 = private unnamed_addr constant [88 x i8] c"define i32 @ludic_entity_count() {\0Aentry:\0A %n = load i32, ptr @L_entc\0A ret i32 %n\0A}\0A\0A\00" +@.str2288 = private unnamed_addr constant [41 x i8] c"define i32 @ludic_kind(i32 %e) {\0Aentry:\0A\00" +@.str2289 = private unnamed_addr constant [33 x i8] c" %kp = getelementptr inbounds [\00" +@.str2290 = private unnamed_addr constant [37 x i8] c" x i32], ptr @L_kind, i32 0, i32 %e\0A\00" +@.str2291 = private unnamed_addr constant [42 x i8] c" %k = load i32, ptr %kp\0A ret i32 %k\0A}\0A\0A\00" +@.str2292 = private unnamed_addr constant [48 x i8] c"define i32 @ludic_model_id(ptr %name) {\0Aentry:\0A\00" +@.str2293 = private unnamed_addr constant [7 x i8] c" %mdc\00" +@.str2294 = private unnamed_addr constant [36 x i8] c" = call i32 @strcmp(ptr %name, ptr \00" +@.str2295 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2296 = private unnamed_addr constant [7 x i8] c" %mde\00" +@.str2297 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %mdc\00" +@.str2298 = private unnamed_addr constant [5 x i8] c", 0\0A\00" +@.str2299 = private unnamed_addr constant [13 x i8] c" br i1 %mde\00" +@.str2300 = private unnamed_addr constant [13 x i8] c", label %mdh\00" +@.str2301 = private unnamed_addr constant [13 x i8] c", label %mdn\00" +@.str2302 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2303 = private unnamed_addr constant [4 x i8] c"mdh\00" +@.str2304 = private unnamed_addr constant [13 x i8] c":\0A ret i32 \00" +@.str2305 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2306 = private unnamed_addr constant [4 x i8] c"mdn\00" +@.str2307 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2308 = private unnamed_addr constant [17 x i8] c" ret i32 -1\0A}\0A\0A\00" +@.str2309 = private unnamed_addr constant [4 x i8] c"int\00" +@.str2310 = private unnamed_addr constant [11 x i8] c" ret i32 \00" +@.str2311 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2312 = private unnamed_addr constant [25 x i8] c"define i32 @ludic_spawn_\00" +@.str2313 = private unnamed_addr constant [13 x i8] c"() {\0Aentry:\0A\00" +@.str2314 = private unnamed_addr constant [4 x i8] c"}\0A\0A\00" +@.str2315 = private unnamed_addr constant [42 x i8] c"define i32 @ludic_spawn(i32 %m) {\0Aentry:\0A\00" +@.str2316 = private unnamed_addr constant [6 x i8] c" %sm\00" +@.str2317 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %m, \00" +@.str2318 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2319 = private unnamed_addr constant [12 x i8] c" br i1 %sm\00" +@.str2320 = private unnamed_addr constant [12 x i8] c", label %sh\00" +@.str2321 = private unnamed_addr constant [12 x i8] c", label %sn\00" +@.str2322 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2323 = private unnamed_addr constant [3 x i8] c"sh\00" +@.str2324 = private unnamed_addr constant [8 x i8] c":\0A %sr\00" +@.str2325 = private unnamed_addr constant [26 x i8] c" = call i32 @ludic_spawn_\00" +@.str2326 = private unnamed_addr constant [17 x i8] c"()\0A ret i32 %sr\00" +@.str2327 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2328 = private unnamed_addr constant [3 x i8] c"sn\00" +@.str2329 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2330 = private unnamed_addr constant [17 x i8] c" ret i32 -1\0A}\0A\0A\00" +@.str2331 = private unnamed_addr constant [58 x i8] c"define i32 @ludic_query_next(i32 %p, i32 %from) {\0Aentry:\0A\00" +@.str2332 = private unnamed_addr constant [47 x i8] c" %n = load i32, ptr @L_entc\0A br label %loop\0A\00" +@.str2333 = private unnamed_addr constant [56 x i8] c"loop:\0A %e = phi i32 [ %from, %entry ], [ %e1, %cont ]\0A\00" +@.str2334 = private unnamed_addr constant [67 x i8] c" %go = icmp slt i32 %e, %n\0A br i1 %go, label %body, label %none\0A\00" +@.str2335 = private unnamed_addr constant [39 x i8] c"body:\0A %ap = getelementptr inbounds [\00" +@.str2336 = private unnamed_addr constant [38 x i8] c" x i32], ptr @L_alive, i32 0, i32 %e\0A\00" +@.str2337 = private unnamed_addr constant [93 x i8] c" %al = load i32, ptr %ap\0A %isa = icmp ne i32 %al, 0\0A br i1 %isa, label %chk, label %cont\0A\00" +@.str2338 = private unnamed_addr constant [115 x i8] c"chk:\0A %h = call i32 @ludic_has(i32 %e, i32 %p)\0A %hit = icmp ne i32 %h, 0\0A br i1 %hit, label %hitb, label %cont\0A\00" +@.str2339 = private unnamed_addr constant [20 x i8] c"hitb:\0A ret i32 %e\0A\00" +@.str2340 = private unnamed_addr constant [46 x i8] c"cont:\0A %e1 = add i32 %e, 1\0A br label %loop\0A\00" +@.str2341 = private unnamed_addr constant [23 x i8] c"none:\0A ret i32 -1\0A}\0A\0A\00" +@.str2342 = private unnamed_addr constant [38 x i8] c"define void @L_tick_fixed() {\0Aentry:\0A\00" +@.str2343 = private unnamed_addr constant [6 x i8] c"Input\00" +@.str2344 = private unnamed_addr constant [12 x i8] c"FixedUpdate\00" +@.str2345 = private unnamed_addr constant [7 x i8] c"Update\00" +@.str2346 = private unnamed_addr constant [11 x i8] c"LateUpdate\00" +@.str2347 = private unnamed_addr constant [15 x i8] c" ret void\0A}\0A\0A\00" +@.str2348 = private unnamed_addr constant [39 x i8] c"define void @L_tick_render() {\0Aentry:\0A\00" +@.str2349 = private unnamed_addr constant [7 x i8] c"Render\00" +@.str2350 = private unnamed_addr constant [15 x i8] c" ret void\0A}\0A\0A\00" +@.str2351 = private unnamed_addr constant [49 x i8] c"define i32 @main(i32 %argc, ptr %argv) {\0Aentry:\0A\00" +@.str2352 = private unnamed_addr constant [32 x i8] c" store i32 %argc, ptr @L_argc\0A\00" +@.str2353 = private unnamed_addr constant [32 x i8] c" store ptr %argv, ptr @L_argv\0A\00" +@.str2354 = private unnamed_addr constant [8 x i8] c"rt_init\00" +@.str2355 = private unnamed_addr constant [27 x i8] c" call void @fn_rt_init()\0A\00" +@.str2356 = private unnamed_addr constant [6 x i8] c"Start\00" +@.str2357 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str2358 = private unnamed_addr constant [16 x i8] c", ptr @L_scene\0A\00" +@.str2359 = private unnamed_addr constant [26 x i8] c" call void @scene_enter_\00" +@.str2360 = private unnamed_addr constant [4 x i8] c"()\0A\00" +@.str2361 = private unnamed_addr constant [14 x i8] c"program_start\00" +@.str2362 = private unnamed_addr constant [33 x i8] c" call void @ev_program_start()\0A\00" +@.str2363 = private unnamed_addr constant [18 x i8] c" br label %loop\0A\00" +@.str2364 = private unnamed_addr constant [7 x i8] c"loop:\0A\00" +@.str2365 = private unnamed_addr constant [25 x i8] c"load i32, ptr @L_running\00" +@.str2366 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str2367 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str2368 = private unnamed_addr constant [11 x i8] c"rt_running\00" +@.str2369 = private unnamed_addr constant [26 x i8] c"call i32 @fn_rt_running()\00" +@.str2370 = private unnamed_addr constant [13 x i8] c"icmp ne i32 \00" +@.str2371 = private unnamed_addr constant [4 x i8] c", 0\00" +@.str2372 = private unnamed_addr constant [8 x i8] c"and i1 \00" +@.str2373 = private unnamed_addr constant [3 x i8] c", \00" +@.str2374 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str2375 = private unnamed_addr constant [28 x i8] c", label %body, label %done\0A\00" +@.str2376 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str2377 = private unnamed_addr constant [28 x i8] c", label %body, label %done\0A\00" +@.str2378 = private unnamed_addr constant [7 x i8] c"body:\0A\00" +@.str2379 = private unnamed_addr constant [8 x i8] c"rt_poll\00" +@.str2380 = private unnamed_addr constant [23 x i8] c"call i32 @fn_rt_poll()\00" +@.str2381 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str2382 = private unnamed_addr constant [14 x i8] c", ptr @L_key\0A\00" +@.str2383 = private unnamed_addr constant [6 x i8] c"Input\00" +@.str2384 = private unnamed_addr constant [12 x i8] c"FixedUpdate\00" +@.str2385 = private unnamed_addr constant [7 x i8] c"Update\00" +@.str2386 = private unnamed_addr constant [11 x i8] c"LateUpdate\00" +@.str2387 = private unnamed_addr constant [7 x i8] c"Render\00" +@.str2388 = private unnamed_addr constant [18 x i8] c" br label %loop\0A\00" +@.str2389 = private unnamed_addr constant [7 x i8] c"done:\0A\00" +@.str2390 = private unnamed_addr constant [35 x i8] c" call void @L_despawn_all(i32 2)\0A\00" +@.str2391 = private unnamed_addr constant [7 x i8] c"OnQuit\00" +@.str2392 = private unnamed_addr constant [13 x i8] c"program_quit\00" +@.str2393 = private unnamed_addr constant [32 x i8] c" call void @ev_program_quit()\0A\00" +@.str2394 = private unnamed_addr constant [12 x i8] c"rt_shutdown\00" +@.str2395 = private unnamed_addr constant [31 x i8] c" call void @fn_rt_shutdown()\0A\00" +@.str2396 = private unnamed_addr constant [15 x i8] c" ret i32 0\0A}\0A\00" +@.str2397 = private unnamed_addr constant [25 x i8] c"call i32 @fn_rt_reg(i32 \00" +@.str2398 = private unnamed_addr constant [2 x i8] c")\00" +@.str2399 = private unnamed_addr constant [6 x i8] c"smend\00" +@.str2400 = private unnamed_addr constant [13 x i8] c"icmp eq i32 \00" +@.str2401 = private unnamed_addr constant [3 x i8] c", \00" +@.str2402 = private unnamed_addr constant [6 x i8] c"sbody\00" +@.str2403 = private unnamed_addr constant [5 x i8] c"sarm\00" +@.str2404 = private unnamed_addr constant [9 x i8] c" br i1 \00" +@.str2405 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str2406 = private unnamed_addr constant [10 x i8] c", label %\00" +@.str2407 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2408 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2409 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str2410 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2411 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2412 = private unnamed_addr constant [13 x i8] c" br label %\00" +@.str2413 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2414 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2415 = private unnamed_addr constant [32 x i8] c" call void @fn_rt_set_reg(i32 \00" +@.str2416 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str2417 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2418 = private unnamed_addr constant [27 x i8] c"become: no state or scene \00" +@.str2419 = private unnamed_addr constant [25 x i8] c" call void @scene_exit_\00" +@.str2420 = private unnamed_addr constant [4 x i8] c"()\0A\00" +@.str2421 = private unnamed_addr constant [13 x i8] c" store i32 \00" +@.str2422 = private unnamed_addr constant [16 x i8] c", ptr @L_scene\0A\00" +@.str2423 = private unnamed_addr constant [26 x i8] c" call void @scene_enter_\00" +@.str2424 = private unnamed_addr constant [4 x i8] c"()\0A\00" +@.str2425 = private unnamed_addr constant [5 x i8] c"file\00" +@.str2426 = private unnamed_addr constant [4 x i8] c"%io\00" +@.str2427 = private unnamed_addr constant [3 x i8] c" \00" +@.str2428 = private unnamed_addr constant [14 x i8] c" = call i64 @\00" +@.str2429 = private unnamed_addr constant [6 x i8] c"(ptr \00" +@.str2430 = private unnamed_addr constant [14 x i8] c", i64 1, i64 \00" +@.str2431 = private unnamed_addr constant [11 x i8] c", ptr %f)\0A\00" +@.str2432 = private unnamed_addr constant [5 x i8] c"size\00" +@.str2433 = private unnamed_addr constant [6 x i8] c"%ioff\00" +@.str2434 = private unnamed_addr constant [3 x i8] c" \00" +@.str2435 = private unnamed_addr constant [12 x i8] c" = add i64 \00" +@.str2436 = private unnamed_addr constant [3 x i8] c", \00" +@.str2437 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2438 = private unnamed_addr constant [5 x i8] c"%ioa\00" +@.str2439 = private unnamed_addr constant [3 x i8] c" \00" +@.str2440 = private unnamed_addr constant [45 x i8] c" = getelementptr inbounds i8, ptr %buf, i64 \00" +@.str2441 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2442 = private unnamed_addr constant [5 x i8] c"save\00" +@.str2443 = private unnamed_addr constant [24 x i8] c" call ptr @memcpy(ptr \00" +@.str2444 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str2445 = private unnamed_addr constant [7 x i8] c", i64 \00" +@.str2446 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2447 = private unnamed_addr constant [24 x i8] c" call ptr @memcpy(ptr \00" +@.str2448 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str2449 = private unnamed_addr constant [7 x i8] c", i64 \00" +@.str2450 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2451 = private unnamed_addr constant [6 x i8] c"%ioff\00" +@.str2452 = private unnamed_addr constant [3 x i8] c" \00" +@.str2453 = private unnamed_addr constant [12 x i8] c" = add i64 \00" +@.str2454 = private unnamed_addr constant [3 x i8] c", \00" +@.str2455 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2456 = private unnamed_addr constant [2 x i8] c"0\00" +@.str2457 = private unnamed_addr constant [8 x i8] c"@L_entc\00" +@.str2458 = private unnamed_addr constant [2 x i8] c"4\00" +@.str2459 = private unnamed_addr constant [9 x i8] c"@L_freen\00" +@.str2460 = private unnamed_addr constant [2 x i8] c"4\00" +@.str2461 = private unnamed_addr constant [21 x i8] c" %nalive = mul i64 \00" +@.str2462 = private unnamed_addr constant [5 x i8] c", 4\0A\00" +@.str2463 = private unnamed_addr constant [9 x i8] c"@L_alive\00" +@.str2464 = private unnamed_addr constant [8 x i8] c"%nalive\00" +@.str2465 = private unnamed_addr constant [12 x i8] c"@L_freelist\00" +@.str2466 = private unnamed_addr constant [8 x i8] c"%nalive\00" +@.str2467 = private unnamed_addr constant [8 x i8] c"@L_kind\00" +@.str2468 = private unnamed_addr constant [8 x i8] c"%nalive\00" +@.str2469 = private unnamed_addr constant [13 x i8] c"@L_owner_arr\00" +@.str2470 = private unnamed_addr constant [8 x i8] c"%nalive\00" +@.str2471 = private unnamed_addr constant [4 x i8] c"@g_\00" +@.str2472 = private unnamed_addr constant [2 x i8] c"4\00" +@.str2473 = private unnamed_addr constant [5 x i8] c"%csz\00" +@.str2474 = private unnamed_addr constant [3 x i8] c" \00" +@.str2475 = private unnamed_addr constant [37 x i8] c" = ptrtoint ptr getelementptr (%Cmp_\00" +@.str2476 = private unnamed_addr constant [17 x i8] c", ptr null, i32 \00" +@.str2477 = private unnamed_addr constant [10 x i8] c") to i64\0A\00" +@.str2478 = private unnamed_addr constant [4 x i8] c"@S_\00" +@.str2479 = private unnamed_addr constant [4 x i8] c"@H_\00" +@.str2480 = private unnamed_addr constant [5 x i8] c"file\00" +@.str2481 = private unnamed_addr constant [70 x i8] c"@.sav_path = private unnamed_addr constant [10 x i8] c\22ludic.sav\5C00\22\0A\00" +@.str2482 = private unnamed_addr constant [60 x i8] c"@.sav_wb = private unnamed_addr constant [3 x i8] c\22wb\5C00\22\0A\00" +@.str2483 = private unnamed_addr constant [60 x i8] c"@.sav_rb = private unnamed_addr constant [3 x i8] c\22rb\5C00\22\0A\00" +@.str2484 = private unnamed_addr constant [14 x i8] c"rt_save_state\00" +@.str2485 = private unnamed_addr constant [14 x i8] c"rt_load_state\00" +@.str2486 = private unnamed_addr constant [32 x i8] c"define void @L_save() {\0Aentry:\0A\00" +@.str2487 = private unnamed_addr constant [54 x i8] c" %f = call ptr @fopen(ptr @.sav_path, ptr @.sav_wb)\0A\00" +@.str2488 = private unnamed_addr constant [31 x i8] c" %bad = icmp eq ptr %f, null\0A\00" +@.str2489 = private unnamed_addr constant [41 x i8] c" br i1 %bad, label %out, label %go\0Ago:\0A\00" +@.str2490 = private unnamed_addr constant [7 x i8] c"fwrite\00" +@.str2491 = private unnamed_addr constant [39 x i8] c" call void @fn_rt_save_state(ptr %f)\0A\00" +@.str2492 = private unnamed_addr constant [68 x i8] c" %c = call i32 @fclose(ptr %f)\0A br label %out\0Aout:\0A ret void\0A}\0A\0A\00" +@.str2493 = private unnamed_addr constant [31 x i8] c"define i32 @L_load() {\0Aentry:\0A\00" +@.str2494 = private unnamed_addr constant [54 x i8] c" %f = call ptr @fopen(ptr @.sav_path, ptr @.sav_rb)\0A\00" +@.str2495 = private unnamed_addr constant [31 x i8] c" %bad = icmp eq ptr %f, null\0A\00" +@.str2496 = private unnamed_addr constant [60 x i8] c" br i1 %bad, label %miss, label %go\0Amiss:\0A ret i32 0\0Ago:\0A\00" +@.str2497 = private unnamed_addr constant [6 x i8] c"fread\00" +@.str2498 = private unnamed_addr constant [39 x i8] c" call void @fn_rt_load_state(ptr %f)\0A\00" +@.str2499 = private unnamed_addr constant [48 x i8] c" %c = call i32 @fclose(ptr %f)\0A ret i32 1\0A}\0A\0A\00" +@.str2500 = private unnamed_addr constant [45 x i8] c"define i32 @L_world_save(ptr %buf) {\0Aentry:\0A\00" +@.str2501 = private unnamed_addr constant [5 x i8] c"save\00" +@.str2502 = private unnamed_addr constant [1 x i8] c"\00" +@.str2503 = private unnamed_addr constant [5 x i8] c"%wsn\00" +@.str2504 = private unnamed_addr constant [3 x i8] c" \00" +@.str2505 = private unnamed_addr constant [14 x i8] c" = trunc i64 \00" +@.str2506 = private unnamed_addr constant [9 x i8] c" to i32\0A\00" +@.str2507 = private unnamed_addr constant [11 x i8] c" ret i32 \00" +@.str2508 = private unnamed_addr constant [5 x i8] c"\0A}\0A\0A\00" +@.str2509 = private unnamed_addr constant [56 x i8] c"define void @L_world_load(ptr %buf, i32 %len) {\0Aentry:\0A\00" +@.str2510 = private unnamed_addr constant [5 x i8] c"load\00" +@.str2511 = private unnamed_addr constant [1 x i8] c"\00" +@.str2512 = private unnamed_addr constant [15 x i8] c" ret void\0A}\0A\0A\00" +@.str2513 = private unnamed_addr constant [37 x i8] c"define i32 @L_world_size() {\0Aentry:\0A\00" +@.str2514 = private unnamed_addr constant [5 x i8] c"size\00" +@.str2515 = private unnamed_addr constant [1 x i8] c"\00" +@.str2516 = private unnamed_addr constant [5 x i8] c"%wzn\00" +@.str2517 = private unnamed_addr constant [3 x i8] c" \00" +@.str2518 = private unnamed_addr constant [14 x i8] c" = trunc i64 \00" +@.str2519 = private unnamed_addr constant [9 x i8] c" to i32\0A\00" +@.str2520 = private unnamed_addr constant [11 x i8] c" ret i32 \00" +@.str2521 = private unnamed_addr constant [5 x i8] c"\0A}\0A\0A\00" +@.str2522 = private unnamed_addr constant [5 x i8] c"file\00" +@.str2523 = private unnamed_addr constant [3 x i8] c"i8\00" +@.str2524 = private unnamed_addr constant [3 x i8] c"i8\00" +@.str2525 = private unnamed_addr constant [2 x i8] c"1\00" +@.str2526 = private unnamed_addr constant [2 x i8] c"4\00" +@.str2527 = private unnamed_addr constant [24 x i8] c"ludicc(self): warning: \00" +@.str2528 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2529 = private unnamed_addr constant [4 x i8] c"ptr\00" +@.str2530 = private unnamed_addr constant [13 x i8] c"@Sync field \00" +@.str2531 = private unnamed_addr constant [2 x i8] c".\00" +@.str2532 = private unnamed_addr constant [68 x i8] c" is not a POD scalar (networked fields must be int/bool/fixed/byte)\00" +@.str2533 = private unnamed_addr constant [7 x i8] c"model \00" +@.str2534 = private unnamed_addr constant [9 x i8] c" @Syncs \00" +@.str2535 = private unnamed_addr constant [51 x i8] c" but it has no @Sync fields \E2\80\94 nothing replicates\00" +@.str2536 = private unnamed_addr constant [25 x i8] c"define i32 @L_serialize_\00" +@.str2537 = private unnamed_addr constant [29 x i8] c"(i32 %e, ptr %buf) {\0Aentry:\0A\00" +@.str2538 = private unnamed_addr constant [3 x i8] c" \00" +@.str2539 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str2540 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" +@.str2541 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" +@.str2542 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %e\0A\00" +@.str2543 = private unnamed_addr constant [3 x i8] c" \00" +@.str2544 = private unnamed_addr constant [32 x i8] c" = getelementptr inbounds %Cmp_\00" +@.str2545 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str2546 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str2547 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2548 = private unnamed_addr constant [3 x i8] c" \00" +@.str2549 = private unnamed_addr constant [45 x i8] c" = getelementptr inbounds i8, ptr %buf, i32 \00" +@.str2550 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2551 = private unnamed_addr constant [24 x i8] c" call ptr @memcpy(ptr \00" +@.str2552 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str2553 = private unnamed_addr constant [7 x i8] c", i64 \00" +@.str2554 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2555 = private unnamed_addr constant [11 x i8] c" ret i32 \00" +@.str2556 = private unnamed_addr constant [5 x i8] c"\0A}\0A\0A\00" +@.str2557 = private unnamed_addr constant [22 x i8] c"define void @L_apply_\00" +@.str2558 = private unnamed_addr constant [39 x i8] c"(i32 %e, ptr %buf, i32 %len) {\0Aentry:\0A\00" +@.str2559 = private unnamed_addr constant [3 x i8] c" \00" +@.str2560 = private unnamed_addr constant [28 x i8] c" = getelementptr inbounds [\00" +@.str2561 = private unnamed_addr constant [9 x i8] c" x %Cmp_\00" +@.str2562 = private unnamed_addr constant [11 x i8] c"], ptr @S_\00" +@.str2563 = private unnamed_addr constant [17 x i8] c", i32 0, i32 %e\0A\00" +@.str2564 = private unnamed_addr constant [3 x i8] c" \00" +@.str2565 = private unnamed_addr constant [32 x i8] c" = getelementptr inbounds %Cmp_\00" +@.str2566 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str2567 = private unnamed_addr constant [14 x i8] c", i32 0, i32 \00" +@.str2568 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2569 = private unnamed_addr constant [3 x i8] c" \00" +@.str2570 = private unnamed_addr constant [45 x i8] c" = getelementptr inbounds i8, ptr %buf, i32 \00" +@.str2571 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2572 = private unnamed_addr constant [24 x i8] c" call ptr @memcpy(ptr \00" +@.str2573 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str2574 = private unnamed_addr constant [7 x i8] c", i64 \00" +@.str2575 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2576 = private unnamed_addr constant [15 x i8] c" ret void\0A}\0A\0A\00" +@.str2577 = private unnamed_addr constant [56 x i8] c"define i32 @ludic_serialize(i32 %e, ptr %buf) {\0Aentry:\0A\00" +@.str2578 = private unnamed_addr constant [33 x i8] c" %kp = getelementptr inbounds [\00" +@.str2579 = private unnamed_addr constant [62 x i8] c" x i32], ptr @L_kind, i32 0, i32 %e\0A %k = load i32, ptr %kp\0A\00" +@.str2580 = private unnamed_addr constant [5 x i8] c" %c\00" +@.str2581 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %k, \00" +@.str2582 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2583 = private unnamed_addr constant [11 x i8] c" br i1 %c\00" +@.str2584 = private unnamed_addr constant [11 x i8] c", label %h\00" +@.str2585 = private unnamed_addr constant [11 x i8] c", label %n\00" +@.str2586 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2587 = private unnamed_addr constant [2 x i8] c"h\00" +@.str2588 = private unnamed_addr constant [7 x i8] c":\0A %r\00" +@.str2589 = private unnamed_addr constant [26 x i8] c" = call i32 @L_serialize_\00" +@.str2590 = private unnamed_addr constant [32 x i8] c"(i32 %e, ptr %buf)\0A ret i32 %r\00" +@.str2591 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2592 = private unnamed_addr constant [2 x i8] c"n\00" +@.str2593 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2594 = private unnamed_addr constant [16 x i8] c" ret i32 0\0A}\0A\0A\00" +@.str2595 = private unnamed_addr constant [63 x i8] c"define void @ludic_apply(i32 %e, ptr %buf, i32 %len) {\0Aentry:\0A\00" +@.str2596 = private unnamed_addr constant [33 x i8] c" %kp = getelementptr inbounds [\00" +@.str2597 = private unnamed_addr constant [62 x i8] c" x i32], ptr @L_kind, i32 0, i32 %e\0A %k = load i32, ptr %kp\0A\00" +@.str2598 = private unnamed_addr constant [5 x i8] c" %c\00" +@.str2599 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %k, \00" +@.str2600 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2601 = private unnamed_addr constant [11 x i8] c" br i1 %c\00" +@.str2602 = private unnamed_addr constant [11 x i8] c", label %h\00" +@.str2603 = private unnamed_addr constant [11 x i8] c", label %n\00" +@.str2604 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2605 = private unnamed_addr constant [2 x i8] c"h\00" +@.str2606 = private unnamed_addr constant [24 x i8] c":\0A call void @L_apply_\00" +@.str2607 = private unnamed_addr constant [41 x i8] c"(i32 %e, ptr %buf, i32 %len)\0A ret void\0A\00" +@.str2608 = private unnamed_addr constant [2 x i8] c"n\00" +@.str2609 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2610 = private unnamed_addr constant [15 x i8] c" ret void\0A}\0A\0A\00" +@.str2611 = private unnamed_addr constant [46 x i8] c"define i32 @ludic_sync_size(i32 %e) {\0Aentry:\0A\00" +@.str2612 = private unnamed_addr constant [33 x i8] c" %kp = getelementptr inbounds [\00" +@.str2613 = private unnamed_addr constant [62 x i8] c" x i32], ptr @L_kind, i32 0, i32 %e\0A %k = load i32, ptr %kp\0A\00" +@.str2614 = private unnamed_addr constant [5 x i8] c" %c\00" +@.str2615 = private unnamed_addr constant [20 x i8] c" = icmp eq i32 %k, \00" +@.str2616 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2617 = private unnamed_addr constant [11 x i8] c" br i1 %c\00" +@.str2618 = private unnamed_addr constant [11 x i8] c", label %h\00" +@.str2619 = private unnamed_addr constant [11 x i8] c", label %n\00" +@.str2620 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2621 = private unnamed_addr constant [2 x i8] c"h\00" +@.str2622 = private unnamed_addr constant [13 x i8] c":\0A ret i32 \00" +@.str2623 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2624 = private unnamed_addr constant [2 x i8] c"n\00" +@.str2625 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2626 = private unnamed_addr constant [16 x i8] c" ret i32 0\0A}\0A\0A\00" +@.str2627 = private unnamed_addr constant [38 x i8] c"define i32 @L_owner(i32 %e) {\0Aentry:\0A\00" +@.str2628 = private unnamed_addr constant [32 x i8] c" %p = getelementptr inbounds [\00" +@.str2629 = private unnamed_addr constant [82 x i8] c" x i32], ptr @L_owner_arr, i32 0, i32 %e\0A %v = load i32, ptr %p\0A ret i32 %v\0A}\0A\0A\00" +@.str2630 = private unnamed_addr constant [52 x i8] c"define void @L_set_owner(i32 %e, i32 %id) {\0Aentry:\0A\00" +@.str2631 = private unnamed_addr constant [32 x i8] c" %p = getelementptr inbounds [\00" +@.str2632 = private unnamed_addr constant [80 x i8] c" x i32], ptr @L_owner_arr, i32 0, i32 %e\0A store i32 %id, ptr %p\0A ret void\0A}\0A\0A\00" +@.str2633 = private unnamed_addr constant [41 x i8] c"define i32 @L_is_owner(i32 %e) {\0Aentry:\0A\00" +@.str2634 = private unnamed_addr constant [32 x i8] c" %p = getelementptr inbounds [\00" +@.str2635 = private unnamed_addr constant [66 x i8] c" x i32], ptr @L_owner_arr, i32 0, i32 %e\0A %o = load i32, ptr %p\0A\00" +@.str2636 = private unnamed_addr constant [106 x i8] c" %lid = load i32, ptr @L_localid\0A %eq = icmp eq i32 %o, %lid\0A %r = zext i1 %eq to i32\0A ret i32 %r\0A}\0A\0A\00" +@.str2637 = private unnamed_addr constant [62 x i8] c"@L_netq = internal global [64 x [2048 x i8]] zeroinitializer\0A\00" +@.str2638 = private unnamed_addr constant [56 x i8] c"@L_netlen = internal global [64 x i32] zeroinitializer\0A\00" +@.str2639 = private unnamed_addr constant [36 x i8] c"@L_nethead = internal global i32 0\0A\00" +@.str2640 = private unnamed_addr constant [36 x i8] c"@L_nettail = internal global i32 0\0A\00" +@.str2641 = private unnamed_addr constant [65 x i8] c"define void @L_net_send(i32 %peer, ptr %buf, i32 %len) {\0Aentry:\0A\00" +@.str2642 = private unnamed_addr constant [71 x i8] c" %l0 = icmp slt i32 %len, 0\0A %len1 = select i1 %l0, i32 0, i32 %len\0A\00" +@.str2643 = private unnamed_addr constant [76 x i8] c" %l1 = icmp sgt i32 %len1, 2048\0A %n = select i1 %l1, i32 2048, i32 %len1\0A\00" +@.str2644 = private unnamed_addr constant [65 x i8] c" %t = load i32, ptr @L_nettail\0A %h = load i32, ptr @L_nethead\0A\00" +@.str2645 = private unnamed_addr constant [78 x i8] c" %t1 = add i32 %t, 1\0A %tn = srem i32 %t1, 64\0A %full = icmp eq i32 %tn, %h\0A\00" +@.str2646 = private unnamed_addr constant [39 x i8] c" br i1 %full, label %drop, label %go\0A\00" +@.str2647 = private unnamed_addr constant [5 x i8] c"go:\0A\00" +@.str2648 = private unnamed_addr constant [80 x i8] c" %row = getelementptr inbounds [64 x [2048 x i8]], ptr @L_netq, i32 0, i32 %t\0A\00" +@.str2649 = private unnamed_addr constant [76 x i8] c" %nz = zext i32 %n to i64\0A call ptr @memcpy(ptr %row, ptr %buf, i64 %nz)\0A\00" +@.str2650 = private unnamed_addr constant [97 x i8] c" %lp = getelementptr inbounds [64 x i32], ptr @L_netlen, i32 0, i32 %t\0A store i32 %n, ptr %lp\0A\00" +@.str2651 = private unnamed_addr constant [50 x i8] c" store i32 %tn, ptr @L_nettail\0A br label %drop\0A\00" +@.str2652 = private unnamed_addr constant [21 x i8] c"drop:\0A ret void\0A}\0A\0A\00" +@.str2653 = private unnamed_addr constant [53 x i8] c"define i32 @L_net_poll(ptr %buf, i32 %cap) {\0Aentry:\0A\00" +@.str2654 = private unnamed_addr constant [95 x i8] c" %h = load i32, ptr @L_nethead\0A %t = load i32, ptr @L_nettail\0A %empty = icmp eq i32 %h, %t\0A\00" +@.str2655 = private unnamed_addr constant [40 x i8] c" br i1 %empty, label %none, label %go\0A\00" +@.str2656 = private unnamed_addr constant [5 x i8] c"go:\0A\00" +@.str2657 = private unnamed_addr constant [99 x i8] c" %lp = getelementptr inbounds [64 x i32], ptr @L_netlen, i32 0, i32 %h\0A %ln = load i32, ptr %lp\0A\00" +@.str2658 = private unnamed_addr constant [74 x i8] c" %big = icmp sgt i32 %ln, %cap\0A %n = select i1 %big, i32 %cap, i32 %ln\0A\00" +@.str2659 = private unnamed_addr constant [80 x i8] c" %row = getelementptr inbounds [64 x [2048 x i8]], ptr @L_netq, i32 0, i32 %h\0A\00" +@.str2660 = private unnamed_addr constant [76 x i8] c" %nz = zext i32 %n to i64\0A call ptr @memcpy(ptr %buf, ptr %row, i64 %nz)\0A\00" +@.str2661 = private unnamed_addr constant [93 x i8] c" %h1 = add i32 %h, 1\0A %hn = srem i32 %h1, 64\0A store i32 %hn, ptr @L_nethead\0A ret i32 %n\0A\00" +@.str2662 = private unnamed_addr constant [22 x i8] c"none:\0A ret i32 0\0A}\0A\0A\00" +@.str2663 = private unnamed_addr constant [9 x i8] c"net_send\00" +@.str2664 = private unnamed_addr constant [11 x i8] c"L_net_send\00" +@.str2665 = private unnamed_addr constant [9 x i8] c"net_poll\00" +@.str2666 = private unnamed_addr constant [11 x i8] c"L_net_poll\00" +@.str2667 = private unnamed_addr constant [58 x i8] c"@L_recvbuf = internal global [2048 x i8] zeroinitializer\0A\00" +@.str2668 = private unnamed_addr constant [9 x i8] c"net_poll\00" +@.str2669 = private unnamed_addr constant [53 x i8] c"define void @L_net_pump() {\0Aentry:\0A br label %loop\0A\00" +@.str2670 = private unnamed_addr constant [24 x i8] c"loop:\0A %n = call i32 @\00" +@.str2671 = private unnamed_addr constant [28 x i8] c"(ptr @L_recvbuf, i32 2048)\0A\00" +@.str2672 = private unnamed_addr constant [68 x i8] c" %done = icmp eq i32 %n, 0\0A br i1 %done, label %fin, label %body\0A\00" +@.str2673 = private unnamed_addr constant [41 x i8] c"body:\0A %eid = load i32, ptr @L_recvbuf\0A\00" +@.str2674 = private unnamed_addr constant [5 x i8] c" %c\00" +@.str2675 = private unnamed_addr constant [22 x i8] c" = icmp eq i32 %eid, \00" +@.str2676 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2677 = private unnamed_addr constant [11 x i8] c" br i1 %c\00" +@.str2678 = private unnamed_addr constant [11 x i8] c", label %h\00" +@.str2679 = private unnamed_addr constant [11 x i8] c", label %x\00" +@.str2680 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2681 = private unnamed_addr constant [2 x i8] c"h\00" +@.str2682 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2683 = private unnamed_addr constant [2 x i8] c"_\00" +@.str2684 = private unnamed_addr constant [6 x i8] c" %fa\00" +@.str2685 = private unnamed_addr constant [51 x i8] c" = getelementptr inbounds i8, ptr @L_recvbuf, i32 \00" +@.str2686 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2687 = private unnamed_addr constant [6 x i8] c" %fv\00" +@.str2688 = private unnamed_addr constant [9 x i8] c" = load \00" +@.str2689 = private unnamed_addr constant [10 x i8] c", ptr %fa\00" +@.str2690 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2691 = private unnamed_addr constant [3 x i8] c", \00" +@.str2692 = private unnamed_addr constant [5 x i8] c" %fv\00" +@.str2693 = private unnamed_addr constant [17 x i8] c" call void @ev_\00" +@.str2694 = private unnamed_addr constant [2 x i8] c"(\00" +@.str2695 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2696 = private unnamed_addr constant [18 x i8] c" br label %loop\0A\00" +@.str2697 = private unnamed_addr constant [2 x i8] c"x\00" +@.str2698 = private unnamed_addr constant [3 x i8] c":\0A\00" +@.str2699 = private unnamed_addr constant [18 x i8] c" br label %loop\0A\00" +@.str2700 = private unnamed_addr constant [20 x i8] c"fin:\0A ret void\0A}\0A\0A\00" +@.str2701 = private unnamed_addr constant [58 x i8] c"@L_sendbuf = internal global [2048 x i8] zeroinitializer\0A\00" +@.str2702 = private unnamed_addr constant [6 x i8] c"panel\00" +@.str2703 = private unnamed_addr constant [4 x i8] c"col\00" +@.str2704 = private unnamed_addr constant [4 x i8] c"row\00" +@.str2705 = private unnamed_addr constant [6 x i8] c"label\00" +@.str2706 = private unnamed_addr constant [7 x i8] c"button\00" +@.str2707 = private unnamed_addr constant [6 x i8] c"image\00" +@.str2708 = private unnamed_addr constant [7 x i8] c"spacer\00" +@.str2709 = private unnamed_addr constant [3 x i8] c"id\00" +@.str2710 = private unnamed_addr constant [31 x i8] c" call void @fn_rt_ui_set(i32 \00" +@.str2711 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str2712 = private unnamed_addr constant [7 x i8] c", i32 \00" +@.str2713 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2714 = private unnamed_addr constant [2 x i8] c"w\00" +@.str2715 = private unnamed_addr constant [2 x i8] c"h\00" +@.str2716 = private unnamed_addr constant [2 x i8] c"x\00" +@.str2717 = private unnamed_addr constant [2 x i8] c"y\00" +@.str2718 = private unnamed_addr constant [4 x i8] c"pad\00" +@.str2719 = private unnamed_addr constant [4 x i8] c"gap\00" +@.str2720 = private unnamed_addr constant [3 x i8] c"bg\00" +@.str2721 = private unnamed_addr constant [3 x i8] c"fg\00" +@.str2722 = private unnamed_addr constant [7 x i8] c"border\00" +@.str2723 = private unnamed_addr constant [5 x i8] c"grow\00" +@.str2724 = private unnamed_addr constant [5 x i8] c"font\00" +@.str2725 = private unnamed_addr constant [5 x i8] c"size\00" +@.str2726 = private unnamed_addr constant [6 x i8] c"inset\00" +@.str2727 = private unnamed_addr constant [6 x i8] c"focus\00" +@.str2728 = private unnamed_addr constant [33 x i8] c" call void @fn_rt_ui_reset(i32 \00" +@.str2729 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2730 = private unnamed_addr constant [2 x i8] c"1\00" +@.str2731 = private unnamed_addr constant [3 x i8] c"id\00" +@.str2732 = private unnamed_addr constant [5 x i8] c"text\00" +@.str2733 = private unnamed_addr constant [39 x i8] c" call void @fn_rt_ui_static_text(i32 \00" +@.str2734 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str2735 = private unnamed_addr constant [3 x i8] c")\0A\00" +@.str2736 = private unnamed_addr constant [5 x i8] c"skin\00" +@.str2737 = private unnamed_addr constant [6 x i8] c"image\00" +@.str2738 = private unnamed_addr constant [32 x i8] c"call i32 @fn_rt_image_load(ptr \00" +@.str2739 = private unnamed_addr constant [2 x i8] c")\00" +@.str2740 = private unnamed_addr constant [5 x i8] c"skin\00" +@.str2741 = private unnamed_addr constant [6 x i8] c"align\00" +@.str2742 = private unnamed_addr constant [7 x i8] c"center\00" +@.str2743 = private unnamed_addr constant [4 x i8] c"end\00" +@.str2744 = private unnamed_addr constant [2 x i8] c"1\00" +@.str2745 = private unnamed_addr constant [34 x i8] c"define void @ui_build() {\0Aentry:\0A\00" +@.str2746 = private unnamed_addr constant [15 x i8] c" ret void\0A}\0A\0A\00" +@.str2747 = private unnamed_addr constant [3 x i8] c", \00" +@.str2748 = private unnamed_addr constant [7 x i8] c" %arg_\00" +@.str2749 = private unnamed_addr constant [5 x i8] c"void\00" +@.str2750 = private unnamed_addr constant [20 x i8] c" %retval = alloca \00" +@.str2751 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2752 = private unnamed_addr constant [9 x i8] c" store \00" +@.str2753 = private unnamed_addr constant [7 x i8] c" %arg_\00" +@.str2754 = private unnamed_addr constant [7 x i8] c", ptr \00" +@.str2755 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2756 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" +@.str2757 = private unnamed_addr constant [6 x i8] c"ret:\0A\00" +@.str2758 = private unnamed_addr constant [5 x i8] c"void\00" +@.str2759 = private unnamed_addr constant [12 x i8] c" ret void\0A\00" +@.str2760 = private unnamed_addr constant [6 x i8] c"load \00" +@.str2761 = private unnamed_addr constant [14 x i8] c", ptr %retval\00" +@.str2762 = private unnamed_addr constant [7 x i8] c" ret \00" +@.str2763 = private unnamed_addr constant [2 x i8] c" \00" +@.str2764 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2765 = private unnamed_addr constant [8 x i8] c"define \00" +@.str2766 = private unnamed_addr constant [6 x i8] c" @fn_\00" +@.str2767 = private unnamed_addr constant [2 x i8] c"(\00" +@.str2768 = private unnamed_addr constant [12 x i8] c") {\0Aentry:\0A\00" +@.str2769 = private unnamed_addr constant [4 x i8] c"}\0A\0A\00" +@.str2770 = private unnamed_addr constant [4 x i8] c"int\00" +@.str2771 = private unnamed_addr constant [24 x i8] c" %retval = alloca i32\0A\00" +@.str2772 = private unnamed_addr constant [32 x i8] c" store i32 %argc, ptr @L_argc\0A\00" +@.str2773 = private unnamed_addr constant [32 x i8] c" store ptr %argv, ptr @L_argv\0A\00" +@.str2774 = private unnamed_addr constant [28 x i8] c" store i32 0, ptr %retval\0A\00" +@.str2775 = private unnamed_addr constant [17 x i8] c" br label %ret\0A\00" +@.str2776 = private unnamed_addr constant [6 x i8] c"ret:\0A\00" +@.str2777 = private unnamed_addr constant [22 x i8] c"load i32, ptr %retval\00" +@.str2778 = private unnamed_addr constant [11 x i8] c" ret i32 \00" +@.str2779 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2780 = private unnamed_addr constant [49 x i8] c"define i32 @main(i32 %argc, ptr %argv) {\0Aentry:\0A\00" +@.str2781 = private unnamed_addr constant [3 x i8] c"}\0A\00" +@.str2782 = private unnamed_addr constant [3 x i8] c"wb\00" +@.str2783 = private unnamed_addr constant [7 x i8] c".ludic\00" +@.str2784 = private unnamed_addr constant [2 x i8] c"/\00" +@.str2785 = private unnamed_addr constant [6 x i8] c"ludic\00" +@.str2786 = private unnamed_addr constant [11 x i8] c"--windowed\00" +@.str2787 = private unnamed_addr constant [11 x i8] c"--headless\00" +@.str2788 = private unnamed_addr constant [12 x i8] c"--emit-llvm\00" +@.str2789 = private unnamed_addr constant [6 x i8] c"--fmt\00" +@.str2790 = private unnamed_addr constant [13 x i8] c"--save-temps\00" +@.str2791 = private unnamed_addr constant [6 x i8] c"--run\00" +@.str2792 = private unnamed_addr constant [3 x i8] c"-o\00" +@.str2793 = private unnamed_addr constant [31 x i8] c"ludicc: ignoring unknown flag \00" +@.str2794 = private unnamed_addr constant [2 x i8] c"\0A\00" +@.str2795 = private unnamed_addr constant [90 x i8] c"usage: ludicc [-o out] [--windowed|--headless] [--emit-llvm] [--save-temps]\0A\00" +@.str2796 = private unnamed_addr constant [27 x i8] c"ludicc: cannot open input\0A\00" +@.str2797 = private unnamed_addr constant [16 x i8] c"/tmp/ludic-run-\00" +@.str2798 = private unnamed_addr constant [10 x i8] c"mkdir -p \00" +@.str2799 = private unnamed_addr constant [4 x i8] c".ll\00" +@.str2800 = private unnamed_addr constant [25 x i8] c"ludicc: cannot write IR\0A\00" +@.str2801 = private unnamed_addr constant [9 x i8] c"LUDIC_CC\00" +@.str2802 = private unnamed_addr constant [6 x i8] c"clang\00" +@.str2803 = private unnamed_addr constant [11 x i8] c"LUDIC_HOME\00" +@.str2804 = private unnamed_addr constant [27 x i8] c" -O2 -Wno-override-module \00" +@.str2805 = private unnamed_addr constant [24 x i8] c"runtime/native/cocoa.ll\00" +@.str2806 = private unnamed_addr constant [2 x i8] c" \00" +@.str2807 = private unnamed_addr constant [42 x i8] c" -framework Cocoa -Wl,-rpath,@loader_path\00" +@.str2808 = private unnamed_addr constant [5 x i8] c" -o \00" +@.str2809 = private unnamed_addr constant [7 x i8] c"rm -f \00" +@.str2810 = private unnamed_addr constant [21 x i8] c"ludicc: link failed\0A\00" define i32 @fn_str_eq(ptr %a, ptr %b) { entry: br label %loop @@ -4731,18 +5979,114 @@ ret: ret ptr %t191 } +define ptr @fn_parse_emit() { +entry: + %retval = alloca ptr + %t3 = alloca ptr + %t8 = alloca ptr + %t14 = alloca ptr + %t0 = load i32, ptr @g_pi + %t1 = add i32 %t0, 1 + store i32 %t1, ptr @g_pi + %t2 = call ptr @fn_node(i32 49) + store ptr %t2, ptr %t3 + %t4 = load ptr, ptr %t3 + %t5 = getelementptr inbounds %Cmp_Node, ptr %t4, i32 0, i32 1 + %t6 = call ptr @fn_eat_id() + store ptr %t6, ptr %t5 + %t7 = call ptr @fn_node(i32 41) + store ptr %t7, ptr %t8 + call void @fn_eat_op(ptr @.str12) + call void @fn_skipnl() + br label %wcond0 +wcond0: + %t9 = call i32 @fn_is_op(ptr @.str13) + %t10 = icmp eq i32 %t9, 0 + %t11 = zext i1 %t10 to i32 + %t12 = icmp ne i32 %t11, 0 + br i1 %t12, label %wbody1, label %wend2 +wbody1: + %t13 = call ptr @fn_node(i32 42) + store ptr %t13, ptr %t14 + %t15 = load ptr, ptr %t14 + %t16 = getelementptr inbounds %Cmp_Node, ptr %t15, i32 0, i32 1 + %t17 = call ptr @fn_eat_id() + store ptr %t17, ptr %t16 + call void @fn_eat_op(ptr @.str14) + %t18 = load ptr, ptr %t14 + %t19 = getelementptr inbounds %Cmp_Node, ptr %t18, i32 0, i32 4 + %t20 = call ptr @fn_expr() + store ptr %t20, ptr %t19 + %t21 = load ptr, ptr %t8 + %t22 = getelementptr inbounds %Cmp_Node, ptr %t21, i32 0, i32 7 + %t23 = load ptr, ptr %t22 + %t24 = getelementptr inbounds %LSlice, ptr %t23, i32 0, i32 1 + %t25 = getelementptr inbounds %LSlice, ptr %t23, i32 0, i32 2 + %t26 = getelementptr inbounds %LSlice, ptr %t23, i32 0, i32 0 + %t27 = load i32, ptr %t24 + %t28 = load i32, ptr %t25 + %t29 = icmp sge i32 %t27, %t28 + br i1 %t29, label %grow3, label %put4 +grow3: + %t30 = mul i32 %t28, 2 + %t31 = icmp eq i32 %t28, 0 + %t32 = select i1 %t31, i32 8, i32 %t30 + %t33 = getelementptr ptr, ptr null, i32 1 + %t34 = ptrtoint ptr %t33 to i64 + %t35 = zext i32 %t32 to i64 + %t36 = mul i64 %t35, %t34 + %t37 = load ptr, ptr %t26 + %t38 = call ptr @realloc(ptr %t37, i64 %t36) + store ptr %t38, ptr %t26 + store i32 %t32, ptr %t25 + br label %put4 +put4: + %t39 = load ptr, ptr %t14 + %t40 = load ptr, ptr %t26 + %t41 = getelementptr inbounds ptr, ptr %t40, i32 %t27 + store ptr %t39, ptr %t41 + %t42 = add i32 %t27, 1 + store i32 %t42, ptr %t24 + call void @fn_skipnl() + %t43 = call i32 @fn_is_op(ptr @.str15) + %t44 = icmp ne i32 %t43, 0 + br i1 %t44, label %then5, label %ifend7 +then5: + %t45 = load i32, ptr @g_pi + %t46 = add i32 %t45, 1 + store i32 %t46, ptr @g_pi + call void @fn_skipnl() + br label %ifend7 +ifend7: + br label %wcond0 +wend2: + call void @fn_eat_op(ptr @.str16) + %t47 = load ptr, ptr %t3 + %t48 = getelementptr inbounds %Cmp_Node, ptr %t47, i32 0, i32 4 + %t49 = load ptr, ptr %t8 + store ptr %t49, ptr %t48 + %t50 = load ptr, ptr %t3 + store ptr %t50, ptr %retval + br label %ret +ret: + %t51 = load ptr, ptr %retval + ret ptr %t51 +} + define ptr @fn_p_primary() { entry: %retval = alloca ptr %t6 = alloca ptr - %t26 = alloca ptr - %t42 = alloca ptr - %t58 = alloca ptr - %t79 = alloca ptr - %t91 = alloca ptr + %t19 = alloca i32 + %t20 = alloca i32 + %t60 = alloca ptr + %t76 = alloca ptr + %t92 = alloca ptr %t113 = alloca ptr - %t119 = alloca ptr - %t133 = alloca ptr + %t125 = alloca ptr + %t147 = alloca ptr + %t153 = alloca ptr + %t167 = alloca ptr %t0 = load ptr, ptr @g_toks %t1 = getelementptr inbounds %LSlice, ptr %t0, i32 0, i32 0 %t2 = load ptr, ptr %t1 @@ -4768,193 +6112,242 @@ then0: store ptr %t18, ptr %retval br label %ret ifend2: - %t19 = load ptr, ptr %t6 - %t20 = getelementptr inbounds %Cmp_Tok, ptr %t19, i32 0, i32 0 - %t21 = load i32, ptr %t20 - %t22 = icmp eq i32 %t21, 1 - %t23 = zext i1 %t22 to i32 - %t24 = icmp ne i32 %t23, 0 - br i1 %t24, label %then3, label %ifend5 -then3: - %t25 = call ptr @fn_node(i32 30) - store ptr %t25, ptr %t26 - %t27 = load ptr, ptr %t26 - %t28 = getelementptr inbounds %Cmp_Node, ptr %t27, i32 0, i32 2 - %t29 = load ptr, ptr %t6 - %t30 = getelementptr inbounds %Cmp_Tok, ptr %t29, i32 0, i32 2 - %t31 = load i32, ptr %t30 - store i32 %t31, ptr %t28 - %t32 = load i32, ptr @g_pi - %t33 = add i32 %t32, 1 - store i32 %t33, ptr @g_pi - %t34 = load ptr, ptr %t26 - store ptr %t34, ptr %retval - br label %ret -ifend5: - %t35 = load ptr, ptr %t6 - %t36 = getelementptr inbounds %Cmp_Tok, ptr %t35, i32 0, i32 0 - %t37 = load i32, ptr %t36 - %t38 = icmp eq i32 %t37, 6 - %t39 = zext i1 %t38 to i32 - %t40 = icmp ne i32 %t39, 0 - br i1 %t40, label %then6, label %ifend8 -then6: - %t41 = call ptr @fn_node(i32 40) - store ptr %t41, ptr %t42 + %t21 = load ptr, ptr %t6 + %t22 = getelementptr inbounds %Cmp_Tok, ptr %t21, i32 0, i32 0 + %t23 = load i32, ptr %t22 + %t24 = icmp eq i32 %t23, 0 + %t25 = zext i1 %t24 to i32 + %t26 = icmp ne i32 %t25, 0 + %t27 = zext i1 %t26 to i32 + store i32 %t27, ptr %t20 + br i1 %t26, label %sc3, label %scend4 +sc3: + %t28 = load ptr, ptr %t6 + %t29 = getelementptr inbounds %Cmp_Tok, ptr %t28, i32 0, i32 1 + %t30 = load ptr, ptr %t29 + %t31 = call i32 @fn_str_eq(ptr %t30, ptr @.str17) + %t32 = icmp ne i32 %t31, 0 + %t33 = zext i1 %t32 to i32 + store i32 %t33, ptr %t20 + br label %scend4 +scend4: + %t34 = load i32, ptr %t20 + %t35 = icmp ne i32 %t34, 0 + %t36 = zext i1 %t35 to i32 + store i32 %t36, ptr %t19 + br i1 %t35, label %sc5, label %scend6 +sc5: + %t37 = load ptr, ptr @g_toks + %t38 = getelementptr inbounds %LSlice, ptr %t37, i32 0, i32 0 + %t39 = load ptr, ptr %t38 + %t40 = load i32, ptr @g_pi + %t41 = add i32 %t40, 1 + %t42 = getelementptr inbounds ptr, ptr %t39, i32 %t41 %t43 = load ptr, ptr %t42 - %t44 = getelementptr inbounds %Cmp_Node, ptr %t43, i32 0, i32 2 - %t45 = load ptr, ptr %t6 - %t46 = getelementptr inbounds %Cmp_Tok, ptr %t45, i32 0, i32 2 - %t47 = load i32, ptr %t46 - store i32 %t47, ptr %t44 - %t48 = load i32, ptr @g_pi - %t49 = add i32 %t48, 1 - store i32 %t49, ptr @g_pi - %t50 = load ptr, ptr %t42 - store ptr %t50, ptr %retval + %t44 = getelementptr inbounds %Cmp_Tok, ptr %t43, i32 0, i32 0 + %t45 = load i32, ptr %t44 + %t46 = icmp eq i32 %t45, 0 + %t47 = zext i1 %t46 to i32 + %t48 = icmp ne i32 %t47, 0 + %t49 = zext i1 %t48 to i32 + store i32 %t49, ptr %t19 + br label %scend6 +scend6: + %t50 = load i32, ptr %t19 + %t51 = icmp ne i32 %t50, 0 + br i1 %t51, label %then7, label %ifend9 +then7: + %t52 = call ptr @fn_parse_emit() + store ptr %t52, ptr %retval br label %ret -ifend8: - %t51 = load ptr, ptr %t6 - %t52 = getelementptr inbounds %Cmp_Tok, ptr %t51, i32 0, i32 0 - %t53 = load i32, ptr %t52 - %t54 = icmp eq i32 %t53, 2 - %t55 = zext i1 %t54 to i32 - %t56 = icmp ne i32 %t55, 0 - br i1 %t56, label %then9, label %ifend11 -then9: - %t57 = call ptr @fn_node(i32 31) - store ptr %t57, ptr %t58 - %t59 = load ptr, ptr %t58 - %t60 = getelementptr inbounds %Cmp_Node, ptr %t59, i32 0, i32 1 - %t61 = load ptr, ptr %t6 - %t62 = getelementptr inbounds %Cmp_Tok, ptr %t61, i32 0, i32 1 - %t63 = load ptr, ptr %t62 - store ptr %t63, ptr %t60 - %t64 = load i32, ptr @g_pi - %t65 = add i32 %t64, 1 - store i32 %t65, ptr @g_pi - %t66 = load ptr, ptr %t58 - store ptr %t66, ptr %retval +ifend9: + %t53 = load ptr, ptr %t6 + %t54 = getelementptr inbounds %Cmp_Tok, ptr %t53, i32 0, i32 0 + %t55 = load i32, ptr %t54 + %t56 = icmp eq i32 %t55, 1 + %t57 = zext i1 %t56 to i32 + %t58 = icmp ne i32 %t57, 0 + br i1 %t58, label %then10, label %ifend12 +then10: + %t59 = call ptr @fn_node(i32 30) + store ptr %t59, ptr %t60 + %t61 = load ptr, ptr %t60 + %t62 = getelementptr inbounds %Cmp_Node, ptr %t61, i32 0, i32 2 + %t63 = load ptr, ptr %t6 + %t64 = getelementptr inbounds %Cmp_Tok, ptr %t63, i32 0, i32 2 + %t65 = load i32, ptr %t64 + store i32 %t65, ptr %t62 + %t66 = load i32, ptr @g_pi + %t67 = add i32 %t66, 1 + store i32 %t67, ptr @g_pi + %t68 = load ptr, ptr %t60 + store ptr %t68, ptr %retval br label %ret -ifend11: - %t67 = load ptr, ptr %t6 - %t68 = getelementptr inbounds %Cmp_Tok, ptr %t67, i32 0, i32 0 - %t69 = load i32, ptr %t68 - %t70 = icmp eq i32 %t69, 0 - %t71 = zext i1 %t70 to i32 - %t72 = icmp ne i32 %t71, 0 - br i1 %t72, label %then12, label %ifend14 -then12: - %t73 = load ptr, ptr %t6 - %t74 = getelementptr inbounds %Cmp_Tok, ptr %t73, i32 0, i32 1 - %t75 = load ptr, ptr %t74 - %t76 = call i32 @fn_str_eq(ptr %t75, ptr @.str12) - %t77 = icmp ne i32 %t76, 0 - br i1 %t77, label %then15, label %ifend17 -then15: - %t78 = call ptr @fn_node(i32 32) - store ptr %t78, ptr %t79 - %t80 = load ptr, ptr %t79 - %t81 = getelementptr inbounds %Cmp_Node, ptr %t80, i32 0, i32 2 - store i32 1, ptr %t81 +ifend12: + %t69 = load ptr, ptr %t6 + %t70 = getelementptr inbounds %Cmp_Tok, ptr %t69, i32 0, i32 0 + %t71 = load i32, ptr %t70 + %t72 = icmp eq i32 %t71, 6 + %t73 = zext i1 %t72 to i32 + %t74 = icmp ne i32 %t73, 0 + br i1 %t74, label %then13, label %ifend15 +then13: + %t75 = call ptr @fn_node(i32 40) + store ptr %t75, ptr %t76 + %t77 = load ptr, ptr %t76 + %t78 = getelementptr inbounds %Cmp_Node, ptr %t77, i32 0, i32 2 + %t79 = load ptr, ptr %t6 + %t80 = getelementptr inbounds %Cmp_Tok, ptr %t79, i32 0, i32 2 + %t81 = load i32, ptr %t80 + store i32 %t81, ptr %t78 %t82 = load i32, ptr @g_pi %t83 = add i32 %t82, 1 store i32 %t83, ptr @g_pi - %t84 = load ptr, ptr %t79 + %t84 = load ptr, ptr %t76 store ptr %t84, ptr %retval br label %ret -ifend17: +ifend15: %t85 = load ptr, ptr %t6 - %t86 = getelementptr inbounds %Cmp_Tok, ptr %t85, i32 0, i32 1 - %t87 = load ptr, ptr %t86 - %t88 = call i32 @fn_str_eq(ptr %t87, ptr @.str13) - %t89 = icmp ne i32 %t88, 0 - br i1 %t89, label %then18, label %ifend20 -then18: - %t90 = call ptr @fn_node(i32 32) - store ptr %t90, ptr %t91 - %t92 = load ptr, ptr %t91 - %t93 = getelementptr inbounds %Cmp_Node, ptr %t92, i32 0, i32 2 - store i32 0, ptr %t93 - %t94 = load i32, ptr @g_pi - %t95 = add i32 %t94, 1 - store i32 %t95, ptr @g_pi - %t96 = load ptr, ptr %t91 - store ptr %t96, ptr %retval + %t86 = getelementptr inbounds %Cmp_Tok, ptr %t85, i32 0, i32 0 + %t87 = load i32, ptr %t86 + %t88 = icmp eq i32 %t87, 2 + %t89 = zext i1 %t88 to i32 + %t90 = icmp ne i32 %t89, 0 + br i1 %t90, label %then16, label %ifend18 +then16: + %t91 = call ptr @fn_node(i32 31) + store ptr %t91, ptr %t92 + %t93 = load ptr, ptr %t92 + %t94 = getelementptr inbounds %Cmp_Node, ptr %t93, i32 0, i32 1 + %t95 = load ptr, ptr %t6 + %t96 = getelementptr inbounds %Cmp_Tok, ptr %t95, i32 0, i32 1 + %t97 = load ptr, ptr %t96 + store ptr %t97, ptr %t94 + %t98 = load i32, ptr @g_pi + %t99 = add i32 %t98, 1 + store i32 %t99, ptr @g_pi + %t100 = load ptr, ptr %t92 + store ptr %t100, ptr %retval br label %ret -ifend20: - %t97 = load ptr, ptr %t6 - %t98 = getelementptr inbounds %Cmp_Tok, ptr %t97, i32 0, i32 1 - %t99 = load ptr, ptr %t98 - %t100 = call i32 @fn_str_eq(ptr %t99, ptr @.str14) - %t101 = icmp ne i32 %t100, 0 - br i1 %t101, label %then21, label %ifend23 -then21: - %t102 = load i32, ptr @g_pi - %t103 = add i32 %t102, 1 - store i32 %t103, ptr @g_pi - %t104 = call ptr @fn_node(i32 43) - store ptr %t104, ptr %retval - br label %ret -ifend23: - %t105 = load ptr, ptr %t6 - %t106 = getelementptr inbounds %Cmp_Tok, ptr %t105, i32 0, i32 1 - %t107 = load ptr, ptr %t106 - %t108 = call i32 @fn_str_eq(ptr %t107, ptr @.str15) - %t109 = icmp ne i32 %t108, 0 - br i1 %t109, label %then24, label %ifend26 -then24: - %t110 = load i32, ptr @g_pi - %t111 = add i32 %t110, 1 - store i32 %t111, ptr @g_pi - %t112 = call ptr @fn_node(i32 39) +ifend18: + %t101 = load ptr, ptr %t6 + %t102 = getelementptr inbounds %Cmp_Tok, ptr %t101, i32 0, i32 0 + %t103 = load i32, ptr %t102 + %t104 = icmp eq i32 %t103, 0 + %t105 = zext i1 %t104 to i32 + %t106 = icmp ne i32 %t105, 0 + br i1 %t106, label %then19, label %ifend21 +then19: + %t107 = load ptr, ptr %t6 + %t108 = getelementptr inbounds %Cmp_Tok, ptr %t107, i32 0, i32 1 + %t109 = load ptr, ptr %t108 + %t110 = call i32 @fn_str_eq(ptr %t109, ptr @.str18) + %t111 = icmp ne i32 %t110, 0 + br i1 %t111, label %then22, label %ifend24 +then22: + %t112 = call ptr @fn_node(i32 32) store ptr %t112, ptr %t113 %t114 = load ptr, ptr %t113 - %t115 = getelementptr inbounds %Cmp_Node, ptr %t114, i32 0, i32 1 - %t116 = call ptr @fn_ptype() - store ptr %t116, ptr %t115 - %t117 = load ptr, ptr %t113 - store ptr %t117, ptr %retval + %t115 = getelementptr inbounds %Cmp_Node, ptr %t114, i32 0, i32 2 + store i32 1, ptr %t115 + %t116 = load i32, ptr @g_pi + %t117 = add i32 %t116, 1 + store i32 %t117, ptr @g_pi + %t118 = load ptr, ptr %t113 + store ptr %t118, ptr %retval br label %ret -ifend26: - %t118 = call ptr @fn_node(i32 33) - store ptr %t118, ptr %t119 - %t120 = load ptr, ptr %t119 - %t121 = getelementptr inbounds %Cmp_Node, ptr %t120, i32 0, i32 1 - %t122 = load ptr, ptr %t6 - %t123 = getelementptr inbounds %Cmp_Tok, ptr %t122, i32 0, i32 1 - %t124 = load ptr, ptr %t123 - store ptr %t124, ptr %t121 - %t125 = load i32, ptr @g_pi - %t126 = add i32 %t125, 1 - store i32 %t126, ptr @g_pi - %t127 = load ptr, ptr %t119 - store ptr %t127, ptr %retval +ifend24: + %t119 = load ptr, ptr %t6 + %t120 = getelementptr inbounds %Cmp_Tok, ptr %t119, i32 0, i32 1 + %t121 = load ptr, ptr %t120 + %t122 = call i32 @fn_str_eq(ptr %t121, ptr @.str19) + %t123 = icmp ne i32 %t122, 0 + br i1 %t123, label %then25, label %ifend27 +then25: + %t124 = call ptr @fn_node(i32 32) + store ptr %t124, ptr %t125 + %t126 = load ptr, ptr %t125 + %t127 = getelementptr inbounds %Cmp_Node, ptr %t126, i32 0, i32 2 + store i32 0, ptr %t127 + %t128 = load i32, ptr @g_pi + %t129 = add i32 %t128, 1 + store i32 %t129, ptr @g_pi + %t130 = load ptr, ptr %t125 + store ptr %t130, ptr %retval br label %ret -ifend14: - %t128 = call i32 @fn_is_op(ptr @.str16) - %t129 = icmp ne i32 %t128, 0 - br i1 %t129, label %then27, label %ifend29 -then27: - %t130 = load i32, ptr @g_pi - %t131 = add i32 %t130, 1 - store i32 %t131, ptr @g_pi +ifend27: + %t131 = load ptr, ptr %t6 + %t132 = getelementptr inbounds %Cmp_Tok, ptr %t131, i32 0, i32 1 + %t133 = load ptr, ptr %t132 + %t134 = call i32 @fn_str_eq(ptr %t133, ptr @.str20) + %t135 = icmp ne i32 %t134, 0 + br i1 %t135, label %then28, label %ifend30 +then28: + %t136 = load i32, ptr @g_pi + %t137 = add i32 %t136, 1 + store i32 %t137, ptr @g_pi + %t138 = call ptr @fn_node(i32 43) + store ptr %t138, ptr %retval + br label %ret +ifend30: + %t139 = load ptr, ptr %t6 + %t140 = getelementptr inbounds %Cmp_Tok, ptr %t139, i32 0, i32 1 + %t141 = load ptr, ptr %t140 + %t142 = call i32 @fn_str_eq(ptr %t141, ptr @.str21) + %t143 = icmp ne i32 %t142, 0 + br i1 %t143, label %then31, label %ifend33 +then31: + %t144 = load i32, ptr @g_pi + %t145 = add i32 %t144, 1 + store i32 %t145, ptr @g_pi + %t146 = call ptr @fn_node(i32 39) + store ptr %t146, ptr %t147 + %t148 = load ptr, ptr %t147 + %t149 = getelementptr inbounds %Cmp_Node, ptr %t148, i32 0, i32 1 + %t150 = call ptr @fn_ptype() + store ptr %t150, ptr %t149 + %t151 = load ptr, ptr %t147 + store ptr %t151, ptr %retval + br label %ret +ifend33: + %t152 = call ptr @fn_node(i32 33) + store ptr %t152, ptr %t153 + %t154 = load ptr, ptr %t153 + %t155 = getelementptr inbounds %Cmp_Node, ptr %t154, i32 0, i32 1 + %t156 = load ptr, ptr %t6 + %t157 = getelementptr inbounds %Cmp_Tok, ptr %t156, i32 0, i32 1 + %t158 = load ptr, ptr %t157 + store ptr %t158, ptr %t155 + %t159 = load i32, ptr @g_pi + %t160 = add i32 %t159, 1 + store i32 %t160, ptr @g_pi + %t161 = load ptr, ptr %t153 + store ptr %t161, ptr %retval + br label %ret +ifend21: + %t162 = call i32 @fn_is_op(ptr @.str22) + %t163 = icmp ne i32 %t162, 0 + br i1 %t163, label %then34, label %ifend36 +then34: + %t164 = load i32, ptr @g_pi + %t165 = add i32 %t164, 1 + store i32 %t165, ptr @g_pi call void @fn_skipnl() - %t132 = call ptr @fn_expr() - store ptr %t132, ptr %t133 + %t166 = call ptr @fn_expr() + store ptr %t166, ptr %t167 call void @fn_skipnl() - call void @fn_eat_op(ptr @.str17) - %t134 = load ptr, ptr %t133 - store ptr %t134, ptr %retval + call void @fn_eat_op(ptr @.str23) + %t168 = load ptr, ptr %t167 + store ptr %t168, ptr %retval br label %ret -ifend29: - call void @fn_perr(ptr @.str18) - %t135 = call ptr @fn_node(i32 30) - store ptr %t135, ptr %retval +ifend36: + call void @fn_perr(ptr @.str24) + %t169 = call ptr @fn_node(i32 30) + store ptr %t169, ptr %retval br label %ret ret: - %t136 = load ptr, ptr %retval - ret ptr %t136 + %t170 = load ptr, ptr %retval + ret ptr %t170 } define ptr @fn_p_postfix() { @@ -4973,7 +6366,7 @@ wcond0: %t2 = icmp ne i32 1, 0 br i1 %t2, label %wbody1, label %wend2 wbody1: - %t3 = call i32 @fn_is_op(ptr @.str19) + %t3 = call i32 @fn_is_op(ptr @.str25) %t4 = icmp ne i32 %t3, 0 br i1 %t4, label %then3, label %else4 then3: @@ -4994,7 +6387,7 @@ then3: store ptr %t15, ptr %t1 br label %ifend5 else4: - %t16 = call i32 @fn_is_op(ptr @.str20) + %t16 = call i32 @fn_is_op(ptr @.str26) %t17 = icmp ne i32 %t16, 0 br i1 %t17, label %then6, label %else7 then6: @@ -5003,7 +6396,7 @@ then6: store i32 %t19, ptr @g_pi %t20 = call ptr @fn_expr() store ptr %t20, ptr %t21 - %t22 = call i32 @fn_is_op(ptr @.str21) + %t22 = call i32 @fn_is_op(ptr @.str27) %t23 = icmp ne i32 %t22, 0 br i1 %t23, label %then9, label %else10 then9: @@ -5024,7 +6417,7 @@ then9: %t35 = getelementptr inbounds %Cmp_Node, ptr %t34, i32 0, i32 6 %t36 = call ptr @fn_expr() store ptr %t36, ptr %t35 - call void @fn_eat_op(ptr @.str22) + call void @fn_eat_op(ptr @.str28) %t37 = load ptr, ptr %t27 store ptr %t37, ptr %t1 br label %ifend11 @@ -5039,14 +6432,14 @@ else10: %t44 = getelementptr inbounds %Cmp_Node, ptr %t43, i32 0, i32 5 %t45 = load ptr, ptr %t21 store ptr %t45, ptr %t44 - call void @fn_eat_op(ptr @.str23) + call void @fn_eat_op(ptr @.str29) %t46 = load ptr, ptr %t39 store ptr %t46, ptr %t1 br label %ifend11 ifend11: br label %ifend8 else7: - %t47 = call i32 @fn_is_op(ptr @.str24) + %t47 = call i32 @fn_is_op(ptr @.str30) %t48 = icmp ne i32 %t47, 0 br i1 %t48, label %then12, label %else13 then12: @@ -5084,7 +6477,7 @@ entry: %t5 = alloca ptr %t17 = alloca ptr %t29 = alloca ptr - %t0 = call i32 @fn_is_op(ptr @.str25) + %t0 = call i32 @fn_is_op(ptr @.str31) %t1 = icmp ne i32 %t0, 0 br i1 %t1, label %then0, label %ifend2 then0: @@ -5095,7 +6488,7 @@ then0: store ptr %t4, ptr %t5 %t6 = load ptr, ptr %t5 %t7 = getelementptr inbounds %Cmp_Node, ptr %t6, i32 0, i32 1 - store ptr @.str26, ptr %t7 + store ptr @.str32, ptr %t7 %t8 = load ptr, ptr %t5 %t9 = getelementptr inbounds %Cmp_Node, ptr %t8, i32 0, i32 4 %t10 = call ptr @fn_p_unary() @@ -5104,7 +6497,7 @@ then0: store ptr %t11, ptr %retval br label %ret ifend2: - %t12 = call i32 @fn_is_op(ptr @.str27) + %t12 = call i32 @fn_is_op(ptr @.str33) %t13 = icmp ne i32 %t12, 0 br i1 %t13, label %then3, label %ifend5 then3: @@ -5115,7 +6508,7 @@ then3: store ptr %t16, ptr %t17 %t18 = load ptr, ptr %t17 %t19 = getelementptr inbounds %Cmp_Node, ptr %t18, i32 0, i32 1 - store ptr @.str28, ptr %t19 + store ptr @.str34, ptr %t19 %t20 = load ptr, ptr %t17 %t21 = getelementptr inbounds %Cmp_Node, ptr %t20, i32 0, i32 4 %t22 = call ptr @fn_p_unary() @@ -5124,7 +6517,7 @@ then3: store ptr %t23, ptr %retval br label %ret ifend5: - %t24 = call i32 @fn_is_id(ptr @.str29) + %t24 = call i32 @fn_is_id(ptr @.str35) %t25 = icmp ne i32 %t24, 0 br i1 %t25, label %then6, label %ifend8 then6: @@ -5135,7 +6528,7 @@ then6: store ptr %t28, ptr %t29 %t30 = load ptr, ptr %t29 %t31 = getelementptr inbounds %Cmp_Node, ptr %t30, i32 0, i32 1 - store ptr @.str30, ptr %t31 + store ptr @.str36, ptr %t31 %t32 = load ptr, ptr %t29 %t33 = getelementptr inbounds %Cmp_Node, ptr %t32, i32 0, i32 4 %t34 = call ptr @fn_p_unary() @@ -5198,13 +6591,13 @@ entry: store ptr %t0, ptr %t1 br label %wcond0 wcond0: - %t7 = call i32 @fn_is_op(ptr @.str31) + %t7 = call i32 @fn_is_op(ptr @.str37) %t8 = icmp ne i32 %t7, 0 %t9 = zext i1 %t8 to i32 store i32 %t9, ptr %t6 br i1 %t8, label %scend4, label %sc3 sc3: - %t10 = call i32 @fn_is_op(ptr @.str32) + %t10 = call i32 @fn_is_op(ptr @.str38) %t11 = icmp ne i32 %t10, 0 %t12 = zext i1 %t11 to i32 store i32 %t12, ptr %t6 @@ -5216,7 +6609,7 @@ scend4: store i32 %t15, ptr %t5 br i1 %t14, label %scend6, label %sc5 sc5: - %t16 = call i32 @fn_is_op(ptr @.str33) + %t16 = call i32 @fn_is_op(ptr @.str39) %t17 = icmp ne i32 %t16, 0 %t18 = zext i1 %t17 to i32 store i32 %t18, ptr %t5 @@ -5228,7 +6621,7 @@ scend6: store i32 %t21, ptr %t4 br i1 %t20, label %scend8, label %sc7 sc7: - %t22 = call i32 @fn_is_op(ptr @.str34) + %t22 = call i32 @fn_is_op(ptr @.str40) %t23 = icmp ne i32 %t22, 0 %t24 = zext i1 %t23 to i32 store i32 %t24, ptr %t4 @@ -5240,7 +6633,7 @@ scend8: store i32 %t27, ptr %t3 br i1 %t26, label %scend10, label %sc9 sc9: - %t28 = call i32 @fn_is_op(ptr @.str35) + %t28 = call i32 @fn_is_op(ptr @.str41) %t29 = icmp ne i32 %t28, 0 %t30 = zext i1 %t29 to i32 store i32 %t30, ptr %t3 @@ -5252,7 +6645,7 @@ scend10: store i32 %t33, ptr %t2 br i1 %t32, label %scend12, label %sc11 sc11: - %t34 = call i32 @fn_is_op(ptr @.str36) + %t34 = call i32 @fn_is_op(ptr @.str42) %t35 = icmp ne i32 %t34, 0 %t36 = zext i1 %t35 to i32 store i32 %t36, ptr %t2 @@ -5301,13 +6694,13 @@ entry: store ptr %t0, ptr %t1 br label %wcond0 wcond0: - %t5 = call i32 @fn_is_op(ptr @.str37) + %t5 = call i32 @fn_is_op(ptr @.str43) %t6 = icmp ne i32 %t5, 0 %t7 = zext i1 %t6 to i32 store i32 %t7, ptr %t4 br i1 %t6, label %scend4, label %sc3 sc3: - %t8 = call i32 @fn_is_op(ptr @.str38) + %t8 = call i32 @fn_is_op(ptr @.str44) %t9 = icmp ne i32 %t8, 0 %t10 = zext i1 %t9 to i32 store i32 %t10, ptr %t4 @@ -5319,7 +6712,7 @@ scend4: store i32 %t13, ptr %t3 br i1 %t12, label %scend6, label %sc5 sc5: - %t14 = call i32 @fn_is_op(ptr @.str39) + %t14 = call i32 @fn_is_op(ptr @.str45) %t15 = icmp ne i32 %t14, 0 %t16 = zext i1 %t15 to i32 store i32 %t16, ptr %t3 @@ -5331,7 +6724,7 @@ scend6: store i32 %t19, ptr %t2 br i1 %t18, label %scend8, label %sc7 sc7: - %t20 = call i32 @fn_is_op(ptr @.str40) + %t20 = call i32 @fn_is_op(ptr @.str46) %t21 = icmp ne i32 %t20, 0 %t22 = zext i1 %t21 to i32 store i32 %t22, ptr %t2 @@ -5382,13 +6775,13 @@ entry: store ptr %t0, ptr %t1 br label %wcond0 wcond0: - %t7 = call i32 @fn_is_op(ptr @.str41) + %t7 = call i32 @fn_is_op(ptr @.str47) %t8 = icmp ne i32 %t7, 0 %t9 = zext i1 %t8 to i32 store i32 %t9, ptr %t6 br i1 %t8, label %scend4, label %sc3 sc3: - %t10 = call i32 @fn_is_op(ptr @.str42) + %t10 = call i32 @fn_is_op(ptr @.str48) %t11 = icmp ne i32 %t10, 0 %t12 = zext i1 %t11 to i32 store i32 %t12, ptr %t6 @@ -5400,7 +6793,7 @@ scend4: store i32 %t15, ptr %t5 br i1 %t14, label %scend6, label %sc5 sc5: - %t16 = call i32 @fn_is_op(ptr @.str43) + %t16 = call i32 @fn_is_op(ptr @.str49) %t17 = icmp ne i32 %t16, 0 %t18 = zext i1 %t17 to i32 store i32 %t18, ptr %t5 @@ -5412,7 +6805,7 @@ scend6: store i32 %t21, ptr %t4 br i1 %t20, label %scend8, label %sc7 sc7: - %t22 = call i32 @fn_is_op(ptr @.str44) + %t22 = call i32 @fn_is_op(ptr @.str50) %t23 = icmp ne i32 %t22, 0 %t24 = zext i1 %t23 to i32 store i32 %t24, ptr %t4 @@ -5424,7 +6817,7 @@ scend8: store i32 %t27, ptr %t3 br i1 %t26, label %scend10, label %sc9 sc9: - %t28 = call i32 @fn_is_op(ptr @.str45) + %t28 = call i32 @fn_is_op(ptr @.str51) %t29 = icmp ne i32 %t28, 0 %t30 = zext i1 %t29 to i32 store i32 %t30, ptr %t3 @@ -5436,7 +6829,7 @@ scend10: store i32 %t33, ptr %t2 br i1 %t32, label %scend12, label %sc11 sc11: - %t34 = call i32 @fn_is_op(ptr @.str46) + %t34 = call i32 @fn_is_op(ptr @.str52) %t35 = icmp ne i32 %t34, 0 %t36 = zext i1 %t35 to i32 store i32 %t36, ptr %t2 @@ -5481,7 +6874,7 @@ entry: store ptr %t0, ptr %t1 br label %wcond0 wcond0: - %t2 = call i32 @fn_is_id(ptr @.str47) + %t2 = call i32 @fn_is_id(ptr @.str53) %t3 = icmp ne i32 %t2, 0 br i1 %t3, label %wbody1, label %wend2 wbody1: @@ -5490,7 +6883,7 @@ wbody1: store i32 %t5, ptr @g_pi %t6 = load ptr, ptr %t1 %t7 = call ptr @fn_p_cmp() - %t8 = call ptr @fn_mkbin(ptr @.str48, ptr %t6, ptr %t7) + %t8 = call ptr @fn_mkbin(ptr @.str54, ptr %t6, ptr %t7) store ptr %t8, ptr %t1 br label %wcond0 wend2: @@ -5510,7 +6903,7 @@ entry: store ptr %t0, ptr %t1 br label %wcond0 wcond0: - %t2 = call i32 @fn_is_id(ptr @.str49) + %t2 = call i32 @fn_is_id(ptr @.str55) %t3 = icmp ne i32 %t2, 0 br i1 %t3, label %wbody1, label %wend2 wbody1: @@ -5519,7 +6912,7 @@ wbody1: store i32 %t5, ptr @g_pi %t6 = load ptr, ptr %t1 %t7 = call ptr @fn_p_and() - %t8 = call ptr @fn_mkbin(ptr @.str50, ptr %t6, ptr %t7) + %t8 = call ptr @fn_mkbin(ptr @.str56, ptr %t6, ptr %t7) store ptr %t8, ptr %t1 br label %wcond0 wend2: @@ -5536,7 +6929,7 @@ entry: %retval = alloca ptr %t1 = alloca ptr %t6 = alloca ptr - call void @fn_eat_op(ptr @.str51) + call void @fn_eat_op(ptr @.str57) %t0 = call ptr @fn_node(i32 41) store ptr %t0, ptr %t1 br label %wcond0 @@ -5545,7 +6938,7 @@ wcond0: br i1 %t2, label %wbody1, label %wend2 wbody1: call void @fn_skipnl() - %t3 = call i32 @fn_is_op(ptr @.str52) + %t3 = call i32 @fn_is_op(ptr @.str58) %t4 = icmp ne i32 %t3, 0 br i1 %t4, label %then3, label %ifend5 then3: @@ -5557,7 +6950,7 @@ ifend5: %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 1 %t9 = call ptr @fn_eat_id() store ptr %t9, ptr %t8 - call void @fn_eat_op(ptr @.str53) + call void @fn_eat_op(ptr @.str59) %t10 = load ptr, ptr %t6 %t11 = getelementptr inbounds %Cmp_Node, ptr %t10, i32 0, i32 4 %t12 = call ptr @fn_expr() @@ -5592,7 +6985,7 @@ put7: store ptr %t31, ptr %t33 %t34 = add i32 %t19, 1 store i32 %t34, ptr %t16 - %t35 = call i32 @fn_is_op(ptr @.str54) + %t35 = call i32 @fn_is_op(ptr @.str60) %t36 = icmp ne i32 %t35, 0 br i1 %t36, label %then8, label %ifend10 then8: @@ -5603,7 +6996,7 @@ then8: ifend10: br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str55) + call void @fn_eat_op(ptr @.str61) %t39 = load ptr, ptr %t1 store ptr %t39, ptr %retval br label %ret @@ -5618,7 +7011,7 @@ entry: %t1 = alloca ptr %t37 = alloca i32 call void @fn_skipnl() - call void @fn_eat_op(ptr @.str56) + call void @fn_eat_op(ptr @.str62) %t0 = call ptr @fn_node(i32 7) store ptr %t0, ptr %t1 br label %wcond0 @@ -5627,7 +7020,7 @@ wcond0: br i1 %t2, label %wbody1, label %wend2 wbody1: call void @fn_skipnl() - %t3 = call i32 @fn_is_op(ptr @.str57) + %t3 = call i32 @fn_is_op(ptr @.str63) %t4 = icmp ne i32 %t3, 0 br i1 %t4, label %then3, label %ifend5 then3: @@ -5674,7 +7067,7 @@ put7: %t35 = icmp eq i32 %t34, 4 %t36 = zext i1 %t35 to i32 store i32 %t36, ptr %t37 - %t38 = call i32 @fn_is_op(ptr @.str58) + %t38 = call i32 @fn_is_op(ptr @.str64) %t39 = icmp ne i32 %t38, 0 br i1 %t39, label %then8, label %ifend10 then8: @@ -5687,12 +7080,12 @@ ifend10: %t43 = icmp ne i32 %t42, 0 br i1 %t43, label %then11, label %ifend13 then11: - call void @fn_perr(ptr @.str59) + call void @fn_perr(ptr @.str65) br label %ifend13 ifend13: br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str60) + call void @fn_eat_op(ptr @.str66) %t44 = load ptr, ptr %t1 store ptr %t44, ptr %retval br label %ret @@ -5720,21 +7113,24 @@ entry: %t199 = alloca ptr %t201 = alloca ptr %t213 = alloca ptr - %t256 = alloca ptr - %t269 = alloca ptr - %t274 = alloca i32 - %t289 = alloca i32 - %t298 = alloca ptr - %t337 = alloca ptr - %t345 = alloca ptr - %t379 = alloca ptr - %t429 = alloca ptr - %t430 = alloca i32 - %t431 = alloca i32 - %t432 = alloca i32 - %t433 = alloca i32 - %t461 = alloca ptr - %t492 = alloca ptr + %t248 = alloca i32 + %t279 = alloca ptr + %t292 = alloca ptr + %t297 = alloca i32 + %t312 = alloca i32 + %t321 = alloca ptr + %t357 = alloca ptr + %t384 = alloca ptr + %t430 = alloca ptr + %t438 = alloca ptr + %t472 = alloca ptr + %t522 = alloca ptr + %t523 = alloca i32 + %t524 = alloca i32 + %t525 = alloca i32 + %t526 = alloca i32 + %t554 = alloca ptr + %t585 = alloca ptr %t0 = load ptr, ptr @g_toks %t1 = getelementptr inbounds %LSlice, ptr %t0, i32 0, i32 0 %t2 = load ptr, ptr %t1 @@ -5753,7 +7149,7 @@ then0: %t14 = load ptr, ptr %t6 %t15 = getelementptr inbounds %Cmp_Tok, ptr %t14, i32 0, i32 1 %t16 = load ptr, ptr %t15 - %t17 = call i32 @fn_str_eq(ptr %t16, ptr @.str61) + %t17 = call i32 @fn_str_eq(ptr %t16, ptr @.str67) %t18 = icmp ne i32 %t17, 0 %t19 = zext i1 %t18 to i32 store i32 %t19, ptr %t13 @@ -5762,7 +7158,7 @@ sc3: %t20 = load ptr, ptr %t6 %t21 = getelementptr inbounds %Cmp_Tok, ptr %t20, i32 0, i32 1 %t22 = load ptr, ptr %t21 - %t23 = call i32 @fn_str_eq(ptr %t22, ptr @.str62) + %t23 = call i32 @fn_str_eq(ptr %t22, ptr @.str68) %t24 = icmp ne i32 %t23, 0 %t25 = zext i1 %t24 to i32 store i32 %t25, ptr %t13 @@ -5776,7 +7172,7 @@ then5: %t29 = load ptr, ptr %t6 %t30 = getelementptr inbounds %Cmp_Tok, ptr %t29, i32 0, i32 1 %t31 = load ptr, ptr %t30 - %t32 = call i32 @fn_str_eq(ptr %t31, ptr @.str63) + %t32 = call i32 @fn_str_eq(ptr %t31, ptr @.str69) %t33 = icmp ne i32 %t32, 0 br i1 %t33, label %then8, label %ifend10 then8: @@ -5807,7 +7203,7 @@ ifend10: %t52 = getelementptr inbounds %Cmp_Node, ptr %t51, i32 0, i32 1 %t53 = call ptr @fn_eat_id() store ptr %t53, ptr %t52 - %t54 = call i32 @fn_is_op(ptr @.str64) + %t54 = call i32 @fn_is_op(ptr @.str70) %t55 = icmp ne i32 %t54, 0 br i1 %t55, label %then11, label %ifend13 then11: @@ -5820,7 +7216,7 @@ then11: store ptr %t60, ptr %t59 br label %ifend13 ifend13: - %t61 = call i32 @fn_is_op(ptr @.str65) + %t61 = call i32 @fn_is_op(ptr @.str71) %t62 = icmp ne i32 %t61, 0 br i1 %t62, label %then14, label %ifend16 then14: @@ -5840,7 +7236,7 @@ ifend7: %t69 = load ptr, ptr %t6 %t70 = getelementptr inbounds %Cmp_Tok, ptr %t69, i32 0, i32 1 %t71 = load ptr, ptr %t70 - %t72 = call i32 @fn_str_eq(ptr %t71, ptr @.str66) + %t72 = call i32 @fn_str_eq(ptr %t71, ptr @.str72) %t73 = icmp ne i32 %t72, 0 br i1 %t73, label %then17, label %ifend19 then17: @@ -5864,7 +7260,7 @@ then17: store i32 %t90, ptr %t78 br i1 %t89, label %sc20, label %scend21 sc20: - %t91 = call i32 @fn_is_op(ptr @.str67) + %t91 = call i32 @fn_is_op(ptr @.str73) %t92 = icmp eq i32 %t91, 0 %t93 = zext i1 %t92 to i32 %t94 = icmp ne i32 %t93, 0 @@ -5889,7 +7285,7 @@ ifend19: %t102 = load ptr, ptr %t6 %t103 = getelementptr inbounds %Cmp_Tok, ptr %t102, i32 0, i32 1 %t104 = load ptr, ptr %t103 - %t105 = call i32 @fn_str_eq(ptr %t104, ptr @.str68) + %t105 = call i32 @fn_str_eq(ptr %t104, ptr @.str74) %t106 = icmp ne i32 %t105, 0 br i1 %t106, label %then25, label %ifend27 then25: @@ -5909,7 +7305,7 @@ then25: %t117 = load i32, ptr @g_pi store i32 %t117, ptr %t118 call void @fn_skipnl() - %t119 = call i32 @fn_is_id(ptr @.str69) + %t119 = call i32 @fn_is_id(ptr @.str75) %t120 = icmp ne i32 %t119, 0 br i1 %t120, label %then28, label %else29 then28: @@ -5917,7 +7313,7 @@ then28: %t122 = add i32 %t121, 1 store i32 %t122, ptr @g_pi call void @fn_skipnl() - %t123 = call i32 @fn_is_id(ptr @.str70) + %t123 = call i32 @fn_is_id(ptr @.str76) %t124 = icmp ne i32 %t123, 0 br i1 %t124, label %then31, label %else32 then31: @@ -5946,7 +7342,7 @@ ifend27: %t133 = load ptr, ptr %t6 %t134 = getelementptr inbounds %Cmp_Tok, ptr %t133, i32 0, i32 1 %t135 = load ptr, ptr %t134 - %t136 = call i32 @fn_str_eq(ptr %t135, ptr @.str71) + %t136 = call i32 @fn_str_eq(ptr %t135, ptr @.str77) %t137 = icmp ne i32 %t136, 0 br i1 %t137, label %then34, label %ifend36 then34: @@ -5970,14 +7366,14 @@ ifend36: %t149 = load ptr, ptr %t6 %t150 = getelementptr inbounds %Cmp_Tok, ptr %t149, i32 0, i32 1 %t151 = load ptr, ptr %t150 - %t152 = call i32 @fn_str_eq(ptr %t151, ptr @.str72) + %t152 = call i32 @fn_str_eq(ptr %t151, ptr @.str78) %t153 = icmp ne i32 %t152, 0 br i1 %t153, label %then37, label %ifend39 then37: %t154 = load i32, ptr @g_pi %t155 = add i32 %t154, 1 store i32 %t155, ptr @g_pi - %t156 = call i32 @fn_is_op(ptr @.str73) + %t156 = call i32 @fn_is_op(ptr @.str79) %t157 = icmp ne i32 %t156, 0 br i1 %t157, label %then40, label %ifend42 then40: @@ -5997,7 +7393,7 @@ ifend42: %t167 = getelementptr inbounds %Cmp_Node, ptr %t166, i32 0, i32 4 %t168 = call ptr @fn_expr() store ptr %t168, ptr %t167 - call void @fn_eat_op(ptr @.str74) + call void @fn_eat_op(ptr @.str80) %t169 = load ptr, ptr %t160 %t170 = getelementptr inbounds %Cmp_Node, ptr %t169, i32 0, i32 5 %t171 = call ptr @fn_expr() @@ -6013,7 +7409,7 @@ ifend39: %t176 = load ptr, ptr %t6 %t177 = getelementptr inbounds %Cmp_Tok, ptr %t176, i32 0, i32 1 %t178 = load ptr, ptr %t177 - %t179 = call i32 @fn_str_eq(ptr %t178, ptr @.str75) + %t179 = call i32 @fn_str_eq(ptr %t178, ptr @.str81) %t180 = icmp ne i32 %t179, 0 br i1 %t180, label %then43, label %ifend45 then43: @@ -6024,7 +7420,7 @@ ifend45: %t182 = load ptr, ptr %t6 %t183 = getelementptr inbounds %Cmp_Tok, ptr %t182, i32 0, i32 1 %t184 = load ptr, ptr %t183 - %t185 = call i32 @fn_str_eq(ptr %t184, ptr @.str76) + %t185 = call i32 @fn_str_eq(ptr %t184, ptr @.str82) %t186 = icmp ne i32 %t185, 0 br i1 %t186, label %then46, label %ifend48 then46: @@ -6038,7 +7434,7 @@ then46: %t193 = call ptr @fn_expr() store ptr %t193, ptr %t192 call void @fn_skipnl() - call void @fn_eat_op(ptr @.str77) + call void @fn_eat_op(ptr @.str83) store i32 0, ptr %t194 br label %wcond49 wcond49: @@ -6046,7 +7442,7 @@ wcond49: br i1 %t195, label %wbody50, label %wend51 wbody50: call void @fn_skipnl() - %t196 = call i32 @fn_is_op(ptr @.str78) + %t196 = call i32 @fn_is_op(ptr @.str84) %t197 = icmp ne i32 %t196, 0 br i1 %t197, label %then52, label %ifend54 then52: @@ -6060,7 +7456,7 @@ ifend54: %t203 = getelementptr inbounds %Cmp_Node, ptr %t202, i32 0, i32 1 %t204 = call ptr @fn_eat_id() store ptr %t204, ptr %t203 - %t205 = call i32 @fn_is_op(ptr @.str79) + %t205 = call i32 @fn_is_op(ptr @.str85) %t206 = icmp ne i32 %t205, 0 br i1 %t206, label %then55, label %else56 then55: @@ -6125,415 +7521,566 @@ put59: store i32 %t246, ptr %t194 br label %wcond49 wend51: - call void @fn_eat_op(ptr @.str80) + call void @fn_eat_op(ptr @.str86) %t247 = load ptr, ptr %t190 store ptr %t247, ptr %retval br label %ret ifend48: - %t248 = load ptr, ptr %t6 - %t249 = getelementptr inbounds %Cmp_Tok, ptr %t248, i32 0, i32 1 - %t250 = load ptr, ptr %t249 - %t251 = call i32 @fn_str_eq(ptr %t250, ptr @.str81) - %t252 = icmp ne i32 %t251, 0 - br i1 %t252, label %then60, label %ifend62 -then60: - %t253 = load i32, ptr @g_pi - %t254 = add i32 %t253, 1 - store i32 %t254, ptr @g_pi - %t255 = call ptr @fn_node(i32 26) - store ptr %t255, ptr %t256 + %t249 = load ptr, ptr %t6 + %t250 = getelementptr inbounds %Cmp_Tok, ptr %t249, i32 0, i32 1 + %t251 = load ptr, ptr %t250 + %t252 = call i32 @fn_str_eq(ptr %t251, ptr @.str87) + %t253 = icmp ne i32 %t252, 0 + %t254 = zext i1 %t253 to i32 + store i32 %t254, ptr %t248 + br i1 %t253, label %sc60, label %scend61 +sc60: + %t255 = load ptr, ptr @g_toks + %t256 = getelementptr inbounds %LSlice, ptr %t255, i32 0, i32 0 %t257 = load ptr, ptr %t256 - %t258 = getelementptr inbounds %Cmp_Node, ptr %t257, i32 0, i32 1 - %t259 = call ptr @fn_eat_id() - store ptr %t259, ptr %t258 - %t260 = load ptr, ptr %t256 - store ptr %t260, ptr %retval + %t258 = load i32, ptr @g_pi + %t259 = add i32 %t258, 1 + %t260 = getelementptr inbounds ptr, ptr %t257, i32 %t259 + %t261 = load ptr, ptr %t260 + %t262 = getelementptr inbounds %Cmp_Tok, ptr %t261, i32 0, i32 0 + %t263 = load i32, ptr %t262 + %t264 = icmp eq i32 %t263, 0 + %t265 = zext i1 %t264 to i32 + %t266 = icmp ne i32 %t265, 0 + %t267 = zext i1 %t266 to i32 + store i32 %t267, ptr %t248 + br label %scend61 +scend61: + %t268 = load i32, ptr %t248 + %t269 = icmp ne i32 %t268, 0 + br i1 %t269, label %then62, label %ifend64 +then62: + %t270 = call ptr @fn_parse_emit() + store ptr %t270, ptr %retval br label %ret -ifend62: - %t261 = load ptr, ptr %t6 - %t262 = getelementptr inbounds %Cmp_Tok, ptr %t261, i32 0, i32 1 - %t263 = load ptr, ptr %t262 - %t264 = call i32 @fn_str_eq(ptr %t263, ptr @.str82) - %t265 = icmp ne i32 %t264, 0 - br i1 %t265, label %then63, label %ifend65 -then63: - %t266 = load i32, ptr @g_pi - %t267 = add i32 %t266, 1 - store i32 %t267, ptr @g_pi - %t268 = call ptr @fn_node(i32 23) - store ptr %t268, ptr %t269 - %t270 = load ptr, ptr %t269 - %t271 = getelementptr inbounds %Cmp_Node, ptr %t270, i32 0, i32 4 - %t272 = call ptr @fn_expr() - store ptr %t272, ptr %t271 - %t273 = load ptr, ptr %t269 - store ptr %t273, ptr %retval +ifend64: + %t271 = load ptr, ptr %t6 + %t272 = getelementptr inbounds %Cmp_Tok, ptr %t271, i32 0, i32 1 + %t273 = load ptr, ptr %t272 + %t274 = call i32 @fn_str_eq(ptr %t273, ptr @.str88) + %t275 = icmp ne i32 %t274, 0 + br i1 %t275, label %then65, label %ifend67 +then65: + %t276 = load i32, ptr @g_pi + %t277 = add i32 %t276, 1 + store i32 %t277, ptr @g_pi + %t278 = call ptr @fn_node(i32 26) + store ptr %t278, ptr %t279 + %t280 = load ptr, ptr %t279 + %t281 = getelementptr inbounds %Cmp_Node, ptr %t280, i32 0, i32 1 + %t282 = call ptr @fn_eat_id() + store ptr %t282, ptr %t281 + %t283 = load ptr, ptr %t279 + store ptr %t283, ptr %retval br label %ret -ifend65: - %t275 = load ptr, ptr %t6 - %t276 = getelementptr inbounds %Cmp_Tok, ptr %t275, i32 0, i32 1 - %t277 = load ptr, ptr %t276 - %t278 = call i32 @fn_str_eq(ptr %t277, ptr @.str83) - %t279 = icmp ne i32 %t278, 0 - %t280 = zext i1 %t279 to i32 - store i32 %t280, ptr %t274 - br i1 %t279, label %scend67, label %sc66 -sc66: - %t281 = load ptr, ptr %t6 - %t282 = getelementptr inbounds %Cmp_Tok, ptr %t281, i32 0, i32 1 - %t283 = load ptr, ptr %t282 - %t284 = call i32 @fn_str_eq(ptr %t283, ptr @.str84) - %t285 = icmp ne i32 %t284, 0 - %t286 = zext i1 %t285 to i32 - store i32 %t286, ptr %t274 - br label %scend67 -scend67: - %t287 = load i32, ptr %t274 +ifend67: + %t284 = load ptr, ptr %t6 + %t285 = getelementptr inbounds %Cmp_Tok, ptr %t284, i32 0, i32 1 + %t286 = load ptr, ptr %t285 + %t287 = call i32 @fn_str_eq(ptr %t286, ptr @.str89) %t288 = icmp ne i32 %t287, 0 br i1 %t288, label %then68, label %ifend70 then68: - store i32 0, ptr %t289 - %t290 = load ptr, ptr %t6 - %t291 = getelementptr inbounds %Cmp_Tok, ptr %t290, i32 0, i32 1 - %t292 = load ptr, ptr %t291 - %t293 = call i32 @fn_str_eq(ptr %t292, ptr @.str85) - %t294 = icmp ne i32 %t293, 0 - br i1 %t294, label %then71, label %ifend73 -then71: - store i32 1, ptr %t289 - br label %ifend73 -ifend73: - %t295 = load i32, ptr @g_pi - %t296 = add i32 %t295, 1 - store i32 %t296, ptr @g_pi - %t297 = call ptr @fn_node(i32 28) - store ptr %t297, ptr %t298 - %t299 = load ptr, ptr %t298 - %t300 = getelementptr inbounds %Cmp_Node, ptr %t299, i32 0, i32 2 - %t301 = load i32, ptr %t289 - store i32 %t301, ptr %t300 - %t302 = load ptr, ptr %t298 - %t303 = getelementptr inbounds %Cmp_Node, ptr %t302, i32 0, i32 1 - %t304 = call ptr @fn_eat_id() - store ptr %t304, ptr %t303 - %t305 = call i32 @fn_is_id(ptr @.str86) - %t306 = icmp ne i32 %t305, 0 - br i1 %t306, label %then74, label %ifend76 -then74: - %t307 = load i32, ptr @g_pi - %t308 = add i32 %t307, 1 - store i32 %t308, ptr @g_pi - %t309 = load ptr, ptr %t298 - %t310 = getelementptr inbounds %Cmp_Node, ptr %t309, i32 0, i32 4 - %t311 = call ptr @fn_expr() - store ptr %t311, ptr %t310 - br label %ifend76 -ifend76: - %t312 = load ptr, ptr %t298 - store ptr %t312, ptr %retval + %t289 = load i32, ptr @g_pi + %t290 = add i32 %t289, 1 + store i32 %t290, ptr @g_pi + %t291 = call ptr @fn_node(i32 23) + store ptr %t291, ptr %t292 + %t293 = load ptr, ptr %t292 + %t294 = getelementptr inbounds %Cmp_Node, ptr %t293, i32 0, i32 4 + %t295 = call ptr @fn_expr() + store ptr %t295, ptr %t294 + %t296 = load ptr, ptr %t292 + store ptr %t296, ptr %retval br label %ret ifend70: + %t298 = load ptr, ptr %t6 + %t299 = getelementptr inbounds %Cmp_Tok, ptr %t298, i32 0, i32 1 + %t300 = load ptr, ptr %t299 + %t301 = call i32 @fn_str_eq(ptr %t300, ptr @.str90) + %t302 = icmp ne i32 %t301, 0 + %t303 = zext i1 %t302 to i32 + store i32 %t303, ptr %t297 + br i1 %t302, label %scend72, label %sc71 +sc71: + %t304 = load ptr, ptr %t6 + %t305 = getelementptr inbounds %Cmp_Tok, ptr %t304, i32 0, i32 1 + %t306 = load ptr, ptr %t305 + %t307 = call i32 @fn_str_eq(ptr %t306, ptr @.str91) + %t308 = icmp ne i32 %t307, 0 + %t309 = zext i1 %t308 to i32 + store i32 %t309, ptr %t297 + br label %scend72 +scend72: + %t310 = load i32, ptr %t297 + %t311 = icmp ne i32 %t310, 0 + br i1 %t311, label %then73, label %ifend75 +then73: + store i32 0, ptr %t312 %t313 = load ptr, ptr %t6 %t314 = getelementptr inbounds %Cmp_Tok, ptr %t313, i32 0, i32 1 %t315 = load ptr, ptr %t314 - %t316 = call i32 @fn_str_eq(ptr %t315, ptr @.str87) + %t316 = call i32 @fn_str_eq(ptr %t315, ptr @.str92) %t317 = icmp ne i32 %t316, 0 - br i1 %t317, label %then77, label %ifend79 -then77: + br i1 %t317, label %then76, label %ifend78 +then76: + store i32 1, ptr %t312 + br label %ifend78 +ifend78: %t318 = load i32, ptr @g_pi %t319 = add i32 %t318, 1 store i32 %t319, ptr @g_pi - %t320 = call ptr @fn_node(i32 17) - store ptr %t320, ptr %retval + %t320 = call ptr @fn_node(i32 28) + store ptr %t320, ptr %t321 + %t322 = load ptr, ptr %t321 + %t323 = getelementptr inbounds %Cmp_Node, ptr %t322, i32 0, i32 2 + %t324 = load i32, ptr %t312 + store i32 %t324, ptr %t323 + %t325 = call i32 @fn_is_id(ptr @.str93) + %t326 = icmp ne i32 %t325, 0 + br i1 %t326, label %then79, label %ifend81 +then79: + %t327 = load i32, ptr @g_pi + %t328 = add i32 %t327, 1 + store i32 %t328, ptr @g_pi + %t329 = load ptr, ptr %t321 + %t330 = getelementptr inbounds %Cmp_Node, ptr %t329, i32 0, i32 3 + store ptr @.str94, ptr %t330 + %t331 = load ptr, ptr %t321 + %t332 = getelementptr inbounds %Cmp_Node, ptr %t331, i32 0, i32 1 + %t333 = call ptr @fn_eat_id() + store ptr %t333, ptr %t332 + %t334 = load ptr, ptr %t321 + %t335 = getelementptr inbounds %Cmp_Node, ptr %t334, i32 0, i32 1 + %t336 = load ptr, ptr %t335 + call void @fn_note_toggled_layer(ptr %t336) + %t337 = load ptr, ptr %t321 + store ptr %t337, ptr %retval br label %ret -ifend79: - %t321 = load ptr, ptr %t6 - %t322 = getelementptr inbounds %Cmp_Tok, ptr %t321, i32 0, i32 1 - %t323 = load ptr, ptr %t322 - %t324 = call i32 @fn_str_eq(ptr %t323, ptr @.str88) - %t325 = icmp ne i32 %t324, 0 - br i1 %t325, label %then80, label %ifend82 -then80: - %t326 = load i32, ptr @g_pi - %t327 = add i32 %t326, 1 - store i32 %t327, ptr @g_pi - %t328 = call ptr @fn_node(i32 18) - store ptr %t328, ptr %retval - br label %ret -ifend82: - %t329 = load ptr, ptr %t6 - %t330 = getelementptr inbounds %Cmp_Tok, ptr %t329, i32 0, i32 1 - %t331 = load ptr, ptr %t330 - %t332 = call i32 @fn_str_eq(ptr %t331, ptr @.str89) - %t333 = icmp ne i32 %t332, 0 - br i1 %t333, label %then83, label %ifend85 -then83: - %t334 = load i32, ptr @g_pi - %t335 = add i32 %t334, 1 - store i32 %t335, ptr @g_pi - %t336 = call ptr @fn_node(i32 19) - store ptr %t336, ptr %t337 - %t338 = load ptr, ptr %t337 - %t339 = getelementptr inbounds %Cmp_Node, ptr %t338, i32 0, i32 4 - %t340 = call ptr @fn_expr() +ifend81: + %t338 = load ptr, ptr %t321 + %t339 = getelementptr inbounds %Cmp_Node, ptr %t338, i32 0, i32 1 + %t340 = call ptr @fn_eat_id() store ptr %t340, ptr %t339 - call void @fn_skipnl() - call void @fn_eat_op(ptr @.str90) - br label %wcond86 -wcond86: - %t341 = icmp ne i32 1, 0 - br i1 %t341, label %wbody87, label %wend88 -wbody87: - call void @fn_skipnl() - %t342 = call i32 @fn_is_op(ptr @.str91) - %t343 = icmp ne i32 %t342, 0 - br i1 %t343, label %then89, label %ifend91 -then89: - br label %wend88 -ifend91: - %t344 = call ptr @fn_node(i32 20) - store ptr %t344, ptr %t345 - br label %wcond92 -wcond92: - %t346 = icmp ne i32 1, 0 - br i1 %t346, label %wbody93, label %wend94 -wbody93: - %t347 = load ptr, ptr %t345 - %t348 = getelementptr inbounds %Cmp_Node, ptr %t347, i32 0, i32 7 - %t349 = load ptr, ptr %t348 - %t350 = getelementptr inbounds %LSlice, ptr %t349, i32 0, i32 1 - %t351 = getelementptr inbounds %LSlice, ptr %t349, i32 0, i32 2 - %t352 = getelementptr inbounds %LSlice, ptr %t349, i32 0, i32 0 - %t353 = load i32, ptr %t350 - %t354 = load i32, ptr %t351 - %t355 = icmp sge i32 %t353, %t354 - br i1 %t355, label %grow95, label %put96 -grow95: - %t356 = mul i32 %t354, 2 - %t357 = icmp eq i32 %t354, 0 - %t358 = select i1 %t357, i32 8, i32 %t356 - %t359 = getelementptr ptr, ptr null, i32 1 - %t360 = ptrtoint ptr %t359 to i64 - %t361 = zext i32 %t358 to i64 - %t362 = mul i64 %t361, %t360 - %t363 = load ptr, ptr %t352 - %t364 = call ptr @realloc(ptr %t363, i64 %t362) - store ptr %t364, ptr %t352 - store i32 %t358, ptr %t351 - br label %put96 -put96: - %t365 = call ptr @fn_expr() - %t366 = load ptr, ptr %t352 - %t367 = getelementptr inbounds ptr, ptr %t366, i32 %t353 - store ptr %t365, ptr %t367 - %t368 = add i32 %t353, 1 - store i32 %t368, ptr %t350 - %t369 = call i32 @fn_is_op(ptr @.str92) - %t370 = icmp ne i32 %t369, 0 - br i1 %t370, label %then97, label %ifend99 -then97: - %t371 = load i32, ptr @g_pi - %t372 = add i32 %t371, 1 - store i32 %t372, ptr @g_pi - call void @fn_skipnl() - br label %wcond92 -ifend99: - br label %wend94 -wend94: - call void @fn_eat_op(ptr @.str93) - call void @fn_skipnl() - %t373 = call i32 @fn_is_op(ptr @.str94) - %t374 = icmp ne i32 %t373, 0 - br i1 %t374, label %then100, label %else101 -then100: - %t375 = load ptr, ptr %t345 - %t376 = getelementptr inbounds %Cmp_Node, ptr %t375, i32 0, i32 4 - %t377 = call ptr @fn_block() - store ptr %t377, ptr %t376 - br label %ifend102 -else101: - %t378 = call ptr @fn_node(i32 7) - store ptr %t378, ptr %t379 - %t380 = load ptr, ptr %t379 - %t381 = getelementptr inbounds %Cmp_Node, ptr %t380, i32 0, i32 7 - %t382 = load ptr, ptr %t381 - %t383 = getelementptr inbounds %LSlice, ptr %t382, i32 0, i32 1 - %t384 = getelementptr inbounds %LSlice, ptr %t382, i32 0, i32 2 - %t385 = getelementptr inbounds %LSlice, ptr %t382, i32 0, i32 0 - %t386 = load i32, ptr %t383 - %t387 = load i32, ptr %t384 - %t388 = icmp sge i32 %t386, %t387 - br i1 %t388, label %grow103, label %put104 -grow103: - %t389 = mul i32 %t387, 2 - %t390 = icmp eq i32 %t387, 0 - %t391 = select i1 %t390, i32 8, i32 %t389 - %t392 = getelementptr ptr, ptr null, i32 1 - %t393 = ptrtoint ptr %t392 to i64 - %t394 = zext i32 %t391 to i64 - %t395 = mul i64 %t394, %t393 - %t396 = load ptr, ptr %t385 - %t397 = call ptr @realloc(ptr %t396, i64 %t395) - store ptr %t397, ptr %t385 - store i32 %t391, ptr %t384 - br label %put104 -put104: - %t398 = call ptr @fn_stmt() - %t399 = load ptr, ptr %t385 - %t400 = getelementptr inbounds ptr, ptr %t399, i32 %t386 - store ptr %t398, ptr %t400 - %t401 = add i32 %t386, 1 - store i32 %t401, ptr %t383 - %t402 = load ptr, ptr %t345 - %t403 = getelementptr inbounds %Cmp_Node, ptr %t402, i32 0, i32 4 - %t404 = load ptr, ptr %t379 - store ptr %t404, ptr %t403 - br label %ifend102 -ifend102: - %t405 = load ptr, ptr %t337 - %t406 = getelementptr inbounds %Cmp_Node, ptr %t405, i32 0, i32 7 - %t407 = load ptr, ptr %t406 - %t408 = getelementptr inbounds %LSlice, ptr %t407, i32 0, i32 1 - %t409 = getelementptr inbounds %LSlice, ptr %t407, i32 0, i32 2 - %t410 = getelementptr inbounds %LSlice, ptr %t407, i32 0, i32 0 - %t411 = load i32, ptr %t408 - %t412 = load i32, ptr %t409 - %t413 = icmp sge i32 %t411, %t412 - br i1 %t413, label %grow105, label %put106 -grow105: - %t414 = mul i32 %t412, 2 - %t415 = icmp eq i32 %t412, 0 - %t416 = select i1 %t415, i32 8, i32 %t414 - %t417 = getelementptr ptr, ptr null, i32 1 - %t418 = ptrtoint ptr %t417 to i64 - %t419 = zext i32 %t416 to i64 - %t420 = mul i64 %t419, %t418 - %t421 = load ptr, ptr %t410 - %t422 = call ptr @realloc(ptr %t421, i64 %t420) - store ptr %t422, ptr %t410 - store i32 %t416, ptr %t409 - br label %put106 -put106: - %t423 = load ptr, ptr %t345 - %t424 = load ptr, ptr %t410 - %t425 = getelementptr inbounds ptr, ptr %t424, i32 %t411 - store ptr %t423, ptr %t425 - %t426 = add i32 %t411, 1 - store i32 %t426, ptr %t408 - br label %wcond86 -wend88: - call void @fn_eat_op(ptr @.str95) - %t427 = load ptr, ptr %t337 - store ptr %t427, ptr %retval + %t341 = call i32 @fn_is_id(ptr @.str95) + %t342 = icmp ne i32 %t341, 0 + br i1 %t342, label %then82, label %ifend84 +then82: + %t343 = load i32, ptr @g_pi + %t344 = add i32 %t343, 1 + store i32 %t344, ptr @g_pi + %t345 = load ptr, ptr %t321 + %t346 = getelementptr inbounds %Cmp_Node, ptr %t345, i32 0, i32 4 + %t347 = call ptr @fn_expr() + store ptr %t347, ptr %t346 + br label %ifend84 +ifend84: + %t348 = load ptr, ptr %t321 + store ptr %t348, ptr %retval br label %ret -ifend85: +ifend75: + %t349 = load ptr, ptr %t6 + %t350 = getelementptr inbounds %Cmp_Tok, ptr %t349, i32 0, i32 1 + %t351 = load ptr, ptr %t350 + %t352 = call i32 @fn_str_eq(ptr %t351, ptr @.str96) + %t353 = icmp ne i32 %t352, 0 + br i1 %t353, label %then85, label %ifend87 +then85: + %t354 = load i32, ptr @g_pi + %t355 = add i32 %t354, 1 + store i32 %t355, ptr @g_pi + %t356 = call ptr @fn_node(i32 46) + store ptr %t356, ptr %t357 + %t358 = load ptr, ptr %t357 + %t359 = getelementptr inbounds %Cmp_Node, ptr %t358, i32 0, i32 1 + %t360 = call ptr @fn_eat_id() + store ptr %t360, ptr %t359 + %t361 = call i32 @fn_is_id(ptr @.str97) + %t362 = icmp eq i32 %t361, 0 + %t363 = zext i1 %t362 to i32 + %t364 = icmp ne i32 %t363, 0 + br i1 %t364, label %then88, label %ifend90 +then88: + call void @fn_perr(ptr @.str98) + br label %ifend90 +ifend90: + %t365 = load i32, ptr @g_pi + %t366 = add i32 %t365, 1 + store i32 %t366, ptr @g_pi + %t367 = load ptr, ptr %t357 + %t368 = getelementptr inbounds %Cmp_Node, ptr %t367, i32 0, i32 4 + %t369 = call ptr @fn_expr() + store ptr %t369, ptr %t368 + %t370 = call i32 @fn_is_op(ptr @.str99) + %t371 = icmp ne i32 %t370, 0 + br i1 %t371, label %then91, label %ifend93 +then91: + %t372 = load ptr, ptr %t357 + %t373 = getelementptr inbounds %Cmp_Node, ptr %t372, i32 0, i32 5 + %t374 = call ptr @fn_record() + store ptr %t374, ptr %t373 + br label %ifend93 +ifend93: + %t375 = load ptr, ptr %t357 + store ptr %t375, ptr %retval + br label %ret +ifend87: + %t376 = load ptr, ptr %t6 + %t377 = getelementptr inbounds %Cmp_Tok, ptr %t376, i32 0, i32 1 + %t378 = load ptr, ptr %t377 + %t379 = call i32 @fn_str_eq(ptr %t378, ptr @.str100) + %t380 = icmp ne i32 %t379, 0 + br i1 %t380, label %then94, label %ifend96 +then94: + %t381 = load i32, ptr @g_pi + %t382 = add i32 %t381, 1 + store i32 %t382, ptr @g_pi + %t383 = call ptr @fn_node(i32 47) + store ptr %t383, ptr %t384 + %t385 = load ptr, ptr %t384 + %t386 = getelementptr inbounds %Cmp_Node, ptr %t385, i32 0, i32 1 + %t387 = call ptr @fn_eat_id() + store ptr %t387, ptr %t386 + %t388 = call i32 @fn_is_id(ptr @.str101) + %t389 = icmp eq i32 %t388, 0 + %t390 = zext i1 %t389 to i32 + %t391 = icmp ne i32 %t390, 0 + br i1 %t391, label %then97, label %ifend99 +then97: + call void @fn_perr(ptr @.str102) + br label %ifend99 +ifend99: + %t392 = load i32, ptr @g_pi + %t393 = add i32 %t392, 1 + store i32 %t393, ptr @g_pi + %t394 = load ptr, ptr %t384 + %t395 = getelementptr inbounds %Cmp_Node, ptr %t394, i32 0, i32 4 + %t396 = call ptr @fn_expr() + store ptr %t396, ptr %t395 + %t397 = load ptr, ptr %t384 + store ptr %t397, ptr %retval + br label %ret +ifend96: + %t398 = load ptr, ptr %t6 + %t399 = getelementptr inbounds %Cmp_Tok, ptr %t398, i32 0, i32 1 + %t400 = load ptr, ptr %t399 + %t401 = call i32 @fn_str_eq(ptr %t400, ptr @.str103) + %t402 = icmp ne i32 %t401, 0 + br i1 %t402, label %then100, label %ifend102 +then100: + %t403 = load i32, ptr @g_pi + %t404 = add i32 %t403, 1 + store i32 %t404, ptr @g_pi + %t405 = call ptr @fn_node(i32 17) + store ptr %t405, ptr %retval + br label %ret +ifend102: + %t406 = load ptr, ptr %t6 + %t407 = getelementptr inbounds %Cmp_Tok, ptr %t406, i32 0, i32 1 + %t408 = load ptr, ptr %t407 + %t409 = call i32 @fn_str_eq(ptr %t408, ptr @.str104) + %t410 = icmp ne i32 %t409, 0 + br i1 %t410, label %then103, label %ifend105 +then103: + %t411 = load i32, ptr @g_pi + %t412 = add i32 %t411, 1 + store i32 %t412, ptr @g_pi + %t413 = call ptr @fn_node(i32 18) + store ptr %t413, ptr %retval + br label %ret +ifend105: + %t414 = load ptr, ptr %t6 + %t415 = getelementptr inbounds %Cmp_Tok, ptr %t414, i32 0, i32 1 + %t416 = load ptr, ptr %t415 + %t417 = call i32 @fn_str_eq(ptr %t416, ptr @.str105) + %t418 = icmp ne i32 %t417, 0 + br i1 %t418, label %then106, label %ifend108 +then106: + %t419 = load i32, ptr @g_pi + %t420 = add i32 %t419, 1 + store i32 %t420, ptr @g_pi + %t421 = call ptr @fn_node(i32 50) + store ptr %t421, ptr %retval + br label %ret +ifend108: + %t422 = load ptr, ptr %t6 + %t423 = getelementptr inbounds %Cmp_Tok, ptr %t422, i32 0, i32 1 + %t424 = load ptr, ptr %t423 + %t425 = call i32 @fn_str_eq(ptr %t424, ptr @.str106) + %t426 = icmp ne i32 %t425, 0 + br i1 %t426, label %then109, label %ifend111 +then109: + %t427 = load i32, ptr @g_pi + %t428 = add i32 %t427, 1 + store i32 %t428, ptr @g_pi + %t429 = call ptr @fn_node(i32 19) + store ptr %t429, ptr %t430 + %t431 = load ptr, ptr %t430 + %t432 = getelementptr inbounds %Cmp_Node, ptr %t431, i32 0, i32 4 + %t433 = call ptr @fn_expr() + store ptr %t433, ptr %t432 + call void @fn_skipnl() + call void @fn_eat_op(ptr @.str107) + br label %wcond112 +wcond112: + %t434 = icmp ne i32 1, 0 + br i1 %t434, label %wbody113, label %wend114 +wbody113: + call void @fn_skipnl() + %t435 = call i32 @fn_is_op(ptr @.str108) + %t436 = icmp ne i32 %t435, 0 + br i1 %t436, label %then115, label %ifend117 +then115: + br label %wend114 +ifend117: + %t437 = call ptr @fn_node(i32 20) + store ptr %t437, ptr %t438 + br label %wcond118 +wcond118: + %t439 = icmp ne i32 1, 0 + br i1 %t439, label %wbody119, label %wend120 +wbody119: + %t440 = load ptr, ptr %t438 + %t441 = getelementptr inbounds %Cmp_Node, ptr %t440, i32 0, i32 7 + %t442 = load ptr, ptr %t441 + %t443 = getelementptr inbounds %LSlice, ptr %t442, i32 0, i32 1 + %t444 = getelementptr inbounds %LSlice, ptr %t442, i32 0, i32 2 + %t445 = getelementptr inbounds %LSlice, ptr %t442, i32 0, i32 0 + %t446 = load i32, ptr %t443 + %t447 = load i32, ptr %t444 + %t448 = icmp sge i32 %t446, %t447 + br i1 %t448, label %grow121, label %put122 +grow121: + %t449 = mul i32 %t447, 2 + %t450 = icmp eq i32 %t447, 0 + %t451 = select i1 %t450, i32 8, i32 %t449 + %t452 = getelementptr ptr, ptr null, i32 1 + %t453 = ptrtoint ptr %t452 to i64 + %t454 = zext i32 %t451 to i64 + %t455 = mul i64 %t454, %t453 + %t456 = load ptr, ptr %t445 + %t457 = call ptr @realloc(ptr %t456, i64 %t455) + store ptr %t457, ptr %t445 + store i32 %t451, ptr %t444 + br label %put122 +put122: + %t458 = call ptr @fn_expr() + %t459 = load ptr, ptr %t445 + %t460 = getelementptr inbounds ptr, ptr %t459, i32 %t446 + store ptr %t458, ptr %t460 + %t461 = add i32 %t446, 1 + store i32 %t461, ptr %t443 + %t462 = call i32 @fn_is_op(ptr @.str109) + %t463 = icmp ne i32 %t462, 0 + br i1 %t463, label %then123, label %ifend125 +then123: + %t464 = load i32, ptr @g_pi + %t465 = add i32 %t464, 1 + store i32 %t465, ptr @g_pi + call void @fn_skipnl() + br label %wcond118 +ifend125: + br label %wend120 +wend120: + call void @fn_eat_op(ptr @.str110) + call void @fn_skipnl() + %t466 = call i32 @fn_is_op(ptr @.str111) + %t467 = icmp ne i32 %t466, 0 + br i1 %t467, label %then126, label %else127 +then126: + %t468 = load ptr, ptr %t438 + %t469 = getelementptr inbounds %Cmp_Node, ptr %t468, i32 0, i32 4 + %t470 = call ptr @fn_block() + store ptr %t470, ptr %t469 + br label %ifend128 +else127: + %t471 = call ptr @fn_node(i32 7) + store ptr %t471, ptr %t472 + %t473 = load ptr, ptr %t472 + %t474 = getelementptr inbounds %Cmp_Node, ptr %t473, i32 0, i32 7 + %t475 = load ptr, ptr %t474 + %t476 = getelementptr inbounds %LSlice, ptr %t475, i32 0, i32 1 + %t477 = getelementptr inbounds %LSlice, ptr %t475, i32 0, i32 2 + %t478 = getelementptr inbounds %LSlice, ptr %t475, i32 0, i32 0 + %t479 = load i32, ptr %t476 + %t480 = load i32, ptr %t477 + %t481 = icmp sge i32 %t479, %t480 + br i1 %t481, label %grow129, label %put130 +grow129: + %t482 = mul i32 %t480, 2 + %t483 = icmp eq i32 %t480, 0 + %t484 = select i1 %t483, i32 8, i32 %t482 + %t485 = getelementptr ptr, ptr null, i32 1 + %t486 = ptrtoint ptr %t485 to i64 + %t487 = zext i32 %t484 to i64 + %t488 = mul i64 %t487, %t486 + %t489 = load ptr, ptr %t478 + %t490 = call ptr @realloc(ptr %t489, i64 %t488) + store ptr %t490, ptr %t478 + store i32 %t484, ptr %t477 + br label %put130 +put130: + %t491 = call ptr @fn_stmt() + %t492 = load ptr, ptr %t478 + %t493 = getelementptr inbounds ptr, ptr %t492, i32 %t479 + store ptr %t491, ptr %t493 + %t494 = add i32 %t479, 1 + store i32 %t494, ptr %t476 + %t495 = load ptr, ptr %t438 + %t496 = getelementptr inbounds %Cmp_Node, ptr %t495, i32 0, i32 4 + %t497 = load ptr, ptr %t472 + store ptr %t497, ptr %t496 + br label %ifend128 +ifend128: + %t498 = load ptr, ptr %t430 + %t499 = getelementptr inbounds %Cmp_Node, ptr %t498, i32 0, i32 7 + %t500 = load ptr, ptr %t499 + %t501 = getelementptr inbounds %LSlice, ptr %t500, i32 0, i32 1 + %t502 = getelementptr inbounds %LSlice, ptr %t500, i32 0, i32 2 + %t503 = getelementptr inbounds %LSlice, ptr %t500, i32 0, i32 0 + %t504 = load i32, ptr %t501 + %t505 = load i32, ptr %t502 + %t506 = icmp sge i32 %t504, %t505 + br i1 %t506, label %grow131, label %put132 +grow131: + %t507 = mul i32 %t505, 2 + %t508 = icmp eq i32 %t505, 0 + %t509 = select i1 %t508, i32 8, i32 %t507 + %t510 = getelementptr ptr, ptr null, i32 1 + %t511 = ptrtoint ptr %t510 to i64 + %t512 = zext i32 %t509 to i64 + %t513 = mul i64 %t512, %t511 + %t514 = load ptr, ptr %t503 + %t515 = call ptr @realloc(ptr %t514, i64 %t513) + store ptr %t515, ptr %t503 + store i32 %t509, ptr %t502 + br label %put132 +put132: + %t516 = load ptr, ptr %t438 + %t517 = load ptr, ptr %t503 + %t518 = getelementptr inbounds ptr, ptr %t517, i32 %t504 + store ptr %t516, ptr %t518 + %t519 = add i32 %t504, 1 + store i32 %t519, ptr %t501 + br label %wcond112 +wend114: + call void @fn_eat_op(ptr @.str112) + %t520 = load ptr, ptr %t430 + store ptr %t520, ptr %retval + br label %ret +ifend111: br label %ifend2 ifend2: - %t428 = call ptr @fn_expr() - store ptr %t428, ptr %t429 - %t434 = call i32 @fn_is_op(ptr @.str96) - %t435 = icmp ne i32 %t434, 0 - %t436 = zext i1 %t435 to i32 - store i32 %t436, ptr %t433 - br i1 %t435, label %scend108, label %sc107 -sc107: - %t437 = call i32 @fn_is_op(ptr @.str97) - %t438 = icmp ne i32 %t437, 0 - %t439 = zext i1 %t438 to i32 - store i32 %t439, ptr %t433 - br label %scend108 -scend108: - %t440 = load i32, ptr %t433 - %t441 = icmp ne i32 %t440, 0 - %t442 = zext i1 %t441 to i32 - store i32 %t442, ptr %t432 - br i1 %t441, label %scend110, label %sc109 -sc109: - %t443 = call i32 @fn_is_op(ptr @.str98) - %t444 = icmp ne i32 %t443, 0 - %t445 = zext i1 %t444 to i32 - store i32 %t445, ptr %t432 - br label %scend110 -scend110: - %t446 = load i32, ptr %t432 - %t447 = icmp ne i32 %t446, 0 - %t448 = zext i1 %t447 to i32 - store i32 %t448, ptr %t431 - br i1 %t447, label %scend112, label %sc111 -sc111: - %t449 = call i32 @fn_is_op(ptr @.str99) - %t450 = icmp ne i32 %t449, 0 - %t451 = zext i1 %t450 to i32 - store i32 %t451, ptr %t431 - br label %scend112 -scend112: - %t452 = load i32, ptr %t431 - %t453 = icmp ne i32 %t452, 0 - %t454 = zext i1 %t453 to i32 - store i32 %t454, ptr %t430 - br i1 %t453, label %scend114, label %sc113 -sc113: - %t455 = call i32 @fn_is_op(ptr @.str100) - %t456 = icmp ne i32 %t455, 0 - %t457 = zext i1 %t456 to i32 - store i32 %t457, ptr %t430 - br label %scend114 -scend114: - %t458 = load i32, ptr %t430 - %t459 = icmp ne i32 %t458, 0 - br i1 %t459, label %then115, label %ifend117 -then115: - %t460 = call ptr @fn_node(i32 11) - store ptr %t460, ptr %t461 - %t462 = load ptr, ptr %t461 - %t463 = getelementptr inbounds %Cmp_Node, ptr %t462, i32 0, i32 8 - %t464 = load ptr, ptr @g_toks - %t465 = getelementptr inbounds %LSlice, ptr %t464, i32 0, i32 0 - %t466 = load ptr, ptr %t465 - %t467 = load i32, ptr @g_pi - %t468 = getelementptr inbounds ptr, ptr %t466, i32 %t467 - %t469 = load ptr, ptr %t468 - %t470 = getelementptr inbounds %Cmp_Tok, ptr %t469, i32 0, i32 3 - %t471 = load i32, ptr %t470 - store i32 %t471, ptr %t463 - %t472 = load ptr, ptr %t461 - %t473 = getelementptr inbounds %Cmp_Node, ptr %t472, i32 0, i32 1 - %t474 = load ptr, ptr @g_toks - %t475 = getelementptr inbounds %LSlice, ptr %t474, i32 0, i32 0 - %t476 = load ptr, ptr %t475 - %t477 = load i32, ptr @g_pi - %t478 = getelementptr inbounds ptr, ptr %t476, i32 %t477 - %t479 = load ptr, ptr %t478 - %t480 = getelementptr inbounds %Cmp_Tok, ptr %t479, i32 0, i32 1 - %t481 = load ptr, ptr %t480 - store ptr %t481, ptr %t473 - %t482 = load i32, ptr @g_pi - %t483 = add i32 %t482, 1 - store i32 %t483, ptr @g_pi - %t484 = load ptr, ptr %t461 - %t485 = getelementptr inbounds %Cmp_Node, ptr %t484, i32 0, i32 4 - %t486 = load ptr, ptr %t429 - store ptr %t486, ptr %t485 - %t487 = load ptr, ptr %t461 - %t488 = getelementptr inbounds %Cmp_Node, ptr %t487, i32 0, i32 5 - %t489 = call ptr @fn_expr() - store ptr %t489, ptr %t488 - %t490 = load ptr, ptr %t461 - store ptr %t490, ptr %retval + %t521 = call ptr @fn_expr() + store ptr %t521, ptr %t522 + %t527 = call i32 @fn_is_op(ptr @.str113) + %t528 = icmp ne i32 %t527, 0 + %t529 = zext i1 %t528 to i32 + store i32 %t529, ptr %t526 + br i1 %t528, label %scend134, label %sc133 +sc133: + %t530 = call i32 @fn_is_op(ptr @.str114) + %t531 = icmp ne i32 %t530, 0 + %t532 = zext i1 %t531 to i32 + store i32 %t532, ptr %t526 + br label %scend134 +scend134: + %t533 = load i32, ptr %t526 + %t534 = icmp ne i32 %t533, 0 + %t535 = zext i1 %t534 to i32 + store i32 %t535, ptr %t525 + br i1 %t534, label %scend136, label %sc135 +sc135: + %t536 = call i32 @fn_is_op(ptr @.str115) + %t537 = icmp ne i32 %t536, 0 + %t538 = zext i1 %t537 to i32 + store i32 %t538, ptr %t525 + br label %scend136 +scend136: + %t539 = load i32, ptr %t525 + %t540 = icmp ne i32 %t539, 0 + %t541 = zext i1 %t540 to i32 + store i32 %t541, ptr %t524 + br i1 %t540, label %scend138, label %sc137 +sc137: + %t542 = call i32 @fn_is_op(ptr @.str116) + %t543 = icmp ne i32 %t542, 0 + %t544 = zext i1 %t543 to i32 + store i32 %t544, ptr %t524 + br label %scend138 +scend138: + %t545 = load i32, ptr %t524 + %t546 = icmp ne i32 %t545, 0 + %t547 = zext i1 %t546 to i32 + store i32 %t547, ptr %t523 + br i1 %t546, label %scend140, label %sc139 +sc139: + %t548 = call i32 @fn_is_op(ptr @.str117) + %t549 = icmp ne i32 %t548, 0 + %t550 = zext i1 %t549 to i32 + store i32 %t550, ptr %t523 + br label %scend140 +scend140: + %t551 = load i32, ptr %t523 + %t552 = icmp ne i32 %t551, 0 + br i1 %t552, label %then141, label %ifend143 +then141: + %t553 = call ptr @fn_node(i32 11) + store ptr %t553, ptr %t554 + %t555 = load ptr, ptr %t554 + %t556 = getelementptr inbounds %Cmp_Node, ptr %t555, i32 0, i32 8 + %t557 = load ptr, ptr @g_toks + %t558 = getelementptr inbounds %LSlice, ptr %t557, i32 0, i32 0 + %t559 = load ptr, ptr %t558 + %t560 = load i32, ptr @g_pi + %t561 = getelementptr inbounds ptr, ptr %t559, i32 %t560 + %t562 = load ptr, ptr %t561 + %t563 = getelementptr inbounds %Cmp_Tok, ptr %t562, i32 0, i32 3 + %t564 = load i32, ptr %t563 + store i32 %t564, ptr %t556 + %t565 = load ptr, ptr %t554 + %t566 = getelementptr inbounds %Cmp_Node, ptr %t565, i32 0, i32 1 + %t567 = load ptr, ptr @g_toks + %t568 = getelementptr inbounds %LSlice, ptr %t567, i32 0, i32 0 + %t569 = load ptr, ptr %t568 + %t570 = load i32, ptr @g_pi + %t571 = getelementptr inbounds ptr, ptr %t569, i32 %t570 + %t572 = load ptr, ptr %t571 + %t573 = getelementptr inbounds %Cmp_Tok, ptr %t572, i32 0, i32 1 + %t574 = load ptr, ptr %t573 + store ptr %t574, ptr %t566 + %t575 = load i32, ptr @g_pi + %t576 = add i32 %t575, 1 + store i32 %t576, ptr @g_pi + %t577 = load ptr, ptr %t554 + %t578 = getelementptr inbounds %Cmp_Node, ptr %t577, i32 0, i32 4 + %t579 = load ptr, ptr %t522 + store ptr %t579, ptr %t578 + %t580 = load ptr, ptr %t554 + %t581 = getelementptr inbounds %Cmp_Node, ptr %t580, i32 0, i32 5 + %t582 = call ptr @fn_expr() + store ptr %t582, ptr %t581 + %t583 = load ptr, ptr %t554 + store ptr %t583, ptr %retval br label %ret -ifend117: - %t491 = call ptr @fn_node(i32 16) - store ptr %t491, ptr %t492 - %t493 = load ptr, ptr %t492 - %t494 = getelementptr inbounds %Cmp_Node, ptr %t493, i32 0, i32 4 - %t495 = load ptr, ptr %t429 - store ptr %t495, ptr %t494 - %t496 = load ptr, ptr %t492 - store ptr %t496, ptr %retval +ifend143: + %t584 = call ptr @fn_node(i32 16) + store ptr %t584, ptr %t585 + %t586 = load ptr, ptr %t585 + %t587 = getelementptr inbounds %Cmp_Node, ptr %t586, i32 0, i32 4 + %t588 = load ptr, ptr %t522 + store ptr %t588, ptr %t587 + %t589 = load ptr, ptr %t585 + store ptr %t589, ptr %retval br label %ret ret: - %t497 = load ptr, ptr %retval - ret ptr %t497 + %t590 = load ptr, ptr %retval + ret ptr %t590 } define ptr @fn_parse_var() { @@ -6549,12 +8096,12 @@ entry: %t5 = getelementptr inbounds %Cmp_Node, ptr %t4, i32 0, i32 1 %t6 = call ptr @fn_eat_id() store ptr %t6, ptr %t5 - call void @fn_eat_op(ptr @.str101) + call void @fn_eat_op(ptr @.str118) %t7 = load ptr, ptr %t3 %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 3 %t9 = call ptr @fn_ptype() store ptr %t9, ptr %t8 - %t10 = call i32 @fn_is_op(ptr @.str102) + %t10 = call i32 @fn_is_op(ptr @.str119) %t11 = icmp ne i32 %t10, 0 br i1 %t11, label %then0, label %ifend2 then0: @@ -6588,12 +8135,12 @@ entry: %t5 = getelementptr inbounds %Cmp_Node, ptr %t4, i32 0, i32 1 %t6 = call ptr @fn_eat_id() store ptr %t6, ptr %t5 - call void @fn_eat_op(ptr @.str103) + call void @fn_eat_op(ptr @.str120) %t7 = load ptr, ptr %t3 %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 3 %t9 = call ptr @fn_ptype() store ptr %t9, ptr %t8 - call void @fn_eat_op(ptr @.str104) + call void @fn_eat_op(ptr @.str121) %t10 = load ptr, ptr %t3 %t11 = getelementptr inbounds %Cmp_Node, ptr %t10, i32 0, i32 4 %t12 = call ptr @fn_expr() @@ -6620,10 +8167,10 @@ entry: %t5 = getelementptr inbounds %Cmp_Node, ptr %t4, i32 0, i32 1 %t6 = call ptr @fn_eat_id() store ptr %t6, ptr %t5 - call void @fn_eat_op(ptr @.str105) + call void @fn_eat_op(ptr @.str122) br label %wcond0 wcond0: - %t7 = call i32 @fn_is_op(ptr @.str106) + %t7 = call i32 @fn_is_op(ptr @.str123) %t8 = icmp eq i32 %t7, 0 %t9 = zext i1 %t8 to i32 %t10 = icmp ne i32 %t9, 0 @@ -6635,7 +8182,7 @@ wbody1: %t14 = getelementptr inbounds %Cmp_Node, ptr %t13, i32 0, i32 1 %t15 = call ptr @fn_eat_id() store ptr %t15, ptr %t14 - call void @fn_eat_op(ptr @.str107) + call void @fn_eat_op(ptr @.str124) %t16 = load ptr, ptr %t12 %t17 = getelementptr inbounds %Cmp_Node, ptr %t16, i32 0, i32 3 %t18 = call ptr @fn_ptype() @@ -6670,7 +8217,7 @@ put4: store ptr %t37, ptr %t39 %t40 = add i32 %t25, 1 store i32 %t40, ptr %t22 - %t41 = call i32 @fn_is_op(ptr @.str108) + %t41 = call i32 @fn_is_op(ptr @.str125) %t42 = icmp ne i32 %t41, 0 br i1 %t42, label %then5, label %ifend7 then5: @@ -6681,11 +8228,11 @@ then5: ifend7: br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str109) + call void @fn_eat_op(ptr @.str126) %t45 = load ptr, ptr %t3 %t46 = getelementptr inbounds %Cmp_Node, ptr %t45, i32 0, i32 3 - store ptr @.str110, ptr %t46 - %t47 = call i32 @fn_is_op(ptr @.str111) + store ptr @.str127, ptr %t46 + %t47 = call i32 @fn_is_op(ptr @.str128) %t48 = icmp ne i32 %t47, 0 br i1 %t48, label %then8, label %ifend10 then8: @@ -6778,7 +8325,7 @@ wend2: %t26 = icmp ne i32 %t25, 0 br i1 %t26, label %then6, label %ifend8 then6: - store ptr @.str112, ptr %retval + store ptr @.str129, ptr %retval br label %ret ifend8: %t27 = load ptr, ptr %t0 @@ -6877,13 +8424,25 @@ entry: %t5 = alloca ptr %t6 = alloca ptr %t7 = alloca ptr - %t13 = alloca ptr - %t49 = alloca i32 - %t75 = alloca ptr - %t85 = alloca ptr - %t158 = alloca ptr + %t8 = alloca ptr + %t9 = alloca ptr + %t10 = alloca i32 + %t11 = alloca ptr + %t12 = alloca i32 + %t13 = alloca i32 + %t14 = alloca ptr + %t15 = alloca ptr + %t21 = alloca ptr + %t92 = alloca i32 + %t118 = alloca ptr + %t128 = alloca ptr + %t157 = alloca ptr + %t169 = alloca ptr + %t172 = alloca i32 %t216 = alloca ptr - %t331 = alloca ptr + %t246 = alloca ptr + %t367 = alloca ptr + %t482 = alloca ptr store i32 0, ptr %t0 store ptr null, ptr %t1 store ptr null, ptr %t2 @@ -6892,154 +8451,271 @@ entry: store ptr null, ptr %t5 store ptr null, ptr %t6 store ptr null, ptr %t7 + store ptr null, ptr %t8 + store ptr null, ptr %t9 + store i32 0, ptr %t10 + store ptr null, ptr %t11 + store i32 0, ptr %t12 + store i32 0, ptr %t13 + store ptr null, ptr %t14 + store ptr null, ptr %t15 br label %wcond0 wcond0: - %t8 = call i32 @fn_is_op(ptr @.str113) - %t9 = icmp ne i32 %t8, 0 - br i1 %t9, label %wbody1, label %wend2 + %t16 = call i32 @fn_is_op(ptr @.str130) + %t17 = icmp ne i32 %t16, 0 + br i1 %t17, label %wbody1, label %wend2 wbody1: - %t10 = load i32, ptr @g_pi - %t11 = add i32 %t10, 1 - store i32 %t11, ptr @g_pi - %t12 = call ptr @fn_eat_id() - store ptr %t12, ptr %t13 - %t14 = load ptr, ptr %t13 - %t15 = call i32 @fn_str_eq(ptr %t14, ptr @.str114) - %t16 = icmp ne i32 %t15, 0 - br i1 %t16, label %then3, label %else4 + %t18 = load i32, ptr @g_pi + %t19 = add i32 %t18, 1 + store i32 %t19, ptr @g_pi + %t20 = call ptr @fn_eat_id() + store ptr %t20, ptr %t21 + %t22 = load ptr, ptr %t21 + %t23 = call i32 @fn_str_eq(ptr %t22, ptr @.str131) + %t24 = icmp ne i32 %t23, 0 + br i1 %t24, label %then3, label %else4 then3: store i32 1, ptr %t0 br label %ifend5 else4: - %t17 = load ptr, ptr %t13 - %t18 = call i32 @fn_str_eq(ptr %t17, ptr @.str115) - %t19 = icmp ne i32 %t18, 0 - br i1 %t19, label %then6, label %else7 + %t25 = load ptr, ptr %t21 + %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str132) + %t27 = icmp ne i32 %t26, 0 + br i1 %t27, label %then6, label %else7 then6: - %t20 = call ptr @fn_parse_queries_anno() - store ptr %t20, ptr %t1 + store i32 1, ptr %t10 br label %ifend8 else7: - %t21 = load ptr, ptr %t13 - %t22 = call i32 @fn_str_eq(ptr %t21, ptr @.str116) - %t23 = icmp ne i32 %t22, 0 - br i1 %t23, label %then9, label %else10 + %t28 = load ptr, ptr %t21 + %t29 = call i32 @fn_str_eq(ptr %t28, ptr @.str133) + %t30 = icmp ne i32 %t29, 0 + br i1 %t30, label %then9, label %else10 then9: - call void @fn_eat_op(ptr @.str117) - %t24 = call ptr @fn_eat_id() - store ptr %t24, ptr %t2 - call void @fn_eat_op(ptr @.str118) + call void @fn_eat_op(ptr @.str134) + %t31 = call ptr @fn_eat_id() + store ptr %t31, ptr %t9 + call void @fn_eat_op(ptr @.str135) br label %ifend11 else10: - %t25 = load ptr, ptr %t13 - %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str119) - %t27 = icmp ne i32 %t26, 0 - br i1 %t27, label %then12, label %else13 + %t32 = load ptr, ptr %t21 + %t33 = call i32 @fn_str_eq(ptr %t32, ptr @.str136) + %t34 = icmp ne i32 %t33, 0 + br i1 %t34, label %then12, label %else13 then12: - call void @fn_eat_op(ptr @.str120) - %t28 = call ptr @fn_eat_id() - store ptr %t28, ptr %t3 - call void @fn_eat_op(ptr @.str121) + %t35 = call ptr @fn_parse_queries_anno() + store ptr %t35, ptr %t1 br label %ifend14 else13: - %t29 = load ptr, ptr %t13 - %t30 = call i32 @fn_str_eq(ptr %t29, ptr @.str122) - %t31 = icmp ne i32 %t30, 0 - br i1 %t31, label %then15, label %else16 + %t36 = load ptr, ptr %t21 + %t37 = call i32 @fn_str_eq(ptr %t36, ptr @.str137) + %t38 = icmp ne i32 %t37, 0 + br i1 %t38, label %then15, label %else16 then15: - call void @fn_eat_op(ptr @.str123) - %t32 = call ptr @fn_eat_id() - store ptr %t32, ptr %t4 - call void @fn_eat_op(ptr @.str124) + call void @fn_eat_op(ptr @.str138) + %t39 = call ptr @fn_eat_id() + store ptr %t39, ptr %t2 + call void @fn_eat_op(ptr @.str139) br label %ifend17 else16: - %t33 = load ptr, ptr %t13 - %t34 = call i32 @fn_str_eq(ptr %t33, ptr @.str125) - %t35 = icmp ne i32 %t34, 0 - br i1 %t35, label %then18, label %else19 + %t40 = load ptr, ptr %t21 + %t41 = call i32 @fn_str_eq(ptr %t40, ptr @.str140) + %t42 = icmp ne i32 %t41, 0 + br i1 %t42, label %then18, label %else19 then18: - call void @fn_eat_op(ptr @.str126) - %t36 = call ptr @fn_eat_id() - store ptr %t36, ptr %t5 - call void @fn_eat_op(ptr @.str127) + call void @fn_eat_op(ptr @.str141) + %t43 = call ptr @fn_eat_id() + store ptr %t43, ptr %t3 + %t44 = call i32 @fn_is_op(ptr @.str142) + %t45 = icmp ne i32 %t44, 0 + br i1 %t45, label %then21, label %ifend23 +then21: + %t46 = load i32, ptr @g_pi + %t47 = add i32 %t46, 1 + store i32 %t47, ptr @g_pi + %t48 = call ptr @fn_eat_id() + call void @fn_eat_op(ptr @.str143) + %t49 = call ptr @fn_eat_id() + store ptr %t49, ptr %t4 + br label %ifend23 +ifend23: + call void @fn_eat_op(ptr @.str144) br label %ifend20 else19: - %t37 = load ptr, ptr %t13 - %t38 = call i32 @fn_str_eq(ptr %t37, ptr @.str128) - %t39 = icmp ne i32 %t38, 0 - br i1 %t39, label %then21, label %else22 -then21: - call void @fn_eat_op(ptr @.str129) - %t40 = call ptr @fn_eat_id() - store ptr %t40, ptr %t6 - call void @fn_eat_op(ptr @.str130) - br label %ifend23 -else22: - %t41 = load ptr, ptr %t13 - %t42 = call i32 @fn_str_eq(ptr %t41, ptr @.str131) - %t43 = icmp ne i32 %t42, 0 - br i1 %t43, label %then24, label %else25 + %t50 = load ptr, ptr %t21 + %t51 = call i32 @fn_str_eq(ptr %t50, ptr @.str145) + %t52 = icmp ne i32 %t51, 0 + br i1 %t52, label %then24, label %else25 then24: - store ptr @.str132, ptr %t7 + call void @fn_eat_op(ptr @.str146) + %t53 = call ptr @fn_eat_id() + store ptr %t53, ptr %t5 + call void @fn_eat_op(ptr @.str147) br label %ifend26 else25: - %t44 = load ptr, ptr %t13 - %t45 = call i32 @fn_str_eq(ptr %t44, ptr @.str133) - %t46 = icmp ne i32 %t45, 0 - br i1 %t46, label %then27, label %else28 + %t54 = load ptr, ptr %t21 + %t55 = call i32 @fn_str_eq(ptr %t54, ptr @.str148) + %t56 = icmp ne i32 %t55, 0 + br i1 %t56, label %then27, label %else28 then27: - store ptr @.str134, ptr %t7 + call void @fn_eat_op(ptr @.str149) + %t57 = call ptr @fn_eat_id() + store ptr %t57, ptr %t6 + call void @fn_eat_op(ptr @.str150) br label %ifend29 else28: - %t47 = call i32 @fn_is_op(ptr @.str135) - %t48 = icmp ne i32 %t47, 0 - br i1 %t48, label %then30, label %ifend32 + %t58 = load ptr, ptr %t21 + %t59 = call i32 @fn_str_eq(ptr %t58, ptr @.str151) + %t60 = icmp ne i32 %t59, 0 + br i1 %t60, label %then30, label %else31 then30: - store i32 0, ptr %t49 - br label %wcond33 -wcond33: - %t50 = icmp ne i32 1, 0 - br i1 %t50, label %wbody34, label %wend35 -wbody34: - %t51 = call i32 @fn_is_op(ptr @.str136) - %t52 = icmp ne i32 %t51, 0 - br i1 %t52, label %then36, label %ifend38 + call void @fn_eat_op(ptr @.str152) + %t61 = call ptr @fn_eat_id() + store ptr %t61, ptr %t7 + call void @fn_eat_op(ptr @.str153) + br label %ifend32 +else31: + %t62 = load ptr, ptr %t21 + %t63 = call i32 @fn_str_eq(ptr %t62, ptr @.str154) + %t64 = icmp ne i32 %t63, 0 + br i1 %t64, label %then33, label %else34 +then33: + call void @fn_eat_op(ptr @.str155) + %t65 = call ptr @fn_eat_id() + store ptr %t65, ptr %t8 + call void @fn_eat_op(ptr @.str156) + br label %ifend35 +else34: + %t66 = load ptr, ptr %t21 + %t67 = call i32 @fn_str_eq(ptr %t66, ptr @.str157) + %t68 = icmp ne i32 %t67, 0 + br i1 %t68, label %then36, label %else37 then36: - %t53 = load i32, ptr %t49 - %t54 = add i32 %t53, 1 - store i32 %t54, ptr %t49 + store ptr @.str158, ptr %t11 br label %ifend38 -ifend38: - %t55 = call i32 @fn_is_op(ptr @.str137) - %t56 = icmp ne i32 %t55, 0 - br i1 %t56, label %then39, label %ifend41 +else37: + %t69 = load ptr, ptr %t21 + %t70 = call i32 @fn_str_eq(ptr %t69, ptr @.str159) + %t71 = icmp ne i32 %t70, 0 + br i1 %t71, label %then39, label %else40 then39: - %t57 = load i32, ptr %t49 - %t58 = sub i32 %t57, 1 - store i32 %t58, ptr %t49 + store ptr @.str160, ptr %t11 + br label %ifend41 +else40: + %t72 = load ptr, ptr %t21 + %t73 = call i32 @fn_str_eq(ptr %t72, ptr @.str161) + %t74 = icmp ne i32 %t73, 0 + br i1 %t74, label %then42, label %else43 +then42: + store i32 1, ptr %t12 + br label %ifend44 +else43: + %t75 = load ptr, ptr %t21 + %t76 = call i32 @fn_str_eq(ptr %t75, ptr @.str162) + %t77 = icmp ne i32 %t76, 0 + br i1 %t77, label %then45, label %else46 +then45: + store i32 1, ptr %t13 + br label %ifend47 +else46: + %t78 = load ptr, ptr %t21 + %t79 = call i32 @fn_str_eq(ptr %t78, ptr @.str163) + %t80 = icmp ne i32 %t79, 0 + br i1 %t80, label %then48, label %else49 +then48: + store ptr @.str164, ptr %t14 + br label %ifend50 +else49: + %t81 = load ptr, ptr %t21 + %t82 = call i32 @fn_str_eq(ptr %t81, ptr @.str165) + %t83 = icmp ne i32 %t82, 0 + br i1 %t83, label %then51, label %else52 +then51: + store ptr @.str166, ptr %t14 + br label %ifend53 +else52: + %t84 = load ptr, ptr %t21 + %t85 = call i32 @fn_str_eq(ptr %t84, ptr @.str167) + %t86 = icmp ne i32 %t85, 0 + br i1 %t86, label %then54, label %else55 +then54: + store ptr @.str168, ptr %t15 + br label %ifend56 +else55: + %t87 = load ptr, ptr %t21 + %t88 = call i32 @fn_str_eq(ptr %t87, ptr @.str169) + %t89 = icmp ne i32 %t88, 0 + br i1 %t89, label %then57, label %else58 +then57: + store ptr @.str170, ptr %t15 + br label %ifend59 +else58: + %t90 = call i32 @fn_is_op(ptr @.str171) + %t91 = icmp ne i32 %t90, 0 + br i1 %t91, label %then60, label %ifend62 +then60: + store i32 0, ptr %t92 + br label %wcond63 +wcond63: + %t93 = icmp ne i32 1, 0 + br i1 %t93, label %wbody64, label %wend65 +wbody64: + %t94 = call i32 @fn_is_op(ptr @.str172) + %t95 = icmp ne i32 %t94, 0 + br i1 %t95, label %then66, label %ifend68 +then66: + %t96 = load i32, ptr %t92 + %t97 = add i32 %t96, 1 + store i32 %t97, ptr %t92 + br label %ifend68 +ifend68: + %t98 = call i32 @fn_is_op(ptr @.str173) + %t99 = icmp ne i32 %t98, 0 + br i1 %t99, label %then69, label %ifend71 +then69: + %t100 = load i32, ptr %t92 + %t101 = sub i32 %t100, 1 + store i32 %t101, ptr %t92 + br label %ifend71 +ifend71: + %t102 = load i32, ptr @g_pi + %t103 = add i32 %t102, 1 + store i32 %t103, ptr @g_pi + %t104 = load i32, ptr %t92 + %t105 = icmp eq i32 %t104, 0 + %t106 = zext i1 %t105 to i32 + %t107 = icmp ne i32 %t106, 0 + br i1 %t107, label %then72, label %ifend74 +then72: + br label %wend65 +ifend74: + br label %wcond63 +wend65: + br label %ifend62 +ifend62: + br label %ifend59 +ifend59: + br label %ifend56 +ifend56: + br label %ifend53 +ifend53: + br label %ifend50 +ifend50: + br label %ifend47 +ifend47: + br label %ifend44 +ifend44: br label %ifend41 ifend41: - %t59 = load i32, ptr @g_pi - %t60 = add i32 %t59, 1 - store i32 %t60, ptr @g_pi - %t61 = load i32, ptr %t49 - %t62 = icmp eq i32 %t61, 0 - %t63 = zext i1 %t62 to i32 - %t64 = icmp ne i32 %t63, 0 - br i1 %t64, label %then42, label %ifend44 -then42: - br label %wend35 -ifend44: - br label %wcond33 -wend35: + br label %ifend38 +ifend38: + br label %ifend35 +ifend35: br label %ifend32 ifend32: br label %ifend29 ifend29: br label %ifend26 ifend26: - br label %ifend23 -ifend23: br label %ifend20 ifend20: br label %ifend17 @@ -7055,523 +8731,727 @@ ifend5: call void @fn_skipnl() br label %wcond0 wend2: - %t65 = call i32 @fn_is_id(ptr @.str138) - %t66 = icmp ne i32 %t65, 0 - br i1 %t66, label %then45, label %ifend47 -then45: - %t67 = load i32, ptr @g_pi - %t68 = add i32 %t67, 1 - store i32 %t68, ptr @g_pi - %t69 = load ptr, ptr @g_toks - %t70 = getelementptr inbounds %LSlice, ptr %t69, i32 0, i32 0 - %t71 = load ptr, ptr %t70 - %t72 = load i32, ptr @g_pi - %t73 = getelementptr inbounds ptr, ptr %t71, i32 %t72 - %t74 = load ptr, ptr %t73 - store ptr %t74, ptr %t75 - %t76 = load ptr, ptr %t75 - %t77 = getelementptr inbounds %Cmp_Tok, ptr %t76, i32 0, i32 0 - %t78 = load i32, ptr %t77 - %t79 = icmp ne i32 %t78, 2 - %t80 = zext i1 %t79 to i32 - %t81 = icmp ne i32 %t80, 0 - br i1 %t81, label %then48, label %ifend50 -then48: - call void @fn_perr(ptr @.str139) - br label %ifend50 -ifend50: - %t82 = load ptr, ptr %t75 - %t83 = getelementptr inbounds %Cmp_Tok, ptr %t82, i32 0, i32 1 - %t84 = load ptr, ptr %t83 - store ptr %t84, ptr %t85 - %t86 = load i32, ptr @g_pi - %t87 = add i32 %t86, 1 - store i32 %t87, ptr @g_pi - %t88 = load ptr, ptr %t85 - call void @fn_do_import(ptr %t88) - br label %ret -ifend47: - %t89 = call i32 @fn_is_id(ptr @.str140) - %t90 = icmp ne i32 %t89, 0 - br i1 %t90, label %then51, label %ifend53 -then51: - %t91 = load ptr, ptr @g_prog - %t92 = getelementptr inbounds %LSlice, ptr %t91, i32 0, i32 1 - %t93 = getelementptr inbounds %LSlice, ptr %t91, i32 0, i32 2 - %t94 = getelementptr inbounds %LSlice, ptr %t91, i32 0, i32 0 - %t95 = load i32, ptr %t92 - %t96 = load i32, ptr %t93 - %t97 = icmp sge i32 %t95, %t96 - br i1 %t97, label %grow54, label %put55 -grow54: - %t98 = mul i32 %t96, 2 - %t99 = icmp eq i32 %t96, 0 - %t100 = select i1 %t99, i32 8, i32 %t98 - %t101 = getelementptr ptr, ptr null, i32 1 - %t102 = ptrtoint ptr %t101 to i64 - %t103 = zext i32 %t100 to i64 - %t104 = mul i64 %t103, %t102 - %t105 = load ptr, ptr %t94 - %t106 = call ptr @realloc(ptr %t105, i64 %t104) - store ptr %t106, ptr %t94 - store i32 %t100, ptr %t93 - br label %put55 -put55: - %t107 = call ptr @fn_parse_enum() - %t108 = load ptr, ptr %t94 - %t109 = getelementptr inbounds ptr, ptr %t108, i32 %t95 - store ptr %t107, ptr %t109 - %t110 = add i32 %t95, 1 - store i32 %t110, ptr %t92 - br label %ret -ifend53: - %t111 = call i32 @fn_is_id(ptr @.str141) - %t112 = icmp ne i32 %t111, 0 - br i1 %t112, label %then56, label %ifend58 -then56: - %t113 = load ptr, ptr @g_prog - %t114 = getelementptr inbounds %LSlice, ptr %t113, i32 0, i32 1 - %t115 = getelementptr inbounds %LSlice, ptr %t113, i32 0, i32 2 - %t116 = getelementptr inbounds %LSlice, ptr %t113, i32 0, i32 0 - %t117 = load i32, ptr %t114 - %t118 = load i32, ptr %t115 - %t119 = icmp sge i32 %t117, %t118 - br i1 %t119, label %grow59, label %put60 -grow59: - %t120 = mul i32 %t118, 2 - %t121 = icmp eq i32 %t118, 0 - %t122 = select i1 %t121, i32 8, i32 %t120 - %t123 = getelementptr ptr, ptr null, i32 1 - %t124 = ptrtoint ptr %t123 to i64 - %t125 = zext i32 %t122 to i64 - %t126 = mul i64 %t125, %t124 - %t127 = load ptr, ptr %t116 - %t128 = call ptr @realloc(ptr %t127, i64 %t126) - store ptr %t128, ptr %t116 - store i32 %t122, ptr %t115 - br label %put60 -put60: - %t129 = call ptr @fn_parse_component() - %t130 = load ptr, ptr %t116 - %t131 = getelementptr inbounds ptr, ptr %t130, i32 %t117 - store ptr %t129, ptr %t131 - %t132 = add i32 %t117, 1 - store i32 %t132, ptr %t114 - br label %ret -ifend58: - %t133 = call i32 @fn_is_id(ptr @.str142) - %t134 = icmp ne i32 %t133, 0 - br i1 %t134, label %then61, label %ifend63 -then61: - %t135 = load ptr, ptr @g_prog - %t136 = getelementptr inbounds %LSlice, ptr %t135, i32 0, i32 1 - %t137 = getelementptr inbounds %LSlice, ptr %t135, i32 0, i32 2 - %t138 = getelementptr inbounds %LSlice, ptr %t135, i32 0, i32 0 - %t139 = load i32, ptr %t136 - %t140 = load i32, ptr %t137 - %t141 = icmp sge i32 %t139, %t140 - br i1 %t141, label %grow64, label %put65 -grow64: - %t142 = mul i32 %t140, 2 - %t143 = icmp eq i32 %t140, 0 - %t144 = select i1 %t143, i32 8, i32 %t142 - %t145 = getelementptr ptr, ptr null, i32 1 - %t146 = ptrtoint ptr %t145 to i64 - %t147 = zext i32 %t144 to i64 - %t148 = mul i64 %t147, %t146 - %t149 = load ptr, ptr %t138 - %t150 = call ptr @realloc(ptr %t149, i64 %t148) - store ptr %t150, ptr %t138 - store i32 %t144, ptr %t137 - br label %put65 -put65: - %t151 = call ptr @fn_parse_archetype() - %t152 = load ptr, ptr %t138 - %t153 = getelementptr inbounds ptr, ptr %t152, i32 %t139 - store ptr %t151, ptr %t153 - %t154 = add i32 %t139, 1 - store i32 %t154, ptr %t136 - br label %ret -ifend63: - %t155 = call i32 @fn_is_id(ptr @.str143) - %t156 = icmp ne i32 %t155, 0 - br i1 %t156, label %then66, label %ifend68 -then66: - %t157 = call ptr @fn_parse_system() - store ptr %t157, ptr %t158 - %t159 = load ptr, ptr %t2 - %t160 = icmp ne ptr %t159, null - %t161 = zext i1 %t160 to i32 - %t162 = icmp ne i32 %t161, 0 - br i1 %t162, label %then69, label %ifend71 -then69: - %t163 = load ptr, ptr %t2 - %t164 = load ptr, ptr %t158 - %t165 = getelementptr inbounds %Cmp_Node, ptr %t164, i32 0, i32 4 - %t166 = load ptr, ptr %t165 - call void @fn_register_onspawn(ptr %t163, ptr %t166) - br label %ret -ifend71: - %t167 = load ptr, ptr %t3 - %t168 = icmp ne ptr %t167, null - %t169 = zext i1 %t168 to i32 - %t170 = icmp ne i32 %t169, 0 - br i1 %t170, label %then72, label %ifend74 -then72: - %t171 = load ptr, ptr %t3 - %t172 = load ptr, ptr %t158 - %t173 = getelementptr inbounds %Cmp_Node, ptr %t172, i32 0, i32 4 - %t174 = load ptr, ptr %t173 - call void @fn_register_ondespawn(ptr %t171, ptr %t174) - br label %ret -ifend74: - %t175 = load ptr, ptr %t4 - %t176 = icmp ne ptr %t175, null - %t177 = zext i1 %t176 to i32 - %t178 = icmp ne i32 %t177, 0 - br i1 %t178, label %then75, label %ifend77 + %t108 = call i32 @fn_is_id(ptr @.str174) + %t109 = icmp ne i32 %t108, 0 + br i1 %t109, label %then75, label %ifend77 then75: - %t179 = load ptr, ptr %t4 - %t180 = load ptr, ptr %t158 - %t181 = getelementptr inbounds %Cmp_Node, ptr %t180, i32 0, i32 4 - %t182 = load ptr, ptr %t181 - call void @fn_register_onattach(ptr %t179, ptr %t182) + %t110 = load i32, ptr @g_pi + %t111 = add i32 %t110, 1 + store i32 %t111, ptr @g_pi + %t112 = load ptr, ptr @g_toks + %t113 = getelementptr inbounds %LSlice, ptr %t112, i32 0, i32 0 + %t114 = load ptr, ptr %t113 + %t115 = load i32, ptr @g_pi + %t116 = getelementptr inbounds ptr, ptr %t114, i32 %t115 + %t117 = load ptr, ptr %t116 + store ptr %t117, ptr %t118 + %t119 = load ptr, ptr %t118 + %t120 = getelementptr inbounds %Cmp_Tok, ptr %t119, i32 0, i32 0 + %t121 = load i32, ptr %t120 + %t122 = icmp ne i32 %t121, 2 + %t123 = zext i1 %t122 to i32 + %t124 = icmp ne i32 %t123, 0 + br i1 %t124, label %then78, label %ifend80 +then78: + call void @fn_perr(ptr @.str175) + br label %ifend80 +ifend80: + %t125 = load ptr, ptr %t118 + %t126 = getelementptr inbounds %Cmp_Tok, ptr %t125, i32 0, i32 1 + %t127 = load ptr, ptr %t126 + store ptr %t127, ptr %t128 + %t129 = load i32, ptr @g_pi + %t130 = add i32 %t129, 1 + store i32 %t130, ptr @g_pi + %t131 = load ptr, ptr %t128 + call void @fn_do_import(ptr %t131) br label %ret ifend77: - %t183 = load ptr, ptr %t5 - %t184 = icmp ne ptr %t183, null - %t185 = zext i1 %t184 to i32 - %t186 = icmp ne i32 %t185, 0 - br i1 %t186, label %then78, label %ifend80 -then78: - %t187 = load ptr, ptr %t5 - %t188 = load ptr, ptr %t158 - %t189 = getelementptr inbounds %Cmp_Node, ptr %t188, i32 0, i32 4 - %t190 = load ptr, ptr %t189 - call void @fn_register_onenable(ptr %t187, ptr %t190) - br label %ret -ifend80: - %t191 = load ptr, ptr %t6 - %t192 = icmp ne ptr %t191, null - %t193 = zext i1 %t192 to i32 - %t194 = icmp ne i32 %t193, 0 - br i1 %t194, label %then81, label %ifend83 + %t132 = call i32 @fn_is_id(ptr @.str176) + %t133 = icmp ne i32 %t132, 0 + br i1 %t133, label %then81, label %ifend83 then81: - %t195 = load ptr, ptr %t6 - %t196 = load ptr, ptr %t158 - %t197 = getelementptr inbounds %Cmp_Node, ptr %t196, i32 0, i32 4 - %t198 = load ptr, ptr %t197 - call void @fn_register_ondisable(ptr %t195, ptr %t198) + %t134 = load ptr, ptr @g_prog + %t135 = getelementptr inbounds %LSlice, ptr %t134, i32 0, i32 1 + %t136 = getelementptr inbounds %LSlice, ptr %t134, i32 0, i32 2 + %t137 = getelementptr inbounds %LSlice, ptr %t134, i32 0, i32 0 + %t138 = load i32, ptr %t135 + %t139 = load i32, ptr %t136 + %t140 = icmp sge i32 %t138, %t139 + br i1 %t140, label %grow84, label %put85 +grow84: + %t141 = mul i32 %t139, 2 + %t142 = icmp eq i32 %t139, 0 + %t143 = select i1 %t142, i32 8, i32 %t141 + %t144 = getelementptr ptr, ptr null, i32 1 + %t145 = ptrtoint ptr %t144 to i64 + %t146 = zext i32 %t143 to i64 + %t147 = mul i64 %t146, %t145 + %t148 = load ptr, ptr %t137 + %t149 = call ptr @realloc(ptr %t148, i64 %t147) + store ptr %t149, ptr %t137 + store i32 %t143, ptr %t136 + br label %put85 +put85: + %t150 = call ptr @fn_parse_enum() + %t151 = load ptr, ptr %t137 + %t152 = getelementptr inbounds ptr, ptr %t151, i32 %t138 + store ptr %t150, ptr %t152 + %t153 = add i32 %t138, 1 + store i32 %t153, ptr %t135 br label %ret ifend83: - %t199 = load ptr, ptr %t7 - %t200 = icmp ne ptr %t199, null - %t201 = zext i1 %t200 to i32 - %t202 = icmp ne i32 %t201, 0 - br i1 %t202, label %then84, label %ifend86 -then84: - %t203 = load ptr, ptr %t158 - %t204 = getelementptr inbounds %Cmp_Node, ptr %t203, i32 0, i32 3 - %t205 = load ptr, ptr %t7 - store ptr %t205, ptr %t204 - br label %ifend86 -ifend86: - %t206 = load ptr, ptr %t1 - %t207 = icmp ne ptr %t206, null - %t208 = zext i1 %t207 to i32 - %t209 = icmp ne i32 %t208, 0 - br i1 %t209, label %then87, label %ifend89 -then87: - %t210 = load ptr, ptr %t1 - %t211 = getelementptr inbounds %Cmp_Node, ptr %t210, i32 0, i32 4 - %t212 = load ptr, ptr %t158 - %t213 = getelementptr inbounds %Cmp_Node, ptr %t212, i32 0, i32 4 - %t214 = load ptr, ptr %t213 - store ptr %t214, ptr %t211 - %t215 = call ptr @fn_node(i32 7) + %t154 = call i32 @fn_is_id(ptr @.str177) + %t155 = icmp ne i32 %t154, 0 + br i1 %t155, label %then86, label %ifend88 +then86: + %t156 = call ptr @fn_parse_event() + store ptr %t156, ptr %t157 + %t158 = load ptr, ptr %t15 + %t159 = icmp ne ptr %t158, null + %t160 = zext i1 %t159 to i32 + %t161 = icmp ne i32 %t160, 0 + br i1 %t161, label %then89, label %ifend91 +then89: + %t162 = load ptr, ptr %t157 + %t163 = getelementptr inbounds %Cmp_Node, ptr %t162, i32 0, i32 3 + %t164 = load ptr, ptr %t15 + store ptr %t164, ptr %t163 + br label %ifend91 +ifend91: + %t165 = load ptr, ptr %t157 + call void @fn_register_event(ptr %t165) + br label %ret +ifend88: + %t166 = call i32 @fn_is_id(ptr @.str178) + %t167 = icmp ne i32 %t166, 0 + br i1 %t167, label %then92, label %ifend94 +then92: + %t168 = call ptr @fn_parse_component() + store ptr %t168, ptr %t169 + %t170 = load i32, ptr %t12 + %t171 = icmp ne i32 %t170, 0 + br i1 %t171, label %then95, label %ifend97 +then95: + store i32 0, ptr %t172 + br label %wcond98 +wcond98: + %t173 = load i32, ptr %t172 + %t174 = load ptr, ptr %t169 + %t175 = getelementptr inbounds %Cmp_Node, ptr %t174, i32 0, i32 7 + %t176 = load ptr, ptr %t175 + %t177 = getelementptr inbounds %LSlice, ptr %t176, i32 0, i32 1 + %t178 = load i32, ptr %t177 + %t179 = icmp slt i32 %t173, %t178 + %t180 = zext i1 %t179 to i32 + %t181 = icmp ne i32 %t180, 0 + br i1 %t181, label %wbody99, label %wend100 +wbody99: + %t182 = load ptr, ptr %t169 + %t183 = getelementptr inbounds %Cmp_Node, ptr %t182, i32 0, i32 7 + %t184 = load ptr, ptr %t183 + %t185 = getelementptr inbounds %LSlice, ptr %t184, i32 0, i32 0 + %t186 = load ptr, ptr %t185 + %t187 = load i32, ptr %t172 + %t188 = getelementptr inbounds ptr, ptr %t186, i32 %t187 + %t189 = load ptr, ptr %t188 + %t190 = getelementptr inbounds %Cmp_Node, ptr %t189, i32 0, i32 2 + store i32 1, ptr %t190 + %t191 = load i32, ptr %t172 + %t192 = add i32 %t191, 1 + store i32 %t192, ptr %t172 + br label %wcond98 +wend100: + br label %ifend97 +ifend97: + %t193 = load ptr, ptr @g_prog + %t194 = getelementptr inbounds %LSlice, ptr %t193, i32 0, i32 1 + %t195 = getelementptr inbounds %LSlice, ptr %t193, i32 0, i32 2 + %t196 = getelementptr inbounds %LSlice, ptr %t193, i32 0, i32 0 + %t197 = load i32, ptr %t194 + %t198 = load i32, ptr %t195 + %t199 = icmp sge i32 %t197, %t198 + br i1 %t199, label %grow101, label %put102 +grow101: + %t200 = mul i32 %t198, 2 + %t201 = icmp eq i32 %t198, 0 + %t202 = select i1 %t201, i32 8, i32 %t200 + %t203 = getelementptr ptr, ptr null, i32 1 + %t204 = ptrtoint ptr %t203 to i64 + %t205 = zext i32 %t202 to i64 + %t206 = mul i64 %t205, %t204 + %t207 = load ptr, ptr %t196 + %t208 = call ptr @realloc(ptr %t207, i64 %t206) + store ptr %t208, ptr %t196 + store i32 %t202, ptr %t195 + br label %put102 +put102: + %t209 = load ptr, ptr %t169 + %t210 = load ptr, ptr %t196 + %t211 = getelementptr inbounds ptr, ptr %t210, i32 %t197 + store ptr %t209, ptr %t211 + %t212 = add i32 %t197, 1 + store i32 %t212, ptr %t194 + br label %ret +ifend94: + %t213 = call i32 @fn_is_id(ptr @.str179) + %t214 = icmp ne i32 %t213, 0 + br i1 %t214, label %then103, label %ifend105 +then103: + %t215 = call ptr @fn_parse_archetype() store ptr %t215, ptr %t216 - %t217 = load ptr, ptr %t216 - %t218 = getelementptr inbounds %Cmp_Node, ptr %t217, i32 0, i32 7 - %t219 = load ptr, ptr %t218 - %t220 = getelementptr inbounds %LSlice, ptr %t219, i32 0, i32 1 - %t221 = getelementptr inbounds %LSlice, ptr %t219, i32 0, i32 2 - %t222 = getelementptr inbounds %LSlice, ptr %t219, i32 0, i32 0 - %t223 = load i32, ptr %t220 - %t224 = load i32, ptr %t221 - %t225 = icmp sge i32 %t223, %t224 - br i1 %t225, label %grow90, label %put91 -grow90: - %t226 = mul i32 %t224, 2 - %t227 = icmp eq i32 %t224, 0 - %t228 = select i1 %t227, i32 8, i32 %t226 - %t229 = getelementptr ptr, ptr null, i32 1 - %t230 = ptrtoint ptr %t229 to i64 - %t231 = zext i32 %t228 to i64 - %t232 = mul i64 %t231, %t230 - %t233 = load ptr, ptr %t222 - %t234 = call ptr @realloc(ptr %t233, i64 %t232) - store ptr %t234, ptr %t222 - store i32 %t228, ptr %t221 - br label %put91 -put91: - %t235 = load ptr, ptr %t1 - %t236 = load ptr, ptr %t222 - %t237 = getelementptr inbounds ptr, ptr %t236, i32 %t223 - store ptr %t235, ptr %t237 - %t238 = add i32 %t223, 1 - store i32 %t238, ptr %t220 - %t239 = load ptr, ptr %t158 - %t240 = getelementptr inbounds %Cmp_Node, ptr %t239, i32 0, i32 4 - %t241 = load ptr, ptr %t216 - store ptr %t241, ptr %t240 - br label %ifend89 -ifend89: - %t242 = load ptr, ptr @g_prog - %t243 = getelementptr inbounds %LSlice, ptr %t242, i32 0, i32 1 - %t244 = getelementptr inbounds %LSlice, ptr %t242, i32 0, i32 2 - %t245 = getelementptr inbounds %LSlice, ptr %t242, i32 0, i32 0 - %t246 = load i32, ptr %t243 - %t247 = load i32, ptr %t244 - %t248 = icmp sge i32 %t246, %t247 - br i1 %t248, label %grow92, label %put93 -grow92: - %t249 = mul i32 %t247, 2 - %t250 = icmp eq i32 %t247, 0 - %t251 = select i1 %t250, i32 8, i32 %t249 - %t252 = getelementptr ptr, ptr null, i32 1 - %t253 = ptrtoint ptr %t252 to i64 - %t254 = zext i32 %t251 to i64 - %t255 = mul i64 %t254, %t253 - %t256 = load ptr, ptr %t245 - %t257 = call ptr @realloc(ptr %t256, i64 %t255) - store ptr %t257, ptr %t245 - store i32 %t251, ptr %t244 - br label %put93 -put93: - %t258 = load ptr, ptr %t158 - %t259 = load ptr, ptr %t245 - %t260 = getelementptr inbounds ptr, ptr %t259, i32 %t246 - store ptr %t258, ptr %t260 - %t261 = add i32 %t246, 1 - store i32 %t261, ptr %t243 + %t217 = load i32, ptr %t13 + %t218 = icmp ne i32 %t217, 0 + br i1 %t218, label %then106, label %ifend108 +then106: + %t219 = load ptr, ptr %t216 + %t220 = getelementptr inbounds %Cmp_Node, ptr %t219, i32 0, i32 2 + store i32 1, ptr %t220 + br label %ifend108 +ifend108: + %t221 = load ptr, ptr @g_prog + %t222 = getelementptr inbounds %LSlice, ptr %t221, i32 0, i32 1 + %t223 = getelementptr inbounds %LSlice, ptr %t221, i32 0, i32 2 + %t224 = getelementptr inbounds %LSlice, ptr %t221, i32 0, i32 0 + %t225 = load i32, ptr %t222 + %t226 = load i32, ptr %t223 + %t227 = icmp sge i32 %t225, %t226 + br i1 %t227, label %grow109, label %put110 +grow109: + %t228 = mul i32 %t226, 2 + %t229 = icmp eq i32 %t226, 0 + %t230 = select i1 %t229, i32 8, i32 %t228 + %t231 = getelementptr ptr, ptr null, i32 1 + %t232 = ptrtoint ptr %t231 to i64 + %t233 = zext i32 %t230 to i64 + %t234 = mul i64 %t233, %t232 + %t235 = load ptr, ptr %t224 + %t236 = call ptr @realloc(ptr %t235, i64 %t234) + store ptr %t236, ptr %t224 + store i32 %t230, ptr %t223 + br label %put110 +put110: + %t237 = load ptr, ptr %t216 + %t238 = load ptr, ptr %t224 + %t239 = getelementptr inbounds ptr, ptr %t238, i32 %t225 + store ptr %t237, ptr %t239 + %t240 = add i32 %t225, 1 + store i32 %t240, ptr %t222 br label %ret -ifend68: - %t262 = call i32 @fn_is_id(ptr @.str144) - %t263 = icmp ne i32 %t262, 0 - br i1 %t263, label %then94, label %ifend96 -then94: - %t264 = load ptr, ptr @g_prog - %t265 = getelementptr inbounds %LSlice, ptr %t264, i32 0, i32 1 - %t266 = getelementptr inbounds %LSlice, ptr %t264, i32 0, i32 2 - %t267 = getelementptr inbounds %LSlice, ptr %t264, i32 0, i32 0 - %t268 = load i32, ptr %t265 - %t269 = load i32, ptr %t266 - %t270 = icmp sge i32 %t268, %t269 - br i1 %t270, label %grow97, label %put98 -grow97: - %t271 = mul i32 %t269, 2 - %t272 = icmp eq i32 %t269, 0 - %t273 = select i1 %t272, i32 8, i32 %t271 - %t274 = getelementptr ptr, ptr null, i32 1 - %t275 = ptrtoint ptr %t274 to i64 - %t276 = zext i32 %t273 to i64 - %t277 = mul i64 %t276, %t275 - %t278 = load ptr, ptr %t267 - %t279 = call ptr @realloc(ptr %t278, i64 %t277) - store ptr %t279, ptr %t267 - store i32 %t273, ptr %t266 - br label %put98 -put98: - %t280 = call ptr @fn_parse_ui() - %t281 = load ptr, ptr %t267 - %t282 = getelementptr inbounds ptr, ptr %t281, i32 %t268 - store ptr %t280, ptr %t282 - %t283 = add i32 %t268, 1 - store i32 %t283, ptr %t265 +ifend105: + %t241 = call i32 @fn_is_id(ptr @.str180) + %t242 = icmp ne i32 %t241, 0 + br i1 %t242, label %then111, label %ifend113 +then111: + call void @fn_parse_scene() br label %ret -ifend96: - %t284 = call i32 @fn_is_id(ptr @.str145) - %t285 = icmp ne i32 %t284, 0 - br i1 %t285, label %then99, label %ifend101 -then99: - %t286 = load ptr, ptr @g_prog - %t287 = getelementptr inbounds %LSlice, ptr %t286, i32 0, i32 1 - %t288 = getelementptr inbounds %LSlice, ptr %t286, i32 0, i32 2 - %t289 = getelementptr inbounds %LSlice, ptr %t286, i32 0, i32 0 - %t290 = load i32, ptr %t287 - %t291 = load i32, ptr %t288 - %t292 = icmp sge i32 %t290, %t291 - br i1 %t292, label %grow102, label %put103 -grow102: - %t293 = mul i32 %t291, 2 - %t294 = icmp eq i32 %t291, 0 - %t295 = select i1 %t294, i32 8, i32 %t293 - %t296 = getelementptr ptr, ptr null, i32 1 - %t297 = ptrtoint ptr %t296 to i64 - %t298 = zext i32 %t295 to i64 - %t299 = mul i64 %t298, %t297 - %t300 = load ptr, ptr %t289 - %t301 = call ptr @realloc(ptr %t300, i64 %t299) - store ptr %t301, ptr %t289 - store i32 %t295, ptr %t288 - br label %put103 -put103: - %t302 = call ptr @fn_parse_var() - %t303 = load ptr, ptr %t289 - %t304 = getelementptr inbounds ptr, ptr %t303, i32 %t290 - store ptr %t302, ptr %t304 - %t305 = add i32 %t290, 1 - store i32 %t305, ptr %t287 - br label %ret -ifend101: - %t306 = call i32 @fn_is_id(ptr @.str146) - %t307 = icmp ne i32 %t306, 0 - br i1 %t307, label %then104, label %ifend106 -then104: - %t308 = load ptr, ptr @g_prog - %t309 = getelementptr inbounds %LSlice, ptr %t308, i32 0, i32 1 - %t310 = getelementptr inbounds %LSlice, ptr %t308, i32 0, i32 2 - %t311 = getelementptr inbounds %LSlice, ptr %t308, i32 0, i32 0 - %t312 = load i32, ptr %t309 - %t313 = load i32, ptr %t310 - %t314 = icmp sge i32 %t312, %t313 - br i1 %t314, label %grow107, label %put108 -grow107: - %t315 = mul i32 %t313, 2 - %t316 = icmp eq i32 %t313, 0 - %t317 = select i1 %t316, i32 8, i32 %t315 - %t318 = getelementptr ptr, ptr null, i32 1 - %t319 = ptrtoint ptr %t318 to i64 - %t320 = zext i32 %t317 to i64 - %t321 = mul i64 %t320, %t319 - %t322 = load ptr, ptr %t311 - %t323 = call ptr @realloc(ptr %t322, i64 %t321) - store ptr %t323, ptr %t311 - store i32 %t317, ptr %t310 - br label %put108 -put108: - %t324 = call ptr @fn_parse_const() - %t325 = load ptr, ptr %t311 - %t326 = getelementptr inbounds ptr, ptr %t325, i32 %t312 - store ptr %t324, ptr %t326 - %t327 = add i32 %t312, 1 - store i32 %t327, ptr %t309 - br label %ret -ifend106: - %t328 = call i32 @fn_is_id(ptr @.str147) - %t329 = icmp ne i32 %t328, 0 - br i1 %t329, label %then109, label %ifend111 -then109: - %t330 = call ptr @fn_parse_fn() - store ptr %t330, ptr %t331 - %t332 = load i32, ptr %t0 - %t333 = icmp ne i32 %t332, 0 - br i1 %t333, label %then112, label %ifend114 -then112: - %t334 = load ptr, ptr %t331 - %t335 = getelementptr inbounds %Cmp_Node, ptr %t334, i32 0, i32 2 - store i32 1, ptr %t335 - br label %ifend114 -ifend114: - %t336 = load ptr, ptr @g_prog - %t337 = getelementptr inbounds %LSlice, ptr %t336, i32 0, i32 1 - %t338 = getelementptr inbounds %LSlice, ptr %t336, i32 0, i32 2 - %t339 = getelementptr inbounds %LSlice, ptr %t336, i32 0, i32 0 - %t340 = load i32, ptr %t337 - %t341 = load i32, ptr %t338 - %t342 = icmp sge i32 %t340, %t341 - br i1 %t342, label %grow115, label %put116 -grow115: - %t343 = mul i32 %t341, 2 - %t344 = icmp eq i32 %t341, 0 - %t345 = select i1 %t344, i32 8, i32 %t343 - %t346 = getelementptr ptr, ptr null, i32 1 - %t347 = ptrtoint ptr %t346 to i64 - %t348 = zext i32 %t345 to i64 - %t349 = mul i64 %t348, %t347 - %t350 = load ptr, ptr %t339 - %t351 = call ptr @realloc(ptr %t350, i64 %t349) - store ptr %t351, ptr %t339 - store i32 %t345, ptr %t338 - br label %put116 -put116: - %t352 = load ptr, ptr %t331 - %t353 = load ptr, ptr %t339 - %t354 = getelementptr inbounds ptr, ptr %t353, i32 %t340 - store ptr %t352, ptr %t354 - %t355 = add i32 %t340, 1 - store i32 %t355, ptr %t337 - br label %ret -ifend111: - %t356 = call i32 @fn_is_id(ptr @.str148) - %t357 = icmp ne i32 %t356, 0 - br i1 %t357, label %then117, label %ifend119 +ifend113: + %t243 = call i32 @fn_is_id(ptr @.str181) + %t244 = icmp ne i32 %t243, 0 + br i1 %t244, label %then114, label %ifend116 +then114: + %t245 = call ptr @fn_parse_system() + store ptr %t245, ptr %t246 + %t247 = load ptr, ptr %t14 + %t248 = icmp ne ptr %t247, null + %t249 = zext i1 %t248 to i32 + %t250 = icmp ne i32 %t249, 0 + br i1 %t250, label %then117, label %ifend119 then117: - %t358 = load ptr, ptr @g_prog - %t359 = getelementptr inbounds %LSlice, ptr %t358, i32 0, i32 1 - %t360 = getelementptr inbounds %LSlice, ptr %t358, i32 0, i32 2 - %t361 = getelementptr inbounds %LSlice, ptr %t358, i32 0, i32 0 - %t362 = load i32, ptr %t359 - %t363 = load i32, ptr %t360 - %t364 = icmp sge i32 %t362, %t363 - br i1 %t364, label %grow120, label %put121 -grow120: - %t365 = mul i32 %t363, 2 - %t366 = icmp eq i32 %t363, 0 - %t367 = select i1 %t366, i32 8, i32 %t365 - %t368 = getelementptr ptr, ptr null, i32 1 - %t369 = ptrtoint ptr %t368 to i64 - %t370 = zext i32 %t367 to i64 - %t371 = mul i64 %t370, %t369 - %t372 = load ptr, ptr %t361 - %t373 = call ptr @realloc(ptr %t372, i64 %t371) - store ptr %t373, ptr %t361 - store i32 %t367, ptr %t360 - br label %put121 -put121: - %t374 = call ptr @fn_parse_extern() - %t375 = load ptr, ptr %t361 - %t376 = getelementptr inbounds ptr, ptr %t375, i32 %t362 - store ptr %t374, ptr %t376 - %t377 = add i32 %t362, 1 - store i32 %t377, ptr %t359 - br label %ret + %t251 = load ptr, ptr %t14 + %t252 = call i32 @fn_str_eq(ptr %t251, ptr @.str182) + %t253 = icmp ne i32 %t252, 0 + br i1 %t253, label %then120, label %else121 +then120: + %t254 = load ptr, ptr %t246 + %t255 = getelementptr inbounds %Cmp_Node, ptr %t254, i32 0, i32 2 + store i32 1, ptr %t255 + br label %ifend122 +else121: + %t256 = load ptr, ptr %t246 + %t257 = getelementptr inbounds %Cmp_Node, ptr %t256, i32 0, i32 2 + store i32 2, ptr %t257 + br label %ifend122 +ifend122: + br label %ifend119 ifend119: - %t378 = call i32 @fn_is_id(ptr @.str149) - %t379 = icmp ne i32 %t378, 0 - br i1 %t379, label %then122, label %ifend124 -then122: - %t380 = load ptr, ptr @g_prog - %t381 = getelementptr inbounds %LSlice, ptr %t380, i32 0, i32 1 - %t382 = getelementptr inbounds %LSlice, ptr %t380, i32 0, i32 2 - %t383 = getelementptr inbounds %LSlice, ptr %t380, i32 0, i32 0 - %t384 = load i32, ptr %t381 - %t385 = load i32, ptr %t382 - %t386 = icmp sge i32 %t384, %t385 - br i1 %t386, label %grow125, label %put126 -grow125: - %t387 = mul i32 %t385, 2 - %t388 = icmp eq i32 %t385, 0 - %t389 = select i1 %t388, i32 8, i32 %t387 - %t390 = getelementptr ptr, ptr null, i32 1 - %t391 = ptrtoint ptr %t390 to i64 - %t392 = zext i32 %t389 to i64 - %t393 = mul i64 %t392, %t391 - %t394 = load ptr, ptr %t383 - %t395 = call ptr @realloc(ptr %t394, i64 %t393) - store ptr %t395, ptr %t383 - store i32 %t389, ptr %t382 - br label %put126 -put126: - %t396 = call ptr @fn_parse_main() - %t397 = load ptr, ptr %t383 - %t398 = getelementptr inbounds ptr, ptr %t397, i32 %t384 - store ptr %t396, ptr %t398 - %t399 = add i32 %t384, 1 - store i32 %t399, ptr %t381 + %t258 = load ptr, ptr %t9 + %t259 = icmp ne ptr %t258, null + %t260 = zext i1 %t259 to i32 + %t261 = icmp ne i32 %t260, 0 + br i1 %t261, label %then123, label %ifend125 +then123: + %t262 = load ptr, ptr %t9 + %t263 = load ptr, ptr %t246 + %t264 = getelementptr inbounds %Cmp_Node, ptr %t263, i32 0, i32 4 + %t265 = load ptr, ptr %t264 + call void @fn_register_onlisten(ptr %t262, ptr %t265) br label %ret -ifend124: - call void @fn_perr(ptr @.str150) +ifend125: + %t266 = load ptr, ptr %t2 + %t267 = icmp ne ptr %t266, null + %t268 = zext i1 %t267 to i32 + %t269 = icmp ne i32 %t268, 0 + br i1 %t269, label %then126, label %ifend128 +then126: + %t270 = load ptr, ptr %t2 + %t271 = load ptr, ptr %t246 + %t272 = getelementptr inbounds %Cmp_Node, ptr %t271, i32 0, i32 4 + %t273 = load ptr, ptr %t272 + call void @fn_register_onspawn(ptr %t270, ptr %t273) + %t274 = load i32, ptr %t10 + %t275 = icmp ne i32 %t274, 0 + br i1 %t275, label %then129, label %ifend131 +then129: + %t276 = load ptr, ptr %t2 + %t277 = call ptr @fn_str_concat(ptr @.str183, ptr %t276) + %t278 = call ptr @fn_str_concat(ptr %t277, ptr @.str184) + call void @fn_ensure_event(ptr %t278, i32 0) + br label %ifend131 +ifend131: + br label %ret +ifend128: + %t279 = load ptr, ptr %t3 + %t280 = icmp ne ptr %t279, null + %t281 = zext i1 %t280 to i32 + %t282 = icmp ne i32 %t281, 0 + br i1 %t282, label %then132, label %ifend134 +then132: + %t283 = load ptr, ptr %t3 + %t284 = load ptr, ptr %t246 + %t285 = getelementptr inbounds %Cmp_Node, ptr %t284, i32 0, i32 4 + %t286 = load ptr, ptr %t285 + %t287 = load ptr, ptr %t4 + call void @fn_register_ondespawn(ptr %t283, ptr %t286, ptr %t287) + %t288 = load i32, ptr %t10 + %t289 = icmp ne i32 %t288, 0 + br i1 %t289, label %then135, label %ifend137 +then135: + %t290 = load ptr, ptr %t3 + %t291 = call ptr @fn_str_concat(ptr @.str185, ptr %t290) + %t292 = call ptr @fn_str_concat(ptr %t291, ptr @.str186) + call void @fn_ensure_event(ptr %t292, i32 1) + br label %ifend137 +ifend137: + br label %ret +ifend134: + %t293 = load ptr, ptr %t5 + %t294 = icmp ne ptr %t293, null + %t295 = zext i1 %t294 to i32 + %t296 = icmp ne i32 %t295, 0 + br i1 %t296, label %then138, label %ifend140 +then138: + %t297 = load ptr, ptr %t5 + %t298 = load ptr, ptr %t246 + %t299 = getelementptr inbounds %Cmp_Node, ptr %t298, i32 0, i32 4 + %t300 = load ptr, ptr %t299 + call void @fn_register_onattach(ptr %t297, ptr %t300) + %t301 = load i32, ptr %t10 + %t302 = icmp ne i32 %t301, 0 + br i1 %t302, label %then141, label %ifend143 +then141: + %t303 = load ptr, ptr %t5 + %t304 = call ptr @fn_str_concat(ptr @.str187, ptr %t303) + %t305 = call ptr @fn_str_concat(ptr %t304, ptr @.str188) + call void @fn_ensure_event(ptr %t305, i32 0) + br label %ifend143 +ifend143: + br label %ret +ifend140: + %t306 = load ptr, ptr %t6 + %t307 = icmp ne ptr %t306, null + %t308 = zext i1 %t307 to i32 + %t309 = icmp ne i32 %t308, 0 + br i1 %t309, label %then144, label %ifend146 +then144: + %t310 = load ptr, ptr %t6 + %t311 = load ptr, ptr %t246 + %t312 = getelementptr inbounds %Cmp_Node, ptr %t311, i32 0, i32 4 + %t313 = load ptr, ptr %t312 + call void @fn_register_ondetach(ptr %t310, ptr %t313) + %t314 = load i32, ptr %t10 + %t315 = icmp ne i32 %t314, 0 + br i1 %t315, label %then147, label %ifend149 +then147: + %t316 = load ptr, ptr %t6 + %t317 = call ptr @fn_str_concat(ptr @.str189, ptr %t316) + %t318 = call ptr @fn_str_concat(ptr %t317, ptr @.str190) + call void @fn_ensure_event(ptr %t318, i32 0) + br label %ifend149 +ifend149: + br label %ret +ifend146: + %t319 = load ptr, ptr %t7 + %t320 = icmp ne ptr %t319, null + %t321 = zext i1 %t320 to i32 + %t322 = icmp ne i32 %t321, 0 + br i1 %t322, label %then150, label %ifend152 +then150: + %t323 = load ptr, ptr %t7 + %t324 = load ptr, ptr %t246 + %t325 = getelementptr inbounds %Cmp_Node, ptr %t324, i32 0, i32 4 + %t326 = load ptr, ptr %t325 + call void @fn_register_onenable(ptr %t323, ptr %t326) + %t327 = load i32, ptr %t10 + %t328 = icmp ne i32 %t327, 0 + br i1 %t328, label %then153, label %ifend155 +then153: + %t329 = load ptr, ptr %t7 + %t330 = call ptr @fn_str_concat(ptr @.str191, ptr %t329) + %t331 = call ptr @fn_str_concat(ptr %t330, ptr @.str192) + call void @fn_ensure_event(ptr %t331, i32 0) + br label %ifend155 +ifend155: + br label %ret +ifend152: + %t332 = load ptr, ptr %t8 + %t333 = icmp ne ptr %t332, null + %t334 = zext i1 %t333 to i32 + %t335 = icmp ne i32 %t334, 0 + br i1 %t335, label %then156, label %ifend158 +then156: + %t336 = load ptr, ptr %t8 + %t337 = load ptr, ptr %t246 + %t338 = getelementptr inbounds %Cmp_Node, ptr %t337, i32 0, i32 4 + %t339 = load ptr, ptr %t338 + call void @fn_register_ondisable(ptr %t336, ptr %t339) + %t340 = load i32, ptr %t10 + %t341 = icmp ne i32 %t340, 0 + br i1 %t341, label %then159, label %ifend161 +then159: + %t342 = load ptr, ptr %t8 + %t343 = call ptr @fn_str_concat(ptr @.str193, ptr %t342) + %t344 = call ptr @fn_str_concat(ptr %t343, ptr @.str194) + call void @fn_ensure_event(ptr %t344, i32 0) + br label %ifend161 +ifend161: + br label %ret +ifend158: + %t345 = load ptr, ptr %t11 + %t346 = icmp ne ptr %t345, null + %t347 = zext i1 %t346 to i32 + %t348 = icmp ne i32 %t347, 0 + br i1 %t348, label %then162, label %ifend164 +then162: + %t349 = load ptr, ptr %t246 + %t350 = getelementptr inbounds %Cmp_Node, ptr %t349, i32 0, i32 3 + %t351 = load ptr, ptr %t11 + store ptr %t351, ptr %t350 + %t352 = load i32, ptr %t10 + %t353 = icmp ne i32 %t352, 0 + br i1 %t353, label %then165, label %ifend167 +then165: + %t354 = load ptr, ptr %t11 + %t355 = call i32 @fn_str_eq(ptr %t354, ptr @.str195) + %t356 = icmp ne i32 %t355, 0 + br i1 %t356, label %then168, label %else169 +then168: + call void @fn_ensure_event_empty(ptr @.str196) + br label %ifend170 +else169: + call void @fn_ensure_event_empty(ptr @.str197) + br label %ifend170 +ifend170: + br label %ifend167 +ifend167: + br label %ifend164 +ifend164: + %t357 = load ptr, ptr %t1 + %t358 = icmp ne ptr %t357, null + %t359 = zext i1 %t358 to i32 + %t360 = icmp ne i32 %t359, 0 + br i1 %t360, label %then171, label %ifend173 +then171: + %t361 = load ptr, ptr %t1 + %t362 = getelementptr inbounds %Cmp_Node, ptr %t361, i32 0, i32 4 + %t363 = load ptr, ptr %t246 + %t364 = getelementptr inbounds %Cmp_Node, ptr %t363, i32 0, i32 4 + %t365 = load ptr, ptr %t364 + store ptr %t365, ptr %t362 + %t366 = call ptr @fn_node(i32 7) + store ptr %t366, ptr %t367 + %t368 = load ptr, ptr %t367 + %t369 = getelementptr inbounds %Cmp_Node, ptr %t368, i32 0, i32 7 + %t370 = load ptr, ptr %t369 + %t371 = getelementptr inbounds %LSlice, ptr %t370, i32 0, i32 1 + %t372 = getelementptr inbounds %LSlice, ptr %t370, i32 0, i32 2 + %t373 = getelementptr inbounds %LSlice, ptr %t370, i32 0, i32 0 + %t374 = load i32, ptr %t371 + %t375 = load i32, ptr %t372 + %t376 = icmp sge i32 %t374, %t375 + br i1 %t376, label %grow174, label %put175 +grow174: + %t377 = mul i32 %t375, 2 + %t378 = icmp eq i32 %t375, 0 + %t379 = select i1 %t378, i32 8, i32 %t377 + %t380 = getelementptr ptr, ptr null, i32 1 + %t381 = ptrtoint ptr %t380 to i64 + %t382 = zext i32 %t379 to i64 + %t383 = mul i64 %t382, %t381 + %t384 = load ptr, ptr %t373 + %t385 = call ptr @realloc(ptr %t384, i64 %t383) + store ptr %t385, ptr %t373 + store i32 %t379, ptr %t372 + br label %put175 +put175: + %t386 = load ptr, ptr %t1 + %t387 = load ptr, ptr %t373 + %t388 = getelementptr inbounds ptr, ptr %t387, i32 %t374 + store ptr %t386, ptr %t388 + %t389 = add i32 %t374, 1 + store i32 %t389, ptr %t371 + %t390 = load ptr, ptr %t246 + %t391 = getelementptr inbounds %Cmp_Node, ptr %t390, i32 0, i32 4 + %t392 = load ptr, ptr %t367 + store ptr %t392, ptr %t391 + br label %ifend173 +ifend173: + %t393 = load ptr, ptr @g_prog + %t394 = getelementptr inbounds %LSlice, ptr %t393, i32 0, i32 1 + %t395 = getelementptr inbounds %LSlice, ptr %t393, i32 0, i32 2 + %t396 = getelementptr inbounds %LSlice, ptr %t393, i32 0, i32 0 + %t397 = load i32, ptr %t394 + %t398 = load i32, ptr %t395 + %t399 = icmp sge i32 %t397, %t398 + br i1 %t399, label %grow176, label %put177 +grow176: + %t400 = mul i32 %t398, 2 + %t401 = icmp eq i32 %t398, 0 + %t402 = select i1 %t401, i32 8, i32 %t400 + %t403 = getelementptr ptr, ptr null, i32 1 + %t404 = ptrtoint ptr %t403 to i64 + %t405 = zext i32 %t402 to i64 + %t406 = mul i64 %t405, %t404 + %t407 = load ptr, ptr %t396 + %t408 = call ptr @realloc(ptr %t407, i64 %t406) + store ptr %t408, ptr %t396 + store i32 %t402, ptr %t395 + br label %put177 +put177: + %t409 = load ptr, ptr %t246 + %t410 = load ptr, ptr %t396 + %t411 = getelementptr inbounds ptr, ptr %t410, i32 %t397 + store ptr %t409, ptr %t411 + %t412 = add i32 %t397, 1 + store i32 %t412, ptr %t394 + br label %ret +ifend116: + %t413 = call i32 @fn_is_id(ptr @.str198) + %t414 = icmp ne i32 %t413, 0 + br i1 %t414, label %then178, label %ifend180 +then178: + %t415 = load ptr, ptr @g_prog + %t416 = getelementptr inbounds %LSlice, ptr %t415, i32 0, i32 1 + %t417 = getelementptr inbounds %LSlice, ptr %t415, i32 0, i32 2 + %t418 = getelementptr inbounds %LSlice, ptr %t415, i32 0, i32 0 + %t419 = load i32, ptr %t416 + %t420 = load i32, ptr %t417 + %t421 = icmp sge i32 %t419, %t420 + br i1 %t421, label %grow181, label %put182 +grow181: + %t422 = mul i32 %t420, 2 + %t423 = icmp eq i32 %t420, 0 + %t424 = select i1 %t423, i32 8, i32 %t422 + %t425 = getelementptr ptr, ptr null, i32 1 + %t426 = ptrtoint ptr %t425 to i64 + %t427 = zext i32 %t424 to i64 + %t428 = mul i64 %t427, %t426 + %t429 = load ptr, ptr %t418 + %t430 = call ptr @realloc(ptr %t429, i64 %t428) + store ptr %t430, ptr %t418 + store i32 %t424, ptr %t417 + br label %put182 +put182: + %t431 = call ptr @fn_parse_ui() + %t432 = load ptr, ptr %t418 + %t433 = getelementptr inbounds ptr, ptr %t432, i32 %t419 + store ptr %t431, ptr %t433 + %t434 = add i32 %t419, 1 + store i32 %t434, ptr %t416 + br label %ret +ifend180: + %t435 = call i32 @fn_is_id(ptr @.str199) + %t436 = icmp ne i32 %t435, 0 + br i1 %t436, label %then183, label %ifend185 +then183: + %t437 = load ptr, ptr @g_prog + %t438 = getelementptr inbounds %LSlice, ptr %t437, i32 0, i32 1 + %t439 = getelementptr inbounds %LSlice, ptr %t437, i32 0, i32 2 + %t440 = getelementptr inbounds %LSlice, ptr %t437, i32 0, i32 0 + %t441 = load i32, ptr %t438 + %t442 = load i32, ptr %t439 + %t443 = icmp sge i32 %t441, %t442 + br i1 %t443, label %grow186, label %put187 +grow186: + %t444 = mul i32 %t442, 2 + %t445 = icmp eq i32 %t442, 0 + %t446 = select i1 %t445, i32 8, i32 %t444 + %t447 = getelementptr ptr, ptr null, i32 1 + %t448 = ptrtoint ptr %t447 to i64 + %t449 = zext i32 %t446 to i64 + %t450 = mul i64 %t449, %t448 + %t451 = load ptr, ptr %t440 + %t452 = call ptr @realloc(ptr %t451, i64 %t450) + store ptr %t452, ptr %t440 + store i32 %t446, ptr %t439 + br label %put187 +put187: + %t453 = call ptr @fn_parse_var() + %t454 = load ptr, ptr %t440 + %t455 = getelementptr inbounds ptr, ptr %t454, i32 %t441 + store ptr %t453, ptr %t455 + %t456 = add i32 %t441, 1 + store i32 %t456, ptr %t438 + br label %ret +ifend185: + %t457 = call i32 @fn_is_id(ptr @.str200) + %t458 = icmp ne i32 %t457, 0 + br i1 %t458, label %then188, label %ifend190 +then188: + %t459 = load ptr, ptr @g_prog + %t460 = getelementptr inbounds %LSlice, ptr %t459, i32 0, i32 1 + %t461 = getelementptr inbounds %LSlice, ptr %t459, i32 0, i32 2 + %t462 = getelementptr inbounds %LSlice, ptr %t459, i32 0, i32 0 + %t463 = load i32, ptr %t460 + %t464 = load i32, ptr %t461 + %t465 = icmp sge i32 %t463, %t464 + br i1 %t465, label %grow191, label %put192 +grow191: + %t466 = mul i32 %t464, 2 + %t467 = icmp eq i32 %t464, 0 + %t468 = select i1 %t467, i32 8, i32 %t466 + %t469 = getelementptr ptr, ptr null, i32 1 + %t470 = ptrtoint ptr %t469 to i64 + %t471 = zext i32 %t468 to i64 + %t472 = mul i64 %t471, %t470 + %t473 = load ptr, ptr %t462 + %t474 = call ptr @realloc(ptr %t473, i64 %t472) + store ptr %t474, ptr %t462 + store i32 %t468, ptr %t461 + br label %put192 +put192: + %t475 = call ptr @fn_parse_const() + %t476 = load ptr, ptr %t462 + %t477 = getelementptr inbounds ptr, ptr %t476, i32 %t463 + store ptr %t475, ptr %t477 + %t478 = add i32 %t463, 1 + store i32 %t478, ptr %t460 + br label %ret +ifend190: + %t479 = call i32 @fn_is_id(ptr @.str201) + %t480 = icmp ne i32 %t479, 0 + br i1 %t480, label %then193, label %ifend195 +then193: + %t481 = call ptr @fn_parse_fn() + store ptr %t481, ptr %t482 + %t483 = load i32, ptr %t0 + %t484 = icmp ne i32 %t483, 0 + br i1 %t484, label %then196, label %ifend198 +then196: + %t485 = load ptr, ptr %t482 + %t486 = getelementptr inbounds %Cmp_Node, ptr %t485, i32 0, i32 2 + store i32 1, ptr %t486 + br label %ifend198 +ifend198: + %t487 = load ptr, ptr @g_prog + %t488 = getelementptr inbounds %LSlice, ptr %t487, i32 0, i32 1 + %t489 = getelementptr inbounds %LSlice, ptr %t487, i32 0, i32 2 + %t490 = getelementptr inbounds %LSlice, ptr %t487, i32 0, i32 0 + %t491 = load i32, ptr %t488 + %t492 = load i32, ptr %t489 + %t493 = icmp sge i32 %t491, %t492 + br i1 %t493, label %grow199, label %put200 +grow199: + %t494 = mul i32 %t492, 2 + %t495 = icmp eq i32 %t492, 0 + %t496 = select i1 %t495, i32 8, i32 %t494 + %t497 = getelementptr ptr, ptr null, i32 1 + %t498 = ptrtoint ptr %t497 to i64 + %t499 = zext i32 %t496 to i64 + %t500 = mul i64 %t499, %t498 + %t501 = load ptr, ptr %t490 + %t502 = call ptr @realloc(ptr %t501, i64 %t500) + store ptr %t502, ptr %t490 + store i32 %t496, ptr %t489 + br label %put200 +put200: + %t503 = load ptr, ptr %t482 + %t504 = load ptr, ptr %t490 + %t505 = getelementptr inbounds ptr, ptr %t504, i32 %t491 + store ptr %t503, ptr %t505 + %t506 = add i32 %t491, 1 + store i32 %t506, ptr %t488 + br label %ret +ifend195: + %t507 = call i32 @fn_is_id(ptr @.str202) + %t508 = icmp ne i32 %t507, 0 + br i1 %t508, label %then201, label %ifend203 +then201: + %t509 = load ptr, ptr @g_prog + %t510 = getelementptr inbounds %LSlice, ptr %t509, i32 0, i32 1 + %t511 = getelementptr inbounds %LSlice, ptr %t509, i32 0, i32 2 + %t512 = getelementptr inbounds %LSlice, ptr %t509, i32 0, i32 0 + %t513 = load i32, ptr %t510 + %t514 = load i32, ptr %t511 + %t515 = icmp sge i32 %t513, %t514 + br i1 %t515, label %grow204, label %put205 +grow204: + %t516 = mul i32 %t514, 2 + %t517 = icmp eq i32 %t514, 0 + %t518 = select i1 %t517, i32 8, i32 %t516 + %t519 = getelementptr ptr, ptr null, i32 1 + %t520 = ptrtoint ptr %t519 to i64 + %t521 = zext i32 %t518 to i64 + %t522 = mul i64 %t521, %t520 + %t523 = load ptr, ptr %t512 + %t524 = call ptr @realloc(ptr %t523, i64 %t522) + store ptr %t524, ptr %t512 + store i32 %t518, ptr %t511 + br label %put205 +put205: + %t525 = call ptr @fn_parse_extern() + %t526 = load ptr, ptr %t512 + %t527 = getelementptr inbounds ptr, ptr %t526, i32 %t513 + store ptr %t525, ptr %t527 + %t528 = add i32 %t513, 1 + store i32 %t528, ptr %t510 + br label %ret +ifend203: + %t529 = call i32 @fn_is_id(ptr @.str203) + %t530 = icmp ne i32 %t529, 0 + br i1 %t530, label %then206, label %ifend208 +then206: + %t531 = load ptr, ptr @g_prog + %t532 = getelementptr inbounds %LSlice, ptr %t531, i32 0, i32 1 + %t533 = getelementptr inbounds %LSlice, ptr %t531, i32 0, i32 2 + %t534 = getelementptr inbounds %LSlice, ptr %t531, i32 0, i32 0 + %t535 = load i32, ptr %t532 + %t536 = load i32, ptr %t533 + %t537 = icmp sge i32 %t535, %t536 + br i1 %t537, label %grow209, label %put210 +grow209: + %t538 = mul i32 %t536, 2 + %t539 = icmp eq i32 %t536, 0 + %t540 = select i1 %t539, i32 8, i32 %t538 + %t541 = getelementptr ptr, ptr null, i32 1 + %t542 = ptrtoint ptr %t541 to i64 + %t543 = zext i32 %t540 to i64 + %t544 = mul i64 %t543, %t542 + %t545 = load ptr, ptr %t534 + %t546 = call ptr @realloc(ptr %t545, i64 %t544) + store ptr %t546, ptr %t534 + store i32 %t540, ptr %t533 + br label %put210 +put210: + %t547 = call ptr @fn_parse_main() + %t548 = load ptr, ptr %t534 + %t549 = getelementptr inbounds ptr, ptr %t548, i32 %t535 + store ptr %t547, ptr %t549 + %t550 = add i32 %t535, 1 + store i32 %t550, ptr %t532 + br label %ret +ifend208: + call void @fn_perr(ptr @.str204) br label %ret ret: ret void @@ -7635,7 +9515,7 @@ put4: br i1 %t34, label %then5, label %ifend7 then5: %t35 = load ptr, ptr %t4 - %t36 = call ptr @fn_str_concat(ptr @.str151, ptr %t35) + %t36 = call ptr @fn_str_concat(ptr @.str205, ptr %t35) call void @fn_perr(ptr %t36) br label %ifend7 ifend7: @@ -7695,8 +9575,8 @@ then0: ifend2: %t4 = load ptr, ptr @g_cur_dir store ptr %t4, ptr %t5 - store ptr @.str152, ptr @g_cur_dir - call void @fn_do_import(ptr @.str153) + store ptr @.str206, ptr @g_cur_dir + call void @fn_do_import(ptr @.str207) %t6 = load ptr, ptr %t5 store ptr %t6, ptr @g_cur_dir br label %ret @@ -7706,10 +9586,10 @@ ret: define void @fn_parse_program() { entry: - %t58 = alloca ptr - %t62 = alloca ptr - %t71 = alloca ptr - %t74 = alloca i32 + %t88 = alloca ptr + %t92 = alloca ptr + %t101 = alloca ptr + %t104 = alloca i32 %t0 = getelementptr %LSlice, ptr null, i32 1 %t1 = ptrtoint ptr %t0 to i64 %t2 = call ptr @malloc(i64 %t1) @@ -7769,7 +9649,7 @@ entry: store i32 0, ptr %t34 %t35 = getelementptr inbounds %LSlice, ptr %t32, i32 0, i32 2 store i32 0, ptr %t35 - store ptr %t32, ptr @g_g_onenable + store ptr %t32, ptr @g_g_ondetach %t36 = getelementptr %LSlice, ptr null, i32 1 %t37 = ptrtoint ptr %t36 to i64 %t38 = call ptr @malloc(i64 %t37) @@ -7779,7 +9659,7 @@ entry: store i32 0, ptr %t40 %t41 = getelementptr inbounds %LSlice, ptr %t38, i32 0, i32 2 store i32 0, ptr %t41 - store ptr %t38, ptr @g_g_ondisable + store ptr %t38, ptr @g_g_onenable %t42 = getelementptr %LSlice, ptr null, i32 1 %t43 = ptrtoint ptr %t42 to i64 %t44 = call ptr @malloc(i64 %t43) @@ -7789,84 +9669,136 @@ entry: store i32 0, ptr %t46 %t47 = getelementptr inbounds %LSlice, ptr %t44, i32 0, i32 2 store i32 0, ptr %t47 - store ptr %t44, ptr @g_loaded_paths + store ptr %t44, ptr @g_g_ondisable + %t48 = getelementptr %LSlice, ptr null, i32 1 + %t49 = ptrtoint ptr %t48 to i64 + %t50 = call ptr @malloc(i64 %t49) + %t51 = getelementptr inbounds %LSlice, ptr %t50, i32 0, i32 0 + store ptr null, ptr %t51 + %t52 = getelementptr inbounds %LSlice, ptr %t50, i32 0, i32 1 + store i32 0, ptr %t52 + %t53 = getelementptr inbounds %LSlice, ptr %t50, i32 0, i32 2 + store i32 0, ptr %t53 + store ptr %t50, ptr @g_g_scenes + store i32 0, ptr @g_g_scene_count + store i32 0, ptr @g_g_start_scene + %t54 = getelementptr %LSlice, ptr null, i32 1 + %t55 = ptrtoint ptr %t54 to i64 + %t56 = call ptr @malloc(i64 %t55) + %t57 = getelementptr inbounds %LSlice, ptr %t56, i32 0, i32 0 + store ptr null, ptr %t57 + %t58 = getelementptr inbounds %LSlice, ptr %t56, i32 0, i32 1 + store i32 0, ptr %t58 + %t59 = getelementptr inbounds %LSlice, ptr %t56, i32 0, i32 2 + store i32 0, ptr %t59 + store ptr %t56, ptr @g_g_events + %t60 = getelementptr %LSlice, ptr null, i32 1 + %t61 = ptrtoint ptr %t60 to i64 + %t62 = call ptr @malloc(i64 %t61) + %t63 = getelementptr inbounds %LSlice, ptr %t62, i32 0, i32 0 + store ptr null, ptr %t63 + %t64 = getelementptr inbounds %LSlice, ptr %t62, i32 0, i32 1 + store i32 0, ptr %t64 + %t65 = getelementptr inbounds %LSlice, ptr %t62, i32 0, i32 2 + store i32 0, ptr %t65 + store ptr %t62, ptr @g_g_onlisten + %t66 = getelementptr %LSlice, ptr null, i32 1 + %t67 = ptrtoint ptr %t66 to i64 + %t68 = call ptr @malloc(i64 %t67) + %t69 = getelementptr inbounds %LSlice, ptr %t68, i32 0, i32 0 + store ptr null, ptr %t69 + %t70 = getelementptr inbounds %LSlice, ptr %t68, i32 0, i32 1 + store i32 0, ptr %t70 + %t71 = getelementptr inbounds %LSlice, ptr %t68, i32 0, i32 2 + store i32 0, ptr %t71 + store ptr %t68, ptr @g_g_toggled_layers + %t72 = getelementptr %LSlice, ptr null, i32 1 + %t73 = ptrtoint ptr %t72 to i64 + %t74 = call ptr @malloc(i64 %t73) + %t75 = getelementptr inbounds %LSlice, ptr %t74, i32 0, i32 0 + store ptr null, ptr %t75 + %t76 = getelementptr inbounds %LSlice, ptr %t74, i32 0, i32 1 + store i32 0, ptr %t76 + %t77 = getelementptr inbounds %LSlice, ptr %t74, i32 0, i32 2 + store i32 0, ptr %t77 + store ptr %t74, ptr @g_loaded_paths call void @fn_skipnl() - store ptr @.str154, ptr @g_g_game_name + store ptr @.str208, ptr @g_g_game_name br label %wcond0 wcond0: - %t48 = call i32 @fn_is_id(ptr @.str155) - %t49 = icmp ne i32 %t48, 0 - br i1 %t49, label %wbody1, label %wend2 + %t78 = call i32 @fn_is_id(ptr @.str209) + %t79 = icmp ne i32 %t78, 0 + br i1 %t79, label %wbody1, label %wend2 wbody1: - %t50 = load i32, ptr @g_pi - %t51 = add i32 %t50, 1 - store i32 %t51, ptr @g_pi - %t52 = load ptr, ptr @g_toks - %t53 = getelementptr inbounds %LSlice, ptr %t52, i32 0, i32 0 - %t54 = load ptr, ptr %t53 - %t55 = load i32, ptr @g_pi - %t56 = getelementptr inbounds ptr, ptr %t54, i32 %t55 - %t57 = load ptr, ptr %t56 - store ptr %t57, ptr %t58 - %t59 = load ptr, ptr %t58 - %t60 = getelementptr inbounds %Cmp_Tok, ptr %t59, i32 0, i32 1 - %t61 = load ptr, ptr %t60 - store ptr %t61, ptr %t62 - %t63 = load i32, ptr @g_pi - %t64 = add i32 %t63, 1 - store i32 %t64, ptr @g_pi - %t65 = load ptr, ptr %t62 - call void @fn_do_import(ptr %t65) + %t80 = load i32, ptr @g_pi + %t81 = add i32 %t80, 1 + store i32 %t81, ptr @g_pi + %t82 = load ptr, ptr @g_toks + %t83 = getelementptr inbounds %LSlice, ptr %t82, i32 0, i32 0 + %t84 = load ptr, ptr %t83 + %t85 = load i32, ptr @g_pi + %t86 = getelementptr inbounds ptr, ptr %t84, i32 %t85 + %t87 = load ptr, ptr %t86 + store ptr %t87, ptr %t88 + %t89 = load ptr, ptr %t88 + %t90 = getelementptr inbounds %Cmp_Tok, ptr %t89, i32 0, i32 1 + %t91 = load ptr, ptr %t90 + store ptr %t91, ptr %t92 + %t93 = load i32, ptr @g_pi + %t94 = add i32 %t93, 1 + store i32 %t94, ptr @g_pi + %t95 = load ptr, ptr %t92 + call void @fn_do_import(ptr %t95) call void @fn_skipnl() br label %wcond0 wend2: br label %wcond3 wcond3: - %t66 = call i32 @fn_is_op(ptr @.str156) - %t67 = icmp ne i32 %t66, 0 - br i1 %t67, label %wbody4, label %wend5 + %t96 = call i32 @fn_is_op(ptr @.str210) + %t97 = icmp ne i32 %t96, 0 + br i1 %t97, label %wbody4, label %wend5 wbody4: - %t68 = load i32, ptr @g_pi - %t69 = add i32 %t68, 1 - store i32 %t69, ptr @g_pi - %t70 = call ptr @fn_eat_id() - store ptr %t70, ptr %t71 - %t72 = call i32 @fn_is_op(ptr @.str157) - %t73 = icmp ne i32 %t72, 0 - br i1 %t73, label %then6, label %ifend8 + %t98 = load i32, ptr @g_pi + %t99 = add i32 %t98, 1 + store i32 %t99, ptr @g_pi + %t100 = call ptr @fn_eat_id() + store ptr %t100, ptr %t101 + %t102 = call i32 @fn_is_op(ptr @.str211) + %t103 = icmp ne i32 %t102, 0 + br i1 %t103, label %then6, label %ifend8 then6: - store i32 0, ptr %t74 + store i32 0, ptr %t104 br label %wcond9 wcond9: - %t75 = icmp ne i32 1, 0 - br i1 %t75, label %wbody10, label %wend11 + %t105 = icmp ne i32 1, 0 + br i1 %t105, label %wbody10, label %wend11 wbody10: - %t76 = call i32 @fn_is_op(ptr @.str158) - %t77 = icmp ne i32 %t76, 0 - br i1 %t77, label %then12, label %ifend14 + %t106 = call i32 @fn_is_op(ptr @.str212) + %t107 = icmp ne i32 %t106, 0 + br i1 %t107, label %then12, label %ifend14 then12: - %t78 = load i32, ptr %t74 - %t79 = add i32 %t78, 1 - store i32 %t79, ptr %t74 + %t108 = load i32, ptr %t104 + %t109 = add i32 %t108, 1 + store i32 %t109, ptr %t104 br label %ifend14 ifend14: - %t80 = call i32 @fn_is_op(ptr @.str159) - %t81 = icmp ne i32 %t80, 0 - br i1 %t81, label %then15, label %ifend17 + %t110 = call i32 @fn_is_op(ptr @.str213) + %t111 = icmp ne i32 %t110, 0 + br i1 %t111, label %then15, label %ifend17 then15: - %t82 = load i32, ptr %t74 - %t83 = sub i32 %t82, 1 - store i32 %t83, ptr %t74 + %t112 = load i32, ptr %t104 + %t113 = sub i32 %t112, 1 + store i32 %t113, ptr %t104 br label %ifend17 ifend17: - %t84 = load i32, ptr @g_pi - %t85 = add i32 %t84, 1 - store i32 %t85, ptr @g_pi - %t86 = load i32, ptr %t74 - %t87 = icmp eq i32 %t86, 0 - %t88 = zext i1 %t87 to i32 - %t89 = icmp ne i32 %t88, 0 - br i1 %t89, label %then18, label %ifend20 + %t114 = load i32, ptr @g_pi + %t115 = add i32 %t114, 1 + store i32 %t115, ptr @g_pi + %t116 = load i32, ptr %t104 + %t117 = icmp eq i32 %t116, 0 + %t118 = zext i1 %t117 to i32 + %t119 = icmp ne i32 %t118, 0 + br i1 %t119, label %then18, label %ifend20 then18: br label %wend11 ifend20: @@ -7877,43 +9809,43 @@ ifend8: call void @fn_skipnl() br label %wcond3 wend5: - %t90 = call i32 @fn_is_id(ptr @.str160) - %t91 = icmp ne i32 %t90, 0 - br i1 %t91, label %then21, label %ifend23 + %t120 = call i32 @fn_is_id(ptr @.str214) + %t121 = icmp ne i32 %t120, 0 + br i1 %t121, label %then21, label %ifend23 then21: - %t92 = load i32, ptr @g_pi - %t93 = add i32 %t92, 1 - store i32 %t93, ptr @g_pi - %t94 = call ptr @fn_eat_id() - store ptr %t94, ptr @g_g_game_name + %t122 = load i32, ptr @g_pi + %t123 = add i32 %t122, 1 + store i32 %t123, ptr @g_pi + %t124 = call ptr @fn_eat_id() + store ptr %t124, ptr @g_g_game_name call void @fn_skipnl() - call void @fn_eat_op(ptr @.str161) + call void @fn_eat_op(ptr @.str215) br label %ifend23 ifend23: br label %wcond24 wcond24: - %t95 = icmp ne i32 1, 0 - br i1 %t95, label %wbody25, label %wend26 + %t125 = icmp ne i32 1, 0 + br i1 %t125, label %wbody25, label %wend26 wbody25: call void @fn_skipnl() - %t96 = load ptr, ptr @g_toks - %t97 = getelementptr inbounds %LSlice, ptr %t96, i32 0, i32 0 - %t98 = load ptr, ptr %t97 - %t99 = load i32, ptr @g_pi - %t100 = getelementptr inbounds ptr, ptr %t98, i32 %t99 - %t101 = load ptr, ptr %t100 - %t102 = getelementptr inbounds %Cmp_Tok, ptr %t101, i32 0, i32 0 - %t103 = load i32, ptr %t102 - %t104 = icmp eq i32 %t103, 5 - %t105 = zext i1 %t104 to i32 - %t106 = icmp ne i32 %t105, 0 - br i1 %t106, label %then27, label %ifend29 + %t126 = load ptr, ptr @g_toks + %t127 = getelementptr inbounds %LSlice, ptr %t126, i32 0, i32 0 + %t128 = load ptr, ptr %t127 + %t129 = load i32, ptr @g_pi + %t130 = getelementptr inbounds ptr, ptr %t128, i32 %t129 + %t131 = load ptr, ptr %t130 + %t132 = getelementptr inbounds %Cmp_Tok, ptr %t131, i32 0, i32 0 + %t133 = load i32, ptr %t132 + %t134 = icmp eq i32 %t133, 5 + %t135 = zext i1 %t134 to i32 + %t136 = icmp ne i32 %t135, 0 + br i1 %t136, label %then27, label %ifend29 then27: br label %wend26 ifend29: - %t107 = call i32 @fn_is_op(ptr @.str162) - %t108 = icmp ne i32 %t107, 0 - br i1 %t108, label %then30, label %ifend32 + %t137 = call i32 @fn_is_op(ptr @.str216) + %t138 = icmp ne i32 %t137, 0 + br i1 %t138, label %then30, label %ifend32 then30: br label %wend26 ifend32: @@ -7930,8 +9862,9 @@ entry: %retval = alloca ptr %t3 = alloca ptr %t10 = alloca i32 - %t16 = alloca ptr - %t21 = alloca ptr + %t11 = alloca i32 + %t17 = alloca ptr + %t25 = alloca ptr %t0 = load i32, ptr @g_pi %t1 = add i32 %t0, 1 store i32 %t1, ptr @g_pi @@ -7942,133 +9875,267 @@ entry: %t6 = call ptr @fn_eat_id() store ptr %t6, ptr %t5 call void @fn_skipnl() - call void @fn_eat_op(ptr @.str163) + call void @fn_eat_op(ptr @.str217) br label %wcond0 wcond0: %t7 = icmp ne i32 1, 0 br i1 %t7, label %wbody1, label %wend2 wbody1: call void @fn_skipnl() - %t8 = call i32 @fn_is_op(ptr @.str164) + %t8 = call i32 @fn_is_op(ptr @.str218) %t9 = icmp ne i32 %t8, 0 br i1 %t9, label %then3, label %ifend5 then3: br label %wend2 ifend5: store i32 0, ptr %t10 - %t11 = call i32 @fn_is_op(ptr @.str165) - %t12 = icmp ne i32 %t11, 0 - br i1 %t12, label %then6, label %ifend8 + store i32 0, ptr %t11 + %t12 = call i32 @fn_is_op(ptr @.str219) + %t13 = icmp ne i32 %t12, 0 + br i1 %t13, label %then6, label %ifend8 then6: - %t13 = load i32, ptr @g_pi - %t14 = add i32 %t13, 1 - store i32 %t14, ptr @g_pi - %t15 = call ptr @fn_eat_id() - store ptr %t15, ptr %t16 - %t17 = load ptr, ptr %t16 - %t18 = call i32 @fn_str_eq(ptr %t17, ptr @.str166) - %t19 = icmp ne i32 %t18, 0 - br i1 %t19, label %then9, label %ifend11 + %t14 = load i32, ptr @g_pi + %t15 = add i32 %t14, 1 + store i32 %t15, ptr @g_pi + %t16 = call ptr @fn_eat_id() + store ptr %t16, ptr %t17 + %t18 = load ptr, ptr %t17 + %t19 = call i32 @fn_str_eq(ptr %t18, ptr @.str220) + %t20 = icmp ne i32 %t19, 0 + br i1 %t20, label %then9, label %else10 then9: store i32 1, ptr %t10 br label %ifend11 +else10: + %t21 = load ptr, ptr %t17 + %t22 = call i32 @fn_str_eq(ptr %t21, ptr @.str221) + %t23 = icmp ne i32 %t22, 0 + br i1 %t23, label %then12, label %ifend14 +then12: + store i32 1, ptr %t11 + br label %ifend14 +ifend14: + br label %ifend11 ifend11: call void @fn_skipnl() br label %ifend8 ifend8: - %t20 = call ptr @fn_node(i32 1) - store ptr %t20, ptr %t21 - %t22 = load ptr, ptr %t21 - %t23 = getelementptr inbounds %Cmp_Node, ptr %t22, i32 0, i32 1 - %t24 = call ptr @fn_eat_id() - store ptr %t24, ptr %t23 - call void @fn_eat_op(ptr @.str167) - %t25 = load ptr, ptr %t21 - %t26 = getelementptr inbounds %Cmp_Node, ptr %t25, i32 0, i32 3 - %t27 = call ptr @fn_ptype() - store ptr %t27, ptr %t26 - %t28 = call i32 @fn_is_op(ptr @.str168) - %t29 = icmp ne i32 %t28, 0 - br i1 %t29, label %then12, label %ifend14 -then12: - %t30 = load i32, ptr @g_pi - %t31 = add i32 %t30, 1 - store i32 %t31, ptr @g_pi - %t32 = load ptr, ptr %t21 - %t33 = getelementptr inbounds %Cmp_Node, ptr %t32, i32 0, i32 4 - %t34 = call ptr @fn_expr() - store ptr %t34, ptr %t33 - br label %ifend14 -ifend14: - %t35 = load i32, ptr %t10 - %t36 = icmp ne i32 %t35, 0 - br i1 %t36, label %then15, label %else16 + %t24 = call ptr @fn_node(i32 1) + store ptr %t24, ptr %t25 + %t26 = load ptr, ptr %t25 + %t27 = getelementptr inbounds %Cmp_Node, ptr %t26, i32 0, i32 1 + %t28 = call ptr @fn_eat_id() + store ptr %t28, ptr %t27 + call void @fn_eat_op(ptr @.str222) + %t29 = load ptr, ptr %t25 + %t30 = getelementptr inbounds %Cmp_Node, ptr %t29, i32 0, i32 3 + %t31 = call ptr @fn_ptype() + store ptr %t31, ptr %t30 + %t32 = call i32 @fn_is_op(ptr @.str223) + %t33 = icmp ne i32 %t32, 0 + br i1 %t33, label %then15, label %ifend17 then15: - %t37 = load ptr, ptr %t3 - %t38 = getelementptr inbounds %Cmp_Node, ptr %t37, i32 0, i32 1 - %t39 = load ptr, ptr %t38 - %t40 = load ptr, ptr %t21 - %t41 = getelementptr inbounds %Cmp_Node, ptr %t40, i32 0, i32 1 - %t42 = load ptr, ptr %t41 - %t43 = load ptr, ptr %t21 - %t44 = getelementptr inbounds %Cmp_Node, ptr %t43, i32 0, i32 3 - %t45 = load ptr, ptr %t44 - %t46 = load ptr, ptr %t21 - %t47 = getelementptr inbounds %Cmp_Node, ptr %t46, i32 0, i32 4 - %t48 = load ptr, ptr %t47 - call void @fn_register_computed(ptr %t39, ptr %t42, ptr %t45, ptr %t48) - br label %ifend17 -else16: - %t49 = load ptr, ptr %t3 - %t50 = getelementptr inbounds %Cmp_Node, ptr %t49, i32 0, i32 7 - %t51 = load ptr, ptr %t50 - %t52 = getelementptr inbounds %LSlice, ptr %t51, i32 0, i32 1 - %t53 = getelementptr inbounds %LSlice, ptr %t51, i32 0, i32 2 - %t54 = getelementptr inbounds %LSlice, ptr %t51, i32 0, i32 0 - %t55 = load i32, ptr %t52 - %t56 = load i32, ptr %t53 - %t57 = icmp sge i32 %t55, %t56 - br i1 %t57, label %grow18, label %put19 -grow18: - %t58 = mul i32 %t56, 2 - %t59 = icmp eq i32 %t56, 0 - %t60 = select i1 %t59, i32 8, i32 %t58 - %t61 = getelementptr ptr, ptr null, i32 1 - %t62 = ptrtoint ptr %t61 to i64 - %t63 = zext i32 %t60 to i64 - %t64 = mul i64 %t63, %t62 - %t65 = load ptr, ptr %t54 - %t66 = call ptr @realloc(ptr %t65, i64 %t64) - store ptr %t66, ptr %t54 - store i32 %t60, ptr %t53 - br label %put19 -put19: - %t67 = load ptr, ptr %t21 - %t68 = load ptr, ptr %t54 - %t69 = getelementptr inbounds ptr, ptr %t68, i32 %t55 - store ptr %t67, ptr %t69 - %t70 = add i32 %t55, 1 - store i32 %t70, ptr %t52 + %t34 = load i32, ptr @g_pi + %t35 = add i32 %t34, 1 + store i32 %t35, ptr @g_pi + %t36 = load ptr, ptr %t25 + %t37 = getelementptr inbounds %Cmp_Node, ptr %t36, i32 0, i32 4 + %t38 = call ptr @fn_expr() + store ptr %t38, ptr %t37 br label %ifend17 ifend17: - %t71 = call i32 @fn_is_op(ptr @.str169) - %t72 = icmp ne i32 %t71, 0 - br i1 %t72, label %then20, label %ifend22 -then20: - %t73 = load i32, ptr @g_pi - %t74 = add i32 %t73, 1 - store i32 %t74, ptr @g_pi - br label %ifend22 -ifend22: + %t39 = load i32, ptr %t11 + %t40 = icmp ne i32 %t39, 0 + br i1 %t40, label %then18, label %ifend20 +then18: + %t41 = load ptr, ptr %t25 + %t42 = getelementptr inbounds %Cmp_Node, ptr %t41, i32 0, i32 2 + store i32 1, ptr %t42 + br label %ifend20 +ifend20: + %t43 = load i32, ptr %t10 + %t44 = icmp ne i32 %t43, 0 + br i1 %t44, label %then21, label %else22 +then21: + %t45 = load ptr, ptr %t3 + %t46 = getelementptr inbounds %Cmp_Node, ptr %t45, i32 0, i32 1 + %t47 = load ptr, ptr %t46 + %t48 = load ptr, ptr %t25 + %t49 = getelementptr inbounds %Cmp_Node, ptr %t48, i32 0, i32 1 + %t50 = load ptr, ptr %t49 + %t51 = load ptr, ptr %t25 + %t52 = getelementptr inbounds %Cmp_Node, ptr %t51, i32 0, i32 3 + %t53 = load ptr, ptr %t52 + %t54 = load ptr, ptr %t25 + %t55 = getelementptr inbounds %Cmp_Node, ptr %t54, i32 0, i32 4 + %t56 = load ptr, ptr %t55 + call void @fn_register_computed(ptr %t47, ptr %t50, ptr %t53, ptr %t56) + br label %ifend23 +else22: + %t57 = load ptr, ptr %t3 + %t58 = getelementptr inbounds %Cmp_Node, ptr %t57, i32 0, i32 7 + %t59 = load ptr, ptr %t58 + %t60 = getelementptr inbounds %LSlice, ptr %t59, i32 0, i32 1 + %t61 = getelementptr inbounds %LSlice, ptr %t59, i32 0, i32 2 + %t62 = getelementptr inbounds %LSlice, ptr %t59, i32 0, i32 0 + %t63 = load i32, ptr %t60 + %t64 = load i32, ptr %t61 + %t65 = icmp sge i32 %t63, %t64 + br i1 %t65, label %grow24, label %put25 +grow24: + %t66 = mul i32 %t64, 2 + %t67 = icmp eq i32 %t64, 0 + %t68 = select i1 %t67, i32 8, i32 %t66 + %t69 = getelementptr ptr, ptr null, i32 1 + %t70 = ptrtoint ptr %t69 to i64 + %t71 = zext i32 %t68 to i64 + %t72 = mul i64 %t71, %t70 + %t73 = load ptr, ptr %t62 + %t74 = call ptr @realloc(ptr %t73, i64 %t72) + store ptr %t74, ptr %t62 + store i32 %t68, ptr %t61 + br label %put25 +put25: + %t75 = load ptr, ptr %t25 + %t76 = load ptr, ptr %t62 + %t77 = getelementptr inbounds ptr, ptr %t76, i32 %t63 + store ptr %t75, ptr %t77 + %t78 = add i32 %t63, 1 + store i32 %t78, ptr %t60 + br label %ifend23 +ifend23: + %t79 = call i32 @fn_is_op(ptr @.str224) + %t80 = icmp ne i32 %t79, 0 + br i1 %t80, label %then26, label %ifend28 +then26: + %t81 = load i32, ptr @g_pi + %t82 = add i32 %t81, 1 + store i32 %t82, ptr @g_pi + br label %ifend28 +ifend28: br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str170) - %t75 = load ptr, ptr %t3 - store ptr %t75, ptr %retval + call void @fn_eat_op(ptr @.str225) + %t83 = load ptr, ptr %t3 + store ptr %t83, ptr %retval br label %ret ret: - %t76 = load ptr, ptr %retval - ret ptr %t76 + %t84 = load ptr, ptr %retval + ret ptr %t84 +} + +define ptr @fn_parse_event() { +entry: + %retval = alloca ptr + %t3 = alloca ptr + %t17 = alloca ptr + %t0 = load i32, ptr @g_pi + %t1 = add i32 %t0, 1 + store i32 %t1, ptr @g_pi + %t2 = call ptr @fn_node(i32 48) + store ptr %t2, ptr %t3 + %t4 = call i32 @fn_is_id(ptr @.str226) + %t5 = icmp ne i32 %t4, 0 + br i1 %t5, label %then0, label %ifend2 +then0: + %t6 = load i32, ptr @g_pi + %t7 = add i32 %t6, 1 + store i32 %t7, ptr @g_pi + %t8 = load ptr, ptr %t3 + %t9 = getelementptr inbounds %Cmp_Node, ptr %t8, i32 0, i32 2 + store i32 1, ptr %t9 + br label %ifend2 +ifend2: + %t10 = load ptr, ptr %t3 + %t11 = getelementptr inbounds %Cmp_Node, ptr %t10, i32 0, i32 1 + %t12 = call ptr @fn_eat_id() + store ptr %t12, ptr %t11 + call void @fn_skipnl() + call void @fn_eat_op(ptr @.str227) + br label %wcond3 +wcond3: + %t13 = icmp ne i32 1, 0 + br i1 %t13, label %wbody4, label %wend5 +wbody4: + call void @fn_skipnl() + %t14 = call i32 @fn_is_op(ptr @.str228) + %t15 = icmp ne i32 %t14, 0 + br i1 %t15, label %then6, label %ifend8 +then6: + br label %wend5 +ifend8: + %t16 = call ptr @fn_node(i32 1) + store ptr %t16, ptr %t17 + %t18 = load ptr, ptr %t17 + %t19 = getelementptr inbounds %Cmp_Node, ptr %t18, i32 0, i32 1 + %t20 = call ptr @fn_eat_id() + store ptr %t20, ptr %t19 + call void @fn_eat_op(ptr @.str229) + %t21 = load ptr, ptr %t17 + %t22 = getelementptr inbounds %Cmp_Node, ptr %t21, i32 0, i32 3 + %t23 = call ptr @fn_ptype() + store ptr %t23, ptr %t22 + %t24 = call i32 @fn_is_op(ptr @.str230) + %t25 = icmp ne i32 %t24, 0 + br i1 %t25, label %then9, label %ifend11 +then9: + %t26 = load i32, ptr @g_pi + %t27 = add i32 %t26, 1 + store i32 %t27, ptr @g_pi + %t28 = load ptr, ptr %t17 + %t29 = getelementptr inbounds %Cmp_Node, ptr %t28, i32 0, i32 4 + %t30 = call ptr @fn_expr() + store ptr %t30, ptr %t29 + br label %ifend11 +ifend11: + %t31 = load ptr, ptr %t3 + %t32 = getelementptr inbounds %Cmp_Node, ptr %t31, i32 0, i32 7 + %t33 = load ptr, ptr %t32 + %t34 = getelementptr inbounds %LSlice, ptr %t33, i32 0, i32 1 + %t35 = getelementptr inbounds %LSlice, ptr %t33, i32 0, i32 2 + %t36 = getelementptr inbounds %LSlice, ptr %t33, i32 0, i32 0 + %t37 = load i32, ptr %t34 + %t38 = load i32, ptr %t35 + %t39 = icmp sge i32 %t37, %t38 + br i1 %t39, label %grow12, label %put13 +grow12: + %t40 = mul i32 %t38, 2 + %t41 = icmp eq i32 %t38, 0 + %t42 = select i1 %t41, i32 8, i32 %t40 + %t43 = getelementptr ptr, ptr null, i32 1 + %t44 = ptrtoint ptr %t43 to i64 + %t45 = zext i32 %t42 to i64 + %t46 = mul i64 %t45, %t44 + %t47 = load ptr, ptr %t36 + %t48 = call ptr @realloc(ptr %t47, i64 %t46) + store ptr %t48, ptr %t36 + store i32 %t42, ptr %t35 + br label %put13 +put13: + %t49 = load ptr, ptr %t17 + %t50 = load ptr, ptr %t36 + %t51 = getelementptr inbounds ptr, ptr %t50, i32 %t37 + store ptr %t49, ptr %t51 + %t52 = add i32 %t37, 1 + store i32 %t52, ptr %t34 + %t53 = call i32 @fn_is_op(ptr @.str231) + %t54 = icmp ne i32 %t53, 0 + br i1 %t54, label %then14, label %ifend16 +then14: + %t55 = load i32, ptr @g_pi + %t56 = add i32 %t55, 1 + store i32 %t56, ptr @g_pi + br label %ifend16 +ifend16: + br label %wcond3 +wend5: + call void @fn_eat_op(ptr @.str232) + %t57 = load ptr, ptr %t3 + store ptr %t57, ptr %retval + br label %ret +ret: + %t58 = load ptr, ptr %retval + ret ptr %t58 } define ptr @fn_parse_system() { @@ -8088,14 +10155,14 @@ entry: store ptr %t6, ptr %t5 %t7 = load ptr, ptr %t3 %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 3 - store ptr @.str171, ptr %t8 + store ptr @.str233, ptr %t8 br label %wcond0 wcond0: %t9 = icmp ne i32 1, 0 br i1 %t9, label %wbody1, label %wend2 wbody1: call void @fn_skipnl() - %t10 = call i32 @fn_is_op(ptr @.str172) + %t10 = call i32 @fn_is_op(ptr @.str234) %t11 = icmp ne i32 %t10, 0 br i1 %t11, label %then3, label %ifend5 then3: @@ -8104,7 +10171,7 @@ then3: store i32 %t13, ptr @g_pi %t14 = call ptr @fn_eat_id() store ptr %t14, ptr %t15 - %t16 = call i32 @fn_is_op(ptr @.str173) + %t16 = call i32 @fn_is_op(ptr @.str235) %t17 = icmp ne i32 %t16, 0 br i1 %t17, label %then6, label %ifend8 then6: @@ -8114,7 +10181,7 @@ wcond9: %t19 = icmp ne i32 1, 0 br i1 %t19, label %wbody10, label %wend11 wbody10: - %t20 = call i32 @fn_is_op(ptr @.str174) + %t20 = call i32 @fn_is_op(ptr @.str236) %t21 = icmp ne i32 %t20, 0 br i1 %t21, label %then12, label %ifend14 then12: @@ -8123,7 +10190,7 @@ then12: store i32 %t23, ptr %t18 br label %ifend14 ifend14: - %t24 = call i32 @fn_is_op(ptr @.str175) + %t24 = call i32 @fn_is_op(ptr @.str237) %t25 = icmp ne i32 %t24, 0 br i1 %t25, label %then15, label %ifend17 then15: @@ -8149,7 +10216,7 @@ wend11: ifend8: br label %wcond0 ifend5: - %t34 = call i32 @fn_is_id(ptr @.str176) + %t34 = call i32 @fn_is_id(ptr @.str238) %t35 = icmp ne i32 %t34, 0 br i1 %t35, label %then21, label %ifend23 then21: @@ -8183,18 +10250,18 @@ entry: %t1 = alloca ptr %t11 = alloca ptr %t40 = alloca ptr - call void @fn_eat_op(ptr @.str177) + call void @fn_eat_op(ptr @.str239) %t0 = call ptr @fn_node(i32 7) store ptr %t0, ptr %t1 br label %wcond0 wcond0: - %t2 = call i32 @fn_is_op(ptr @.str178) + %t2 = call i32 @fn_is_op(ptr @.str240) %t3 = icmp eq i32 %t2, 0 %t4 = zext i1 %t3 to i32 %t5 = icmp ne i32 %t4, 0 br i1 %t5, label %wbody1, label %wend2 wbody1: - %t6 = call i32 @fn_is_op(ptr @.str179) + %t6 = call i32 @fn_is_op(ptr @.str241) %t7 = icmp ne i32 %t6, 0 br i1 %t7, label %then3, label %else4 then3: @@ -8240,7 +10307,7 @@ put7: store ptr %t35, ptr %t37 %t38 = add i32 %t23, 1 store i32 %t38, ptr %t20 - call void @fn_eat_op(ptr @.str180) + call void @fn_eat_op(ptr @.str242) br label %ifend5 else4: %t39 = call ptr @fn_node(i32 33) @@ -8284,7 +10351,7 @@ put9: store i32 %t67, ptr %t49 br label %ifend5 ifend5: - %t68 = call i32 @fn_is_op(ptr @.str181) + %t68 = call i32 @fn_is_op(ptr @.str243) %t69 = icmp ne i32 %t68, 0 br i1 %t69, label %then10, label %ifend12 then10: @@ -8295,8 +10362,8 @@ then10: ifend12: br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str182) - %t72 = call i32 @fn_is_id(ptr @.str183) + call void @fn_eat_op(ptr @.str244) + %t72 = call i32 @fn_is_id(ptr @.str245) %t73 = icmp ne i32 %t72, 0 br i1 %t73, label %then13, label %ifend15 then13: @@ -8325,10 +10392,10 @@ entry: %t38 = alloca ptr %t0 = call ptr @fn_node(i32 21) store ptr %t0, ptr %t1 - call void @fn_eat_op(ptr @.str184) + call void @fn_eat_op(ptr @.str246) br label %wcond0 wcond0: - %t2 = call i32 @fn_is_op(ptr @.str185) + %t2 = call i32 @fn_is_op(ptr @.str247) %t3 = icmp eq i32 %t2, 0 %t4 = zext i1 %t3 to i32 %t5 = icmp ne i32 %t4, 0 @@ -8370,7 +10437,7 @@ put4: store ptr %t29, ptr %t31 %t32 = add i32 %t17, 1 store i32 %t32, ptr %t14 - %t33 = call i32 @fn_is_op(ptr @.str186) + %t33 = call i32 @fn_is_op(ptr @.str248) %t34 = icmp ne i32 %t33, 0 br i1 %t34, label %then5, label %ifend7 then5: @@ -8381,16 +10448,16 @@ then5: ifend7: br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str187) + call void @fn_eat_op(ptr @.str249) %t37 = call ptr @fn_eat_id() store ptr %t37, ptr %t38 - %t39 = call i32 @fn_is_id(ptr @.str188) + %t39 = call i32 @fn_is_id(ptr @.str250) %t40 = icmp eq i32 %t39, 0 %t41 = zext i1 %t40 to i32 %t42 = icmp ne i32 %t41, 0 br i1 %t42, label %then8, label %ifend10 then8: - call void @fn_perr(ptr @.str189) + call void @fn_perr(ptr @.str251) br label %ifend10 ifend10: %t43 = load i32, ptr @g_pi @@ -8442,7 +10509,7 @@ ifend2: store ptr %t7, ptr %t8 %t9 = load ptr, ptr %t8 %t10 = getelementptr inbounds %Cmp_Node, ptr %t9, i32 0, i32 1 - store ptr @.str190, ptr %t10 + store ptr @.str252, ptr %t10 %t11 = load ptr, ptr %t8 %t12 = getelementptr inbounds %Cmp_Node, ptr %t11, i32 0, i32 4 %t13 = load ptr, ptr %t0 @@ -8589,7 +10656,7 @@ entry: %t85 = alloca ptr %t102 = alloca ptr %t104 = alloca ptr - call void @fn_eat_op(ptr @.str191) + call void @fn_eat_op(ptr @.str253) %t0 = call ptr @fn_node(i32 21) store ptr %t0, ptr %t1 %t2 = call ptr @fn_node(i32 7) @@ -8597,14 +10664,14 @@ entry: store ptr null, ptr %t4 br label %wcond0 wcond0: - %t5 = call i32 @fn_is_op(ptr @.str192) + %t5 = call i32 @fn_is_op(ptr @.str254) %t6 = icmp eq i32 %t5, 0 %t7 = zext i1 %t6 to i32 %t8 = icmp ne i32 %t7, 0 br i1 %t8, label %wbody1, label %wend2 wbody1: call void @fn_skipnl() - %t9 = call i32 @fn_is_op(ptr @.str193) + %t9 = call i32 @fn_is_op(ptr @.str255) %t10 = icmp ne i32 %t9, 0 br i1 %t10, label %then3, label %ifend5 then3: @@ -8612,17 +10679,17 @@ then3: ifend5: %t11 = call ptr @fn_eat_id() store ptr %t11, ptr %t12 - call void @fn_eat_op(ptr @.str194) + call void @fn_eat_op(ptr @.str256) %t13 = load ptr, ptr %t12 - %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str195) + %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str257) %t15 = icmp ne i32 %t14, 0 br i1 %t15, label %then6, label %else7 then6: - call void @fn_eat_op(ptr @.str196) + call void @fn_eat_op(ptr @.str258) call void @fn_skipnl() br label %wcond9 wcond9: - %t16 = call i32 @fn_is_op(ptr @.str197) + %t16 = call i32 @fn_is_op(ptr @.str259) %t17 = icmp eq i32 %t16, 0 %t18 = zext i1 %t17 to i32 %t19 = icmp ne i32 %t18, 0 @@ -8705,7 +10772,7 @@ put15: store ptr %t74, ptr %t76 %t77 = add i32 %t62, 1 store i32 %t77, ptr %t59 - %t78 = call i32 @fn_is_op(ptr @.str198) + %t78 = call i32 @fn_is_op(ptr @.str260) %t79 = icmp ne i32 %t78, 0 br i1 %t79, label %then16, label %ifend18 then16: @@ -8714,7 +10781,7 @@ then16: store i32 %t81, ptr @g_pi %t82 = call ptr @fn_expr() store ptr %t82, ptr %t83 - call void @fn_eat_op(ptr @.str199) + call void @fn_eat_op(ptr @.str261) %t84 = call ptr @fn_node(i32 33) store ptr %t84, ptr %t85 %t86 = load ptr, ptr %t85 @@ -8729,7 +10796,7 @@ then16: store ptr %t93, ptr %t4 br label %ifend18 ifend18: - %t94 = call i32 @fn_is_op(ptr @.str200) + %t94 = call i32 @fn_is_op(ptr @.str262) %t95 = icmp ne i32 %t94, 0 br i1 %t95, label %then19, label %ifend21 then19: @@ -8741,11 +10808,11 @@ ifend21: call void @fn_skipnl() br label %wcond9 wend11: - call void @fn_eat_op(ptr @.str201) + call void @fn_eat_op(ptr @.str263) br label %ifend8 else7: %t98 = load ptr, ptr %t12 - %t99 = call i32 @fn_str_eq(ptr %t98, ptr @.str202) + %t99 = call i32 @fn_str_eq(ptr %t98, ptr @.str264) %t100 = icmp ne i32 %t99, 0 br i1 %t100, label %then22, label %else23 then22: @@ -8797,7 +10864,7 @@ else23: ifend24: br label %ifend8 ifend8: - %t133 = call i32 @fn_is_op(ptr @.str203) + %t133 = call i32 @fn_is_op(ptr @.str265) %t134 = icmp ne i32 %t133, 0 br i1 %t134, label %then27, label %ifend29 then27: @@ -8809,7 +10876,7 @@ ifend29: call void @fn_skipnl() br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str204) + call void @fn_eat_op(ptr @.str266) %t137 = load ptr, ptr %t1 %t138 = getelementptr inbounds %Cmp_Node, ptr %t137, i32 0, i32 6 %t139 = load ptr, ptr %t3 @@ -8841,14 +10908,14 @@ entry: %t6 = call ptr @fn_eat_id() store ptr %t6, ptr %t5 call void @fn_skipnl() - call void @fn_eat_op(ptr @.str205) + call void @fn_eat_op(ptr @.str267) br label %wcond0 wcond0: %t7 = icmp ne i32 1, 0 br i1 %t7, label %wbody1, label %wend2 wbody1: call void @fn_skipnl() - %t8 = call i32 @fn_is_op(ptr @.str206) + %t8 = call i32 @fn_is_op(ptr @.str268) %t9 = icmp ne i32 %t8, 0 br i1 %t9, label %then3, label %ifend5 then3: @@ -8894,7 +10961,7 @@ put7: store ptr %t36, ptr %t38 %t39 = add i32 %t24, 1 store i32 %t39, ptr %t21 - %t40 = call i32 @fn_is_op(ptr @.str207) + %t40 = call i32 @fn_is_op(ptr @.str269) %t41 = icmp ne i32 %t40, 0 br i1 %t41, label %then8, label %ifend10 then8: @@ -8905,7 +10972,7 @@ then8: ifend10: br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str208) + call void @fn_eat_op(ptr @.str270) %t44 = load ptr, ptr %t3 store ptr %t44, ptr %retval br label %ret @@ -8914,6 +10981,276 @@ ret: ret ptr %t45 } +define void @fn_parse_scene() { +entry: + %t3 = alloca ptr + %t10 = alloca i32 + %t11 = alloca i32 + %t49 = alloca ptr + %t67 = alloca ptr + %t79 = alloca ptr + %t91 = alloca ptr + %t0 = load i32, ptr @g_pi + %t1 = add i32 %t0, 1 + store i32 %t1, ptr @g_pi + %t2 = call ptr @fn_node(i32 45) + store ptr %t2, ptr %t3 + %t4 = load ptr, ptr %t3 + %t5 = getelementptr inbounds %Cmp_Node, ptr %t4, i32 0, i32 1 + %t6 = call ptr @fn_eat_id() + store ptr %t6, ptr %t5 + %t7 = load ptr, ptr %t3 + %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 2 + %t9 = load i32, ptr @g_g_scene_count + store i32 %t9, ptr %t8 + store i32 0, ptr %t10 + br label %wcond0 +wcond0: + %t12 = call i32 @fn_is_id(ptr @.str271) + %t13 = icmp ne i32 %t12, 0 + %t14 = zext i1 %t13 to i32 + store i32 %t14, ptr %t11 + br i1 %t13, label %scend4, label %sc3 +sc3: + %t15 = call i32 @fn_is_id(ptr @.str272) + %t16 = icmp ne i32 %t15, 0 + %t17 = zext i1 %t16 to i32 + store i32 %t17, ptr %t11 + br label %scend4 +scend4: + %t18 = load i32, ptr %t11 + %t19 = icmp ne i32 %t18, 0 + br i1 %t19, label %wbody1, label %wend2 +wbody1: + %t20 = call i32 @fn_is_id(ptr @.str273) + %t21 = icmp ne i32 %t20, 0 + br i1 %t21, label %then5, label %else6 +then5: + %t22 = load i32, ptr @g_pi + %t23 = add i32 %t22, 1 + store i32 %t23, ptr @g_pi + %t24 = load i32, ptr @g_g_scene_count + store i32 %t24, ptr @g_g_start_scene + br label %ifend7 +else6: + %t25 = load i32, ptr @g_pi + %t26 = add i32 %t25, 1 + store i32 %t26, ptr @g_pi + store i32 1, ptr %t10 + br label %ifend7 +ifend7: + br label %wcond0 +wend2: + %t27 = load i32, ptr @g_g_scene_count + %t28 = add i32 %t27, 1 + store i32 %t28, ptr @g_g_scene_count + %t29 = load i32, ptr %t10 + %t30 = icmp ne i32 %t29, 0 + br i1 %t30, label %then8, label %ifend10 +then8: + %t31 = load ptr, ptr %t3 + %t32 = getelementptr inbounds %Cmp_Node, ptr %t31, i32 0, i32 1 + %t33 = load ptr, ptr %t32 + %t34 = call ptr @fn_str_concat(ptr @.str274, ptr %t33) + %t35 = call ptr @fn_str_concat(ptr %t34, ptr @.str275) + call void @fn_ensure_event_empty(ptr %t35) + %t36 = load ptr, ptr %t3 + %t37 = getelementptr inbounds %Cmp_Node, ptr %t36, i32 0, i32 1 + %t38 = load ptr, ptr %t37 + %t39 = call ptr @fn_str_concat(ptr @.str276, ptr %t38) + %t40 = call ptr @fn_str_concat(ptr %t39, ptr @.str277) + call void @fn_ensure_event_empty(ptr %t40) + br label %ifend10 +ifend10: + call void @fn_skipnl() + call void @fn_eat_op(ptr @.str278) + br label %wcond11 +wcond11: + %t41 = icmp ne i32 1, 0 + br i1 %t41, label %wbody12, label %wend13 +wbody12: + call void @fn_skipnl() + %t42 = call i32 @fn_is_op(ptr @.str279) + %t43 = icmp ne i32 %t42, 0 + br i1 %t43, label %then14, label %ifend16 +then14: + br label %wend13 +ifend16: + %t44 = call i32 @fn_is_id(ptr @.str280) + %t45 = icmp ne i32 %t44, 0 + br i1 %t45, label %then17, label %ifend19 +then17: + %t46 = load i32, ptr @g_pi + %t47 = add i32 %t46, 1 + store i32 %t47, ptr @g_pi + %t48 = call ptr @fn_eat_id() + store ptr %t48, ptr %t49 + call void @fn_skipnl() + %t50 = load ptr, ptr %t49 + %t51 = call i32 @fn_str_eq(ptr %t50, ptr @.str281) + %t52 = icmp ne i32 %t51, 0 + br i1 %t52, label %then20, label %else21 +then20: + %t53 = load ptr, ptr %t3 + %t54 = getelementptr inbounds %Cmp_Node, ptr %t53, i32 0, i32 4 + %t55 = call ptr @fn_block() + store ptr %t55, ptr %t54 + br label %ifend22 +else21: + %t56 = load ptr, ptr %t49 + %t57 = call i32 @fn_str_eq(ptr %t56, ptr @.str282) + %t58 = icmp ne i32 %t57, 0 + br i1 %t58, label %then23, label %else24 +then23: + %t59 = load ptr, ptr %t3 + %t60 = getelementptr inbounds %Cmp_Node, ptr %t59, i32 0, i32 5 + %t61 = call ptr @fn_block() + store ptr %t61, ptr %t60 + br label %ifend25 +else24: + call void @fn_perr(ptr @.str283) + br label %ifend25 +ifend25: + br label %ifend22 +ifend22: + br label %wcond11 +ifend19: + %t62 = call i32 @fn_is_id(ptr @.str284) + %t63 = icmp ne i32 %t62, 0 + br i1 %t63, label %then26, label %ifend28 +then26: + %t64 = load i32, ptr @g_pi + %t65 = add i32 %t64, 1 + store i32 %t65, ptr @g_pi + %t66 = call ptr @fn_eat_id() + store ptr %t66, ptr %t67 + %t68 = call i32 @fn_is_id(ptr @.str285) + %t69 = icmp ne i32 %t68, 0 + br i1 %t69, label %then29, label %ifend31 +then29: + %t70 = load i32, ptr @g_pi + %t71 = add i32 %t70, 1 + store i32 %t71, ptr @g_pi + %t72 = load ptr, ptr %t67 + %t73 = call ptr @fn_str_concat(ptr @.str286, ptr %t72) + %t74 = call ptr @fn_str_concat(ptr %t73, ptr @.str287) + call void @fn_ensure_event_empty(ptr %t74) + %t75 = load ptr, ptr %t67 + %t76 = call ptr @fn_str_concat(ptr @.str288, ptr %t75) + %t77 = call ptr @fn_str_concat(ptr %t76, ptr @.str289) + call void @fn_ensure_event_empty(ptr %t77) + br label %ifend31 +ifend31: + call void @fn_skipnl() + call void @fn_eat_op(ptr @.str290) + %t78 = call ptr @fn_node(i32 33) + store ptr %t78, ptr %t79 + %t80 = load ptr, ptr %t79 + %t81 = getelementptr inbounds %Cmp_Node, ptr %t80, i32 0, i32 1 + %t82 = load ptr, ptr %t67 + store ptr %t82, ptr %t81 + br label %wcond32 +wcond32: + %t83 = icmp ne i32 1, 0 + br i1 %t83, label %wbody33, label %wend34 +wbody33: + call void @fn_skipnl() + %t84 = call i32 @fn_is_op(ptr @.str291) + %t85 = icmp ne i32 %t84, 0 + br i1 %t85, label %then35, label %ifend37 +then35: + br label %wend34 +ifend37: + %t86 = call i32 @fn_is_id(ptr @.str292) + %t87 = icmp eq i32 %t86, 0 + %t88 = zext i1 %t87 to i32 + %t89 = icmp ne i32 %t88, 0 + br i1 %t89, label %then38, label %ifend40 +then38: + call void @fn_perr(ptr @.str293) + br label %ifend40 +ifend40: + %t90 = call ptr @fn_parse_system() + store ptr %t90, ptr %t91 + %t92 = load ptr, ptr %t91 + %t93 = getelementptr inbounds %Cmp_Node, ptr %t92, i32 0, i32 6 + %t94 = load ptr, ptr %t3 + store ptr %t94, ptr %t93 + %t95 = load ptr, ptr %t91 + %t96 = getelementptr inbounds %Cmp_Node, ptr %t95, i32 0, i32 5 + %t97 = load ptr, ptr %t79 + store ptr %t97, ptr %t96 + %t98 = load ptr, ptr @g_prog + %t99 = getelementptr inbounds %LSlice, ptr %t98, i32 0, i32 1 + %t100 = getelementptr inbounds %LSlice, ptr %t98, i32 0, i32 2 + %t101 = getelementptr inbounds %LSlice, ptr %t98, i32 0, i32 0 + %t102 = load i32, ptr %t99 + %t103 = load i32, ptr %t100 + %t104 = icmp sge i32 %t102, %t103 + br i1 %t104, label %grow41, label %put42 +grow41: + %t105 = mul i32 %t103, 2 + %t106 = icmp eq i32 %t103, 0 + %t107 = select i1 %t106, i32 8, i32 %t105 + %t108 = getelementptr ptr, ptr null, i32 1 + %t109 = ptrtoint ptr %t108 to i64 + %t110 = zext i32 %t107 to i64 + %t111 = mul i64 %t110, %t109 + %t112 = load ptr, ptr %t101 + %t113 = call ptr @realloc(ptr %t112, i64 %t111) + store ptr %t113, ptr %t101 + store i32 %t107, ptr %t100 + br label %put42 +put42: + %t114 = load ptr, ptr %t91 + %t115 = load ptr, ptr %t101 + %t116 = getelementptr inbounds ptr, ptr %t115, i32 %t102 + store ptr %t114, ptr %t116 + %t117 = add i32 %t102, 1 + store i32 %t117, ptr %t99 + call void @fn_skipnl() + br label %wcond32 +wend34: + call void @fn_eat_op(ptr @.str294) + br label %wcond11 +ifend28: + call void @fn_perr(ptr @.str295) + br label %wcond11 +wend13: + call void @fn_eat_op(ptr @.str296) + %t118 = load ptr, ptr @g_g_scenes + %t119 = getelementptr inbounds %LSlice, ptr %t118, i32 0, i32 1 + %t120 = getelementptr inbounds %LSlice, ptr %t118, i32 0, i32 2 + %t121 = getelementptr inbounds %LSlice, ptr %t118, i32 0, i32 0 + %t122 = load i32, ptr %t119 + %t123 = load i32, ptr %t120 + %t124 = icmp sge i32 %t122, %t123 + br i1 %t124, label %grow43, label %put44 +grow43: + %t125 = mul i32 %t123, 2 + %t126 = icmp eq i32 %t123, 0 + %t127 = select i1 %t126, i32 8, i32 %t125 + %t128 = getelementptr ptr, ptr null, i32 1 + %t129 = ptrtoint ptr %t128 to i64 + %t130 = zext i32 %t127 to i64 + %t131 = mul i64 %t130, %t129 + %t132 = load ptr, ptr %t121 + %t133 = call ptr @realloc(ptr %t132, i64 %t131) + store ptr %t133, ptr %t121 + store i32 %t127, ptr %t120 + br label %put44 +put44: + %t134 = load ptr, ptr %t3 + %t135 = load ptr, ptr %t121 + %t136 = getelementptr inbounds ptr, ptr %t135, i32 %t122 + store ptr %t134, ptr %t136 + %t137 = add i32 %t122, 1 + store i32 %t137, ptr %t119 + br label %ret +ret: + ret void +} + define ptr @fn_parse_enum() { entry: %retval = alloca ptr @@ -8929,14 +11266,14 @@ entry: %t6 = call ptr @fn_eat_id() store ptr %t6, ptr %t5 call void @fn_skipnl() - call void @fn_eat_op(ptr @.str209) + call void @fn_eat_op(ptr @.str297) br label %wcond0 wcond0: %t7 = icmp ne i32 1, 0 br i1 %t7, label %wbody1, label %wend2 wbody1: call void @fn_skipnl() - %t8 = call i32 @fn_is_op(ptr @.str210) + %t8 = call i32 @fn_is_op(ptr @.str298) %t9 = icmp ne i32 %t8, 0 br i1 %t9, label %then3, label %ifend5 then3: @@ -8978,7 +11315,7 @@ put7: store ptr %t33, ptr %t35 %t36 = add i32 %t21, 1 store i32 %t36, ptr %t18 - %t37 = call i32 @fn_is_op(ptr @.str211) + %t37 = call i32 @fn_is_op(ptr @.str299) %t38 = icmp ne i32 %t37, 0 br i1 %t38, label %then8, label %ifend10 then8: @@ -8990,7 +11327,7 @@ ifend10: call void @fn_skipnl() br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str212) + call void @fn_eat_op(ptr @.str300) %t41 = load ptr, ptr %t3 store ptr %t41, ptr %retval br label %ret @@ -9004,6 +11341,7 @@ entry: %retval = alloca ptr %t3 = alloca ptr %t11 = alloca ptr + %t17 = alloca ptr %t0 = load i32, ptr @g_pi %t1 = add i32 %t0, 1 store i32 %t1, ptr @g_pi @@ -9014,14 +11352,14 @@ entry: %t6 = call ptr @fn_eat_id() store ptr %t6, ptr %t5 call void @fn_skipnl() - call void @fn_eat_op(ptr @.str213) + call void @fn_eat_op(ptr @.str301) br label %wcond0 wcond0: %t7 = icmp ne i32 1, 0 br i1 %t7, label %wbody1, label %wend2 wbody1: call void @fn_skipnl() - %t8 = call i32 @fn_is_op(ptr @.str214) + %t8 = call i32 @fn_is_op(ptr @.str302) %t9 = icmp ne i32 %t8, 0 br i1 %t9, label %then3, label %ifend5 then3: @@ -9029,59 +11367,81 @@ then3: ifend5: %t10 = call ptr @fn_node(i32 33) store ptr %t10, ptr %t11 - %t12 = load ptr, ptr %t11 - %t13 = getelementptr inbounds %Cmp_Node, ptr %t12, i32 0, i32 1 - %t14 = call ptr @fn_eat_id() - store ptr %t14, ptr %t13 - %t15 = load ptr, ptr %t3 - %t16 = getelementptr inbounds %Cmp_Node, ptr %t15, i32 0, i32 7 - %t17 = load ptr, ptr %t16 - %t18 = getelementptr inbounds %LSlice, ptr %t17, i32 0, i32 1 - %t19 = getelementptr inbounds %LSlice, ptr %t17, i32 0, i32 2 - %t20 = getelementptr inbounds %LSlice, ptr %t17, i32 0, i32 0 - %t21 = load i32, ptr %t18 - %t22 = load i32, ptr %t19 - %t23 = icmp sge i32 %t21, %t22 - br i1 %t23, label %grow6, label %put7 -grow6: - %t24 = mul i32 %t22, 2 - %t25 = icmp eq i32 %t22, 0 - %t26 = select i1 %t25, i32 8, i32 %t24 - %t27 = getelementptr ptr, ptr null, i32 1 - %t28 = ptrtoint ptr %t27 to i64 - %t29 = zext i32 %t26 to i64 - %t30 = mul i64 %t29, %t28 - %t31 = load ptr, ptr %t20 - %t32 = call ptr @realloc(ptr %t31, i64 %t30) - store ptr %t32, ptr %t20 - store i32 %t26, ptr %t19 - br label %put7 -put7: - %t33 = load ptr, ptr %t11 - %t34 = load ptr, ptr %t20 - %t35 = getelementptr inbounds ptr, ptr %t34, i32 %t21 - store ptr %t33, ptr %t35 - %t36 = add i32 %t21, 1 - store i32 %t36, ptr %t18 - %t37 = call i32 @fn_is_op(ptr @.str215) - %t38 = icmp ne i32 %t37, 0 - br i1 %t38, label %then8, label %ifend10 -then8: - %t39 = load i32, ptr @g_pi - %t40 = add i32 %t39, 1 - store i32 %t40, ptr @g_pi - br label %ifend10 -ifend10: + %t12 = call i32 @fn_is_op(ptr @.str303) + %t13 = icmp ne i32 %t12, 0 + br i1 %t13, label %then6, label %ifend8 +then6: + %t14 = load i32, ptr @g_pi + %t15 = add i32 %t14, 1 + store i32 %t15, ptr @g_pi + %t16 = call ptr @fn_eat_id() + store ptr %t16, ptr %t17 + %t18 = load ptr, ptr %t17 + %t19 = call i32 @fn_str_eq(ptr %t18, ptr @.str304) + %t20 = icmp ne i32 %t19, 0 + br i1 %t20, label %then9, label %ifend11 +then9: + %t21 = load ptr, ptr %t11 + %t22 = getelementptr inbounds %Cmp_Node, ptr %t21, i32 0, i32 2 + store i32 1, ptr %t22 + br label %ifend11 +ifend11: + call void @fn_skipnl() + br label %ifend8 +ifend8: + %t23 = load ptr, ptr %t11 + %t24 = getelementptr inbounds %Cmp_Node, ptr %t23, i32 0, i32 1 + %t25 = call ptr @fn_eat_id() + store ptr %t25, ptr %t24 + %t26 = load ptr, ptr %t3 + %t27 = getelementptr inbounds %Cmp_Node, ptr %t26, i32 0, i32 7 + %t28 = load ptr, ptr %t27 + %t29 = getelementptr inbounds %LSlice, ptr %t28, i32 0, i32 1 + %t30 = getelementptr inbounds %LSlice, ptr %t28, i32 0, i32 2 + %t31 = getelementptr inbounds %LSlice, ptr %t28, i32 0, i32 0 + %t32 = load i32, ptr %t29 + %t33 = load i32, ptr %t30 + %t34 = icmp sge i32 %t32, %t33 + br i1 %t34, label %grow12, label %put13 +grow12: + %t35 = mul i32 %t33, 2 + %t36 = icmp eq i32 %t33, 0 + %t37 = select i1 %t36, i32 8, i32 %t35 + %t38 = getelementptr ptr, ptr null, i32 1 + %t39 = ptrtoint ptr %t38 to i64 + %t40 = zext i32 %t37 to i64 + %t41 = mul i64 %t40, %t39 + %t42 = load ptr, ptr %t31 + %t43 = call ptr @realloc(ptr %t42, i64 %t41) + store ptr %t43, ptr %t31 + store i32 %t37, ptr %t30 + br label %put13 +put13: + %t44 = load ptr, ptr %t11 + %t45 = load ptr, ptr %t31 + %t46 = getelementptr inbounds ptr, ptr %t45, i32 %t32 + store ptr %t44, ptr %t46 + %t47 = add i32 %t32, 1 + store i32 %t47, ptr %t29 + %t48 = call i32 @fn_is_op(ptr @.str305) + %t49 = icmp ne i32 %t48, 0 + br i1 %t49, label %then14, label %ifend16 +then14: + %t50 = load i32, ptr @g_pi + %t51 = add i32 %t50, 1 + store i32 %t51, ptr @g_pi + br label %ifend16 +ifend16: call void @fn_skipnl() br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str216) - %t41 = load ptr, ptr %t3 - store ptr %t41, ptr %retval + call void @fn_eat_op(ptr @.str306) + %t52 = load ptr, ptr %t3 + store ptr %t52, ptr %retval br label %ret ret: - %t42 = load ptr, ptr %retval - ret ptr %t42 + %t53 = load ptr, ptr %retval + ret ptr %t53 } define ptr @fn_parse_extern() { @@ -9102,10 +11462,10 @@ entry: %t7 = getelementptr inbounds %Cmp_Node, ptr %t6, i32 0, i32 1 %t8 = call ptr @fn_eat_id() store ptr %t8, ptr %t7 - call void @fn_eat_op(ptr @.str217) + call void @fn_eat_op(ptr @.str307) br label %wcond0 wcond0: - %t9 = call i32 @fn_is_op(ptr @.str218) + %t9 = call i32 @fn_is_op(ptr @.str308) %t10 = icmp eq i32 %t9, 0 %t11 = zext i1 %t10 to i32 %t12 = icmp ne i32 %t11, 0 @@ -9117,7 +11477,7 @@ wbody1: %t16 = getelementptr inbounds %Cmp_Node, ptr %t15, i32 0, i32 1 %t17 = call ptr @fn_eat_id() store ptr %t17, ptr %t16 - call void @fn_eat_op(ptr @.str219) + call void @fn_eat_op(ptr @.str309) %t18 = load ptr, ptr %t14 %t19 = getelementptr inbounds %Cmp_Node, ptr %t18, i32 0, i32 3 %t20 = call ptr @fn_ptype() @@ -9152,7 +11512,7 @@ put4: store ptr %t39, ptr %t41 %t42 = add i32 %t27, 1 store i32 %t42, ptr %t24 - %t43 = call i32 @fn_is_op(ptr @.str220) + %t43 = call i32 @fn_is_op(ptr @.str310) %t44 = icmp ne i32 %t43, 0 br i1 %t44, label %then5, label %ifend7 then5: @@ -9163,11 +11523,11 @@ then5: ifend7: br label %wcond0 wend2: - call void @fn_eat_op(ptr @.str221) + call void @fn_eat_op(ptr @.str311) %t47 = load ptr, ptr %t5 %t48 = getelementptr inbounds %Cmp_Node, ptr %t47, i32 0, i32 3 - store ptr @.str222, ptr %t48 - %t49 = call i32 @fn_is_op(ptr @.str223) + store ptr @.str312, ptr %t48 + %t49 = call i32 @fn_is_op(ptr @.str313) %t50 = icmp ne i32 %t49, 0 br i1 %t50, label %then8, label %ifend10 then8: @@ -9180,7 +11540,7 @@ then8: store ptr %t55, ptr %t54 br label %ifend10 ifend10: - call void @fn_eat_op(ptr @.str224) + call void @fn_eat_op(ptr @.str314) %t56 = load ptr, ptr @g_toks %t57 = getelementptr inbounds %LSlice, ptr %t56, i32 0, i32 0 %t58 = load ptr, ptr %t57 @@ -9276,7 +11636,7 @@ sc5: %t44 = load ptr, ptr %t43 %t45 = getelementptr inbounds %Cmp_Tok, ptr %t44, i32 0, i32 1 %t46 = load ptr, ptr %t45 - %t47 = call i32 @fn_str_eq(ptr %t46, ptr @.str225) + %t47 = call i32 @fn_str_eq(ptr %t46, ptr @.str315) %t48 = icmp ne i32 %t47, 0 %t49 = zext i1 %t48 to i32 store i32 %t49, ptr %t8 @@ -9292,7 +11652,7 @@ wbody1: %t55 = getelementptr inbounds %Cmp_Node, ptr %t54, i32 0, i32 1 %t56 = call ptr @fn_eat_id() store ptr %t56, ptr %t55 - call void @fn_eat_op(ptr @.str226) + call void @fn_eat_op(ptr @.str316) %t57 = load ptr, ptr %t53 %t58 = getelementptr inbounds %Cmp_Node, ptr %t57, i32 0, i32 4 %t59 = call ptr @fn_expr() @@ -9332,7 +11692,7 @@ put8: br label %wcond0 wend2: call void @fn_skipnl() - %t84 = call i32 @fn_is_op(ptr @.str227) + %t84 = call i32 @fn_is_op(ptr @.str317) %t85 = icmp ne i32 %t84, 0 br i1 %t85, label %then9, label %ifend11 then9: @@ -9345,7 +11705,7 @@ wcond12: br i1 %t88, label %wbody13, label %wend14 wbody13: call void @fn_skipnl() - %t89 = call i32 @fn_is_op(ptr @.str228) + %t89 = call i32 @fn_is_op(ptr @.str318) %t90 = icmp ne i32 %t89, 0 br i1 %t90, label %then15, label %ifend17 then15: @@ -9383,7 +11743,7 @@ put19: store i32 %t112, ptr %t94 br label %wcond12 wend14: - call void @fn_eat_op(ptr @.str229) + call void @fn_eat_op(ptr @.str319) br label %ifend11 ifend11: %t113 = load ptr, ptr %t1 @@ -9411,14 +11771,14 @@ entry: %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 2 store i32 1, ptr %t8 call void @fn_skipnl() - call void @fn_eat_op(ptr @.str230) + call void @fn_eat_op(ptr @.str320) call void @fn_skipnl() %t9 = load ptr, ptr %t3 %t10 = getelementptr inbounds %Cmp_Node, ptr %t9, i32 0, i32 4 %t11 = call ptr @fn_parse_widget() store ptr %t11, ptr %t10 call void @fn_skipnl() - call void @fn_eat_op(ptr @.str231) + call void @fn_eat_op(ptr @.str321) %t12 = load ptr, ptr %t3 store ptr %t12, ptr %retval br label %ret @@ -9459,6 +11819,58 @@ ret: ret ptr %t15 } +define ptr @fn_find_scene(ptr %arg_name) { +entry: + %retval = alloca ptr + %t0 = alloca ptr + %t1 = alloca i32 + store ptr %arg_name, ptr %t0 + store i32 0, ptr %t1 + br label %wcond0 +wcond0: + %t2 = load i32, ptr %t1 + %t3 = load ptr, ptr @g_g_scenes + %t4 = getelementptr inbounds %LSlice, ptr %t3, i32 0, i32 1 + %t5 = load i32, ptr %t4 + %t6 = icmp slt i32 %t2, %t5 + %t7 = zext i1 %t6 to i32 + %t8 = icmp ne i32 %t7, 0 + br i1 %t8, label %wbody1, label %wend2 +wbody1: + %t9 = load ptr, ptr @g_g_scenes + %t10 = getelementptr inbounds %LSlice, ptr %t9, i32 0, i32 0 + %t11 = load ptr, ptr %t10 + %t12 = load i32, ptr %t1 + %t13 = getelementptr inbounds ptr, ptr %t11, i32 %t12 + %t14 = load ptr, ptr %t13 + %t15 = getelementptr inbounds %Cmp_Node, ptr %t14, i32 0, i32 1 + %t16 = load ptr, ptr %t15 + %t17 = load ptr, ptr %t0 + %t18 = call i32 @fn_str_eq(ptr %t16, ptr %t17) + %t19 = icmp ne i32 %t18, 0 + br i1 %t19, label %then3, label %ifend5 +then3: + %t20 = load ptr, ptr @g_g_scenes + %t21 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 0 + %t22 = load ptr, ptr %t21 + %t23 = load i32, ptr %t1 + %t24 = getelementptr inbounds ptr, ptr %t22, i32 %t23 + %t25 = load ptr, ptr %t24 + store ptr %t25, ptr %retval + br label %ret +ifend5: + %t26 = load i32, ptr %t1 + %t27 = add i32 %t26, 1 + store i32 %t27, ptr %t1 + br label %wcond0 +wend2: + store ptr null, ptr %retval + br label %ret +ret: + %t28 = load ptr, ptr %retval + ret ptr %t28 +} + define void @fn_emit(ptr %arg_s) { entry: %t0 = alloca ptr @@ -9491,23 +11903,23 @@ entry: store ptr %arg_llt, ptr %t0 %t1 = load i32, ptr @g_ll_t %t2 = call ptr @fn_itoa(i32 %t1) - %t3 = call ptr @fn_str_concat(ptr @.str232, ptr %t2) + %t3 = call ptr @fn_str_concat(ptr @.str322, ptr %t2) store ptr %t3, ptr %t4 %t5 = load i32, ptr @g_ll_t %t6 = add i32 %t5, 1 store i32 %t6, ptr @g_ll_t %t7 = load ptr, ptr @g_falloc - call void @fn_buf_puts(ptr %t7, ptr @.str233) + call void @fn_buf_puts(ptr %t7, ptr @.str323) %t8 = load ptr, ptr @g_falloc %t9 = load ptr, ptr %t4 call void @fn_buf_puts(ptr %t8, ptr %t9) %t10 = load ptr, ptr @g_falloc - call void @fn_buf_puts(ptr %t10, ptr @.str234) + call void @fn_buf_puts(ptr %t10, ptr @.str324) %t11 = load ptr, ptr @g_falloc %t12 = load ptr, ptr %t0 call void @fn_buf_puts(ptr %t11, ptr %t12) %t13 = load ptr, ptr @g_falloc - call void @fn_buf_puts(ptr %t13, ptr @.str235) + call void @fn_buf_puts(ptr %t13, ptr @.str325) %t14 = load ptr, ptr %t4 store ptr %t14, ptr %retval br label %ret @@ -9522,7 +11934,7 @@ entry: %t3 = alloca ptr %t0 = load i32, ptr @g_ll_t %t1 = call ptr @fn_itoa(i32 %t0) - %t2 = call ptr @fn_str_concat(ptr @.str236, ptr %t1) + %t2 = call ptr @fn_str_concat(ptr @.str326, ptr %t1) store ptr %t2, ptr %t3 %t4 = load i32, ptr @g_ll_t %t5 = add i32 %t4, 1 @@ -9563,98 +11975,112 @@ entry: %t0 = alloca ptr %t1 = alloca i32 %t2 = alloca i32 - %t23 = alloca i32 - %t24 = alloca i32 + %t3 = alloca i32 + %t31 = alloca i32 + %t32 = alloca i32 store ptr %arg_t, ptr %t0 - %t3 = load ptr, ptr %t0 - %t4 = call i32 @fn_str_eq(ptr %t3, ptr @.str237) - %t5 = icmp ne i32 %t4, 0 - %t6 = zext i1 %t5 to i32 - store i32 %t6, ptr %t2 - br i1 %t5, label %scend1, label %sc0 + %t4 = load ptr, ptr %t0 + %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str327) + %t6 = icmp ne i32 %t5, 0 + %t7 = zext i1 %t6 to i32 + store i32 %t7, ptr %t3 + br i1 %t6, label %scend1, label %sc0 sc0: - %t7 = load ptr, ptr %t0 - %t8 = call i32 @fn_str_eq(ptr %t7, ptr @.str238) - %t9 = icmp ne i32 %t8, 0 - %t10 = zext i1 %t9 to i32 - store i32 %t10, ptr %t2 + %t8 = load ptr, ptr %t0 + %t9 = call i32 @fn_str_eq(ptr %t8, ptr @.str328) + %t10 = icmp ne i32 %t9, 0 + %t11 = zext i1 %t10 to i32 + store i32 %t11, ptr %t3 br label %scend1 scend1: - %t11 = load i32, ptr %t2 - %t12 = icmp ne i32 %t11, 0 - %t13 = zext i1 %t12 to i32 - store i32 %t13, ptr %t1 - br i1 %t12, label %scend3, label %sc2 + %t12 = load i32, ptr %t3 + %t13 = icmp ne i32 %t12, 0 + %t14 = zext i1 %t13 to i32 + store i32 %t14, ptr %t2 + br i1 %t13, label %scend3, label %sc2 sc2: - %t14 = load ptr, ptr %t0 - %t15 = call i32 @fn_str_eq(ptr %t14, ptr @.str239) - %t16 = icmp ne i32 %t15, 0 - %t17 = zext i1 %t16 to i32 - store i32 %t17, ptr %t1 + %t15 = load ptr, ptr %t0 + %t16 = call i32 @fn_str_eq(ptr %t15, ptr @.str329) + %t17 = icmp ne i32 %t16, 0 + %t18 = zext i1 %t17 to i32 + store i32 %t18, ptr %t2 br label %scend3 scend3: - %t18 = load i32, ptr %t1 - %t19 = icmp ne i32 %t18, 0 - br i1 %t19, label %then4, label %ifend6 -then4: - store ptr @.str240, ptr %retval - br label %ret -ifend6: - %t20 = load ptr, ptr %t0 - %t21 = call i32 @fn_str_eq(ptr %t20, ptr @.str241) - %t22 = icmp ne i32 %t21, 0 - br i1 %t22, label %then7, label %ifend9 -then7: - store ptr @.str242, ptr %retval - br label %ret -ifend9: - %t25 = load ptr, ptr %t0 - %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str243) + %t19 = load i32, ptr %t2 + %t20 = icmp ne i32 %t19, 0 + %t21 = zext i1 %t20 to i32 + store i32 %t21, ptr %t1 + br i1 %t20, label %scend5, label %sc4 +sc4: + %t22 = load ptr, ptr %t0 + %t23 = call i32 @fn_str_eq(ptr %t22, ptr @.str330) + %t24 = icmp ne i32 %t23, 0 + %t25 = zext i1 %t24 to i32 + store i32 %t25, ptr %t1 + br label %scend5 +scend5: + %t26 = load i32, ptr %t1 %t27 = icmp ne i32 %t26, 0 - %t28 = zext i1 %t27 to i32 - store i32 %t28, ptr %t24 - br i1 %t27, label %scend11, label %sc10 -sc10: - %t29 = load ptr, ptr %t0 - %t30 = call i32 @fn_str_eq(ptr %t29, ptr @.str244) - %t31 = icmp ne i32 %t30, 0 - %t32 = zext i1 %t31 to i32 - store i32 %t32, ptr %t24 - br label %scend11 -scend11: - %t33 = load i32, ptr %t24 - %t34 = icmp ne i32 %t33, 0 - %t35 = zext i1 %t34 to i32 - store i32 %t35, ptr %t23 - br i1 %t34, label %scend13, label %sc12 + br i1 %t27, label %then6, label %ifend8 +then6: + store ptr @.str331, ptr %retval + br label %ret +ifend8: + %t28 = load ptr, ptr %t0 + %t29 = call i32 @fn_str_eq(ptr %t28, ptr @.str332) + %t30 = icmp ne i32 %t29, 0 + br i1 %t30, label %then9, label %ifend11 +then9: + store ptr @.str333, ptr %retval + br label %ret +ifend11: + %t33 = load ptr, ptr %t0 + %t34 = call i32 @fn_str_eq(ptr %t33, ptr @.str334) + %t35 = icmp ne i32 %t34, 0 + %t36 = zext i1 %t35 to i32 + store i32 %t36, ptr %t32 + br i1 %t35, label %scend13, label %sc12 sc12: - %t36 = load ptr, ptr %t0 - %t37 = call i32 @fn_str_eq(ptr %t36, ptr @.str245) - %t38 = icmp ne i32 %t37, 0 - %t39 = zext i1 %t38 to i32 - store i32 %t39, ptr %t23 + %t37 = load ptr, ptr %t0 + %t38 = call i32 @fn_str_eq(ptr %t37, ptr @.str335) + %t39 = icmp ne i32 %t38, 0 + %t40 = zext i1 %t39 to i32 + store i32 %t40, ptr %t32 br label %scend13 scend13: - %t40 = load i32, ptr %t23 - %t41 = icmp ne i32 %t40, 0 - br i1 %t41, label %then14, label %ifend16 -then14: - store ptr @.str246, ptr %retval + %t41 = load i32, ptr %t32 + %t42 = icmp ne i32 %t41, 0 + %t43 = zext i1 %t42 to i32 + store i32 %t43, ptr %t31 + br i1 %t42, label %scend15, label %sc14 +sc14: + %t44 = load ptr, ptr %t0 + %t45 = call i32 @fn_str_eq(ptr %t44, ptr @.str336) + %t46 = icmp ne i32 %t45, 0 + %t47 = zext i1 %t46 to i32 + store i32 %t47, ptr %t31 + br label %scend15 +scend15: + %t48 = load i32, ptr %t31 + %t49 = icmp ne i32 %t48, 0 + br i1 %t49, label %then16, label %ifend18 +then16: + store ptr @.str337, ptr %retval br label %ret -ifend16: - %t42 = load ptr, ptr %t0 - %t43 = call i32 @fn_str_eq(ptr %t42, ptr @.str247) - %t44 = icmp ne i32 %t43, 0 - br i1 %t44, label %then17, label %ifend19 -then17: - store ptr @.str248, ptr %retval +ifend18: + %t50 = load ptr, ptr %t0 + %t51 = call i32 @fn_str_eq(ptr %t50, ptr @.str338) + %t52 = icmp ne i32 %t51, 0 + br i1 %t52, label %then19, label %ifend21 +then19: + store ptr @.str339, ptr %retval br label %ret -ifend19: - store ptr @.str249, ptr %retval +ifend21: + store ptr @.str340, ptr %retval br label %ret ret: - %t45 = load ptr, ptr %retval - ret ptr %t45 + %t53 = load ptr, ptr %retval + ret ptr %t53 } define i32 @fn_is_slice_ty(ptr %arg_t) { @@ -9864,7 +12290,7 @@ entry: %t0 = alloca ptr store ptr %arg_name, ptr %t0 %t1 = load ptr, ptr %t0 - %t2 = call ptr @fn_str_concat(ptr @.str250, ptr %t1) + %t2 = call ptr @fn_str_concat(ptr @.str341, ptr %t1) store ptr %t2, ptr %retval br label %ret ret: @@ -9981,7 +12407,7 @@ ifend5: store i32 %t36, ptr %t2 br label %wcond0 wend2: - store ptr @.str251, ptr %retval + store ptr @.str342, ptr %retval br label %ret ret: %t37 = load ptr, ptr %retval @@ -10183,12 +12609,43 @@ ifend7: store i32 %t61, ptr %t2 br label %wcond0 wend2: - %t62 = sub i32 0, 1 - store i32 %t62, ptr %retval + %t62 = load ptr, ptr %t0 + %t63 = call i32 @fn_str_eq(ptr %t62, ptr @.str343) + %t64 = icmp ne i32 %t63, 0 + br i1 %t64, label %then14, label %ifend16 +then14: + %t65 = load ptr, ptr %t1 + %t66 = call i32 @fn_str_eq(ptr %t65, ptr @.str344) + %t67 = icmp ne i32 %t66, 0 + br i1 %t67, label %then17, label %ifend19 +then17: + store i32 0, ptr %retval + br label %ret +ifend19: + %t68 = load ptr, ptr %t1 + %t69 = call i32 @fn_str_eq(ptr %t68, ptr @.str345) + %t70 = icmp ne i32 %t69, 0 + br i1 %t70, label %then20, label %ifend22 +then20: + store i32 1, ptr %retval + br label %ret +ifend22: + %t71 = load ptr, ptr %t1 + %t72 = call i32 @fn_str_eq(ptr %t71, ptr @.str346) + %t73 = icmp ne i32 %t72, 0 + br i1 %t73, label %then23, label %ifend25 +then23: + store i32 2, ptr %retval + br label %ret +ifend25: + br label %ifend16 +ifend16: + %t74 = sub i32 0, 1 + store i32 %t74, ptr %retval br label %ret ret: - %t63 = load i32, ptr %retval - ret i32 %t63 + %t75 = load i32, ptr %retval + ret i32 %t75 } define ptr @fn_find_fn(ptr %arg_name) { @@ -10258,6 +12715,73 @@ ret: ret ptr %t36 } +define ptr @fn_find_extern(ptr %arg_name) { +entry: + %retval = alloca ptr + %t0 = alloca ptr + %t1 = alloca i32 + %t15 = alloca ptr + %t16 = alloca i32 + store ptr %arg_name, ptr %t0 + store i32 0, ptr %t1 + br label %wcond0 +wcond0: + %t2 = load i32, ptr %t1 + %t3 = load ptr, ptr @g_prog + %t4 = getelementptr inbounds %LSlice, ptr %t3, i32 0, i32 1 + %t5 = load i32, ptr %t4 + %t6 = icmp slt i32 %t2, %t5 + %t7 = zext i1 %t6 to i32 + %t8 = icmp ne i32 %t7, 0 + br i1 %t8, label %wbody1, label %wend2 +wbody1: + %t9 = load ptr, ptr @g_prog + %t10 = getelementptr inbounds %LSlice, ptr %t9, i32 0, i32 0 + %t11 = load ptr, ptr %t10 + %t12 = load i32, ptr %t1 + %t13 = getelementptr inbounds ptr, ptr %t11, i32 %t12 + %t14 = load ptr, ptr %t13 + store ptr %t14, ptr %t15 + %t17 = load ptr, ptr %t15 + %t18 = getelementptr inbounds %Cmp_Node, ptr %t17, i32 0, i32 0 + %t19 = load i32, ptr %t18 + %t20 = icmp eq i32 %t19, 11 + %t21 = zext i1 %t20 to i32 + %t22 = icmp ne i32 %t21, 0 + %t23 = zext i1 %t22 to i32 + store i32 %t23, ptr %t16 + br i1 %t22, label %sc3, label %scend4 +sc3: + %t24 = load ptr, ptr %t15 + %t25 = getelementptr inbounds %Cmp_Node, ptr %t24, i32 0, i32 1 + %t26 = load ptr, ptr %t25 + %t27 = load ptr, ptr %t0 + %t28 = call i32 @fn_str_eq(ptr %t26, ptr %t27) + %t29 = icmp ne i32 %t28, 0 + %t30 = zext i1 %t29 to i32 + store i32 %t30, ptr %t16 + br label %scend4 +scend4: + %t31 = load i32, ptr %t16 + %t32 = icmp ne i32 %t31, 0 + br i1 %t32, label %then5, label %ifend7 +then5: + %t33 = load ptr, ptr %t15 + store ptr %t33, ptr %retval + br label %ret +ifend7: + %t34 = load i32, ptr %t1 + %t35 = add i32 %t34, 1 + store i32 %t35, ptr %t1 + br label %wcond0 +wend2: + store ptr null, ptr %retval + br label %ret +ret: + %t36 = load ptr, ptr %retval + ret ptr %t36 +} + define void @fn_register_computed(ptr %arg_prop, ptr %arg_field, ptr %arg_ty, ptr %arg_e) { entry: %t0 = alloca ptr @@ -10274,7 +12798,7 @@ entry: %t6 = load ptr, ptr %t5 %t7 = getelementptr inbounds %Cmp_Node, ptr %t6, i32 0, i32 1 %t8 = load ptr, ptr %t0 - %t9 = call ptr @fn_str_concat(ptr %t8, ptr @.str252) + %t9 = call ptr @fn_str_concat(ptr %t8, ptr @.str347) %t10 = load ptr, ptr %t1 %t11 = call ptr @fn_str_concat(ptr %t9, ptr %t10) store ptr %t11, ptr %t7 @@ -10338,7 +12862,7 @@ then0: br label %ret ifend2: %t6 = load ptr, ptr %t0 - %t7 = call ptr @fn_str_concat(ptr %t6, ptr @.str253) + %t7 = call ptr @fn_str_concat(ptr %t6, ptr @.str348) %t8 = load ptr, ptr %t1 %t9 = call ptr @fn_str_concat(ptr %t7, ptr %t8) store ptr %t9, ptr %t10 @@ -10537,51 +13061,57 @@ ret: ret ptr %t30 } -define void @fn_register_ondespawn(ptr %arg_model, ptr %arg_body) { +define void @fn_register_ondespawn(ptr %arg_model, ptr %arg_body, ptr %arg_reason) { entry: %t0 = alloca ptr %t1 = alloca ptr - %t3 = alloca ptr + %t2 = alloca ptr + %t4 = alloca ptr store ptr %arg_model, ptr %t0 store ptr %arg_body, ptr %t1 - %t2 = call ptr @fn_node(i32 7) - store ptr %t2, ptr %t3 - %t4 = load ptr, ptr %t3 - %t5 = getelementptr inbounds %Cmp_Node, ptr %t4, i32 0, i32 1 - %t6 = load ptr, ptr %t0 - store ptr %t6, ptr %t5 - %t7 = load ptr, ptr %t3 - %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 4 - %t9 = load ptr, ptr %t1 - store ptr %t9, ptr %t8 - %t10 = load ptr, ptr @g_g_ondespawn - %t11 = getelementptr inbounds %LSlice, ptr %t10, i32 0, i32 1 - %t12 = getelementptr inbounds %LSlice, ptr %t10, i32 0, i32 2 - %t13 = getelementptr inbounds %LSlice, ptr %t10, i32 0, i32 0 - %t14 = load i32, ptr %t11 - %t15 = load i32, ptr %t12 - %t16 = icmp sge i32 %t14, %t15 - br i1 %t16, label %grow0, label %put1 + store ptr %arg_reason, ptr %t2 + %t3 = call ptr @fn_node(i32 7) + store ptr %t3, ptr %t4 + %t5 = load ptr, ptr %t4 + %t6 = getelementptr inbounds %Cmp_Node, ptr %t5, i32 0, i32 1 + %t7 = load ptr, ptr %t0 + store ptr %t7, ptr %t6 + %t8 = load ptr, ptr %t4 + %t9 = getelementptr inbounds %Cmp_Node, ptr %t8, i32 0, i32 4 + %t10 = load ptr, ptr %t1 + store ptr %t10, ptr %t9 + %t11 = load ptr, ptr %t4 + %t12 = getelementptr inbounds %Cmp_Node, ptr %t11, i32 0, i32 3 + %t13 = load ptr, ptr %t2 + store ptr %t13, ptr %t12 + %t14 = load ptr, ptr @g_g_ondespawn + %t15 = getelementptr inbounds %LSlice, ptr %t14, i32 0, i32 1 + %t16 = getelementptr inbounds %LSlice, ptr %t14, i32 0, i32 2 + %t17 = getelementptr inbounds %LSlice, ptr %t14, i32 0, i32 0 + %t18 = load i32, ptr %t15 + %t19 = load i32, ptr %t16 + %t20 = icmp sge i32 %t18, %t19 + br i1 %t20, label %grow0, label %put1 grow0: - %t17 = mul i32 %t15, 2 - %t18 = icmp eq i32 %t15, 0 - %t19 = select i1 %t18, i32 8, i32 %t17 - %t20 = getelementptr ptr, ptr null, i32 1 - %t21 = ptrtoint ptr %t20 to i64 - %t22 = zext i32 %t19 to i64 - %t23 = mul i64 %t22, %t21 - %t24 = load ptr, ptr %t13 - %t25 = call ptr @realloc(ptr %t24, i64 %t23) - store ptr %t25, ptr %t13 - store i32 %t19, ptr %t12 + %t21 = mul i32 %t19, 2 + %t22 = icmp eq i32 %t19, 0 + %t23 = select i1 %t22, i32 8, i32 %t21 + %t24 = getelementptr ptr, ptr null, i32 1 + %t25 = ptrtoint ptr %t24 to i64 + %t26 = zext i32 %t23 to i64 + %t27 = mul i64 %t26, %t25 + %t28 = load ptr, ptr %t17 + %t29 = call ptr @realloc(ptr %t28, i64 %t27) + store ptr %t29, ptr %t17 + store i32 %t23, ptr %t16 br label %put1 put1: - %t26 = load ptr, ptr %t3 - %t27 = load ptr, ptr %t13 - %t28 = getelementptr inbounds ptr, ptr %t27, i32 %t14 - store ptr %t26, ptr %t28 - %t29 = add i32 %t14, 1 - store i32 %t29, ptr %t11 + %t30 = load ptr, ptr %t4 + %t31 = load ptr, ptr %t17 + %t32 = getelementptr inbounds ptr, ptr %t31, i32 %t18 + store ptr %t30, ptr %t32 + %t33 = add i32 %t18, 1 + store i32 %t33, ptr %t15 br label %ret ret: ret void @@ -10745,6 +13275,110 @@ ret: ret ptr %t30 } +define void @fn_register_ondetach(ptr %arg_prop, ptr %arg_body) { +entry: + %t0 = alloca ptr + %t1 = alloca ptr + %t3 = alloca ptr + store ptr %arg_prop, ptr %t0 + store ptr %arg_body, ptr %t1 + %t2 = call ptr @fn_node(i32 7) + store ptr %t2, ptr %t3 + %t4 = load ptr, ptr %t3 + %t5 = getelementptr inbounds %Cmp_Node, ptr %t4, i32 0, i32 1 + %t6 = load ptr, ptr %t0 + store ptr %t6, ptr %t5 + %t7 = load ptr, ptr %t3 + %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 4 + %t9 = load ptr, ptr %t1 + store ptr %t9, ptr %t8 + %t10 = load ptr, ptr @g_g_ondetach + %t11 = getelementptr inbounds %LSlice, ptr %t10, i32 0, i32 1 + %t12 = getelementptr inbounds %LSlice, ptr %t10, i32 0, i32 2 + %t13 = getelementptr inbounds %LSlice, ptr %t10, i32 0, i32 0 + %t14 = load i32, ptr %t11 + %t15 = load i32, ptr %t12 + %t16 = icmp sge i32 %t14, %t15 + br i1 %t16, label %grow0, label %put1 +grow0: + %t17 = mul i32 %t15, 2 + %t18 = icmp eq i32 %t15, 0 + %t19 = select i1 %t18, i32 8, i32 %t17 + %t20 = getelementptr ptr, ptr null, i32 1 + %t21 = ptrtoint ptr %t20 to i64 + %t22 = zext i32 %t19 to i64 + %t23 = mul i64 %t22, %t21 + %t24 = load ptr, ptr %t13 + %t25 = call ptr @realloc(ptr %t24, i64 %t23) + store ptr %t25, ptr %t13 + store i32 %t19, ptr %t12 + br label %put1 +put1: + %t26 = load ptr, ptr %t3 + %t27 = load ptr, ptr %t13 + %t28 = getelementptr inbounds ptr, ptr %t27, i32 %t14 + store ptr %t26, ptr %t28 + %t29 = add i32 %t14, 1 + store i32 %t29, ptr %t11 + br label %ret +ret: + ret void +} + +define ptr @fn_ondetach_body(ptr %arg_prop) { +entry: + %retval = alloca ptr + %t0 = alloca ptr + %t1 = alloca i32 + store ptr %arg_prop, ptr %t0 + store i32 0, ptr %t1 + br label %wcond0 +wcond0: + %t2 = load i32, ptr %t1 + %t3 = load ptr, ptr @g_g_ondetach + %t4 = getelementptr inbounds %LSlice, ptr %t3, i32 0, i32 1 + %t5 = load i32, ptr %t4 + %t6 = icmp slt i32 %t2, %t5 + %t7 = zext i1 %t6 to i32 + %t8 = icmp ne i32 %t7, 0 + br i1 %t8, label %wbody1, label %wend2 +wbody1: + %t9 = load ptr, ptr @g_g_ondetach + %t10 = getelementptr inbounds %LSlice, ptr %t9, i32 0, i32 0 + %t11 = load ptr, ptr %t10 + %t12 = load i32, ptr %t1 + %t13 = getelementptr inbounds ptr, ptr %t11, i32 %t12 + %t14 = load ptr, ptr %t13 + %t15 = getelementptr inbounds %Cmp_Node, ptr %t14, i32 0, i32 1 + %t16 = load ptr, ptr %t15 + %t17 = load ptr, ptr %t0 + %t18 = call i32 @fn_str_eq(ptr %t16, ptr %t17) + %t19 = icmp ne i32 %t18, 0 + br i1 %t19, label %then3, label %ifend5 +then3: + %t20 = load ptr, ptr @g_g_ondetach + %t21 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 0 + %t22 = load ptr, ptr %t21 + %t23 = load i32, ptr %t1 + %t24 = getelementptr inbounds ptr, ptr %t22, i32 %t23 + %t25 = load ptr, ptr %t24 + %t26 = getelementptr inbounds %Cmp_Node, ptr %t25, i32 0, i32 4 + %t27 = load ptr, ptr %t26 + store ptr %t27, ptr %retval + br label %ret +ifend5: + %t28 = load i32, ptr %t1 + %t29 = add i32 %t28, 1 + store i32 %t29, ptr %t1 + br label %wcond0 +wend2: + store ptr null, ptr %retval + br label %ret +ret: + %t30 = load ptr, ptr %retval + ret ptr %t30 +} + define void @fn_register_onenable(ptr %arg_prop, ptr %arg_body) { entry: %t0 = alloca ptr @@ -10953,6 +13587,397 @@ ret: ret ptr %t30 } +define void @fn_register_event(ptr %arg_n) { +entry: + %t0 = alloca ptr + store ptr %arg_n, ptr %t0 + %t1 = load ptr, ptr @g_g_events + %t2 = getelementptr inbounds %LSlice, ptr %t1, i32 0, i32 1 + %t3 = getelementptr inbounds %LSlice, ptr %t1, i32 0, i32 2 + %t4 = getelementptr inbounds %LSlice, ptr %t1, i32 0, i32 0 + %t5 = load i32, ptr %t2 + %t6 = load i32, ptr %t3 + %t7 = icmp sge i32 %t5, %t6 + br i1 %t7, label %grow0, label %put1 +grow0: + %t8 = mul i32 %t6, 2 + %t9 = icmp eq i32 %t6, 0 + %t10 = select i1 %t9, i32 8, i32 %t8 + %t11 = getelementptr ptr, ptr null, i32 1 + %t12 = ptrtoint ptr %t11 to i64 + %t13 = zext i32 %t10 to i64 + %t14 = mul i64 %t13, %t12 + %t15 = load ptr, ptr %t4 + %t16 = call ptr @realloc(ptr %t15, i64 %t14) + store ptr %t16, ptr %t4 + store i32 %t10, ptr %t3 + br label %put1 +put1: + %t17 = load ptr, ptr %t0 + %t18 = load ptr, ptr %t4 + %t19 = getelementptr inbounds ptr, ptr %t18, i32 %t5 + store ptr %t17, ptr %t19 + %t20 = add i32 %t5, 1 + store i32 %t20, ptr %t2 + br label %ret +ret: + ret void +} + +define ptr @fn_find_event(ptr %arg_name) { +entry: + %retval = alloca ptr + %t0 = alloca ptr + %t1 = alloca i32 + store ptr %arg_name, ptr %t0 + store i32 0, ptr %t1 + br label %wcond0 +wcond0: + %t2 = load i32, ptr %t1 + %t3 = load ptr, ptr @g_g_events + %t4 = getelementptr inbounds %LSlice, ptr %t3, i32 0, i32 1 + %t5 = load i32, ptr %t4 + %t6 = icmp slt i32 %t2, %t5 + %t7 = zext i1 %t6 to i32 + %t8 = icmp ne i32 %t7, 0 + br i1 %t8, label %wbody1, label %wend2 +wbody1: + %t9 = load ptr, ptr @g_g_events + %t10 = getelementptr inbounds %LSlice, ptr %t9, i32 0, i32 0 + %t11 = load ptr, ptr %t10 + %t12 = load i32, ptr %t1 + %t13 = getelementptr inbounds ptr, ptr %t11, i32 %t12 + %t14 = load ptr, ptr %t13 + %t15 = getelementptr inbounds %Cmp_Node, ptr %t14, i32 0, i32 1 + %t16 = load ptr, ptr %t15 + %t17 = load ptr, ptr %t0 + %t18 = call i32 @fn_str_eq(ptr %t16, ptr %t17) + %t19 = icmp ne i32 %t18, 0 + br i1 %t19, label %then3, label %ifend5 +then3: + %t20 = load ptr, ptr @g_g_events + %t21 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 0 + %t22 = load ptr, ptr %t21 + %t23 = load i32, ptr %t1 + %t24 = getelementptr inbounds ptr, ptr %t22, i32 %t23 + %t25 = load ptr, ptr %t24 + store ptr %t25, ptr %retval + br label %ret +ifend5: + %t26 = load i32, ptr %t1 + %t27 = add i32 %t26, 1 + store i32 %t27, ptr %t1 + br label %wcond0 +wend2: + store ptr null, ptr %retval + br label %ret +ret: + %t28 = load ptr, ptr %retval + ret ptr %t28 +} + +define void @fn_register_onlisten(ptr %arg_evt, ptr %arg_body) { +entry: + %t0 = alloca ptr + %t1 = alloca ptr + %t3 = alloca ptr + store ptr %arg_evt, ptr %t0 + store ptr %arg_body, ptr %t1 + %t2 = call ptr @fn_node(i32 7) + store ptr %t2, ptr %t3 + %t4 = load ptr, ptr %t3 + %t5 = getelementptr inbounds %Cmp_Node, ptr %t4, i32 0, i32 1 + %t6 = load ptr, ptr %t0 + store ptr %t6, ptr %t5 + %t7 = load ptr, ptr %t3 + %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 4 + %t9 = load ptr, ptr %t1 + store ptr %t9, ptr %t8 + %t10 = load ptr, ptr @g_g_onlisten + %t11 = getelementptr inbounds %LSlice, ptr %t10, i32 0, i32 1 + %t12 = getelementptr inbounds %LSlice, ptr %t10, i32 0, i32 2 + %t13 = getelementptr inbounds %LSlice, ptr %t10, i32 0, i32 0 + %t14 = load i32, ptr %t11 + %t15 = load i32, ptr %t12 + %t16 = icmp sge i32 %t14, %t15 + br i1 %t16, label %grow0, label %put1 +grow0: + %t17 = mul i32 %t15, 2 + %t18 = icmp eq i32 %t15, 0 + %t19 = select i1 %t18, i32 8, i32 %t17 + %t20 = getelementptr ptr, ptr null, i32 1 + %t21 = ptrtoint ptr %t20 to i64 + %t22 = zext i32 %t19 to i64 + %t23 = mul i64 %t22, %t21 + %t24 = load ptr, ptr %t13 + %t25 = call ptr @realloc(ptr %t24, i64 %t23) + store ptr %t25, ptr %t13 + store i32 %t19, ptr %t12 + br label %put1 +put1: + %t26 = load ptr, ptr %t3 + %t27 = load ptr, ptr %t13 + %t28 = getelementptr inbounds ptr, ptr %t27, i32 %t14 + store ptr %t26, ptr %t28 + %t29 = add i32 %t14, 1 + store i32 %t29, ptr %t11 + br label %ret +ret: + ret void +} + +define void @fn_ensure_event(ptr %arg_name, i32 %arg_with_reason) { +entry: + %t0 = alloca ptr + %t1 = alloca i32 + %t8 = alloca ptr + %t13 = alloca ptr + %t43 = alloca ptr + store ptr %arg_name, ptr %t0 + store i32 %arg_with_reason, ptr %t1 + %t2 = load ptr, ptr %t0 + %t3 = call ptr @fn_find_event(ptr %t2) + %t4 = icmp ne ptr %t3, null + %t5 = zext i1 %t4 to i32 + %t6 = icmp ne i32 %t5, 0 + br i1 %t6, label %then0, label %ifend2 +then0: + br label %ret +ifend2: + %t7 = call ptr @fn_node(i32 48) + store ptr %t7, ptr %t8 + %t9 = load ptr, ptr %t8 + %t10 = getelementptr inbounds %Cmp_Node, ptr %t9, i32 0, i32 1 + %t11 = load ptr, ptr %t0 + store ptr %t11, ptr %t10 + %t12 = call ptr @fn_node(i32 1) + store ptr %t12, ptr %t13 + %t14 = load ptr, ptr %t13 + %t15 = getelementptr inbounds %Cmp_Node, ptr %t14, i32 0, i32 1 + store ptr @.str349, ptr %t15 + %t16 = load ptr, ptr %t13 + %t17 = getelementptr inbounds %Cmp_Node, ptr %t16, i32 0, i32 3 + store ptr @.str350, ptr %t17 + %t18 = load ptr, ptr %t8 + %t19 = getelementptr inbounds %Cmp_Node, ptr %t18, i32 0, i32 7 + %t20 = load ptr, ptr %t19 + %t21 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 1 + %t22 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 2 + %t23 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 0 + %t24 = load i32, ptr %t21 + %t25 = load i32, ptr %t22 + %t26 = icmp sge i32 %t24, %t25 + br i1 %t26, label %grow3, label %put4 +grow3: + %t27 = mul i32 %t25, 2 + %t28 = icmp eq i32 %t25, 0 + %t29 = select i1 %t28, i32 8, i32 %t27 + %t30 = getelementptr ptr, ptr null, i32 1 + %t31 = ptrtoint ptr %t30 to i64 + %t32 = zext i32 %t29 to i64 + %t33 = mul i64 %t32, %t31 + %t34 = load ptr, ptr %t23 + %t35 = call ptr @realloc(ptr %t34, i64 %t33) + store ptr %t35, ptr %t23 + store i32 %t29, ptr %t22 + br label %put4 +put4: + %t36 = load ptr, ptr %t13 + %t37 = load ptr, ptr %t23 + %t38 = getelementptr inbounds ptr, ptr %t37, i32 %t24 + store ptr %t36, ptr %t38 + %t39 = add i32 %t24, 1 + store i32 %t39, ptr %t21 + %t40 = load i32, ptr %t1 + %t41 = icmp ne i32 %t40, 0 + br i1 %t41, label %then5, label %ifend7 +then5: + %t42 = call ptr @fn_node(i32 1) + store ptr %t42, ptr %t43 + %t44 = load ptr, ptr %t43 + %t45 = getelementptr inbounds %Cmp_Node, ptr %t44, i32 0, i32 1 + store ptr @.str351, ptr %t45 + %t46 = load ptr, ptr %t43 + %t47 = getelementptr inbounds %Cmp_Node, ptr %t46, i32 0, i32 3 + store ptr @.str352, ptr %t47 + %t48 = load ptr, ptr %t8 + %t49 = getelementptr inbounds %Cmp_Node, ptr %t48, i32 0, i32 7 + %t50 = load ptr, ptr %t49 + %t51 = getelementptr inbounds %LSlice, ptr %t50, i32 0, i32 1 + %t52 = getelementptr inbounds %LSlice, ptr %t50, i32 0, i32 2 + %t53 = getelementptr inbounds %LSlice, ptr %t50, i32 0, i32 0 + %t54 = load i32, ptr %t51 + %t55 = load i32, ptr %t52 + %t56 = icmp sge i32 %t54, %t55 + br i1 %t56, label %grow8, label %put9 +grow8: + %t57 = mul i32 %t55, 2 + %t58 = icmp eq i32 %t55, 0 + %t59 = select i1 %t58, i32 8, i32 %t57 + %t60 = getelementptr ptr, ptr null, i32 1 + %t61 = ptrtoint ptr %t60 to i64 + %t62 = zext i32 %t59 to i64 + %t63 = mul i64 %t62, %t61 + %t64 = load ptr, ptr %t53 + %t65 = call ptr @realloc(ptr %t64, i64 %t63) + store ptr %t65, ptr %t53 + store i32 %t59, ptr %t52 + br label %put9 +put9: + %t66 = load ptr, ptr %t43 + %t67 = load ptr, ptr %t53 + %t68 = getelementptr inbounds ptr, ptr %t67, i32 %t54 + store ptr %t66, ptr %t68 + %t69 = add i32 %t54, 1 + store i32 %t69, ptr %t51 + br label %ifend7 +ifend7: + %t70 = load ptr, ptr %t8 + call void @fn_register_event(ptr %t70) + br label %ret +ret: + ret void +} + +define void @fn_ensure_event_empty(ptr %arg_name) { +entry: + %t0 = alloca ptr + %t7 = alloca ptr + store ptr %arg_name, ptr %t0 + %t1 = load ptr, ptr %t0 + %t2 = call ptr @fn_find_event(ptr %t1) + %t3 = icmp ne ptr %t2, null + %t4 = zext i1 %t3 to i32 + %t5 = icmp ne i32 %t4, 0 + br i1 %t5, label %then0, label %ifend2 +then0: + br label %ret +ifend2: + %t6 = call ptr @fn_node(i32 48) + store ptr %t6, ptr %t7 + %t8 = load ptr, ptr %t7 + %t9 = getelementptr inbounds %Cmp_Node, ptr %t8, i32 0, i32 1 + %t10 = load ptr, ptr %t0 + store ptr %t10, ptr %t9 + %t11 = load ptr, ptr %t7 + call void @fn_register_event(ptr %t11) + br label %ret +ret: + ret void +} + +define void @fn_note_toggled_layer(ptr %arg_name) { +entry: + %t0 = alloca ptr + %t1 = alloca i32 + store ptr %arg_name, ptr %t0 + store i32 0, ptr %t1 + br label %wcond0 +wcond0: + %t2 = load i32, ptr %t1 + %t3 = load ptr, ptr @g_g_toggled_layers + %t4 = getelementptr inbounds %LSlice, ptr %t3, i32 0, i32 1 + %t5 = load i32, ptr %t4 + %t6 = icmp slt i32 %t2, %t5 + %t7 = zext i1 %t6 to i32 + %t8 = icmp ne i32 %t7, 0 + br i1 %t8, label %wbody1, label %wend2 +wbody1: + %t9 = load ptr, ptr @g_g_toggled_layers + %t10 = getelementptr inbounds %LSlice, ptr %t9, i32 0, i32 0 + %t11 = load ptr, ptr %t10 + %t12 = load i32, ptr %t1 + %t13 = getelementptr inbounds ptr, ptr %t11, i32 %t12 + %t14 = load ptr, ptr %t13 + %t15 = load ptr, ptr %t0 + %t16 = call i32 @fn_str_eq(ptr %t14, ptr %t15) + %t17 = icmp ne i32 %t16, 0 + br i1 %t17, label %then3, label %ifend5 +then3: + br label %ret +ifend5: + %t18 = load i32, ptr %t1 + %t19 = add i32 %t18, 1 + store i32 %t19, ptr %t1 + br label %wcond0 +wend2: + %t20 = load ptr, ptr @g_g_toggled_layers + %t21 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 1 + %t22 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 2 + %t23 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 0 + %t24 = load i32, ptr %t21 + %t25 = load i32, ptr %t22 + %t26 = icmp sge i32 %t24, %t25 + br i1 %t26, label %grow6, label %put7 +grow6: + %t27 = mul i32 %t25, 2 + %t28 = icmp eq i32 %t25, 0 + %t29 = select i1 %t28, i32 8, i32 %t27 + %t30 = getelementptr ptr, ptr null, i32 1 + %t31 = ptrtoint ptr %t30 to i64 + %t32 = zext i32 %t29 to i64 + %t33 = mul i64 %t32, %t31 + %t34 = load ptr, ptr %t23 + %t35 = call ptr @realloc(ptr %t34, i64 %t33) + store ptr %t35, ptr %t23 + store i32 %t29, ptr %t22 + br label %put7 +put7: + %t36 = load ptr, ptr %t0 + %t37 = load ptr, ptr %t23 + %t38 = getelementptr inbounds ptr, ptr %t37, i32 %t24 + store ptr %t36, ptr %t38 + %t39 = add i32 %t24, 1 + store i32 %t39, ptr %t21 + br label %ret +ret: + ret void +} + +define i32 @fn_is_toggled_layer(ptr %arg_name) { +entry: + %retval = alloca i32 + %t0 = alloca ptr + %t1 = alloca i32 + store ptr %arg_name, ptr %t0 + store i32 0, ptr %t1 + br label %wcond0 +wcond0: + %t2 = load i32, ptr %t1 + %t3 = load ptr, ptr @g_g_toggled_layers + %t4 = getelementptr inbounds %LSlice, ptr %t3, i32 0, i32 1 + %t5 = load i32, ptr %t4 + %t6 = icmp slt i32 %t2, %t5 + %t7 = zext i1 %t6 to i32 + %t8 = icmp ne i32 %t7, 0 + br i1 %t8, label %wbody1, label %wend2 +wbody1: + %t9 = load ptr, ptr @g_g_toggled_layers + %t10 = getelementptr inbounds %LSlice, ptr %t9, i32 0, i32 0 + %t11 = load ptr, ptr %t10 + %t12 = load i32, ptr %t1 + %t13 = getelementptr inbounds ptr, ptr %t11, i32 %t12 + %t14 = load ptr, ptr %t13 + %t15 = load ptr, ptr %t0 + %t16 = call i32 @fn_str_eq(ptr %t14, ptr %t15) + %t17 = icmp ne i32 %t16, 0 + br i1 %t17, label %then3, label %ifend5 +then3: + store i32 1, ptr %retval + br label %ret +ifend5: + %t18 = load i32, ptr %t1 + %t19 = add i32 %t18, 1 + store i32 %t19, ptr %t1 + br label %wcond0 +wend2: + store i32 0, ptr %retval + br label %ret +ret: + %t20 = load i32, ptr %retval + ret i32 %t20 +} + define i32 @fn_is_model(ptr %arg_name) { entry: %retval = alloca i32 @@ -11253,7 +14278,7 @@ entry: store ptr %arg_s, ptr %t0 %t1 = load i32, ptr @g_ll_str %t2 = call ptr @fn_itoa(i32 %t1) - %t3 = call ptr @fn_str_concat(ptr @.str254, ptr %t2) + %t3 = call ptr @fn_str_concat(ptr @.str353, ptr %t2) store ptr %t3, ptr %t4 %t5 = load i32, ptr @g_ll_str %t6 = add i32 %t5, 1 @@ -11264,12 +14289,12 @@ entry: store i32 %t9, ptr %t10 %t11 = load ptr, ptr %t4 call void @fn_emith(ptr %t11) - call void @fn_emith(ptr @.str255) + call void @fn_emith(ptr @.str354) %t12 = load i32, ptr %t10 %t13 = add i32 %t12, 1 %t14 = call ptr @fn_itoa(i32 %t13) call void @fn_emith(ptr %t14) - call void @fn_emith(ptr @.str256) + call void @fn_emith(ptr @.str355) store i32 0, ptr %t15 br label %wcond0 wcond0: @@ -11358,7 +14383,7 @@ ifend11: store i32 %t70, ptr %t15 br label %wcond0 wend2: - call void @fn_emith(ptr @.str257) + call void @fn_emith(ptr @.str356) %t71 = load ptr, ptr %t4 store ptr %t71, ptr %retval br label %ret @@ -11389,14 +14414,14 @@ then0: %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 3 %t9 = load ptr, ptr %t8 %t10 = call ptr @fn_llty(ptr %t9) - %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str258) + %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str357) %t12 = icmp ne i32 %t11, 0 br i1 %t12, label %then3, label %ifend5 then3: - store ptr @.str259, ptr %retval + store ptr @.str358, ptr %retval br label %ret ifend5: - store ptr @.str260, ptr %retval + store ptr @.str359, ptr %retval br label %ret ifend2: %t13 = load ptr, ptr %t0 @@ -11463,7 +14488,7 @@ sc13: %t58 = load ptr, ptr %t16 %t59 = getelementptr inbounds %Cmp_Node, ptr %t58, i32 0, i32 1 %t60 = load ptr, ptr %t59 - %t61 = call i32 @fn_str_eq(ptr %t60, ptr @.str261) + %t61 = call i32 @fn_str_eq(ptr %t60, ptr @.str360) %t62 = icmp ne i32 %t61, 0 %t63 = zext i1 %t62 to i32 store i32 %t63, ptr %t50 @@ -11497,7 +14522,7 @@ then17: %t81 = getelementptr inbounds %Cmp_Node, ptr %t80, i32 0, i32 2 %t82 = load i32, ptr %t81 %t83 = call ptr @fn_itoa(i32 %t82) - %t84 = call ptr @fn_str_concat(ptr @.str262, ptr %t83) + %t84 = call ptr @fn_str_concat(ptr @.str361, ptr %t83) store ptr %t84, ptr %retval br label %ret ifend19: @@ -11505,14 +14530,14 @@ ifend19: %t86 = getelementptr inbounds %Cmp_Node, ptr %t85, i32 0, i32 3 %t87 = load ptr, ptr %t86 %t88 = call ptr @fn_llty(ptr %t87) - %t89 = call i32 @fn_str_eq(ptr %t88, ptr @.str263) + %t89 = call i32 @fn_str_eq(ptr %t88, ptr @.str362) %t90 = icmp ne i32 %t89, 0 br i1 %t90, label %then20, label %ifend22 then20: - store ptr @.str264, ptr %retval + store ptr @.str363, ptr %retval br label %ret ifend22: - store ptr @.str265, ptr %retval + store ptr @.str364, ptr %retval br label %ret ret: %t91 = load ptr, ptr %retval @@ -11525,49 +14550,49 @@ entry: %t20 = alloca ptr %t39 = alloca i32 %t81 = alloca ptr - call void @fn_emith(ptr @.str266) - call void @fn_emith(ptr @.str267) - call void @fn_emith(ptr @.str268) - call void @fn_emith(ptr @.str269) - call void @fn_emith(ptr @.str270) - call void @fn_emith(ptr @.str271) - call void @fn_emith(ptr @.str272) - call void @fn_emith(ptr @.str273) - call void @fn_emith(ptr @.str274) - call void @fn_emith(ptr @.str275) - call void @fn_emith(ptr @.str276) - call void @fn_emith(ptr @.str277) - call void @fn_emith(ptr @.str278) - call void @fn_emith(ptr @.str279) - call void @fn_emith(ptr @.str280) - call void @fn_emith(ptr @.str281) - call void @fn_emith(ptr @.str282) - call void @fn_emith(ptr @.str283) - call void @fn_emith(ptr @.str284) - call void @fn_emith(ptr @.str285) - call void @fn_emith(ptr @.str286) - call void @fn_emith(ptr @.str287) - call void @fn_emith(ptr @.str288) - call void @fn_emith(ptr @.str289) - call void @fn_emith(ptr @.str290) - call void @fn_emith(ptr @.str291) - call void @fn_emith(ptr @.str292) - call void @fn_emith(ptr @.str293) - call void @fn_emith(ptr @.str294) - call void @fn_emith(ptr @.str295) - call void @fn_emith(ptr @.str296) - call void @fn_emith(ptr @.str297) + call void @fn_emith(ptr @.str365) + call void @fn_emith(ptr @.str366) + call void @fn_emith(ptr @.str367) + call void @fn_emith(ptr @.str368) + call void @fn_emith(ptr @.str369) + call void @fn_emith(ptr @.str370) + call void @fn_emith(ptr @.str371) + call void @fn_emith(ptr @.str372) + call void @fn_emith(ptr @.str373) + call void @fn_emith(ptr @.str374) + call void @fn_emith(ptr @.str375) + call void @fn_emith(ptr @.str376) + call void @fn_emith(ptr @.str377) + call void @fn_emith(ptr @.str378) + call void @fn_emith(ptr @.str379) + call void @fn_emith(ptr @.str380) + call void @fn_emith(ptr @.str381) + call void @fn_emith(ptr @.str382) + call void @fn_emith(ptr @.str383) + call void @fn_emith(ptr @.str384) + call void @fn_emith(ptr @.str385) + call void @fn_emith(ptr @.str386) + call void @fn_emith(ptr @.str387) + call void @fn_emith(ptr @.str388) + call void @fn_emith(ptr @.str389) + call void @fn_emith(ptr @.str390) + call void @fn_emith(ptr @.str391) + call void @fn_emith(ptr @.str392) + call void @fn_emith(ptr @.str393) + call void @fn_emith(ptr @.str394) + call void @fn_emith(ptr @.str395) + call void @fn_emith(ptr @.str396) %t0 = load ptr, ptr @g_g_game_name %t1 = call i64 @strlen(ptr %t0) %t2 = trunc i64 %t1 to i32 %t3 = add i32 %t2, 1 %t4 = call ptr @fn_itoa(i32 %t3) call void @fn_emith(ptr %t4) - call void @fn_emith(ptr @.str298) + call void @fn_emith(ptr @.str397) %t5 = load ptr, ptr @g_g_game_name call void @fn_emith(ptr %t5) - call void @fn_emith(ptr @.str299) - call void @fn_emith(ptr @.str300) + call void @fn_emith(ptr @.str398) + call void @fn_emith(ptr @.str399) store i32 0, ptr %t6 br label %wcond0 wcond0: @@ -11600,7 +14625,7 @@ then3: %t29 = load ptr, ptr %t28 %t30 = call ptr @fn_layout_ty(ptr %t29) call void @fn_emith(ptr %t30) - call void @fn_emith(ptr @.str301) + call void @fn_emith(ptr @.str400) %t31 = load ptr, ptr %t20 %t32 = getelementptr inbounds %Cmp_Node, ptr %t31, i32 0, i32 7 %t33 = load ptr, ptr %t32 @@ -11611,7 +14636,7 @@ then3: %t38 = icmp ne i32 %t37, 0 br i1 %t38, label %then6, label %ifend8 then6: - call void @fn_emith(ptr @.str302) + call void @fn_emith(ptr @.str401) br label %ifend8 ifend8: store i32 0, ptr %t39 @@ -11634,7 +14659,7 @@ wbody10: %t52 = icmp ne i32 %t51, 0 br i1 %t52, label %then12, label %ifend14 then12: - call void @fn_emith(ptr @.str303) + call void @fn_emith(ptr @.str402) br label %ifend14 ifend14: %t53 = load ptr, ptr %t20 @@ -11654,7 +14679,7 @@ ifend14: store i32 %t65, ptr %t39 br label %wcond9 wend11: - call void @fn_emith(ptr @.str304) + call void @fn_emith(ptr @.str403) br label %ifend5 ifend5: %t66 = load i32, ptr %t6 @@ -11689,22 +14714,22 @@ wbody16: %t87 = icmp ne i32 %t86, 0 br i1 %t87, label %then18, label %ifend20 then18: - call void @fn_emith(ptr @.str305) + call void @fn_emith(ptr @.str404) %t88 = load ptr, ptr %t81 %t89 = getelementptr inbounds %Cmp_Node, ptr %t88, i32 0, i32 1 %t90 = load ptr, ptr %t89 call void @fn_emith(ptr %t90) - call void @fn_emith(ptr @.str306) + call void @fn_emith(ptr @.str405) %t91 = load ptr, ptr %t81 %t92 = getelementptr inbounds %Cmp_Node, ptr %t91, i32 0, i32 3 %t93 = load ptr, ptr %t92 %t94 = call ptr @fn_llty(ptr %t93) call void @fn_emith(ptr %t94) - call void @fn_emith(ptr @.str307) + call void @fn_emith(ptr @.str406) %t95 = load ptr, ptr %t81 %t96 = call ptr @fn_global_init(ptr %t95) call void @fn_emith(ptr %t96) - call void @fn_emith(ptr @.str308) + call void @fn_emith(ptr @.str407) br label %ifend20 ifend20: %t97 = load i32, ptr %t6 @@ -11717,43 +14742,142 @@ ret: ret void } +define void @fn_emit_extern_decls() { +entry: + %t0 = alloca i32 + %t14 = alloca ptr + %t30 = alloca i32 + store i32 0, ptr %t0 + br label %wcond0 +wcond0: + %t1 = load i32, ptr %t0 + %t2 = load ptr, ptr @g_prog + %t3 = getelementptr inbounds %LSlice, ptr %t2, i32 0, i32 1 + %t4 = load i32, ptr %t3 + %t5 = icmp slt i32 %t1, %t4 + %t6 = zext i1 %t5 to i32 + %t7 = icmp ne i32 %t6, 0 + br i1 %t7, label %wbody1, label %wend2 +wbody1: + %t8 = load ptr, ptr @g_prog + %t9 = getelementptr inbounds %LSlice, ptr %t8, i32 0, i32 0 + %t10 = load ptr, ptr %t9 + %t11 = load i32, ptr %t0 + %t12 = getelementptr inbounds ptr, ptr %t10, i32 %t11 + %t13 = load ptr, ptr %t12 + store ptr %t13, ptr %t14 + %t15 = load ptr, ptr %t14 + %t16 = getelementptr inbounds %Cmp_Node, ptr %t15, i32 0, i32 0 + %t17 = load i32, ptr %t16 + %t18 = icmp eq i32 %t17, 11 + %t19 = zext i1 %t18 to i32 + %t20 = icmp ne i32 %t19, 0 + br i1 %t20, label %then3, label %ifend5 +then3: + call void @fn_emith(ptr @.str408) + %t21 = load ptr, ptr %t14 + %t22 = getelementptr inbounds %Cmp_Node, ptr %t21, i32 0, i32 3 + %t23 = load ptr, ptr %t22 + %t24 = call ptr @fn_llty(ptr %t23) + call void @fn_emith(ptr %t24) + call void @fn_emith(ptr @.str409) + %t25 = load ptr, ptr %t14 + %t26 = getelementptr inbounds %Cmp_Node, ptr %t25, i32 0, i32 4 + %t27 = load ptr, ptr %t26 + %t28 = getelementptr inbounds %Cmp_Node, ptr %t27, i32 0, i32 1 + %t29 = load ptr, ptr %t28 + call void @fn_emith(ptr %t29) + call void @fn_emith(ptr @.str410) + store i32 0, ptr %t30 + br label %wcond6 +wcond6: + %t31 = load i32, ptr %t30 + %t32 = load ptr, ptr %t14 + %t33 = getelementptr inbounds %Cmp_Node, ptr %t32, i32 0, i32 7 + %t34 = load ptr, ptr %t33 + %t35 = getelementptr inbounds %LSlice, ptr %t34, i32 0, i32 1 + %t36 = load i32, ptr %t35 + %t37 = icmp slt i32 %t31, %t36 + %t38 = zext i1 %t37 to i32 + %t39 = icmp ne i32 %t38, 0 + br i1 %t39, label %wbody7, label %wend8 +wbody7: + %t40 = load i32, ptr %t30 + %t41 = icmp sgt i32 %t40, 0 + %t42 = zext i1 %t41 to i32 + %t43 = icmp ne i32 %t42, 0 + br i1 %t43, label %then9, label %ifend11 +then9: + call void @fn_emith(ptr @.str411) + br label %ifend11 +ifend11: + %t44 = load ptr, ptr %t14 + %t45 = getelementptr inbounds %Cmp_Node, ptr %t44, i32 0, i32 7 + %t46 = load ptr, ptr %t45 + %t47 = getelementptr inbounds %LSlice, ptr %t46, i32 0, i32 0 + %t48 = load ptr, ptr %t47 + %t49 = load i32, ptr %t30 + %t50 = getelementptr inbounds ptr, ptr %t48, i32 %t49 + %t51 = load ptr, ptr %t50 + %t52 = getelementptr inbounds %Cmp_Node, ptr %t51, i32 0, i32 3 + %t53 = load ptr, ptr %t52 + %t54 = call ptr @fn_llty(ptr %t53) + call void @fn_emith(ptr %t54) + %t55 = load i32, ptr %t30 + %t56 = add i32 %t55, 1 + store i32 %t56, ptr %t30 + br label %wcond6 +wend8: + call void @fn_emith(ptr @.str412) + br label %ifend5 +ifend5: + %t57 = load i32, ptr %t0 + %t58 = add i32 %t57, 1 + store i32 %t58, ptr %t0 + br label %wcond0 +wend2: + br label %ret +ret: + ret void +} + define void @fn_emit_str_prelude() { entry: - call void @fn_emith(ptr @.str309) - call void @fn_emith(ptr @.str310) - call void @fn_emith(ptr @.str311) - call void @fn_emith(ptr @.str312) - call void @fn_emith(ptr @.str313) - call void @fn_emith(ptr @.str314) - call void @fn_emith(ptr @.str315) - call void @fn_emith(ptr @.str316) - call void @fn_emith(ptr @.str317) - call void @fn_emith(ptr @.str318) - call void @fn_emith(ptr @.str319) - call void @fn_emith(ptr @.str320) - call void @fn_emith(ptr @.str321) - call void @fn_emith(ptr @.str322) - call void @fn_emith(ptr @.str323) - call void @fn_emith(ptr @.str324) - call void @fn_emith(ptr @.str325) - call void @fn_emith(ptr @.str326) - call void @fn_emith(ptr @.str327) - call void @fn_emith(ptr @.str328) - call void @fn_emith(ptr @.str329) - call void @fn_emith(ptr @.str330) - call void @fn_emith(ptr @.str331) - call void @fn_emith(ptr @.str332) - call void @fn_emith(ptr @.str333) - call void @fn_emith(ptr @.str334) - call void @fn_emith(ptr @.str335) - call void @fn_emith(ptr @.str336) - call void @fn_emith(ptr @.str337) - call void @fn_emith(ptr @.str338) - call void @fn_emith(ptr @.str339) - call void @fn_emith(ptr @.str340) - call void @fn_emith(ptr @.str341) - call void @fn_emith(ptr @.str342) - call void @fn_emith(ptr @.str343) + call void @fn_emith(ptr @.str413) + call void @fn_emith(ptr @.str414) + call void @fn_emith(ptr @.str415) + call void @fn_emith(ptr @.str416) + call void @fn_emith(ptr @.str417) + call void @fn_emith(ptr @.str418) + call void @fn_emith(ptr @.str419) + call void @fn_emith(ptr @.str420) + call void @fn_emith(ptr @.str421) + call void @fn_emith(ptr @.str422) + call void @fn_emith(ptr @.str423) + call void @fn_emith(ptr @.str424) + call void @fn_emith(ptr @.str425) + call void @fn_emith(ptr @.str426) + call void @fn_emith(ptr @.str427) + call void @fn_emith(ptr @.str428) + call void @fn_emith(ptr @.str429) + call void @fn_emith(ptr @.str430) + call void @fn_emith(ptr @.str431) + call void @fn_emith(ptr @.str432) + call void @fn_emith(ptr @.str433) + call void @fn_emith(ptr @.str434) + call void @fn_emith(ptr @.str435) + call void @fn_emith(ptr @.str436) + call void @fn_emith(ptr @.str437) + call void @fn_emith(ptr @.str438) + call void @fn_emith(ptr @.str439) + call void @fn_emith(ptr @.str440) + call void @fn_emith(ptr @.str441) + call void @fn_emith(ptr @.str442) + call void @fn_emith(ptr @.str443) + call void @fn_emith(ptr @.str444) + call void @fn_emith(ptr @.str445) + call void @fn_emith(ptr @.str446) + call void @fn_emith(ptr @.str447) br label %ret ret: ret void @@ -11761,23 +14885,23 @@ ret: define void @fn_emit_int_str() { entry: - call void @fn_emith(ptr @.str344) - call void @fn_emith(ptr @.str345) - call void @fn_emith(ptr @.str346) - call void @fn_emith(ptr @.str347) - call void @fn_emith(ptr @.str348) - call void @fn_emith(ptr @.str349) - call void @fn_emith(ptr @.str350) - call void @fn_emith(ptr @.str351) - call void @fn_emith(ptr @.str352) - call void @fn_emith(ptr @.str353) - call void @fn_emith(ptr @.str354) - call void @fn_emith(ptr @.str355) - call void @fn_emith(ptr @.str356) - call void @fn_emith(ptr @.str357) - call void @fn_emith(ptr @.str358) - call void @fn_emith(ptr @.str359) - call void @fn_emith(ptr @.str360) + call void @fn_emith(ptr @.str448) + call void @fn_emith(ptr @.str449) + call void @fn_emith(ptr @.str450) + call void @fn_emith(ptr @.str451) + call void @fn_emith(ptr @.str452) + call void @fn_emith(ptr @.str453) + call void @fn_emith(ptr @.str454) + call void @fn_emith(ptr @.str455) + call void @fn_emith(ptr @.str456) + call void @fn_emith(ptr @.str457) + call void @fn_emith(ptr @.str458) + call void @fn_emith(ptr @.str459) + call void @fn_emith(ptr @.str460) + call void @fn_emith(ptr @.str461) + call void @fn_emith(ptr @.str462) + call void @fn_emith(ptr @.str463) + call void @fn_emith(ptr @.str464) br label %ret ret: ret void @@ -11785,14 +14909,14 @@ ret: define void @fn_emit_str_slice() { entry: - call void @fn_emith(ptr @.str361) - call void @fn_emith(ptr @.str362) - call void @fn_emith(ptr @.str363) - call void @fn_emith(ptr @.str364) - call void @fn_emith(ptr @.str365) - call void @fn_emith(ptr @.str366) - call void @fn_emith(ptr @.str367) - call void @fn_emith(ptr @.str368) + call void @fn_emith(ptr @.str465) + call void @fn_emith(ptr @.str466) + call void @fn_emith(ptr @.str467) + call void @fn_emith(ptr @.str468) + call void @fn_emith(ptr @.str469) + call void @fn_emith(ptr @.str470) + call void @fn_emith(ptr @.str471) + call void @fn_emith(ptr @.str472) br label %ret ret: ret void @@ -11826,7 +14950,7 @@ then0: %t15 = load ptr, ptr %t5 %t16 = getelementptr inbounds %Cmp_Val, ptr %t15, i32 0, i32 1 %t17 = load ptr, ptr %t16 - %t18 = call ptr @fn_str_concat(ptr @.str369, ptr %t17) + %t18 = call ptr @fn_str_concat(ptr @.str473, ptr %t17) call void @fn_perr(ptr %t18) br label %ifend2 ifend2: @@ -11845,7 +14969,7 @@ then3: %t29 = load ptr, ptr %t0 %t30 = getelementptr inbounds %Cmp_Node, ptr %t29, i32 0, i32 1 %t31 = load ptr, ptr %t30 - %t32 = call ptr @fn_str_concat(ptr @.str370, ptr %t31) + %t32 = call ptr @fn_str_concat(ptr @.str474, ptr %t31) call void @fn_perr(ptr %t32) br label %ifend5 ifend5: @@ -11857,25 +14981,25 @@ ifend5: store ptr %t37, ptr @g_g_addr_ty %t38 = call ptr @fn_nreg() store ptr %t38, ptr %t39 - call void @fn_emit(ptr @.str371) + call void @fn_emit(ptr @.str475) %t40 = load ptr, ptr %t39 call void @fn_emit(ptr %t40) - call void @fn_emit(ptr @.str372) + call void @fn_emit(ptr @.str476) %t41 = load ptr, ptr %t5 %t42 = getelementptr inbounds %Cmp_Val, ptr %t41, i32 0, i32 1 %t43 = load ptr, ptr %t42 %t44 = call ptr @fn_layout_ty(ptr %t43) call void @fn_emit(ptr %t44) - call void @fn_emit(ptr @.str373) + call void @fn_emit(ptr @.str477) %t45 = load ptr, ptr %t5 %t46 = getelementptr inbounds %Cmp_Val, ptr %t45, i32 0, i32 0 %t47 = load ptr, ptr %t46 call void @fn_emit(ptr %t47) - call void @fn_emit(ptr @.str374) + call void @fn_emit(ptr @.str478) %t48 = load i32, ptr %t24 %t49 = call ptr @fn_itoa(i32 %t48) call void @fn_emit(ptr %t49) - call void @fn_emit(ptr @.str375) + call void @fn_emit(ptr @.str479) %t50 = load ptr, ptr %t39 store ptr %t50, ptr %retval br label %ret @@ -11922,22 +15046,22 @@ then0: %t18 = load ptr, ptr %t5 %t19 = getelementptr inbounds %Cmp_Val, ptr %t18, i32 0, i32 1 %t20 = load ptr, ptr %t19 - %t21 = call i32 @fn_str_eq(ptr %t20, ptr @.str376) + %t21 = call i32 @fn_str_eq(ptr %t20, ptr @.str480) %t22 = icmp ne i32 %t21, 0 br i1 %t22, label %then3, label %ifend5 then3: %t23 = load ptr, ptr %t5 %t24 = getelementptr inbounds %Cmp_Val, ptr %t23, i32 0, i32 0 %t25 = load ptr, ptr %t24 - %t26 = call ptr @fn_str_concat(ptr @.str377, ptr %t25) - %t27 = call ptr @fn_str_concat(ptr %t26, ptr @.str378) + %t26 = call ptr @fn_str_concat(ptr @.str481, ptr %t25) + %t27 = call ptr @fn_str_concat(ptr %t26, ptr @.str482) %t28 = load ptr, ptr %t17 %t29 = getelementptr inbounds %Cmp_Val, ptr %t28, i32 0, i32 0 %t30 = load ptr, ptr %t29 %t31 = call ptr @fn_str_concat(ptr %t27, ptr %t30) %t32 = call ptr @fn_emit_bind(ptr %t31) store ptr %t32, ptr %t33 - store ptr @.str379, ptr @g_g_addr_ty + store ptr @.str483, ptr @g_g_addr_ty %t34 = load ptr, ptr %t33 store ptr %t34, ptr %retval br label %ret @@ -11945,22 +15069,22 @@ ifend5: %t35 = load ptr, ptr %t5 %t36 = getelementptr inbounds %Cmp_Val, ptr %t35, i32 0, i32 1 %t37 = load ptr, ptr %t36 - %t38 = call i32 @fn_str_eq(ptr %t37, ptr @.str380) + %t38 = call i32 @fn_str_eq(ptr %t37, ptr @.str484) %t39 = icmp ne i32 %t38, 0 br i1 %t39, label %then6, label %ifend8 then6: %t40 = load ptr, ptr %t5 %t41 = getelementptr inbounds %Cmp_Val, ptr %t40, i32 0, i32 0 %t42 = load ptr, ptr %t41 - %t43 = call ptr @fn_str_concat(ptr @.str381, ptr %t42) - %t44 = call ptr @fn_str_concat(ptr %t43, ptr @.str382) + %t43 = call ptr @fn_str_concat(ptr @.str485, ptr %t42) + %t44 = call ptr @fn_str_concat(ptr %t43, ptr @.str486) %t45 = load ptr, ptr %t17 %t46 = getelementptr inbounds %Cmp_Val, ptr %t45, i32 0, i32 0 %t47 = load ptr, ptr %t46 %t48 = call ptr @fn_str_concat(ptr %t44, ptr %t47) %t49 = call ptr @fn_emit_bind(ptr %t48) store ptr %t49, ptr %t50 - store ptr @.str383, ptr @g_g_addr_ty + store ptr @.str487, ptr @g_g_addr_ty %t51 = load ptr, ptr %t50 store ptr %t51, ptr %retval br label %ret @@ -11968,22 +15092,22 @@ ifend8: %t52 = load ptr, ptr %t5 %t53 = getelementptr inbounds %Cmp_Val, ptr %t52, i32 0, i32 1 %t54 = load ptr, ptr %t53 - %t55 = call i32 @fn_str_eq(ptr %t54, ptr @.str384) + %t55 = call i32 @fn_str_eq(ptr %t54, ptr @.str488) %t56 = icmp ne i32 %t55, 0 br i1 %t56, label %then9, label %ifend11 then9: %t57 = load ptr, ptr %t5 %t58 = getelementptr inbounds %Cmp_Val, ptr %t57, i32 0, i32 0 %t59 = load ptr, ptr %t58 - %t60 = call ptr @fn_str_concat(ptr @.str385, ptr %t59) - %t61 = call ptr @fn_str_concat(ptr %t60, ptr @.str386) + %t60 = call ptr @fn_str_concat(ptr @.str489, ptr %t59) + %t61 = call ptr @fn_str_concat(ptr %t60, ptr @.str490) %t62 = load ptr, ptr %t17 %t63 = getelementptr inbounds %Cmp_Val, ptr %t62, i32 0, i32 0 %t64 = load ptr, ptr %t63 %t65 = call ptr @fn_str_concat(ptr %t61, ptr %t64) %t66 = call ptr @fn_emit_bind(ptr %t65) store ptr %t66, ptr %t67 - store ptr @.str387, ptr @g_g_addr_ty + store ptr @.str491, ptr @g_g_addr_ty %t68 = load ptr, ptr %t67 store ptr %t68, ptr %retval br label %ret @@ -11991,15 +15115,15 @@ ifend11: %t69 = load ptr, ptr %t5 %t70 = getelementptr inbounds %Cmp_Val, ptr %t69, i32 0, i32 0 %t71 = load ptr, ptr %t70 - %t72 = call ptr @fn_str_concat(ptr @.str388, ptr %t71) - %t73 = call ptr @fn_str_concat(ptr %t72, ptr @.str389) + %t72 = call ptr @fn_str_concat(ptr @.str492, ptr %t71) + %t73 = call ptr @fn_str_concat(ptr %t72, ptr @.str493) %t74 = load ptr, ptr %t17 %t75 = getelementptr inbounds %Cmp_Val, ptr %t74, i32 0, i32 0 %t76 = load ptr, ptr %t75 %t77 = call ptr @fn_str_concat(ptr %t73, ptr %t76) %t78 = call ptr @fn_emit_bind(ptr %t77) store ptr %t78, ptr %t79 - store ptr @.str390, ptr @g_g_addr_ty + store ptr @.str494, ptr @g_g_addr_ty %t80 = load ptr, ptr %t79 store ptr %t80, ptr %retval br label %ret @@ -12013,24 +15137,24 @@ ifend2: store ptr %t86, ptr @g_g_addr_ty %t87 = call ptr @fn_nreg() store ptr %t87, ptr %t88 - call void @fn_emit(ptr @.str391) + call void @fn_emit(ptr @.str495) %t89 = load ptr, ptr %t88 call void @fn_emit(ptr %t89) - call void @fn_emit(ptr @.str392) + call void @fn_emit(ptr @.str496) %t90 = load ptr, ptr %t5 %t91 = getelementptr inbounds %Cmp_Val, ptr %t90, i32 0, i32 0 %t92 = load ptr, ptr %t91 call void @fn_emit(ptr %t92) - call void @fn_emit(ptr @.str393) + call void @fn_emit(ptr @.str497) %t93 = call ptr @fn_nreg() store ptr %t93, ptr %t94 - call void @fn_emit(ptr @.str394) + call void @fn_emit(ptr @.str498) %t95 = load ptr, ptr %t94 call void @fn_emit(ptr %t95) - call void @fn_emit(ptr @.str395) + call void @fn_emit(ptr @.str499) %t96 = load ptr, ptr %t88 call void @fn_emit(ptr %t96) - call void @fn_emit(ptr @.str396) + call void @fn_emit(ptr @.str500) %t97 = load ptr, ptr %t0 %t98 = getelementptr inbounds %Cmp_Node, ptr %t97, i32 0, i32 5 %t99 = load ptr, ptr %t98 @@ -12038,22 +15162,22 @@ ifend2: store ptr %t100, ptr %t101 %t102 = call ptr @fn_nreg() store ptr %t102, ptr %t103 - call void @fn_emit(ptr @.str397) + call void @fn_emit(ptr @.str501) %t104 = load ptr, ptr %t103 call void @fn_emit(ptr %t104) - call void @fn_emit(ptr @.str398) + call void @fn_emit(ptr @.str502) %t105 = load ptr, ptr %t85 %t106 = call ptr @fn_llty(ptr %t105) call void @fn_emit(ptr %t106) - call void @fn_emit(ptr @.str399) + call void @fn_emit(ptr @.str503) %t107 = load ptr, ptr %t94 call void @fn_emit(ptr %t107) - call void @fn_emit(ptr @.str400) + call void @fn_emit(ptr @.str504) %t108 = load ptr, ptr %t101 %t109 = getelementptr inbounds %Cmp_Val, ptr %t108, i32 0, i32 0 %t110 = load ptr, ptr %t109 call void @fn_emit(ptr %t110) - call void @fn_emit(ptr @.str401) + call void @fn_emit(ptr @.str505) %t111 = load ptr, ptr %t103 store ptr %t111, ptr %retval br label %ret @@ -12076,7 +15200,7 @@ entry: %t72 = alloca i32 store ptr %arg_name, ptr %t0 %t1 = load ptr, ptr %t0 - %t2 = call i32 @fn_str_eq(ptr %t1, ptr @.str402) + %t2 = call i32 @fn_str_eq(ptr %t1, ptr @.str506) %t3 = icmp ne i32 %t2, 0 br i1 %t3, label %then0, label %ifend2 then0: @@ -12084,14 +15208,14 @@ then0: br label %ret ifend2: %t6 = load ptr, ptr %t0 - %t7 = call i32 @fn_str_eq(ptr %t6, ptr @.str403) + %t7 = call i32 @fn_str_eq(ptr %t6, ptr @.str507) %t8 = icmp ne i32 %t7, 0 %t9 = zext i1 %t8 to i32 store i32 %t9, ptr %t5 br i1 %t8, label %scend4, label %sc3 sc3: %t10 = load ptr, ptr %t0 - %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str404) + %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str508) %t12 = icmp ne i32 %t11, 0 %t13 = zext i1 %t12 to i32 store i32 %t13, ptr %t5 @@ -12104,7 +15228,7 @@ scend4: br i1 %t15, label %scend6, label %sc5 sc5: %t17 = load ptr, ptr %t0 - %t18 = call i32 @fn_str_eq(ptr %t17, ptr @.str405) + %t18 = call i32 @fn_str_eq(ptr %t17, ptr @.str509) %t19 = icmp ne i32 %t18, 0 %t20 = zext i1 %t19 to i32 store i32 %t20, ptr %t4 @@ -12118,14 +15242,14 @@ then7: br label %ret ifend9: %t25 = load ptr, ptr %t0 - %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str406) + %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str510) %t27 = icmp ne i32 %t26, 0 %t28 = zext i1 %t27 to i32 store i32 %t28, ptr %t24 br i1 %t27, label %scend11, label %sc10 sc10: %t29 = load ptr, ptr %t0 - %t30 = call i32 @fn_str_eq(ptr %t29, ptr @.str407) + %t30 = call i32 @fn_str_eq(ptr %t29, ptr @.str511) %t31 = icmp ne i32 %t30, 0 %t32 = zext i1 %t31 to i32 store i32 %t32, ptr %t24 @@ -12138,7 +15262,7 @@ scend11: br i1 %t34, label %scend13, label %sc12 sc12: %t36 = load ptr, ptr %t0 - %t37 = call i32 @fn_str_eq(ptr %t36, ptr @.str408) + %t37 = call i32 @fn_str_eq(ptr %t36, ptr @.str512) %t38 = icmp ne i32 %t37, 0 %t39 = zext i1 %t38 to i32 store i32 %t39, ptr %t23 @@ -12152,14 +15276,14 @@ then14: br label %ret ifend16: %t44 = load ptr, ptr %t0 - %t45 = call i32 @fn_str_eq(ptr %t44, ptr @.str409) + %t45 = call i32 @fn_str_eq(ptr %t44, ptr @.str513) %t46 = icmp ne i32 %t45, 0 %t47 = zext i1 %t46 to i32 store i32 %t47, ptr %t43 br i1 %t46, label %scend18, label %sc17 sc17: %t48 = load ptr, ptr %t0 - %t49 = call i32 @fn_str_eq(ptr %t48, ptr @.str410) + %t49 = call i32 @fn_str_eq(ptr %t48, ptr @.str514) %t50 = icmp ne i32 %t49, 0 %t51 = zext i1 %t50 to i32 store i32 %t51, ptr %t43 @@ -12172,7 +15296,7 @@ scend18: br i1 %t53, label %scend20, label %sc19 sc19: %t55 = load ptr, ptr %t0 - %t56 = call i32 @fn_str_eq(ptr %t55, ptr @.str411) + %t56 = call i32 @fn_str_eq(ptr %t55, ptr @.str515) %t57 = icmp ne i32 %t56, 0 %t58 = zext i1 %t57 to i32 store i32 %t58, ptr %t42 @@ -12186,14 +15310,14 @@ then21: br label %ret ifend23: %t62 = load ptr, ptr %t0 - %t63 = call i32 @fn_str_eq(ptr %t62, ptr @.str412) + %t63 = call i32 @fn_str_eq(ptr %t62, ptr @.str516) %t64 = icmp ne i32 %t63, 0 %t65 = zext i1 %t64 to i32 store i32 %t65, ptr %t61 br i1 %t64, label %scend25, label %sc24 sc24: %t66 = load ptr, ptr %t0 - %t67 = call i32 @fn_str_eq(ptr %t66, ptr @.str413) + %t67 = call i32 @fn_str_eq(ptr %t66, ptr @.str517) %t68 = icmp ne i32 %t67, 0 %t69 = zext i1 %t68 to i32 store i32 %t69, ptr %t61 @@ -12207,14 +15331,14 @@ then26: br label %ret ifend28: %t73 = load ptr, ptr %t0 - %t74 = call i32 @fn_str_eq(ptr %t73, ptr @.str414) + %t74 = call i32 @fn_str_eq(ptr %t73, ptr @.str518) %t75 = icmp ne i32 %t74, 0 %t76 = zext i1 %t75 to i32 store i32 %t76, ptr %t72 br i1 %t75, label %scend30, label %sc29 sc29: %t77 = load ptr, ptr %t0 - %t78 = call i32 @fn_str_eq(ptr %t77, ptr @.str415) + %t78 = call i32 @fn_str_eq(ptr %t77, ptr @.str519) %t79 = icmp ne i32 %t78, 0 %t80 = zext i1 %t79 to i32 store i32 %t80, ptr %t72 @@ -12242,13 +15366,13 @@ entry: store ptr %arg_rest, ptr %t0 %t1 = call ptr @fn_nreg() store ptr %t1, ptr %t2 - call void @fn_emit(ptr @.str416) + call void @fn_emit(ptr @.str520) %t3 = load ptr, ptr %t2 call void @fn_emit(ptr %t3) - call void @fn_emit(ptr @.str417) + call void @fn_emit(ptr @.str521) %t4 = load ptr, ptr %t0 call void @fn_emit(ptr %t4) - call void @fn_emit(ptr @.str418) + call void @fn_emit(ptr @.str522) %t5 = load ptr, ptr %t2 store ptr %t5, ptr %retval br label %ret @@ -12319,7 +15443,7 @@ entry: store ptr %arg_e, ptr %t1 store i32 1, ptr @g_g_intrin_ok %t2 = load ptr, ptr %t0 - %t3 = call i32 @fn_str_eq(ptr %t2, ptr @.str419) + %t3 = call i32 @fn_str_eq(ptr %t2, ptr @.str523) %t4 = icmp ne i32 %t3, 0 br i1 %t4, label %then0, label %ifend2 then0: @@ -12330,23 +15454,23 @@ then0: %t9 = call ptr @fn_arg_code(ptr %t8, i32 1) store ptr %t9, ptr %t10 %t11 = load ptr, ptr %t10 - %t12 = call ptr @fn_str_concat(ptr @.str420, ptr %t11) - %t13 = call ptr @fn_str_concat(ptr %t12, ptr @.str421) + %t12 = call ptr @fn_str_concat(ptr @.str524, ptr %t11) + %t13 = call ptr @fn_str_concat(ptr %t12, ptr @.str525) %t14 = call ptr @fn_emit_bind(ptr %t13) store ptr %t14, ptr %t15 %t16 = load ptr, ptr %t7 - %t17 = call ptr @fn_str_concat(ptr @.str422, ptr %t16) - %t18 = call ptr @fn_str_concat(ptr %t17, ptr @.str423) + %t17 = call ptr @fn_str_concat(ptr @.str526, ptr %t16) + %t18 = call ptr @fn_str_concat(ptr %t17, ptr @.str527) %t19 = load ptr, ptr %t15 %t20 = call ptr @fn_str_concat(ptr %t18, ptr %t19) - %t21 = call ptr @fn_str_concat(ptr %t20, ptr @.str424) + %t21 = call ptr @fn_str_concat(ptr %t20, ptr @.str528) %t22 = call ptr @fn_emit_bind(ptr %t21) - %t23 = call ptr @fn_val(ptr %t22, ptr @.str425) + %t23 = call ptr @fn_val(ptr %t22, ptr @.str529) store ptr %t23, ptr %retval br label %ret ifend2: %t24 = load ptr, ptr %t0 - %t25 = call i32 @fn_str_eq(ptr %t24, ptr @.str426) + %t25 = call i32 @fn_str_eq(ptr %t24, ptr @.str530) %t26 = icmp ne i32 %t25, 0 br i1 %t26, label %then3, label %ifend5 then3: @@ -12357,25 +15481,25 @@ then3: %t31 = call ptr @fn_arg_code(ptr %t30, i32 1) store ptr %t31, ptr %t32 %t33 = load ptr, ptr %t29 - %t34 = call ptr @fn_str_concat(ptr @.str427, ptr %t33) - %t35 = call ptr @fn_str_concat(ptr %t34, ptr @.str428) + %t34 = call ptr @fn_str_concat(ptr @.str531, ptr %t33) + %t35 = call ptr @fn_str_concat(ptr %t34, ptr @.str532) %t36 = load ptr, ptr %t32 %t37 = call ptr @fn_str_concat(ptr %t35, ptr %t36) - %t38 = call ptr @fn_str_concat(ptr %t37, ptr @.str429) + %t38 = call ptr @fn_str_concat(ptr %t37, ptr @.str533) %t39 = call ptr @fn_emit_bind(ptr %t38) - %t40 = call ptr @fn_val(ptr %t39, ptr @.str430) + %t40 = call ptr @fn_val(ptr %t39, ptr @.str534) store ptr %t40, ptr %retval br label %ret ifend5: %t42 = load ptr, ptr %t0 - %t43 = call i32 @fn_str_eq(ptr %t42, ptr @.str431) + %t43 = call i32 @fn_str_eq(ptr %t42, ptr @.str535) %t44 = icmp ne i32 %t43, 0 %t45 = zext i1 %t44 to i32 store i32 %t45, ptr %t41 br i1 %t44, label %scend7, label %sc6 sc6: %t46 = load ptr, ptr %t0 - %t47 = call i32 @fn_str_eq(ptr %t46, ptr @.str432) + %t47 = call i32 @fn_str_eq(ptr %t46, ptr @.str536) %t48 = icmp ne i32 %t47, 0 %t49 = zext i1 %t48 to i32 store i32 %t49, ptr %t41 @@ -12395,43 +15519,43 @@ then8: %t59 = call ptr @fn_arg_code(ptr %t58, i32 2) store ptr %t59, ptr %t60 %t61 = load ptr, ptr %t60 - %t62 = call ptr @fn_str_concat(ptr @.str433, ptr %t61) - %t63 = call ptr @fn_str_concat(ptr %t62, ptr @.str434) + %t62 = call ptr @fn_str_concat(ptr @.str537, ptr %t61) + %t63 = call ptr @fn_str_concat(ptr %t62, ptr @.str538) %t64 = call ptr @fn_emit_bind(ptr %t63) store ptr %t64, ptr %t65 - store ptr @.str435, ptr %t66 + store ptr @.str539, ptr %t66 %t67 = load ptr, ptr %t0 - %t68 = call i32 @fn_str_eq(ptr %t67, ptr @.str436) + %t68 = call i32 @fn_str_eq(ptr %t67, ptr @.str540) %t69 = icmp ne i32 %t68, 0 br i1 %t69, label %then11, label %ifend13 then11: - store ptr @.str437, ptr %t66 + store ptr @.str541, ptr %t66 br label %ifend13 ifend13: %t70 = load ptr, ptr %t66 - %t71 = call ptr @fn_str_concat(ptr @.str438, ptr %t70) - %t72 = call ptr @fn_str_concat(ptr %t71, ptr @.str439) + %t71 = call ptr @fn_str_concat(ptr @.str542, ptr %t70) + %t72 = call ptr @fn_str_concat(ptr %t71, ptr @.str543) %t73 = load ptr, ptr %t57 %t74 = call ptr @fn_str_concat(ptr %t72, ptr %t73) - %t75 = call ptr @fn_str_concat(ptr %t74, ptr @.str440) + %t75 = call ptr @fn_str_concat(ptr %t74, ptr @.str544) %t76 = load ptr, ptr %t65 %t77 = call ptr @fn_str_concat(ptr %t75, ptr %t76) - %t78 = call ptr @fn_str_concat(ptr %t77, ptr @.str441) + %t78 = call ptr @fn_str_concat(ptr %t77, ptr @.str545) %t79 = load ptr, ptr %t54 %t80 = call ptr @fn_str_concat(ptr %t78, ptr %t79) - %t81 = call ptr @fn_str_concat(ptr %t80, ptr @.str442) + %t81 = call ptr @fn_str_concat(ptr %t80, ptr @.str546) %t82 = call ptr @fn_emit_bind(ptr %t81) store ptr %t82, ptr %t83 %t84 = load ptr, ptr %t83 - %t85 = call ptr @fn_str_concat(ptr @.str443, ptr %t84) - %t86 = call ptr @fn_str_concat(ptr %t85, ptr @.str444) + %t85 = call ptr @fn_str_concat(ptr @.str547, ptr %t84) + %t86 = call ptr @fn_str_concat(ptr %t85, ptr @.str548) %t87 = call ptr @fn_emit_bind(ptr %t86) - %t88 = call ptr @fn_val(ptr %t87, ptr @.str445) + %t88 = call ptr @fn_val(ptr %t87, ptr @.str549) store ptr %t88, ptr %retval br label %ret ifend10: %t89 = load ptr, ptr %t0 - %t90 = call i32 @fn_str_eq(ptr %t89, ptr @.str446) + %t90 = call i32 @fn_str_eq(ptr %t89, ptr @.str550) %t91 = icmp ne i32 %t90, 0 br i1 %t91, label %then14, label %ifend16 then14: @@ -12445,26 +15569,26 @@ then14: %t99 = call ptr @fn_arg_code(ptr %t98, i32 2) store ptr %t99, ptr %t100 %t101 = load ptr, ptr %t97 - %t102 = call ptr @fn_str_concat(ptr @.str447, ptr %t101) - %t103 = call ptr @fn_str_concat(ptr %t102, ptr @.str448) + %t102 = call ptr @fn_str_concat(ptr @.str551, ptr %t101) + %t103 = call ptr @fn_str_concat(ptr %t102, ptr @.str552) %t104 = call ptr @fn_emit_bind(ptr %t103) store ptr %t104, ptr %t105 %t106 = load ptr, ptr %t94 - %t107 = call ptr @fn_str_concat(ptr @.str449, ptr %t106) - %t108 = call ptr @fn_str_concat(ptr %t107, ptr @.str450) + %t107 = call ptr @fn_str_concat(ptr @.str553, ptr %t106) + %t108 = call ptr @fn_str_concat(ptr %t107, ptr @.str554) %t109 = load ptr, ptr %t105 %t110 = call ptr @fn_str_concat(ptr %t108, ptr %t109) - %t111 = call ptr @fn_str_concat(ptr %t110, ptr @.str451) + %t111 = call ptr @fn_str_concat(ptr %t110, ptr @.str555) %t112 = load ptr, ptr %t100 %t113 = call ptr @fn_str_concat(ptr %t111, ptr %t112) - %t114 = call ptr @fn_str_concat(ptr %t113, ptr @.str452) + %t114 = call ptr @fn_str_concat(ptr %t113, ptr @.str556) %t115 = call ptr @fn_emit_bind(ptr %t114) - %t116 = call ptr @fn_val(ptr %t115, ptr @.str453) + %t116 = call ptr @fn_val(ptr %t115, ptr @.str557) store ptr %t116, ptr %retval br label %ret ifend16: %t117 = load ptr, ptr %t0 - %t118 = call i32 @fn_str_eq(ptr %t117, ptr @.str454) + %t118 = call i32 @fn_str_eq(ptr %t117, ptr @.str558) %t119 = icmp ne i32 %t118, 0 br i1 %t119, label %then17, label %ifend19 then17: @@ -12472,108 +15596,108 @@ then17: %t121 = call ptr @fn_arg_code(ptr %t120, i32 0) store ptr %t121, ptr %t122 %t123 = load ptr, ptr %t122 - %t124 = call ptr @fn_str_concat(ptr @.str455, ptr %t123) - %t125 = call ptr @fn_str_concat(ptr %t124, ptr @.str456) + %t124 = call ptr @fn_str_concat(ptr @.str559, ptr %t123) + %t125 = call ptr @fn_str_concat(ptr %t124, ptr @.str560) %t126 = call ptr @fn_emit_bind(ptr %t125) store ptr %t126, ptr %t127 %t128 = load ptr, ptr %t127 - %t129 = call ptr @fn_str_concat(ptr @.str457, ptr %t128) - %t130 = call ptr @fn_str_concat(ptr %t129, ptr @.str458) + %t129 = call ptr @fn_str_concat(ptr @.str561, ptr %t128) + %t130 = call ptr @fn_str_concat(ptr %t129, ptr @.str562) %t131 = call ptr @fn_emit_bind(ptr %t130) - %t132 = call ptr @fn_val(ptr %t131, ptr @.str459) + %t132 = call ptr @fn_val(ptr %t131, ptr @.str563) store ptr %t132, ptr %retval br label %ret ifend19: %t133 = load ptr, ptr %t0 - %t134 = call i32 @fn_str_eq(ptr %t133, ptr @.str460) + %t134 = call i32 @fn_str_eq(ptr %t133, ptr @.str564) %t135 = icmp ne i32 %t134, 0 br i1 %t135, label %then20, label %ifend22 then20: %t136 = load ptr, ptr %t1 %t137 = call ptr @fn_arg_code(ptr %t136, i32 0) store ptr %t137, ptr %t138 - call void @fn_emit(ptr @.str461) + call void @fn_emit(ptr @.str565) %t139 = load ptr, ptr %t138 call void @fn_emit(ptr %t139) - call void @fn_emit(ptr @.str462) - %t140 = call ptr @fn_val(ptr @.str463, ptr @.str464) + call void @fn_emit(ptr @.str566) + %t140 = call ptr @fn_val(ptr @.str567, ptr @.str568) store ptr %t140, ptr %retval br label %ret ifend22: %t141 = load ptr, ptr %t0 - %t142 = call i32 @fn_str_eq(ptr %t141, ptr @.str465) + %t142 = call i32 @fn_str_eq(ptr %t141, ptr @.str569) %t143 = icmp ne i32 %t142, 0 br i1 %t143, label %then23, label %ifend25 then23: - %t144 = call ptr @fn_emit_bind(ptr @.str466) - %t145 = call ptr @fn_val(ptr %t144, ptr @.str467) + %t144 = call ptr @fn_emit_bind(ptr @.str570) + %t145 = call ptr @fn_val(ptr %t144, ptr @.str571) store ptr %t145, ptr %retval br label %ret ifend25: %t146 = load ptr, ptr %t0 - %t147 = call i32 @fn_str_eq(ptr %t146, ptr @.str468) + %t147 = call i32 @fn_str_eq(ptr %t146, ptr @.str572) %t148 = icmp ne i32 %t147, 0 br i1 %t148, label %then26, label %ifend28 then26: %t149 = load ptr, ptr %t1 %t150 = call ptr @fn_arg_code(ptr %t149, i32 0) store ptr %t150, ptr %t151 - %t152 = call ptr @fn_emit_bind(ptr @.str469) + %t152 = call ptr @fn_emit_bind(ptr @.str573) store ptr %t152, ptr %t153 %t154 = load ptr, ptr %t153 - %t155 = call ptr @fn_str_concat(ptr @.str470, ptr %t154) - %t156 = call ptr @fn_str_concat(ptr %t155, ptr @.str471) + %t155 = call ptr @fn_str_concat(ptr @.str574, ptr %t154) + %t156 = call ptr @fn_str_concat(ptr %t155, ptr @.str575) %t157 = load ptr, ptr %t151 %t158 = call ptr @fn_str_concat(ptr %t156, ptr %t157) %t159 = call ptr @fn_emit_bind(ptr %t158) store ptr %t159, ptr %t160 %t161 = load ptr, ptr %t160 - %t162 = call ptr @fn_str_concat(ptr @.str472, ptr %t161) + %t162 = call ptr @fn_str_concat(ptr @.str576, ptr %t161) %t163 = call ptr @fn_emit_bind(ptr %t162) - %t164 = call ptr @fn_val(ptr %t163, ptr @.str473) + %t164 = call ptr @fn_val(ptr %t163, ptr @.str577) store ptr %t164, ptr %retval br label %ret ifend28: %t165 = load ptr, ptr %t0 - %t166 = call i32 @fn_str_eq(ptr %t165, ptr @.str474) + %t166 = call i32 @fn_str_eq(ptr %t165, ptr @.str578) %t167 = icmp ne i32 %t166, 0 br i1 %t167, label %then29, label %ifend31 then29: %t168 = load ptr, ptr %t1 %t169 = call ptr @fn_arg_code(ptr %t168, i32 0) store ptr %t169, ptr %t170 - call void @fn_emit(ptr @.str475) + call void @fn_emit(ptr @.str579) %t171 = load ptr, ptr %t170 call void @fn_emit(ptr %t171) - call void @fn_emit(ptr @.str476) - call void @fn_emit(ptr @.str477) + call void @fn_emit(ptr @.str580) + call void @fn_emit(ptr @.str581) store i32 1, ptr @g_g_term - %t172 = call ptr @fn_val(ptr @.str478, ptr @.str479) + %t172 = call ptr @fn_val(ptr @.str582, ptr @.str583) store ptr %t172, ptr %retval br label %ret ifend31: %t173 = load ptr, ptr %t0 - %t174 = call i32 @fn_str_eq(ptr %t173, ptr @.str480) + %t174 = call i32 @fn_str_eq(ptr %t173, ptr @.str584) %t175 = icmp ne i32 %t174, 0 br i1 %t175, label %then32, label %ifend34 then32: - %t176 = call ptr @fn_emit_bind(ptr @.str481) - %t177 = call ptr @fn_val(ptr %t176, ptr @.str482) + %t176 = call ptr @fn_emit_bind(ptr @.str585) + %t177 = call ptr @fn_val(ptr %t176, ptr @.str586) store ptr %t177, ptr %retval br label %ret ifend34: %t178 = load ptr, ptr %t0 - %t179 = call i32 @fn_str_eq(ptr %t178, ptr @.str483) + %t179 = call i32 @fn_str_eq(ptr %t178, ptr @.str587) %t180 = icmp ne i32 %t179, 0 br i1 %t180, label %then35, label %ifend37 then35: - %t181 = call ptr @fn_emit_bind(ptr @.str484) - %t182 = call ptr @fn_val(ptr %t181, ptr @.str485) + %t181 = call ptr @fn_emit_bind(ptr @.str588) + %t182 = call ptr @fn_val(ptr %t181, ptr @.str589) store ptr %t182, ptr %retval br label %ret ifend37: %t183 = load ptr, ptr %t0 - %t184 = call i32 @fn_str_eq(ptr %t183, ptr @.str486) + %t184 = call i32 @fn_str_eq(ptr %t183, ptr @.str590) %t185 = icmp ne i32 %t184, 0 br i1 %t185, label %then38, label %ifend40 then38: @@ -12581,15 +15705,15 @@ then38: %t187 = call ptr @fn_arg_code(ptr %t186, i32 0) store ptr %t187, ptr %t188 %t189 = load ptr, ptr %t188 - %t190 = call ptr @fn_str_concat(ptr @.str487, ptr %t189) - %t191 = call ptr @fn_str_concat(ptr %t190, ptr @.str488) + %t190 = call ptr @fn_str_concat(ptr @.str591, ptr %t189) + %t191 = call ptr @fn_str_concat(ptr %t190, ptr @.str592) %t192 = call ptr @fn_emit_bind(ptr %t191) - %t193 = call ptr @fn_val(ptr %t192, ptr @.str489) + %t193 = call ptr @fn_val(ptr %t192, ptr @.str593) store ptr %t193, ptr %retval br label %ret ifend40: %t194 = load ptr, ptr %t0 - %t195 = call i32 @fn_str_eq(ptr %t194, ptr @.str490) + %t195 = call i32 @fn_str_eq(ptr %t194, ptr @.str594) %t196 = icmp ne i32 %t195, 0 br i1 %t196, label %then41, label %ifend43 then41: @@ -12597,15 +15721,15 @@ then41: %t198 = call ptr @fn_arg_code(ptr %t197, i32 0) store ptr %t198, ptr %t199 %t200 = load ptr, ptr %t199 - %t201 = call ptr @fn_str_concat(ptr @.str491, ptr %t200) - %t202 = call ptr @fn_str_concat(ptr %t201, ptr @.str492) + %t201 = call ptr @fn_str_concat(ptr @.str595, ptr %t200) + %t202 = call ptr @fn_str_concat(ptr %t201, ptr @.str596) %t203 = call ptr @fn_emit_bind(ptr %t202) - %t204 = call ptr @fn_val(ptr %t203, ptr @.str493) + %t204 = call ptr @fn_val(ptr %t203, ptr @.str597) store ptr %t204, ptr %retval br label %ret ifend43: store i32 0, ptr @g_g_intrin_ok - %t205 = call ptr @fn_val(ptr @.str494, ptr @.str495) + %t205 = call ptr @fn_val(ptr @.str598, ptr @.str599) store ptr %t205, ptr %retval br label %ret ret: @@ -12626,14 +15750,14 @@ entry: %t64 = alloca i32 store ptr %arg_name, ptr %t0 %t2 = load ptr, ptr %t0 - %t3 = call i32 @fn_str_eq(ptr %t2, ptr @.str496) + %t3 = call i32 @fn_str_eq(ptr %t2, ptr @.str600) %t4 = icmp ne i32 %t3, 0 %t5 = zext i1 %t4 to i32 store i32 %t5, ptr %t1 br i1 %t4, label %scend1, label %sc0 sc0: %t6 = load ptr, ptr %t0 - %t7 = call i32 @fn_str_eq(ptr %t6, ptr @.str497) + %t7 = call i32 @fn_str_eq(ptr %t6, ptr @.str601) %t8 = icmp ne i32 %t7, 0 %t9 = zext i1 %t8 to i32 store i32 %t9, ptr %t1 @@ -12647,14 +15771,14 @@ then2: br label %ret ifend4: %t13 = load ptr, ptr %t0 - %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str498) + %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str602) %t15 = icmp ne i32 %t14, 0 %t16 = zext i1 %t15 to i32 store i32 %t16, ptr %t12 br i1 %t15, label %scend6, label %sc5 sc5: %t17 = load ptr, ptr %t0 - %t18 = call i32 @fn_str_eq(ptr %t17, ptr @.str499) + %t18 = call i32 @fn_str_eq(ptr %t17, ptr @.str603) %t19 = icmp ne i32 %t18, 0 %t20 = zext i1 %t19 to i32 store i32 %t20, ptr %t12 @@ -12668,14 +15792,14 @@ then7: br label %ret ifend9: %t24 = load ptr, ptr %t0 - %t25 = call i32 @fn_str_eq(ptr %t24, ptr @.str500) + %t25 = call i32 @fn_str_eq(ptr %t24, ptr @.str604) %t26 = icmp ne i32 %t25, 0 %t27 = zext i1 %t26 to i32 store i32 %t27, ptr %t23 br i1 %t26, label %scend11, label %sc10 sc10: %t28 = load ptr, ptr %t0 - %t29 = call i32 @fn_str_eq(ptr %t28, ptr @.str501) + %t29 = call i32 @fn_str_eq(ptr %t28, ptr @.str605) %t30 = icmp ne i32 %t29, 0 %t31 = zext i1 %t30 to i32 store i32 %t31, ptr %t23 @@ -12689,14 +15813,14 @@ then12: br label %ret ifend14: %t35 = load ptr, ptr %t0 - %t36 = call i32 @fn_str_eq(ptr %t35, ptr @.str502) + %t36 = call i32 @fn_str_eq(ptr %t35, ptr @.str606) %t37 = icmp ne i32 %t36, 0 %t38 = zext i1 %t37 to i32 store i32 %t38, ptr %t34 br i1 %t37, label %scend16, label %sc15 sc15: %t39 = load ptr, ptr %t0 - %t40 = call i32 @fn_str_eq(ptr %t39, ptr @.str503) + %t40 = call i32 @fn_str_eq(ptr %t39, ptr @.str607) %t41 = icmp ne i32 %t40, 0 %t42 = zext i1 %t41 to i32 store i32 %t42, ptr %t34 @@ -12710,14 +15834,14 @@ then17: br label %ret ifend19: %t47 = load ptr, ptr %t0 - %t48 = call i32 @fn_str_eq(ptr %t47, ptr @.str504) + %t48 = call i32 @fn_str_eq(ptr %t47, ptr @.str608) %t49 = icmp ne i32 %t48, 0 %t50 = zext i1 %t49 to i32 store i32 %t50, ptr %t46 br i1 %t49, label %scend21, label %sc20 sc20: %t51 = load ptr, ptr %t0 - %t52 = call i32 @fn_str_eq(ptr %t51, ptr @.str505) + %t52 = call i32 @fn_str_eq(ptr %t51, ptr @.str609) %t53 = icmp ne i32 %t52, 0 %t54 = zext i1 %t53 to i32 store i32 %t54, ptr %t46 @@ -12730,7 +15854,7 @@ scend21: br i1 %t56, label %scend23, label %sc22 sc22: %t58 = load ptr, ptr %t0 - %t59 = call i32 @fn_str_eq(ptr %t58, ptr @.str506) + %t59 = call i32 @fn_str_eq(ptr %t58, ptr @.str610) %t60 = icmp ne i32 %t59, 0 %t61 = zext i1 %t60 to i32 store i32 %t61, ptr %t45 @@ -12744,14 +15868,14 @@ then24: br label %ret ifend26: %t65 = load ptr, ptr %t0 - %t66 = call i32 @fn_str_eq(ptr %t65, ptr @.str507) + %t66 = call i32 @fn_str_eq(ptr %t65, ptr @.str611) %t67 = icmp ne i32 %t66, 0 %t68 = zext i1 %t67 to i32 store i32 %t68, ptr %t64 br i1 %t67, label %scend28, label %sc27 sc27: %t69 = load ptr, ptr %t0 - %t70 = call i32 @fn_str_eq(ptr %t69, ptr @.str508) + %t70 = call i32 @fn_str_eq(ptr %t69, ptr @.str612) %t71 = icmp ne i32 %t70, 0 %t72 = zext i1 %t71 to i32 store i32 %t72, ptr %t64 @@ -12796,23 +15920,23 @@ entry: store ptr %arg_name, ptr %t0 store ptr %arg_e, ptr %t1 %t2 = load ptr, ptr %t0 - %t3 = call i32 @fn_str_eq(ptr %t2, ptr @.str509) + %t3 = call i32 @fn_str_eq(ptr %t2, ptr @.str613) %t4 = icmp ne i32 %t3, 0 br i1 %t4, label %then0, label %ifend2 then0: %t5 = load ptr, ptr %t1 %t6 = call ptr @fn_arg_code(ptr %t5, i32 0) store ptr %t6, ptr %t7 - call void @fn_emit(ptr @.str510) + call void @fn_emit(ptr @.str614) %t8 = load ptr, ptr %t7 call void @fn_emit(ptr %t8) - call void @fn_emit(ptr @.str511) - %t9 = call ptr @fn_val(ptr @.str512, ptr @.str513) + call void @fn_emit(ptr @.str615) + %t9 = call ptr @fn_val(ptr @.str616, ptr @.str617) store ptr %t9, ptr %retval br label %ret ifend2: %t10 = load ptr, ptr %t0 - %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str514) + %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str618) %t12 = icmp ne i32 %t11, 0 br i1 %t12, label %then3, label %ifend5 then3: @@ -12826,26 +15950,26 @@ then3: %t20 = call ptr @fn_arg_code(ptr %t19, i32 2) store ptr %t20, ptr %t21 %t22 = load ptr, ptr %t21 - %t23 = call ptr @fn_str_concat(ptr @.str515, ptr %t22) - %t24 = call ptr @fn_str_concat(ptr %t23, ptr @.str516) + %t23 = call ptr @fn_str_concat(ptr @.str619, ptr %t22) + %t24 = call ptr @fn_str_concat(ptr %t23, ptr @.str620) %t25 = call ptr @fn_emit_bind(ptr %t24) store ptr %t25, ptr %t26 - call void @fn_emit(ptr @.str517) + call void @fn_emit(ptr @.str621) %t27 = load ptr, ptr %t15 call void @fn_emit(ptr %t27) - call void @fn_emit(ptr @.str518) + call void @fn_emit(ptr @.str622) %t28 = load ptr, ptr %t18 call void @fn_emit(ptr %t28) - call void @fn_emit(ptr @.str519) + call void @fn_emit(ptr @.str623) %t29 = load ptr, ptr %t26 call void @fn_emit(ptr %t29) - call void @fn_emit(ptr @.str520) - %t30 = call ptr @fn_val(ptr @.str521, ptr @.str522) + call void @fn_emit(ptr @.str624) + %t30 = call ptr @fn_val(ptr @.str625, ptr @.str626) store ptr %t30, ptr %retval br label %ret ifend5: %t31 = load ptr, ptr %t0 - %t32 = call i32 @fn_str_eq(ptr %t31, ptr @.str523) + %t32 = call i32 @fn_str_eq(ptr %t31, ptr @.str627) %t33 = icmp ne i32 %t32, 0 br i1 %t33, label %then6, label %ifend8 then6: @@ -12857,33 +15981,33 @@ then6: store ptr %t38, ptr %t39 %t40 = call ptr @fn_nreg() store ptr %t40, ptr %t41 - call void @fn_emit(ptr @.str524) + call void @fn_emit(ptr @.str628) %t42 = load ptr, ptr %t41 call void @fn_emit(ptr %t42) - call void @fn_emit(ptr @.str525) + call void @fn_emit(ptr @.str629) %t43 = load ptr, ptr %t36 call void @fn_emit(ptr %t43) - call void @fn_emit(ptr @.str526) + call void @fn_emit(ptr @.str630) %t44 = load ptr, ptr %t39 call void @fn_emit(ptr %t44) - call void @fn_emit(ptr @.str527) + call void @fn_emit(ptr @.str631) %t45 = load ptr, ptr %t41 - %t46 = call ptr @fn_val(ptr %t45, ptr @.str528) + %t46 = call ptr @fn_val(ptr %t45, ptr @.str632) store ptr %t46, ptr %retval br label %ret ifend8: %t47 = load ptr, ptr %t0 - %t48 = call i32 @fn_str_eq(ptr %t47, ptr @.str529) + %t48 = call i32 @fn_str_eq(ptr %t47, ptr @.str633) %t49 = icmp ne i32 %t48, 0 br i1 %t49, label %then9, label %ifend11 then9: - %t50 = call ptr @fn_emit_bind(ptr @.str530) - %t51 = call ptr @fn_val(ptr %t50, ptr @.str531) + %t50 = call ptr @fn_emit_bind(ptr @.str634) + %t51 = call ptr @fn_val(ptr %t50, ptr @.str635) store ptr %t51, ptr %retval br label %ret ifend11: %t52 = load ptr, ptr %t0 - %t53 = call i32 @fn_str_eq(ptr %t52, ptr @.str532) + %t53 = call i32 @fn_str_eq(ptr %t52, ptr @.str636) %t54 = icmp ne i32 %t53, 0 br i1 %t54, label %then12, label %ifend14 then12: @@ -12899,12 +16023,12 @@ then12: %t64 = load ptr, ptr %t63 %t65 = getelementptr inbounds %Cmp_Val, ptr %t64, i32 0, i32 0 %t66 = load ptr, ptr %t65 - %t67 = call ptr @fn_val(ptr %t66, ptr @.str533) + %t67 = call ptr @fn_val(ptr %t66, ptr @.str637) store ptr %t67, ptr %retval br label %ret ifend14: %t68 = load ptr, ptr %t0 - %t69 = call i32 @fn_str_eq(ptr %t68, ptr @.str534) + %t69 = call i32 @fn_str_eq(ptr %t68, ptr @.str638) %t70 = icmp ne i32 %t69, 0 br i1 %t70, label %then15, label %ifend17 then15: @@ -12920,12 +16044,12 @@ then15: %t80 = load ptr, ptr %t79 %t81 = getelementptr inbounds %Cmp_Val, ptr %t80, i32 0, i32 0 %t82 = load ptr, ptr %t81 - %t83 = call ptr @fn_val(ptr %t82, ptr @.str535) + %t83 = call ptr @fn_val(ptr %t82, ptr @.str639) store ptr %t83, ptr %retval br label %ret ifend17: %t84 = load ptr, ptr %t0 - %t85 = call i32 @fn_str_eq(ptr %t84, ptr @.str536) + %t85 = call i32 @fn_str_eq(ptr %t84, ptr @.str640) %t86 = icmp ne i32 %t85, 0 br i1 %t86, label %then18, label %ifend20 then18: @@ -12933,45 +16057,45 @@ then18: %t88 = icmp ne i32 %t87, 0 br i1 %t88, label %then21, label %ifend23 then21: - %t89 = call ptr @fn_val(ptr @.str537, ptr @.str538) + %t89 = call ptr @fn_val(ptr @.str641, ptr @.str642) store ptr %t89, ptr %retval br label %ret ifend23: - %t90 = call ptr @fn_val(ptr @.str539, ptr @.str540) + %t90 = call ptr @fn_val(ptr @.str643, ptr @.str644) store ptr %t90, ptr %retval br label %ret ifend20: %t91 = load ptr, ptr %t0 - %t92 = call i32 @fn_str_eq(ptr %t91, ptr @.str541) + %t92 = call i32 @fn_str_eq(ptr %t91, ptr @.str645) %t93 = icmp ne i32 %t92, 0 br i1 %t93, label %then24, label %ifend26 then24: - %t94 = call ptr @fn_val(ptr @.str542, ptr @.str543) + %t94 = call ptr @fn_val(ptr @.str646, ptr @.str647) store ptr %t94, ptr %retval br label %ret ifend26: %t95 = load ptr, ptr %t0 - %t96 = call i32 @fn_str_eq(ptr %t95, ptr @.str544) + %t96 = call i32 @fn_str_eq(ptr %t95, ptr @.str648) %t97 = icmp ne i32 %t96, 0 br i1 %t97, label %then27, label %ifend29 then27: - %t98 = call ptr @fn_emit_bind(ptr @.str545) - %t99 = call ptr @fn_val(ptr %t98, ptr @.str546) + %t98 = call ptr @fn_emit_bind(ptr @.str649) + %t99 = call ptr @fn_val(ptr %t98, ptr @.str650) store ptr %t99, ptr %retval br label %ret ifend29: %t100 = load ptr, ptr %t0 - %t101 = call i32 @fn_str_eq(ptr %t100, ptr @.str547) + %t101 = call i32 @fn_str_eq(ptr %t100, ptr @.str651) %t102 = icmp ne i32 %t101, 0 br i1 %t102, label %then30, label %ifend32 then30: - %t103 = call ptr @fn_emit_bind(ptr @.str548) - %t104 = call ptr @fn_val(ptr %t103, ptr @.str549) + %t103 = call ptr @fn_emit_bind(ptr @.str652) + %t104 = call ptr @fn_val(ptr %t103, ptr @.str653) store ptr %t104, ptr %retval br label %ret ifend32: %t105 = load ptr, ptr %t0 - %t106 = call i32 @fn_str_eq(ptr %t105, ptr @.str550) + %t106 = call i32 @fn_str_eq(ptr %t105, ptr @.str654) %t107 = icmp ne i32 %t106, 0 br i1 %t107, label %then33, label %ifend35 then33: @@ -12987,25 +16111,25 @@ then33: %t117 = load ptr, ptr %t1 %t118 = call ptr @fn_arg_code(ptr %t117, i32 3) store ptr %t118, ptr %t119 - call void @fn_emit(ptr @.str551) + call void @fn_emit(ptr @.str655) %t120 = load ptr, ptr %t110 call void @fn_emit(ptr %t120) - call void @fn_emit(ptr @.str552) + call void @fn_emit(ptr @.str656) %t121 = load ptr, ptr %t113 call void @fn_emit(ptr %t121) - call void @fn_emit(ptr @.str553) + call void @fn_emit(ptr @.str657) %t122 = load ptr, ptr %t116 call void @fn_emit(ptr %t122) - call void @fn_emit(ptr @.str554) + call void @fn_emit(ptr @.str658) %t123 = load ptr, ptr %t119 call void @fn_emit(ptr %t123) - call void @fn_emit(ptr @.str555) - %t124 = call ptr @fn_val(ptr @.str556, ptr @.str557) + call void @fn_emit(ptr @.str659) + %t124 = call ptr @fn_val(ptr @.str660, ptr @.str661) store ptr %t124, ptr %retval br label %ret ifend35: %t125 = load ptr, ptr %t0 - %t126 = call i32 @fn_str_eq(ptr %t125, ptr @.str558) + %t126 = call i32 @fn_str_eq(ptr %t125, ptr @.str662) %t127 = icmp ne i32 %t126, 0 br i1 %t127, label %then36, label %ifend38 then36: @@ -13018,31 +16142,31 @@ then36: %t134 = load ptr, ptr %t1 %t135 = call ptr @fn_arg_code(ptr %t134, i32 2) store ptr %t135, ptr %t136 - call void @fn_emit(ptr @.str559) + call void @fn_emit(ptr @.str663) %t137 = load ptr, ptr %t130 call void @fn_emit(ptr %t137) - call void @fn_emit(ptr @.str560) + call void @fn_emit(ptr @.str664) %t138 = load ptr, ptr %t133 call void @fn_emit(ptr %t138) - call void @fn_emit(ptr @.str561) + call void @fn_emit(ptr @.str665) %t139 = load ptr, ptr %t136 call void @fn_emit(ptr %t139) - call void @fn_emit(ptr @.str562) - %t140 = call ptr @fn_val(ptr @.str563, ptr @.str564) + call void @fn_emit(ptr @.str666) + %t140 = call ptr @fn_val(ptr @.str667, ptr @.str668) store ptr %t140, ptr %retval br label %ret ifend38: %t141 = load ptr, ptr %t0 - %t142 = call i32 @fn_str_eq(ptr %t141, ptr @.str565) + %t142 = call i32 @fn_str_eq(ptr %t141, ptr @.str669) %t143 = icmp ne i32 %t142, 0 br i1 %t143, label %then39, label %ifend41 then39: - call void @fn_emit(ptr @.str566) - %t144 = call ptr @fn_val(ptr @.str567, ptr @.str568) + call void @fn_emit(ptr @.str670) + %t144 = call ptr @fn_val(ptr @.str671, ptr @.str672) store ptr %t144, ptr %retval br label %ret ifend41: - %t145 = call ptr @fn_val(ptr @.str569, ptr @.str570) + %t145 = call ptr @fn_val(ptr @.str673, ptr @.str674) store ptr %t145, ptr %retval br label %ret ret: @@ -13059,14 +16183,14 @@ entry: %t3 = alloca i32 store ptr %arg_name, ptr %t0 %t4 = load ptr, ptr %t0 - %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str571) + %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str675) %t6 = icmp ne i32 %t5, 0 %t7 = zext i1 %t6 to i32 store i32 %t7, ptr %t3 br i1 %t6, label %scend1, label %sc0 sc0: %t8 = load ptr, ptr %t0 - %t9 = call i32 @fn_str_eq(ptr %t8, ptr @.str572) + %t9 = call i32 @fn_str_eq(ptr %t8, ptr @.str676) %t10 = icmp ne i32 %t9, 0 %t11 = zext i1 %t10 to i32 store i32 %t11, ptr %t3 @@ -13079,7 +16203,7 @@ scend1: br i1 %t13, label %scend3, label %sc2 sc2: %t15 = load ptr, ptr %t0 - %t16 = call i32 @fn_str_eq(ptr %t15, ptr @.str573) + %t16 = call i32 @fn_str_eq(ptr %t15, ptr @.str677) %t17 = icmp ne i32 %t16, 0 %t18 = zext i1 %t17 to i32 store i32 %t18, ptr %t2 @@ -13092,7 +16216,7 @@ scend3: br i1 %t20, label %scend5, label %sc4 sc4: %t22 = load ptr, ptr %t0 - %t23 = call i32 @fn_str_eq(ptr %t22, ptr @.str574) + %t23 = call i32 @fn_str_eq(ptr %t22, ptr @.str678) %t24 = icmp ne i32 %t23, 0 %t25 = zext i1 %t24 to i32 store i32 %t25, ptr %t1 @@ -13128,7 +16252,7 @@ entry: store ptr %arg_name, ptr %t0 store ptr %arg_e, ptr %t1 %t2 = load ptr, ptr %t0 - %t3 = call i32 @fn_str_eq(ptr %t2, ptr @.str575) + %t3 = call i32 @fn_str_eq(ptr %t2, ptr @.str679) %t4 = icmp ne i32 %t3, 0 br i1 %t4, label %then0, label %ifend2 then0: @@ -13144,40 +16268,40 @@ then0: %t14 = load ptr, ptr %t13 %t15 = getelementptr inbounds %Cmp_Val, ptr %t14, i32 0, i32 0 %t16 = load ptr, ptr %t15 - %t17 = call ptr @fn_str_concat(ptr @.str576, ptr %t16) - %t18 = call ptr @fn_str_concat(ptr %t17, ptr @.str577) + %t17 = call ptr @fn_str_concat(ptr @.str680, ptr %t16) + %t18 = call ptr @fn_str_concat(ptr %t17, ptr @.str681) %t19 = call ptr @fn_emit_bind(ptr %t18) store ptr %t19, ptr %t20 %t21 = load ptr, ptr %t13 %t22 = getelementptr inbounds %Cmp_Val, ptr %t21, i32 0, i32 0 %t23 = load ptr, ptr %t22 - %t24 = call ptr @fn_str_concat(ptr @.str578, ptr %t23) + %t24 = call ptr @fn_str_concat(ptr @.str682, ptr %t23) %t25 = call ptr @fn_emit_bind(ptr %t24) store ptr %t25, ptr %t26 %t27 = load ptr, ptr %t20 - %t28 = call ptr @fn_str_concat(ptr @.str579, ptr %t27) - %t29 = call ptr @fn_str_concat(ptr %t28, ptr @.str580) + %t28 = call ptr @fn_str_concat(ptr @.str683, ptr %t27) + %t29 = call ptr @fn_str_concat(ptr %t28, ptr @.str684) %t30 = load ptr, ptr %t26 %t31 = call ptr @fn_str_concat(ptr %t29, ptr %t30) - %t32 = call ptr @fn_str_concat(ptr %t31, ptr @.str581) + %t32 = call ptr @fn_str_concat(ptr %t31, ptr @.str685) %t33 = load ptr, ptr %t13 %t34 = getelementptr inbounds %Cmp_Val, ptr %t33, i32 0, i32 0 %t35 = load ptr, ptr %t34 %t36 = call ptr @fn_str_concat(ptr %t32, ptr %t35) %t37 = call ptr @fn_emit_bind(ptr %t36) - %t38 = call ptr @fn_val(ptr %t37, ptr @.str582) + %t38 = call ptr @fn_val(ptr %t37, ptr @.str686) store ptr %t38, ptr %retval br label %ret ifend2: %t40 = load ptr, ptr %t0 - %t41 = call i32 @fn_str_eq(ptr %t40, ptr @.str583) + %t41 = call i32 @fn_str_eq(ptr %t40, ptr @.str687) %t42 = icmp ne i32 %t41, 0 %t43 = zext i1 %t42 to i32 store i32 %t43, ptr %t39 br i1 %t42, label %scend4, label %sc3 sc3: %t44 = load ptr, ptr %t0 - %t45 = call i32 @fn_str_eq(ptr %t44, ptr @.str584) + %t45 = call i32 @fn_str_eq(ptr %t44, ptr @.str688) %t46 = icmp ne i32 %t45, 0 %t47 = zext i1 %t46 to i32 store i32 %t47, ptr %t39 @@ -13205,23 +16329,23 @@ then5: %t65 = load ptr, ptr %t64 %t66 = call ptr @fn_emit_expr(ptr %t65) store ptr %t66, ptr %t67 - store ptr @.str585, ptr %t68 + store ptr @.str689, ptr %t68 %t69 = load ptr, ptr %t0 - %t70 = call i32 @fn_str_eq(ptr %t69, ptr @.str586) + %t70 = call i32 @fn_str_eq(ptr %t69, ptr @.str690) %t71 = icmp ne i32 %t70, 0 br i1 %t71, label %then8, label %ifend10 then8: - store ptr @.str587, ptr %t68 + store ptr @.str691, ptr %t68 br label %ifend10 ifend10: %t72 = load ptr, ptr %t68 - %t73 = call ptr @fn_str_concat(ptr @.str588, ptr %t72) - %t74 = call ptr @fn_str_concat(ptr %t73, ptr @.str589) + %t73 = call ptr @fn_str_concat(ptr @.str692, ptr %t72) + %t74 = call ptr @fn_str_concat(ptr %t73, ptr @.str693) %t75 = load ptr, ptr %t58 %t76 = getelementptr inbounds %Cmp_Val, ptr %t75, i32 0, i32 0 %t77 = load ptr, ptr %t76 %t78 = call ptr @fn_str_concat(ptr %t74, ptr %t77) - %t79 = call ptr @fn_str_concat(ptr %t78, ptr @.str590) + %t79 = call ptr @fn_str_concat(ptr %t78, ptr @.str694) %t80 = load ptr, ptr %t67 %t81 = getelementptr inbounds %Cmp_Val, ptr %t80, i32 0, i32 0 %t82 = load ptr, ptr %t81 @@ -13229,19 +16353,19 @@ ifend10: %t84 = call ptr @fn_emit_bind(ptr %t83) store ptr %t84, ptr %t85 %t86 = load ptr, ptr %t85 - %t87 = call ptr @fn_str_concat(ptr @.str591, ptr %t86) - %t88 = call ptr @fn_str_concat(ptr %t87, ptr @.str592) + %t87 = call ptr @fn_str_concat(ptr @.str695, ptr %t86) + %t88 = call ptr @fn_str_concat(ptr %t87, ptr @.str696) %t89 = load ptr, ptr %t58 %t90 = getelementptr inbounds %Cmp_Val, ptr %t89, i32 0, i32 0 %t91 = load ptr, ptr %t90 %t92 = call ptr @fn_str_concat(ptr %t88, ptr %t91) - %t93 = call ptr @fn_str_concat(ptr %t92, ptr @.str593) + %t93 = call ptr @fn_str_concat(ptr %t92, ptr @.str697) %t94 = load ptr, ptr %t67 %t95 = getelementptr inbounds %Cmp_Val, ptr %t94, i32 0, i32 0 %t96 = load ptr, ptr %t95 %t97 = call ptr @fn_str_concat(ptr %t93, ptr %t96) %t98 = call ptr @fn_emit_bind(ptr %t97) - %t99 = call ptr @fn_val(ptr %t98, ptr @.str594) + %t99 = call ptr @fn_val(ptr %t98, ptr @.str698) store ptr %t99, ptr %retval br label %ret ifend7: @@ -13275,8 +16399,8 @@ ifend7: %t127 = load ptr, ptr %t108 %t128 = getelementptr inbounds %Cmp_Val, ptr %t127, i32 0, i32 0 %t129 = load ptr, ptr %t128 - %t130 = call ptr @fn_str_concat(ptr @.str595, ptr %t129) - %t131 = call ptr @fn_str_concat(ptr %t130, ptr @.str596) + %t130 = call ptr @fn_str_concat(ptr @.str699, ptr %t129) + %t131 = call ptr @fn_str_concat(ptr %t130, ptr @.str700) %t132 = load ptr, ptr %t126 %t133 = getelementptr inbounds %Cmp_Val, ptr %t132, i32 0, i32 0 %t134 = load ptr, ptr %t133 @@ -13284,13 +16408,13 @@ ifend7: %t136 = call ptr @fn_emit_bind(ptr %t135) store ptr %t136, ptr %t137 %t138 = load ptr, ptr %t137 - %t139 = call ptr @fn_str_concat(ptr @.str597, ptr %t138) - %t140 = call ptr @fn_str_concat(ptr %t139, ptr @.str598) + %t139 = call ptr @fn_str_concat(ptr @.str701, ptr %t138) + %t140 = call ptr @fn_str_concat(ptr %t139, ptr @.str702) %t141 = load ptr, ptr %t108 %t142 = getelementptr inbounds %Cmp_Val, ptr %t141, i32 0, i32 0 %t143 = load ptr, ptr %t142 %t144 = call ptr @fn_str_concat(ptr %t140, ptr %t143) - %t145 = call ptr @fn_str_concat(ptr %t144, ptr @.str599) + %t145 = call ptr @fn_str_concat(ptr %t144, ptr @.str703) %t146 = load ptr, ptr %t126 %t147 = getelementptr inbounds %Cmp_Val, ptr %t146, i32 0, i32 0 %t148 = load ptr, ptr %t147 @@ -13300,24 +16424,24 @@ ifend7: %t152 = load ptr, ptr %t117 %t153 = getelementptr inbounds %Cmp_Val, ptr %t152, i32 0, i32 0 %t154 = load ptr, ptr %t153 - %t155 = call ptr @fn_str_concat(ptr @.str600, ptr %t154) - %t156 = call ptr @fn_str_concat(ptr %t155, ptr @.str601) + %t155 = call ptr @fn_str_concat(ptr @.str704, ptr %t154) + %t156 = call ptr @fn_str_concat(ptr %t155, ptr @.str705) %t157 = load ptr, ptr %t151 %t158 = call ptr @fn_str_concat(ptr %t156, ptr %t157) %t159 = call ptr @fn_emit_bind(ptr %t158) store ptr %t159, ptr %t160 %t161 = load ptr, ptr %t160 - %t162 = call ptr @fn_str_concat(ptr @.str602, ptr %t161) - %t163 = call ptr @fn_str_concat(ptr %t162, ptr @.str603) + %t162 = call ptr @fn_str_concat(ptr @.str706, ptr %t161) + %t163 = call ptr @fn_str_concat(ptr %t162, ptr @.str707) %t164 = load ptr, ptr %t117 %t165 = getelementptr inbounds %Cmp_Val, ptr %t164, i32 0, i32 0 %t166 = load ptr, ptr %t165 %t167 = call ptr @fn_str_concat(ptr %t163, ptr %t166) - %t168 = call ptr @fn_str_concat(ptr %t167, ptr @.str604) + %t168 = call ptr @fn_str_concat(ptr %t167, ptr @.str708) %t169 = load ptr, ptr %t151 %t170 = call ptr @fn_str_concat(ptr %t168, ptr %t169) %t171 = call ptr @fn_emit_bind(ptr %t170) - %t172 = call ptr @fn_val(ptr %t171, ptr @.str605) + %t172 = call ptr @fn_val(ptr %t171, ptr @.str709) store ptr %t172, ptr %retval br label %ret ret: @@ -13332,13 +16456,13 @@ entry: %t5 = alloca ptr store ptr %arg_llt, ptr %t0 %t1 = load ptr, ptr %t0 - %t2 = call ptr @fn_str_concat(ptr @.str606, ptr %t1) - %t3 = call ptr @fn_str_concat(ptr %t2, ptr @.str607) + %t2 = call ptr @fn_str_concat(ptr @.str710, ptr %t1) + %t3 = call ptr @fn_str_concat(ptr %t2, ptr @.str711) %t4 = call ptr @fn_emit_bind(ptr %t3) store ptr %t4, ptr %t5 %t6 = load ptr, ptr %t5 - %t7 = call ptr @fn_str_concat(ptr @.str608, ptr %t6) - %t8 = call ptr @fn_str_concat(ptr %t7, ptr @.str609) + %t7 = call ptr @fn_str_concat(ptr @.str712, ptr %t6) + %t8 = call ptr @fn_str_concat(ptr %t7, ptr @.str713) %t9 = call ptr @fn_emit_bind(ptr %t8) store ptr %t9, ptr %retval br label %ret @@ -13371,7 +16495,7 @@ entry: %t7 = icmp ne i32 %t6, 0 br i1 %t7, label %then0, label %ifend2 then0: - call void @fn_perr(ptr @.str610) + call void @fn_perr(ptr @.str714) br label %ifend2 ifend2: %t8 = load ptr, ptr %t0 @@ -13381,8 +16505,8 @@ ifend2: %t12 = call ptr @fn_emit_sizeof(ptr %t11) store ptr %t12, ptr %t13 %t14 = load ptr, ptr %t13 - %t15 = call ptr @fn_str_concat(ptr @.str611, ptr %t14) - %t16 = call ptr @fn_str_concat(ptr %t15, ptr @.str612) + %t15 = call ptr @fn_str_concat(ptr @.str715, ptr %t14) + %t16 = call ptr @fn_str_concat(ptr %t15, ptr @.str716) %t17 = call ptr @fn_emit_bind(ptr %t16) store ptr %t17, ptr %t18 store i32 0, ptr %t19 @@ -13410,32 +16534,32 @@ wbody4: store ptr %t36, ptr %t37 %t38 = call ptr @fn_nreg() store ptr %t38, ptr %t39 - call void @fn_emit(ptr @.str613) + call void @fn_emit(ptr @.str717) %t40 = load ptr, ptr %t39 call void @fn_emit(ptr %t40) - call void @fn_emit(ptr @.str614) + call void @fn_emit(ptr @.str718) %t41 = load ptr, ptr %t10 call void @fn_emit(ptr %t41) - call void @fn_emit(ptr @.str615) + call void @fn_emit(ptr @.str719) %t42 = load ptr, ptr %t18 call void @fn_emit(ptr %t42) - call void @fn_emit(ptr @.str616) + call void @fn_emit(ptr @.str720) %t43 = load i32, ptr %t19 %t44 = call ptr @fn_itoa(i32 %t43) call void @fn_emit(ptr %t44) - call void @fn_emit(ptr @.str617) + call void @fn_emit(ptr @.str721) %t45 = load ptr, ptr %t37 %t46 = getelementptr inbounds %Cmp_Node, ptr %t45, i32 0, i32 3 %t47 = load ptr, ptr %t46 %t48 = call ptr @fn_llty(ptr %t47) store ptr %t48, ptr %t49 - store ptr @.str618, ptr %t50 + store ptr @.str722, ptr %t50 %t51 = load ptr, ptr %t49 - %t52 = call i32 @fn_str_eq(ptr %t51, ptr @.str619) + %t52 = call i32 @fn_str_eq(ptr %t51, ptr @.str723) %t53 = icmp ne i32 %t52, 0 br i1 %t53, label %then6, label %ifend8 then6: - store ptr @.str620, ptr %t50 + store ptr @.str724, ptr %t50 br label %ifend8 ifend8: %t54 = load ptr, ptr %t37 @@ -13457,16 +16581,16 @@ then9: store ptr %t67, ptr %t50 br label %ifend11 ifend11: - call void @fn_emit(ptr @.str621) + call void @fn_emit(ptr @.str725) %t68 = load ptr, ptr %t49 call void @fn_emit(ptr %t68) - call void @fn_emit(ptr @.str622) + call void @fn_emit(ptr @.str726) %t69 = load ptr, ptr %t50 call void @fn_emit(ptr %t69) - call void @fn_emit(ptr @.str623) + call void @fn_emit(ptr @.str727) %t70 = load ptr, ptr %t39 call void @fn_emit(ptr %t70) - call void @fn_emit(ptr @.str624) + call void @fn_emit(ptr @.str728) %t71 = load i32, ptr %t19 %t72 = add i32 %t71, 1 store i32 %t72, ptr %t19 @@ -13492,52 +16616,52 @@ entry: %t14 = alloca ptr %t19 = alloca ptr store ptr %arg_ty, ptr %t0 - %t1 = call ptr @fn_emit_sizeof(ptr @.str625) + %t1 = call ptr @fn_emit_sizeof(ptr @.str729) store ptr %t1, ptr %t2 %t3 = load ptr, ptr %t2 - %t4 = call ptr @fn_str_concat(ptr @.str626, ptr %t3) - %t5 = call ptr @fn_str_concat(ptr %t4, ptr @.str627) + %t4 = call ptr @fn_str_concat(ptr @.str730, ptr %t3) + %t5 = call ptr @fn_str_concat(ptr %t4, ptr @.str731) %t6 = call ptr @fn_emit_bind(ptr %t5) store ptr %t6, ptr %t7 %t8 = call ptr @fn_nreg() store ptr %t8, ptr %t9 - call void @fn_emit(ptr @.str628) + call void @fn_emit(ptr @.str732) %t10 = load ptr, ptr %t9 call void @fn_emit(ptr %t10) - call void @fn_emit(ptr @.str629) + call void @fn_emit(ptr @.str733) %t11 = load ptr, ptr %t7 call void @fn_emit(ptr %t11) - call void @fn_emit(ptr @.str630) - call void @fn_emit(ptr @.str631) + call void @fn_emit(ptr @.str734) + call void @fn_emit(ptr @.str735) %t12 = load ptr, ptr %t9 call void @fn_emit(ptr %t12) - call void @fn_emit(ptr @.str632) + call void @fn_emit(ptr @.str736) %t13 = call ptr @fn_nreg() store ptr %t13, ptr %t14 - call void @fn_emit(ptr @.str633) + call void @fn_emit(ptr @.str737) %t15 = load ptr, ptr %t14 call void @fn_emit(ptr %t15) - call void @fn_emit(ptr @.str634) + call void @fn_emit(ptr @.str738) %t16 = load ptr, ptr %t7 call void @fn_emit(ptr %t16) - call void @fn_emit(ptr @.str635) - call void @fn_emit(ptr @.str636) + call void @fn_emit(ptr @.str739) + call void @fn_emit(ptr @.str740) %t17 = load ptr, ptr %t14 call void @fn_emit(ptr %t17) - call void @fn_emit(ptr @.str637) + call void @fn_emit(ptr @.str741) %t18 = call ptr @fn_nreg() store ptr %t18, ptr %t19 - call void @fn_emit(ptr @.str638) + call void @fn_emit(ptr @.str742) %t20 = load ptr, ptr %t19 call void @fn_emit(ptr %t20) - call void @fn_emit(ptr @.str639) + call void @fn_emit(ptr @.str743) %t21 = load ptr, ptr %t7 call void @fn_emit(ptr %t21) - call void @fn_emit(ptr @.str640) - call void @fn_emit(ptr @.str641) + call void @fn_emit(ptr @.str744) + call void @fn_emit(ptr @.str745) %t22 = load ptr, ptr %t19 call void @fn_emit(ptr %t22) - call void @fn_emit(ptr @.str642) + call void @fn_emit(ptr @.str746) %t23 = load ptr, ptr %t7 %t24 = load ptr, ptr %t0 %t25 = call ptr @fn_val(ptr %t23, ptr %t24) @@ -13558,17 +16682,17 @@ entry: store i32 %arg_i, ptr %t1 %t2 = call ptr @fn_nreg() store ptr %t2, ptr %t3 - call void @fn_emit(ptr @.str643) + call void @fn_emit(ptr @.str747) %t4 = load ptr, ptr %t3 call void @fn_emit(ptr %t4) - call void @fn_emit(ptr @.str644) + call void @fn_emit(ptr @.str748) %t5 = load ptr, ptr %t0 call void @fn_emit(ptr %t5) - call void @fn_emit(ptr @.str645) + call void @fn_emit(ptr @.str749) %t6 = load i32, ptr %t1 %t7 = call ptr @fn_itoa(i32 %t6) call void @fn_emit(ptr %t7) - call void @fn_emit(ptr @.str646) + call void @fn_emit(ptr @.str750) %t8 = load ptr, ptr %t3 store ptr %t8, ptr %retval br label %ret @@ -13607,24 +16731,24 @@ then0: %t18 = call ptr @fn_slice_field(ptr %t17, i32 1) store ptr %t18, ptr %t19 %t20 = load ptr, ptr %t19 - %t21 = call ptr @fn_str_concat(ptr @.str647, ptr %t20) + %t21 = call ptr @fn_str_concat(ptr @.str751, ptr %t20) %t22 = call ptr @fn_emit_bind(ptr %t21) - %t23 = call ptr @fn_val(ptr %t22, ptr @.str648) + %t23 = call ptr @fn_val(ptr %t22, ptr @.str752) store ptr %t23, ptr %retval br label %ret ifend2: %t24 = load ptr, ptr %t9 %t25 = getelementptr inbounds %Cmp_Val, ptr %t24, i32 0, i32 0 %t26 = load ptr, ptr %t25 - %t27 = call ptr @fn_str_concat(ptr @.str649, ptr %t26) - %t28 = call ptr @fn_str_concat(ptr %t27, ptr @.str650) + %t27 = call ptr @fn_str_concat(ptr @.str753, ptr %t26) + %t28 = call ptr @fn_str_concat(ptr %t27, ptr @.str754) %t29 = call ptr @fn_emit_bind(ptr %t28) store ptr %t29, ptr %t30 %t31 = load ptr, ptr %t30 - %t32 = call ptr @fn_str_concat(ptr @.str651, ptr %t31) - %t33 = call ptr @fn_str_concat(ptr %t32, ptr @.str652) + %t32 = call ptr @fn_str_concat(ptr @.str755, ptr %t31) + %t33 = call ptr @fn_str_concat(ptr %t32, ptr @.str756) %t34 = call ptr @fn_emit_bind(ptr %t33) - %t35 = call ptr @fn_val(ptr %t34, ptr @.str653) + %t35 = call ptr @fn_val(ptr %t34, ptr @.str757) store ptr %t35, ptr %retval br label %ret ret: @@ -13692,50 +16816,50 @@ entry: %t29 = call ptr @fn_slice_field(ptr %t28, i32 0) store ptr %t29, ptr %t30 %t31 = load ptr, ptr %t24 - %t32 = call ptr @fn_str_concat(ptr @.str654, ptr %t31) + %t32 = call ptr @fn_str_concat(ptr @.str758, ptr %t31) %t33 = call ptr @fn_emit_bind(ptr %t32) store ptr %t33, ptr %t34 %t35 = load ptr, ptr %t27 - %t36 = call ptr @fn_str_concat(ptr @.str655, ptr %t35) + %t36 = call ptr @fn_str_concat(ptr @.str759, ptr %t35) %t37 = call ptr @fn_emit_bind(ptr %t36) store ptr %t37, ptr %t38 %t39 = load ptr, ptr %t34 - %t40 = call ptr @fn_str_concat(ptr @.str656, ptr %t39) - %t41 = call ptr @fn_str_concat(ptr %t40, ptr @.str657) + %t40 = call ptr @fn_str_concat(ptr @.str760, ptr %t39) + %t41 = call ptr @fn_str_concat(ptr %t40, ptr @.str761) %t42 = load ptr, ptr %t38 %t43 = call ptr @fn_str_concat(ptr %t41, ptr %t42) %t44 = call ptr @fn_emit_bind(ptr %t43) store ptr %t44, ptr %t45 - %t46 = call ptr @fn_lbl(ptr @.str658) + %t46 = call ptr @fn_lbl(ptr @.str762) store ptr %t46, ptr %t47 - %t48 = call ptr @fn_lbl(ptr @.str659) + %t48 = call ptr @fn_lbl(ptr @.str763) store ptr %t48, ptr %t49 - call void @fn_emit(ptr @.str660) + call void @fn_emit(ptr @.str764) %t50 = load ptr, ptr %t45 call void @fn_emit(ptr %t50) - call void @fn_emit(ptr @.str661) + call void @fn_emit(ptr @.str765) %t51 = load ptr, ptr %t47 call void @fn_emit(ptr %t51) - call void @fn_emit(ptr @.str662) + call void @fn_emit(ptr @.str766) %t52 = load ptr, ptr %t49 call void @fn_emit(ptr %t52) - call void @fn_emit(ptr @.str663) + call void @fn_emit(ptr @.str767) %t53 = load ptr, ptr %t47 call void @fn_emit(ptr %t53) - call void @fn_emit(ptr @.str664) + call void @fn_emit(ptr @.str768) %t54 = load ptr, ptr %t38 - %t55 = call ptr @fn_str_concat(ptr @.str665, ptr %t54) - %t56 = call ptr @fn_str_concat(ptr %t55, ptr @.str666) + %t55 = call ptr @fn_str_concat(ptr @.str769, ptr %t54) + %t56 = call ptr @fn_str_concat(ptr %t55, ptr @.str770) %t57 = call ptr @fn_emit_bind(ptr %t56) store ptr %t57, ptr %t58 %t59 = load ptr, ptr %t38 - %t60 = call ptr @fn_str_concat(ptr @.str667, ptr %t59) - %t61 = call ptr @fn_str_concat(ptr %t60, ptr @.str668) + %t60 = call ptr @fn_str_concat(ptr @.str771, ptr %t59) + %t61 = call ptr @fn_str_concat(ptr %t60, ptr @.str772) %t62 = call ptr @fn_emit_bind(ptr %t61) store ptr %t62, ptr %t63 %t64 = load ptr, ptr %t63 - %t65 = call ptr @fn_str_concat(ptr @.str669, ptr %t64) - %t66 = call ptr @fn_str_concat(ptr %t65, ptr @.str670) + %t65 = call ptr @fn_str_concat(ptr @.str773, ptr %t64) + %t66 = call ptr @fn_str_concat(ptr %t65, ptr @.str774) %t67 = load ptr, ptr %t58 %t68 = call ptr @fn_str_concat(ptr %t66, ptr %t67) %t69 = call ptr @fn_emit_bind(ptr %t68) @@ -13744,50 +16868,50 @@ entry: %t72 = call ptr @fn_emit_sizeof(ptr %t71) store ptr %t72, ptr %t73 %t74 = load ptr, ptr %t70 - %t75 = call ptr @fn_str_concat(ptr @.str671, ptr %t74) - %t76 = call ptr @fn_str_concat(ptr %t75, ptr @.str672) + %t75 = call ptr @fn_str_concat(ptr @.str775, ptr %t74) + %t76 = call ptr @fn_str_concat(ptr %t75, ptr @.str776) %t77 = call ptr @fn_emit_bind(ptr %t76) store ptr %t77, ptr %t78 %t79 = load ptr, ptr %t78 - %t80 = call ptr @fn_str_concat(ptr @.str673, ptr %t79) - %t81 = call ptr @fn_str_concat(ptr %t80, ptr @.str674) + %t80 = call ptr @fn_str_concat(ptr @.str777, ptr %t79) + %t81 = call ptr @fn_str_concat(ptr %t80, ptr @.str778) %t82 = load ptr, ptr %t73 %t83 = call ptr @fn_str_concat(ptr %t81, ptr %t82) %t84 = call ptr @fn_emit_bind(ptr %t83) store ptr %t84, ptr %t85 %t86 = load ptr, ptr %t30 - %t87 = call ptr @fn_str_concat(ptr @.str675, ptr %t86) + %t87 = call ptr @fn_str_concat(ptr @.str779, ptr %t86) %t88 = call ptr @fn_emit_bind(ptr %t87) store ptr %t88, ptr %t89 %t90 = load ptr, ptr %t89 - %t91 = call ptr @fn_str_concat(ptr @.str676, ptr %t90) - %t92 = call ptr @fn_str_concat(ptr %t91, ptr @.str677) + %t91 = call ptr @fn_str_concat(ptr @.str780, ptr %t90) + %t92 = call ptr @fn_str_concat(ptr %t91, ptr @.str781) %t93 = load ptr, ptr %t85 %t94 = call ptr @fn_str_concat(ptr %t92, ptr %t93) - %t95 = call ptr @fn_str_concat(ptr %t94, ptr @.str678) + %t95 = call ptr @fn_str_concat(ptr %t94, ptr @.str782) %t96 = call ptr @fn_emit_bind(ptr %t95) store ptr %t96, ptr %t97 - call void @fn_emit(ptr @.str679) + call void @fn_emit(ptr @.str783) %t98 = load ptr, ptr %t97 call void @fn_emit(ptr %t98) - call void @fn_emit(ptr @.str680) + call void @fn_emit(ptr @.str784) %t99 = load ptr, ptr %t30 call void @fn_emit(ptr %t99) - call void @fn_emit(ptr @.str681) - call void @fn_emit(ptr @.str682) + call void @fn_emit(ptr @.str785) + call void @fn_emit(ptr @.str786) %t100 = load ptr, ptr %t70 call void @fn_emit(ptr %t100) - call void @fn_emit(ptr @.str683) + call void @fn_emit(ptr @.str787) %t101 = load ptr, ptr %t27 call void @fn_emit(ptr %t101) - call void @fn_emit(ptr @.str684) - call void @fn_emit(ptr @.str685) + call void @fn_emit(ptr @.str788) + call void @fn_emit(ptr @.str789) %t102 = load ptr, ptr %t49 call void @fn_emit(ptr %t102) - call void @fn_emit(ptr @.str686) + call void @fn_emit(ptr @.str790) %t103 = load ptr, ptr %t49 call void @fn_emit(ptr %t103) - call void @fn_emit(ptr @.str687) + call void @fn_emit(ptr @.str791) %t104 = load ptr, ptr %t0 %t105 = getelementptr inbounds %Cmp_Node, ptr %t104, i32 0, i32 7 %t106 = load ptr, ptr %t105 @@ -13798,49 +16922,49 @@ entry: %t111 = call ptr @fn_emit_expr(ptr %t110) store ptr %t111, ptr %t112 %t113 = load ptr, ptr %t30 - %t114 = call ptr @fn_str_concat(ptr @.str688, ptr %t113) + %t114 = call ptr @fn_str_concat(ptr @.str792, ptr %t113) %t115 = call ptr @fn_emit_bind(ptr %t114) store ptr %t115, ptr %t116 %t117 = call ptr @fn_nreg() store ptr %t117, ptr %t118 - call void @fn_emit(ptr @.str689) + call void @fn_emit(ptr @.str793) %t119 = load ptr, ptr %t118 call void @fn_emit(ptr %t119) - call void @fn_emit(ptr @.str690) + call void @fn_emit(ptr @.str794) %t120 = load ptr, ptr %t17 call void @fn_emit(ptr %t120) - call void @fn_emit(ptr @.str691) + call void @fn_emit(ptr @.str795) %t121 = load ptr, ptr %t116 call void @fn_emit(ptr %t121) - call void @fn_emit(ptr @.str692) + call void @fn_emit(ptr @.str796) %t122 = load ptr, ptr %t34 call void @fn_emit(ptr %t122) - call void @fn_emit(ptr @.str693) - call void @fn_emit(ptr @.str694) + call void @fn_emit(ptr @.str797) + call void @fn_emit(ptr @.str798) %t123 = load ptr, ptr %t17 call void @fn_emit(ptr %t123) - call void @fn_emit(ptr @.str695) + call void @fn_emit(ptr @.str799) %t124 = load ptr, ptr %t112 %t125 = getelementptr inbounds %Cmp_Val, ptr %t124, i32 0, i32 0 %t126 = load ptr, ptr %t125 call void @fn_emit(ptr %t126) - call void @fn_emit(ptr @.str696) + call void @fn_emit(ptr @.str800) %t127 = load ptr, ptr %t118 call void @fn_emit(ptr %t127) - call void @fn_emit(ptr @.str697) + call void @fn_emit(ptr @.str801) %t128 = load ptr, ptr %t34 - %t129 = call ptr @fn_str_concat(ptr @.str698, ptr %t128) - %t130 = call ptr @fn_str_concat(ptr %t129, ptr @.str699) + %t129 = call ptr @fn_str_concat(ptr @.str802, ptr %t128) + %t130 = call ptr @fn_str_concat(ptr %t129, ptr @.str803) %t131 = call ptr @fn_emit_bind(ptr %t130) store ptr %t131, ptr %t132 - call void @fn_emit(ptr @.str700) + call void @fn_emit(ptr @.str804) %t133 = load ptr, ptr %t132 call void @fn_emit(ptr %t133) - call void @fn_emit(ptr @.str701) + call void @fn_emit(ptr @.str805) %t134 = load ptr, ptr %t24 call void @fn_emit(ptr %t134) - call void @fn_emit(ptr @.str702) - %t135 = call ptr @fn_val(ptr @.str703, ptr @.str704) + call void @fn_emit(ptr @.str806) + %t135 = call ptr @fn_val(ptr @.str807, ptr @.str808) store ptr %t135, ptr %retval br label %ret ret: @@ -13858,8 +16982,8 @@ entry: store ptr %arg_ty, ptr %t1 %t2 = load ptr, ptr %t1 %t3 = call ptr @fn_llty(ptr %t2) - %t4 = call ptr @fn_str_concat(ptr @.str705, ptr %t3) - %t5 = call ptr @fn_str_concat(ptr %t4, ptr @.str706) + %t4 = call ptr @fn_str_concat(ptr @.str809, ptr %t3) + %t5 = call ptr @fn_str_concat(ptr %t4, ptr @.str810) %t6 = load ptr, ptr %t0 %t7 = call ptr @fn_str_concat(ptr %t5, ptr %t6) %t8 = call ptr @fn_emit_bind(ptr %t7) @@ -13888,7 +17012,7 @@ entry: %t49 = alloca ptr %t54 = alloca ptr store ptr %arg_e, ptr %t0 - %t1 = call ptr @fn_emit_alloca(ptr @.str707) + %t1 = call ptr @fn_emit_alloca(ptr @.str811) store ptr %t1, ptr %t2 %t3 = load ptr, ptr %t0 %t4 = getelementptr inbounds %Cmp_Node, ptr %t3, i32 0, i32 4 @@ -13898,60 +17022,60 @@ entry: %t8 = load ptr, ptr %t7 %t9 = getelementptr inbounds %Cmp_Val, ptr %t8, i32 0, i32 0 %t10 = load ptr, ptr %t9 - %t11 = call ptr @fn_str_concat(ptr @.str708, ptr %t10) - %t12 = call ptr @fn_str_concat(ptr %t11, ptr @.str709) + %t11 = call ptr @fn_str_concat(ptr @.str812, ptr %t10) + %t12 = call ptr @fn_str_concat(ptr %t11, ptr @.str813) %t13 = call ptr @fn_emit_bind(ptr %t12) store ptr %t13, ptr %t14 %t15 = load ptr, ptr %t14 - %t16 = call ptr @fn_str_concat(ptr @.str710, ptr %t15) - %t17 = call ptr @fn_str_concat(ptr %t16, ptr @.str711) + %t16 = call ptr @fn_str_concat(ptr @.str814, ptr %t15) + %t17 = call ptr @fn_str_concat(ptr %t16, ptr @.str815) %t18 = call ptr @fn_emit_bind(ptr %t17) store ptr %t18, ptr %t19 - call void @fn_emit(ptr @.str712) + call void @fn_emit(ptr @.str816) %t20 = load ptr, ptr %t19 call void @fn_emit(ptr %t20) - call void @fn_emit(ptr @.str713) + call void @fn_emit(ptr @.str817) %t21 = load ptr, ptr %t2 call void @fn_emit(ptr %t21) - call void @fn_emit(ptr @.str714) - %t22 = call ptr @fn_lbl(ptr @.str715) + call void @fn_emit(ptr @.str818) + %t22 = call ptr @fn_lbl(ptr @.str819) store ptr %t22, ptr %t23 - %t24 = call ptr @fn_lbl(ptr @.str716) + %t24 = call ptr @fn_lbl(ptr @.str820) store ptr %t24, ptr %t25 %t26 = load ptr, ptr %t0 %t27 = getelementptr inbounds %Cmp_Node, ptr %t26, i32 0, i32 1 %t28 = load ptr, ptr %t27 - %t29 = call i32 @fn_str_eq(ptr %t28, ptr @.str717) + %t29 = call i32 @fn_str_eq(ptr %t28, ptr @.str821) %t30 = icmp ne i32 %t29, 0 br i1 %t30, label %then0, label %else1 then0: - call void @fn_emit(ptr @.str718) + call void @fn_emit(ptr @.str822) %t31 = load ptr, ptr %t14 call void @fn_emit(ptr %t31) - call void @fn_emit(ptr @.str719) + call void @fn_emit(ptr @.str823) %t32 = load ptr, ptr %t23 call void @fn_emit(ptr %t32) - call void @fn_emit(ptr @.str720) + call void @fn_emit(ptr @.str824) %t33 = load ptr, ptr %t25 call void @fn_emit(ptr %t33) - call void @fn_emit(ptr @.str721) + call void @fn_emit(ptr @.str825) br label %ifend2 else1: - call void @fn_emit(ptr @.str722) + call void @fn_emit(ptr @.str826) %t34 = load ptr, ptr %t14 call void @fn_emit(ptr %t34) - call void @fn_emit(ptr @.str723) + call void @fn_emit(ptr @.str827) %t35 = load ptr, ptr %t25 call void @fn_emit(ptr %t35) - call void @fn_emit(ptr @.str724) + call void @fn_emit(ptr @.str828) %t36 = load ptr, ptr %t23 call void @fn_emit(ptr %t36) - call void @fn_emit(ptr @.str725) + call void @fn_emit(ptr @.str829) br label %ifend2 ifend2: %t37 = load ptr, ptr %t23 call void @fn_emit(ptr %t37) - call void @fn_emit(ptr @.str726) + call void @fn_emit(ptr @.str830) %t38 = load ptr, ptr %t0 %t39 = getelementptr inbounds %Cmp_Node, ptr %t38, i32 0, i32 5 %t40 = load ptr, ptr %t39 @@ -13960,33 +17084,33 @@ ifend2: %t43 = load ptr, ptr %t42 %t44 = getelementptr inbounds %Cmp_Val, ptr %t43, i32 0, i32 0 %t45 = load ptr, ptr %t44 - %t46 = call ptr @fn_str_concat(ptr @.str727, ptr %t45) - %t47 = call ptr @fn_str_concat(ptr %t46, ptr @.str728) + %t46 = call ptr @fn_str_concat(ptr @.str831, ptr %t45) + %t47 = call ptr @fn_str_concat(ptr %t46, ptr @.str832) %t48 = call ptr @fn_emit_bind(ptr %t47) store ptr %t48, ptr %t49 %t50 = load ptr, ptr %t49 - %t51 = call ptr @fn_str_concat(ptr @.str729, ptr %t50) - %t52 = call ptr @fn_str_concat(ptr %t51, ptr @.str730) + %t51 = call ptr @fn_str_concat(ptr @.str833, ptr %t50) + %t52 = call ptr @fn_str_concat(ptr %t51, ptr @.str834) %t53 = call ptr @fn_emit_bind(ptr %t52) store ptr %t53, ptr %t54 - call void @fn_emit(ptr @.str731) + call void @fn_emit(ptr @.str835) %t55 = load ptr, ptr %t54 call void @fn_emit(ptr %t55) - call void @fn_emit(ptr @.str732) + call void @fn_emit(ptr @.str836) %t56 = load ptr, ptr %t2 call void @fn_emit(ptr %t56) - call void @fn_emit(ptr @.str733) - call void @fn_emit(ptr @.str734) + call void @fn_emit(ptr @.str837) + call void @fn_emit(ptr @.str838) %t57 = load ptr, ptr %t25 call void @fn_emit(ptr %t57) - call void @fn_emit(ptr @.str735) + call void @fn_emit(ptr @.str839) %t58 = load ptr, ptr %t25 call void @fn_emit(ptr %t58) - call void @fn_emit(ptr @.str736) + call void @fn_emit(ptr @.str840) %t59 = load ptr, ptr %t2 - %t60 = call ptr @fn_str_concat(ptr @.str737, ptr %t59) + %t60 = call ptr @fn_str_concat(ptr @.str841, ptr %t59) %t61 = call ptr @fn_emit_bind(ptr %t60) - %t62 = call ptr @fn_val(ptr %t61, ptr @.str738) + %t62 = call ptr @fn_val(ptr %t61, ptr @.str842) store ptr %t62, ptr %retval br label %ret ret: @@ -14000,46 +17124,46 @@ entry: %t0 = alloca ptr store ptr %arg_op, ptr %t0 %t1 = load ptr, ptr %t0 - %t2 = call i32 @fn_str_eq(ptr %t1, ptr @.str739) + %t2 = call i32 @fn_str_eq(ptr %t1, ptr @.str843) %t3 = icmp ne i32 %t2, 0 br i1 %t3, label %then0, label %ifend2 then0: - store ptr @.str740, ptr %retval + store ptr @.str844, ptr %retval br label %ret ifend2: %t4 = load ptr, ptr %t0 - %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str741) + %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str845) %t6 = icmp ne i32 %t5, 0 br i1 %t6, label %then3, label %ifend5 then3: - store ptr @.str742, ptr %retval + store ptr @.str846, ptr %retval br label %ret ifend5: %t7 = load ptr, ptr %t0 - %t8 = call i32 @fn_str_eq(ptr %t7, ptr @.str743) + %t8 = call i32 @fn_str_eq(ptr %t7, ptr @.str847) %t9 = icmp ne i32 %t8, 0 br i1 %t9, label %then6, label %ifend8 then6: - store ptr @.str744, ptr %retval + store ptr @.str848, ptr %retval br label %ret ifend8: %t10 = load ptr, ptr %t0 - %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str745) + %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str849) %t12 = icmp ne i32 %t11, 0 br i1 %t12, label %then9, label %ifend11 then9: - store ptr @.str746, ptr %retval + store ptr @.str850, ptr %retval br label %ret ifend11: %t13 = load ptr, ptr %t0 - %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str747) + %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str851) %t15 = icmp ne i32 %t14, 0 br i1 %t15, label %then12, label %ifend14 then12: - store ptr @.str748, ptr %retval + store ptr @.str852, ptr %retval br label %ret ifend14: - store ptr @.str749, ptr %retval + store ptr @.str853, ptr %retval br label %ret ret: %t16 = load ptr, ptr %retval @@ -14057,14 +17181,14 @@ entry: %t5 = alloca i32 store ptr %arg_op, ptr %t0 %t6 = load ptr, ptr %t0 - %t7 = call i32 @fn_str_eq(ptr %t6, ptr @.str750) + %t7 = call i32 @fn_str_eq(ptr %t6, ptr @.str854) %t8 = icmp ne i32 %t7, 0 %t9 = zext i1 %t8 to i32 store i32 %t9, ptr %t5 br i1 %t8, label %scend1, label %sc0 sc0: %t10 = load ptr, ptr %t0 - %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str751) + %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str855) %t12 = icmp ne i32 %t11, 0 %t13 = zext i1 %t12 to i32 store i32 %t13, ptr %t5 @@ -14077,7 +17201,7 @@ scend1: br i1 %t15, label %scend3, label %sc2 sc2: %t17 = load ptr, ptr %t0 - %t18 = call i32 @fn_str_eq(ptr %t17, ptr @.str752) + %t18 = call i32 @fn_str_eq(ptr %t17, ptr @.str856) %t19 = icmp ne i32 %t18, 0 %t20 = zext i1 %t19 to i32 store i32 %t20, ptr %t4 @@ -14090,7 +17214,7 @@ scend3: br i1 %t22, label %scend5, label %sc4 sc4: %t24 = load ptr, ptr %t0 - %t25 = call i32 @fn_str_eq(ptr %t24, ptr @.str753) + %t25 = call i32 @fn_str_eq(ptr %t24, ptr @.str857) %t26 = icmp ne i32 %t25, 0 %t27 = zext i1 %t26 to i32 store i32 %t27, ptr %t3 @@ -14103,7 +17227,7 @@ scend5: br i1 %t29, label %scend7, label %sc6 sc6: %t31 = load ptr, ptr %t0 - %t32 = call i32 @fn_str_eq(ptr %t31, ptr @.str754) + %t32 = call i32 @fn_str_eq(ptr %t31, ptr @.str858) %t33 = icmp ne i32 %t32, 0 %t34 = zext i1 %t33 to i32 store i32 %t34, ptr %t2 @@ -14116,7 +17240,7 @@ scend7: br i1 %t36, label %scend9, label %sc8 sc8: %t38 = load ptr, ptr %t0 - %t39 = call i32 @fn_str_eq(ptr %t38, ptr @.str755) + %t39 = call i32 @fn_str_eq(ptr %t38, ptr @.str859) %t40 = icmp ne i32 %t39, 0 %t41 = zext i1 %t40 to i32 store i32 %t41, ptr %t1 @@ -14136,78 +17260,78 @@ entry: %t0 = alloca ptr store ptr %arg_op, ptr %t0 %t1 = load ptr, ptr %t0 - %t2 = call i32 @fn_str_eq(ptr %t1, ptr @.str756) + %t2 = call i32 @fn_str_eq(ptr %t1, ptr @.str860) %t3 = icmp ne i32 %t2, 0 br i1 %t3, label %then0, label %ifend2 then0: - store ptr @.str757, ptr %retval + store ptr @.str861, ptr %retval br label %ret ifend2: %t4 = load ptr, ptr %t0 - %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str758) + %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str862) %t6 = icmp ne i32 %t5, 0 br i1 %t6, label %then3, label %ifend5 then3: - store ptr @.str759, ptr %retval + store ptr @.str863, ptr %retval br label %ret ifend5: %t7 = load ptr, ptr %t0 - %t8 = call i32 @fn_str_eq(ptr %t7, ptr @.str760) + %t8 = call i32 @fn_str_eq(ptr %t7, ptr @.str864) %t9 = icmp ne i32 %t8, 0 br i1 %t9, label %then6, label %ifend8 then6: - store ptr @.str761, ptr %retval + store ptr @.str865, ptr %retval br label %ret ifend8: %t10 = load ptr, ptr %t0 - %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str762) + %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str866) %t12 = icmp ne i32 %t11, 0 br i1 %t12, label %then9, label %ifend11 then9: - store ptr @.str763, ptr %retval + store ptr @.str867, ptr %retval br label %ret ifend11: %t13 = load ptr, ptr %t0 - %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str764) + %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str868) %t15 = icmp ne i32 %t14, 0 br i1 %t15, label %then12, label %ifend14 then12: - store ptr @.str765, ptr %retval + store ptr @.str869, ptr %retval br label %ret ifend14: %t16 = load ptr, ptr %t0 - %t17 = call i32 @fn_str_eq(ptr %t16, ptr @.str766) + %t17 = call i32 @fn_str_eq(ptr %t16, ptr @.str870) %t18 = icmp ne i32 %t17, 0 br i1 %t18, label %then15, label %ifend17 then15: - store ptr @.str767, ptr %retval + store ptr @.str871, ptr %retval br label %ret ifend17: %t19 = load ptr, ptr %t0 - %t20 = call i32 @fn_str_eq(ptr %t19, ptr @.str768) + %t20 = call i32 @fn_str_eq(ptr %t19, ptr @.str872) %t21 = icmp ne i32 %t20, 0 br i1 %t21, label %then18, label %ifend20 then18: - store ptr @.str769, ptr %retval + store ptr @.str873, ptr %retval br label %ret ifend20: %t22 = load ptr, ptr %t0 - %t23 = call i32 @fn_str_eq(ptr %t22, ptr @.str770) + %t23 = call i32 @fn_str_eq(ptr %t22, ptr @.str874) %t24 = icmp ne i32 %t23, 0 br i1 %t24, label %then21, label %ifend23 then21: - store ptr @.str771, ptr %retval + store ptr @.str875, ptr %retval br label %ret ifend23: %t25 = load ptr, ptr %t0 - %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str772) + %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str876) %t27 = icmp ne i32 %t26, 0 br i1 %t27, label %then24, label %ifend26 then24: - store ptr @.str773, ptr %retval + store ptr @.str877, ptr %retval br label %ret ifend26: - store ptr @.str774, ptr %retval + store ptr @.str878, ptr %retval br label %ret ret: %t28 = load ptr, ptr %retval @@ -14222,7 +17346,7 @@ entry: %t1 = load ptr, ptr %t0 %t2 = getelementptr inbounds %Cmp_Val, ptr %t1, i32 0, i32 1 %t3 = load ptr, ptr %t2 - %t4 = call i32 @fn_str_eq(ptr %t3, ptr @.str775) + %t4 = call i32 @fn_str_eq(ptr %t3, ptr @.str879) %t5 = icmp ne i32 %t4, 0 br i1 %t5, label %then0, label %ifend2 then0: @@ -14235,8 +17359,8 @@ ifend2: %t9 = load ptr, ptr %t0 %t10 = getelementptr inbounds %Cmp_Val, ptr %t9, i32 0, i32 0 %t11 = load ptr, ptr %t10 - %t12 = call ptr @fn_str_concat(ptr @.str776, ptr %t11) - %t13 = call ptr @fn_str_concat(ptr %t12, ptr @.str777) + %t12 = call ptr @fn_str_concat(ptr @.str880, ptr %t11) + %t13 = call ptr @fn_str_concat(ptr %t12, ptr @.str881) %t14 = call ptr @fn_emit_bind(ptr %t13) store ptr %t14, ptr %retval br label %ret @@ -14258,57 +17382,57 @@ entry: store ptr %arg_b, ptr %t2 store i32 1, ptr @g_g_uses_str %t3 = load ptr, ptr %t0 - %t4 = call i32 @fn_str_eq(ptr %t3, ptr @.str778) + %t4 = call i32 @fn_str_eq(ptr %t3, ptr @.str882) %t5 = icmp ne i32 %t4, 0 br i1 %t5, label %then0, label %ifend2 then0: %t6 = load ptr, ptr %t1 %t7 = getelementptr inbounds %Cmp_Val, ptr %t6, i32 0, i32 0 %t8 = load ptr, ptr %t7 - %t9 = call ptr @fn_str_concat(ptr @.str779, ptr %t8) - %t10 = call ptr @fn_str_concat(ptr %t9, ptr @.str780) + %t9 = call ptr @fn_str_concat(ptr @.str883, ptr %t8) + %t10 = call ptr @fn_str_concat(ptr %t9, ptr @.str884) %t11 = load ptr, ptr %t2 %t12 = getelementptr inbounds %Cmp_Val, ptr %t11, i32 0, i32 0 %t13 = load ptr, ptr %t12 %t14 = call ptr @fn_str_concat(ptr %t10, ptr %t13) - %t15 = call ptr @fn_str_concat(ptr %t14, ptr @.str781) + %t15 = call ptr @fn_str_concat(ptr %t14, ptr @.str885) %t16 = call ptr @fn_emit_bind(ptr %t15) - %t17 = call ptr @fn_val(ptr %t16, ptr @.str782) + %t17 = call ptr @fn_val(ptr %t16, ptr @.str886) store ptr %t17, ptr %retval br label %ret ifend2: %t18 = load ptr, ptr %t1 %t19 = getelementptr inbounds %Cmp_Val, ptr %t18, i32 0, i32 0 %t20 = load ptr, ptr %t19 - %t21 = call ptr @fn_str_concat(ptr @.str783, ptr %t20) - %t22 = call ptr @fn_str_concat(ptr %t21, ptr @.str784) + %t21 = call ptr @fn_str_concat(ptr @.str887, ptr %t20) + %t22 = call ptr @fn_str_concat(ptr %t21, ptr @.str888) %t23 = load ptr, ptr %t2 %t24 = getelementptr inbounds %Cmp_Val, ptr %t23, i32 0, i32 0 %t25 = load ptr, ptr %t24 %t26 = call ptr @fn_str_concat(ptr %t22, ptr %t25) - %t27 = call ptr @fn_str_concat(ptr %t26, ptr @.str785) + %t27 = call ptr @fn_str_concat(ptr %t26, ptr @.str889) %t28 = call ptr @fn_emit_bind(ptr %t27) store ptr %t28, ptr %t29 %t30 = load ptr, ptr %t0 - %t31 = call i32 @fn_str_eq(ptr %t30, ptr @.str786) + %t31 = call i32 @fn_str_eq(ptr %t30, ptr @.str890) %t32 = icmp ne i32 %t31, 0 br i1 %t32, label %then3, label %ifend5 then3: %t33 = load ptr, ptr %t29 - %t34 = call ptr @fn_str_concat(ptr @.str787, ptr %t33) - %t35 = call ptr @fn_str_concat(ptr %t34, ptr @.str788) + %t34 = call ptr @fn_str_concat(ptr @.str891, ptr %t33) + %t35 = call ptr @fn_str_concat(ptr %t34, ptr @.str892) %t36 = call ptr @fn_emit_bind(ptr %t35) store ptr %t36, ptr %t37 %t38 = load ptr, ptr %t37 - %t39 = call ptr @fn_str_concat(ptr @.str789, ptr %t38) - %t40 = call ptr @fn_str_concat(ptr %t39, ptr @.str790) + %t39 = call ptr @fn_str_concat(ptr @.str893, ptr %t38) + %t40 = call ptr @fn_str_concat(ptr %t39, ptr @.str894) %t41 = call ptr @fn_emit_bind(ptr %t40) - %t42 = call ptr @fn_val(ptr %t41, ptr @.str791) + %t42 = call ptr @fn_val(ptr %t41, ptr @.str895) store ptr %t42, ptr %retval br label %ret ifend5: %t43 = load ptr, ptr %t29 - %t44 = call ptr @fn_val(ptr %t43, ptr @.str792) + %t44 = call ptr @fn_val(ptr %t43, ptr @.str896) store ptr %t44, ptr %retval br label %ret ret: @@ -14352,7 +17476,7 @@ entry: %t2 = load ptr, ptr %t0 %t3 = getelementptr inbounds %Cmp_Node, ptr %t2, i32 0, i32 1 %t4 = load ptr, ptr %t3 - %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str793) + %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str897) %t6 = icmp ne i32 %t5, 0 %t7 = zext i1 %t6 to i32 store i32 %t7, ptr %t1 @@ -14361,7 +17485,7 @@ sc0: %t8 = load ptr, ptr %t0 %t9 = getelementptr inbounds %Cmp_Node, ptr %t8, i32 0, i32 1 %t10 = load ptr, ptr %t9 - %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str794) + %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str898) %t12 = icmp ne i32 %t11, 0 %t13 = zext i1 %t12 to i32 store i32 %t13, ptr %t1 @@ -14390,7 +17514,7 @@ ifend4: %t30 = getelementptr inbounds %Cmp_Val, ptr %t29, i32 0, i32 1 %t31 = load ptr, ptr %t30 %t32 = call ptr @fn_llty(ptr %t31) - %t33 = call i32 @fn_str_eq(ptr %t32, ptr @.str795) + %t33 = call i32 @fn_str_eq(ptr %t32, ptr @.str899) %t34 = icmp ne i32 %t33, 0 %t35 = zext i1 %t34 to i32 store i32 %t35, ptr %t28 @@ -14400,7 +17524,7 @@ sc5: %t37 = getelementptr inbounds %Cmp_Val, ptr %t36, i32 0, i32 1 %t38 = load ptr, ptr %t37 %t39 = call ptr @fn_llty(ptr %t38) - %t40 = call i32 @fn_str_eq(ptr %t39, ptr @.str796) + %t40 = call i32 @fn_str_eq(ptr %t39, ptr @.str900) %t41 = icmp ne i32 %t40, 0 %t42 = zext i1 %t41 to i32 store i32 %t42, ptr %t28 @@ -14441,20 +17565,20 @@ then9: %t68 = load ptr, ptr %t0 %t69 = getelementptr inbounds %Cmp_Node, ptr %t68, i32 0, i32 1 %t70 = load ptr, ptr %t69 - %t71 = call i32 @fn_str_eq(ptr %t70, ptr @.str797) + %t71 = call i32 @fn_str_eq(ptr %t70, ptr @.str901) %t72 = icmp ne i32 %t71, 0 br i1 %t72, label %then12, label %ifend14 then12: %t73 = load ptr, ptr %t22 %t74 = load ptr, ptr %t27 - %t75 = call ptr @fn_emit_str_op(ptr @.str798, ptr %t73, ptr %t74) + %t75 = call ptr @fn_emit_str_op(ptr @.str902, ptr %t73, ptr %t74) store ptr %t75, ptr %retval br label %ret ifend14: %t78 = load ptr, ptr %t0 %t79 = getelementptr inbounds %Cmp_Node, ptr %t78, i32 0, i32 1 %t80 = load ptr, ptr %t79 - %t81 = call i32 @fn_str_eq(ptr %t80, ptr @.str799) + %t81 = call i32 @fn_str_eq(ptr %t80, ptr @.str903) %t82 = icmp ne i32 %t81, 0 %t83 = zext i1 %t82 to i32 store i32 %t83, ptr %t77 @@ -14463,7 +17587,7 @@ sc15: %t84 = load ptr, ptr %t0 %t85 = getelementptr inbounds %Cmp_Node, ptr %t84, i32 0, i32 1 %t86 = load ptr, ptr %t85 - %t87 = call i32 @fn_str_eq(ptr %t86, ptr @.str800) + %t87 = call i32 @fn_str_eq(ptr %t86, ptr @.str904) %t88 = icmp ne i32 %t87, 0 %t89 = zext i1 %t88 to i32 store i32 %t89, ptr %t77 @@ -14501,7 +17625,7 @@ ifend11: %t107 = load ptr, ptr %t22 %t108 = getelementptr inbounds %Cmp_Val, ptr %t107, i32 0, i32 1 %t109 = load ptr, ptr %t108 - %t110 = call i32 @fn_str_eq(ptr %t109, ptr @.str801) + %t110 = call i32 @fn_str_eq(ptr %t109, ptr @.str905) %t111 = icmp ne i32 %t110, 0 %t112 = zext i1 %t111 to i32 store i32 %t112, ptr %t106 @@ -14510,7 +17634,7 @@ sc22: %t113 = load ptr, ptr %t27 %t114 = getelementptr inbounds %Cmp_Val, ptr %t113, i32 0, i32 1 %t115 = load ptr, ptr %t114 - %t116 = call i32 @fn_str_eq(ptr %t115, ptr @.str802) + %t116 = call i32 @fn_str_eq(ptr %t115, ptr @.str906) %t117 = icmp ne i32 %t116, 0 %t118 = zext i1 %t117 to i32 store i32 %t118, ptr %t106 @@ -14533,7 +17657,7 @@ then24: %t131 = getelementptr inbounds %Cmp_Val, ptr %t130, i32 0, i32 0 %t132 = load ptr, ptr %t131 store ptr %t132, ptr %t133 - store ptr @.str803, ptr %t134 + store ptr @.str907, ptr %t134 %t135 = load i32, ptr %t120 %t136 = icmp ne i32 %t135, 0 br i1 %t136, label %then27, label %else28 @@ -14550,7 +17674,7 @@ else28: %t143 = getelementptr inbounds %Cmp_Val, ptr %t142, i32 0, i32 1 %t144 = load ptr, ptr %t143 %t145 = call ptr @fn_llty(ptr %t144) - %t146 = call i32 @fn_str_eq(ptr %t145, ptr @.str804) + %t146 = call i32 @fn_str_eq(ptr %t145, ptr @.str908) %t147 = icmp ne i32 %t146, 0 %t148 = zext i1 %t147 to i32 store i32 %t148, ptr %t141 @@ -14560,7 +17684,7 @@ sc30: %t150 = getelementptr inbounds %Cmp_Val, ptr %t149, i32 0, i32 1 %t151 = load ptr, ptr %t150 %t152 = call ptr @fn_llty(ptr %t151) - %t153 = call i32 @fn_str_eq(ptr %t152, ptr @.str805) + %t153 = call i32 @fn_str_eq(ptr %t152, ptr @.str909) %t154 = icmp ne i32 %t153, 0 %t155 = zext i1 %t154 to i32 store i32 %t155, ptr %t141 @@ -14570,7 +17694,7 @@ scend31: %t157 = icmp ne i32 %t156, 0 br i1 %t157, label %then32, label %ifend34 then32: - store ptr @.str806, ptr %t134 + store ptr @.str910, ptr %t134 br label %ifend34 ifend34: br label %ifend29 @@ -14579,23 +17703,23 @@ ifend29: %t159 = getelementptr inbounds %Cmp_Node, ptr %t158, i32 0, i32 1 %t160 = load ptr, ptr %t159 %t161 = call ptr @fn_cmp_code(ptr %t160) - %t162 = call ptr @fn_str_concat(ptr @.str807, ptr %t161) - %t163 = call ptr @fn_str_concat(ptr %t162, ptr @.str808) + %t162 = call ptr @fn_str_concat(ptr @.str911, ptr %t161) + %t163 = call ptr @fn_str_concat(ptr %t162, ptr @.str912) %t164 = load ptr, ptr %t134 %t165 = call ptr @fn_str_concat(ptr %t163, ptr %t164) - %t166 = call ptr @fn_str_concat(ptr %t165, ptr @.str809) + %t166 = call ptr @fn_str_concat(ptr %t165, ptr @.str913) %t167 = load ptr, ptr %t129 %t168 = call ptr @fn_str_concat(ptr %t166, ptr %t167) - %t169 = call ptr @fn_str_concat(ptr %t168, ptr @.str810) + %t169 = call ptr @fn_str_concat(ptr %t168, ptr @.str914) %t170 = load ptr, ptr %t133 %t171 = call ptr @fn_str_concat(ptr %t169, ptr %t170) %t172 = call ptr @fn_emit_bind(ptr %t171) store ptr %t172, ptr %t173 %t174 = load ptr, ptr %t173 - %t175 = call ptr @fn_str_concat(ptr @.str811, ptr %t174) - %t176 = call ptr @fn_str_concat(ptr %t175, ptr @.str812) + %t175 = call ptr @fn_str_concat(ptr @.str915, ptr %t174) + %t176 = call ptr @fn_str_concat(ptr %t175, ptr @.str916) %t177 = call ptr @fn_emit_bind(ptr %t176) - %t178 = call ptr @fn_val(ptr %t177, ptr @.str813) + %t178 = call ptr @fn_val(ptr %t177, ptr @.str917) store ptr %t178, ptr %retval br label %ret ifend26: @@ -14612,74 +17736,74 @@ then35: %t187 = load ptr, ptr %t0 %t188 = getelementptr inbounds %Cmp_Node, ptr %t187, i32 0, i32 1 %t189 = load ptr, ptr %t188 - %t190 = call i32 @fn_str_eq(ptr %t189, ptr @.str814) + %t190 = call i32 @fn_str_eq(ptr %t189, ptr @.str918) %t191 = icmp ne i32 %t190, 0 br i1 %t191, label %then38, label %ifend40 then38: %t192 = load ptr, ptr %t183 - %t193 = call ptr @fn_str_concat(ptr @.str815, ptr %t192) - %t194 = call ptr @fn_str_concat(ptr %t193, ptr @.str816) + %t193 = call ptr @fn_str_concat(ptr @.str919, ptr %t192) + %t194 = call ptr @fn_str_concat(ptr %t193, ptr @.str920) %t195 = call ptr @fn_emit_bind(ptr %t194) store ptr %t195, ptr %t196 %t197 = load ptr, ptr %t186 - %t198 = call ptr @fn_str_concat(ptr @.str817, ptr %t197) - %t199 = call ptr @fn_str_concat(ptr %t198, ptr @.str818) + %t198 = call ptr @fn_str_concat(ptr @.str921, ptr %t197) + %t199 = call ptr @fn_str_concat(ptr %t198, ptr @.str922) %t200 = call ptr @fn_emit_bind(ptr %t199) store ptr %t200, ptr %t201 %t202 = load ptr, ptr %t196 - %t203 = call ptr @fn_str_concat(ptr @.str819, ptr %t202) - %t204 = call ptr @fn_str_concat(ptr %t203, ptr @.str820) + %t203 = call ptr @fn_str_concat(ptr @.str923, ptr %t202) + %t204 = call ptr @fn_str_concat(ptr %t203, ptr @.str924) %t205 = load ptr, ptr %t201 %t206 = call ptr @fn_str_concat(ptr %t204, ptr %t205) %t207 = call ptr @fn_emit_bind(ptr %t206) store ptr %t207, ptr %t208 %t209 = load ptr, ptr %t208 - %t210 = call ptr @fn_str_concat(ptr @.str821, ptr %t209) - %t211 = call ptr @fn_str_concat(ptr %t210, ptr @.str822) + %t210 = call ptr @fn_str_concat(ptr @.str925, ptr %t209) + %t211 = call ptr @fn_str_concat(ptr %t210, ptr @.str926) %t212 = call ptr @fn_emit_bind(ptr %t211) store ptr %t212, ptr %t213 %t214 = load ptr, ptr %t213 - %t215 = call ptr @fn_str_concat(ptr @.str823, ptr %t214) - %t216 = call ptr @fn_str_concat(ptr %t215, ptr @.str824) + %t215 = call ptr @fn_str_concat(ptr @.str927, ptr %t214) + %t216 = call ptr @fn_str_concat(ptr %t215, ptr @.str928) %t217 = call ptr @fn_emit_bind(ptr %t216) - %t218 = call ptr @fn_val(ptr %t217, ptr @.str825) + %t218 = call ptr @fn_val(ptr %t217, ptr @.str929) store ptr %t218, ptr %retval br label %ret ifend40: %t219 = load ptr, ptr %t0 %t220 = getelementptr inbounds %Cmp_Node, ptr %t219, i32 0, i32 1 %t221 = load ptr, ptr %t220 - %t222 = call i32 @fn_str_eq(ptr %t221, ptr @.str826) + %t222 = call i32 @fn_str_eq(ptr %t221, ptr @.str930) %t223 = icmp ne i32 %t222, 0 br i1 %t223, label %then41, label %ifend43 then41: %t224 = load ptr, ptr %t183 - %t225 = call ptr @fn_str_concat(ptr @.str827, ptr %t224) - %t226 = call ptr @fn_str_concat(ptr %t225, ptr @.str828) + %t225 = call ptr @fn_str_concat(ptr @.str931, ptr %t224) + %t226 = call ptr @fn_str_concat(ptr %t225, ptr @.str932) %t227 = call ptr @fn_emit_bind(ptr %t226) store ptr %t227, ptr %t228 %t229 = load ptr, ptr %t228 - %t230 = call ptr @fn_str_concat(ptr @.str829, ptr %t229) - %t231 = call ptr @fn_str_concat(ptr %t230, ptr @.str830) + %t230 = call ptr @fn_str_concat(ptr @.str933, ptr %t229) + %t231 = call ptr @fn_str_concat(ptr %t230, ptr @.str934) %t232 = call ptr @fn_emit_bind(ptr %t231) store ptr %t232, ptr %t233 %t234 = load ptr, ptr %t186 - %t235 = call ptr @fn_str_concat(ptr @.str831, ptr %t234) - %t236 = call ptr @fn_str_concat(ptr %t235, ptr @.str832) + %t235 = call ptr @fn_str_concat(ptr @.str935, ptr %t234) + %t236 = call ptr @fn_str_concat(ptr %t235, ptr @.str936) %t237 = call ptr @fn_emit_bind(ptr %t236) store ptr %t237, ptr %t238 %t239 = load ptr, ptr %t233 - %t240 = call ptr @fn_str_concat(ptr @.str833, ptr %t239) - %t241 = call ptr @fn_str_concat(ptr %t240, ptr @.str834) + %t240 = call ptr @fn_str_concat(ptr @.str937, ptr %t239) + %t241 = call ptr @fn_str_concat(ptr %t240, ptr @.str938) %t242 = load ptr, ptr %t238 %t243 = call ptr @fn_str_concat(ptr %t241, ptr %t242) %t244 = call ptr @fn_emit_bind(ptr %t243) store ptr %t244, ptr %t245 %t246 = load ptr, ptr %t245 - %t247 = call ptr @fn_str_concat(ptr @.str835, ptr %t246) - %t248 = call ptr @fn_str_concat(ptr %t247, ptr @.str836) + %t247 = call ptr @fn_str_concat(ptr @.str939, ptr %t246) + %t248 = call ptr @fn_str_concat(ptr %t247, ptr @.str940) %t249 = call ptr @fn_emit_bind(ptr %t248) - %t250 = call ptr @fn_val(ptr %t249, ptr @.str837) + %t250 = call ptr @fn_val(ptr %t249, ptr @.str941) store ptr %t250, ptr %retval br label %ret ifend43: @@ -14687,16 +17811,16 @@ ifend43: %t252 = getelementptr inbounds %Cmp_Node, ptr %t251, i32 0, i32 1 %t253 = load ptr, ptr %t252 %t254 = call ptr @fn_arith_code(ptr %t253) - %t255 = call ptr @fn_str_concat(ptr %t254, ptr @.str838) + %t255 = call ptr @fn_str_concat(ptr %t254, ptr @.str942) %t256 = load ptr, ptr %t183 %t257 = call ptr @fn_str_concat(ptr %t255, ptr %t256) - %t258 = call ptr @fn_str_concat(ptr %t257, ptr @.str839) + %t258 = call ptr @fn_str_concat(ptr %t257, ptr @.str943) %t259 = load ptr, ptr %t186 %t260 = call ptr @fn_str_concat(ptr %t258, ptr %t259) %t261 = call ptr @fn_emit_bind(ptr %t260) store ptr %t261, ptr %t262 %t263 = load ptr, ptr %t262 - %t264 = call ptr @fn_val(ptr %t263, ptr @.str840) + %t264 = call ptr @fn_val(ptr %t263, ptr @.str944) store ptr %t264, ptr %retval br label %ret ifend37: @@ -14704,12 +17828,12 @@ ifend37: %t266 = getelementptr inbounds %Cmp_Node, ptr %t265, i32 0, i32 1 %t267 = load ptr, ptr %t266 %t268 = call ptr @fn_arith_code(ptr %t267) - %t269 = call ptr @fn_str_concat(ptr %t268, ptr @.str841) + %t269 = call ptr @fn_str_concat(ptr %t268, ptr @.str945) %t270 = load ptr, ptr %t22 %t271 = getelementptr inbounds %Cmp_Val, ptr %t270, i32 0, i32 0 %t272 = load ptr, ptr %t271 %t273 = call ptr @fn_str_concat(ptr %t269, ptr %t272) - %t274 = call ptr @fn_str_concat(ptr %t273, ptr @.str842) + %t274 = call ptr @fn_str_concat(ptr %t273, ptr @.str946) %t275 = load ptr, ptr %t27 %t276 = getelementptr inbounds %Cmp_Val, ptr %t275, i32 0, i32 0 %t277 = load ptr, ptr %t276 @@ -14717,7 +17841,7 @@ ifend37: %t279 = call ptr @fn_emit_bind(ptr %t278) store ptr %t279, ptr %t280 %t281 = load ptr, ptr %t280 - %t282 = call ptr @fn_val(ptr %t281, ptr @.str843) + %t282 = call ptr @fn_val(ptr %t281, ptr @.str947) store ptr %t282, ptr %retval br label %ret ret: @@ -14730,24 +17854,80 @@ entry: %retval = alloca ptr %t0 = alloca ptr %t6 = alloca ptr - %t68 = alloca ptr - %t94 = alloca ptr - %t123 = alloca ptr - %t130 = alloca ptr - %t147 = alloca ptr - %t154 = alloca ptr - %t159 = alloca ptr - %t176 = alloca ptr - %t195 = alloca ptr - %t223 = alloca ptr - %t225 = alloca ptr - %t232 = alloca ptr - %t248 = alloca ptr - %t255 = alloca ptr - %t256 = alloca i32 - %t275 = alloca ptr - %t326 = alloca ptr - %t327 = alloca ptr + %t59 = alloca ptr + %t78 = alloca ptr + %t87 = alloca ptr + %t110 = alloca ptr + %t119 = alloca ptr + %t143 = alloca ptr + %t152 = alloca ptr + %t161 = alloca ptr + %t183 = alloca ptr + %t202 = alloca ptr + %t221 = alloca ptr + %t230 = alloca ptr + %t249 = alloca ptr + %t261 = alloca ptr + %t266 = alloca ptr + %t300 = alloca ptr + %t316 = alloca ptr + %t321 = alloca i32 + %t341 = alloca ptr + %t350 = alloca ptr + %t359 = alloca ptr + %t370 = alloca i32 + %t390 = alloca ptr + %t399 = alloca ptr + %t433 = alloca ptr + %t459 = alloca ptr + %t488 = alloca ptr + %t495 = alloca ptr + %t512 = alloca ptr + %t519 = alloca ptr + %t524 = alloca ptr + %t541 = alloca ptr + %t560 = alloca ptr + %t579 = alloca ptr + %t598 = alloca ptr + %t607 = alloca ptr + %t631 = alloca ptr + %t640 = alloca ptr + %t649 = alloca ptr + %t666 = alloca ptr + %t683 = alloca ptr + %t692 = alloca ptr + %t701 = alloca ptr + %t710 = alloca ptr + %t717 = alloca ptr + %t740 = alloca ptr + %t749 = alloca ptr + %t778 = alloca ptr + %t797 = alloca ptr + %t816 = alloca ptr + %t825 = alloca ptr + %t849 = alloca ptr + %t858 = alloca ptr + %t882 = alloca ptr + %t891 = alloca ptr + %t910 = alloca ptr + %t919 = alloca ptr + %t938 = alloca ptr + %t966 = alloca ptr + %t977 = alloca ptr + %t984 = alloca ptr + %t985 = alloca i32 + %t1004 = alloca ptr + %t1055 = alloca ptr + %t1056 = alloca ptr + %t1103 = alloca ptr + %t1105 = alloca ptr + %t1112 = alloca ptr + %t1128 = alloca ptr + %t1135 = alloca ptr + %t1136 = alloca i32 + %t1155 = alloca ptr + %t1206 = alloca ptr + %t1207 = alloca ptr store ptr %arg_e, ptr %t0 %t1 = load ptr, ptr %t0 %t2 = getelementptr inbounds %Cmp_Node, ptr %t1, i32 0, i32 4 @@ -14756,7 +17936,7 @@ entry: %t5 = load ptr, ptr %t4 store ptr %t5, ptr %t6 %t7 = load ptr, ptr %t6 - %t8 = call i32 @fn_str_eq(ptr %t7, ptr @.str844) + %t8 = call i32 @fn_str_eq(ptr %t7, ptr @.str948) %t9 = icmp ne i32 %t8, 0 br i1 %t9, label %then0, label %ifend2 then0: @@ -14766,7 +17946,7 @@ then0: %t13 = icmp ne i32 %t12, 0 br i1 %t13, label %then3, label %ifend5 then3: - %t14 = call ptr @fn_val(ptr @.str845, ptr @.str846) + %t14 = call ptr @fn_val(ptr @.str949, ptr @.str950) store ptr %t14, ptr %retval br label %ret ifend5: @@ -14777,527 +17957,1690 @@ ifend5: %t19 = sub i32 %t18, 1 %t20 = getelementptr inbounds ptr, ptr %t17, i32 %t19 %t21 = load ptr, ptr %t20 - %t22 = call ptr @fn_str_concat(ptr @.str847, ptr %t21) + %t22 = call ptr @fn_str_concat(ptr @.str951, ptr %t21) %t23 = call ptr @fn_emit_bind(ptr %t22) - %t24 = call ptr @fn_val(ptr %t23, ptr @.str848) + %t24 = call ptr @fn_val(ptr %t23, ptr @.str952) store ptr %t24, ptr %retval br label %ret ifend2: %t25 = load ptr, ptr %t6 - %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str849) + %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str953) %t27 = icmp ne i32 %t26, 0 br i1 %t27, label %then6, label %ifend8 then6: - %t28 = call ptr @fn_emit_bind(ptr @.str850) - %t29 = call ptr @fn_val(ptr %t28, ptr @.str851) + %t28 = call ptr @fn_emit_bind(ptr @.str954) + %t29 = call ptr @fn_val(ptr %t28, ptr @.str955) store ptr %t29, ptr %retval br label %ret ifend8: %t30 = load ptr, ptr %t6 - %t31 = call i32 @fn_str_eq(ptr %t30, ptr @.str852) + %t31 = call i32 @fn_str_eq(ptr %t30, ptr @.str956) %t32 = icmp ne i32 %t31, 0 br i1 %t32, label %then9, label %ifend11 then9: - call void @fn_emit(ptr @.str853) - %t33 = call ptr @fn_val(ptr @.str854, ptr @.str855) + call void @fn_emit(ptr @.str957) + %t33 = call ptr @fn_val(ptr @.str958, ptr @.str959) store ptr %t33, ptr %retval br label %ret ifend11: %t34 = load ptr, ptr %t6 - %t35 = call i32 @fn_str_eq(ptr %t34, ptr @.str856) + %t35 = call i32 @fn_str_eq(ptr %t34, ptr @.str960) %t36 = icmp ne i32 %t35, 0 br i1 %t36, label %then12, label %ifend14 then12: - call void @fn_emit(ptr @.str857) - %t37 = call ptr @fn_val(ptr @.str858, ptr @.str859) + call void @fn_emit(ptr @.str961) + %t37 = call ptr @fn_val(ptr @.str962, ptr @.str963) store ptr %t37, ptr %retval br label %ret ifend14: %t38 = load ptr, ptr %t6 - %t39 = call i32 @fn_str_eq(ptr %t38, ptr @.str860) + %t39 = call i32 @fn_str_eq(ptr %t38, ptr @.str964) %t40 = icmp ne i32 %t39, 0 br i1 %t40, label %then15, label %ifend17 then15: - %t41 = call ptr @fn_emit_bind(ptr @.str861) - %t42 = call ptr @fn_val(ptr %t41, ptr @.str862) + %t41 = call ptr @fn_emit_bind(ptr @.str965) + %t42 = call ptr @fn_val(ptr %t41, ptr @.str966) store ptr %t42, ptr %retval br label %ret ifend17: %t43 = load ptr, ptr %t6 - %t44 = call i32 @fn_str_eq(ptr %t43, ptr @.str863) + %t44 = call i32 @fn_str_eq(ptr %t43, ptr @.str967) %t45 = icmp ne i32 %t44, 0 br i1 %t45, label %then18, label %ifend20 then18: - call void @fn_emit(ptr @.str864) - %t46 = call ptr @fn_val(ptr @.str865, ptr @.str866) - store ptr %t46, ptr %retval + %t46 = call ptr @fn_emit_bind(ptr @.str968) + %t47 = call ptr @fn_val(ptr %t46, ptr @.str969) + store ptr %t47, ptr %retval br label %ret ifend20: - %t47 = load ptr, ptr %t6 - %t48 = call i32 @fn_str_eq(ptr %t47, ptr @.str867) - %t49 = icmp ne i32 %t48, 0 - br i1 %t49, label %then21, label %ifend23 + %t48 = load ptr, ptr %t6 + %t49 = call i32 @fn_str_eq(ptr %t48, ptr @.str970) + %t50 = icmp ne i32 %t49, 0 + br i1 %t50, label %then21, label %ifend23 then21: - %t50 = load ptr, ptr %t0 - %t51 = call ptr @fn_emit_len(ptr %t50) - store ptr %t51, ptr %retval + %t51 = load ptr, ptr %t0 + %t52 = getelementptr inbounds %Cmp_Node, ptr %t51, i32 0, i32 7 + %t53 = load ptr, ptr %t52 + %t54 = getelementptr inbounds %LSlice, ptr %t53, i32 0, i32 0 + %t55 = load ptr, ptr %t54 + %t56 = getelementptr inbounds ptr, ptr %t55, i32 0 + %t57 = load ptr, ptr %t56 + %t58 = call ptr @fn_emit_expr(ptr %t57) + store ptr %t58, ptr %t59 + %t60 = load ptr, ptr %t59 + %t61 = getelementptr inbounds %Cmp_Val, ptr %t60, i32 0, i32 0 + %t62 = load ptr, ptr %t61 + %t63 = call ptr @fn_str_concat(ptr @.str971, ptr %t62) + %t64 = call ptr @fn_str_concat(ptr %t63, ptr @.str972) + %t65 = call ptr @fn_emit_bind(ptr %t64) + %t66 = call ptr @fn_val(ptr %t65, ptr @.str973) + store ptr %t66, ptr %retval br label %ret ifend23: - %t52 = load ptr, ptr %t6 - %t53 = call i32 @fn_str_eq(ptr %t52, ptr @.str868) - %t54 = icmp ne i32 %t53, 0 - br i1 %t54, label %then24, label %ifend26 + %t67 = load ptr, ptr %t6 + %t68 = call i32 @fn_str_eq(ptr %t67, ptr @.str974) + %t69 = icmp ne i32 %t68, 0 + br i1 %t69, label %then24, label %ifend26 then24: - %t55 = load ptr, ptr %t0 - %t56 = call ptr @fn_emit_push(ptr %t55) - store ptr %t56, ptr %retval + %t70 = load ptr, ptr %t0 + %t71 = getelementptr inbounds %Cmp_Node, ptr %t70, i32 0, i32 7 + %t72 = load ptr, ptr %t71 + %t73 = getelementptr inbounds %LSlice, ptr %t72, i32 0, i32 0 + %t74 = load ptr, ptr %t73 + %t75 = getelementptr inbounds ptr, ptr %t74, i32 0 + %t76 = load ptr, ptr %t75 + %t77 = call ptr @fn_emit_expr(ptr %t76) + store ptr %t77, ptr %t78 + %t79 = load ptr, ptr %t0 + %t80 = getelementptr inbounds %Cmp_Node, ptr %t79, i32 0, i32 7 + %t81 = load ptr, ptr %t80 + %t82 = getelementptr inbounds %LSlice, ptr %t81, i32 0, i32 0 + %t83 = load ptr, ptr %t82 + %t84 = getelementptr inbounds ptr, ptr %t83, i32 1 + %t85 = load ptr, ptr %t84 + %t86 = call ptr @fn_emit_expr(ptr %t85) + store ptr %t86, ptr %t87 + call void @fn_emit(ptr @.str975) + %t88 = load ptr, ptr %t78 + %t89 = getelementptr inbounds %Cmp_Val, ptr %t88, i32 0, i32 0 + %t90 = load ptr, ptr %t89 + call void @fn_emit(ptr %t90) + call void @fn_emit(ptr @.str976) + %t91 = load ptr, ptr %t87 + %t92 = getelementptr inbounds %Cmp_Val, ptr %t91, i32 0, i32 0 + %t93 = load ptr, ptr %t92 + call void @fn_emit(ptr %t93) + call void @fn_emit(ptr @.str977) + %t94 = call ptr @fn_val(ptr @.str978, ptr @.str979) + store ptr %t94, ptr %retval br label %ret ifend26: - %t57 = load ptr, ptr %t6 - %t58 = call i32 @fn_str_eq(ptr %t57, ptr @.str869) - %t59 = icmp ne i32 %t58, 0 - br i1 %t59, label %then27, label %ifend29 + %t95 = load ptr, ptr %t6 + %t96 = call i32 @fn_str_eq(ptr %t95, ptr @.str980) + %t97 = icmp ne i32 %t96, 0 + br i1 %t97, label %then27, label %ifend29 then27: - %t60 = load ptr, ptr %t0 - %t61 = getelementptr inbounds %Cmp_Node, ptr %t60, i32 0, i32 7 - %t62 = load ptr, ptr %t61 - %t63 = getelementptr inbounds %LSlice, ptr %t62, i32 0, i32 0 - %t64 = load ptr, ptr %t63 - %t65 = getelementptr inbounds ptr, ptr %t64, i32 0 - %t66 = load ptr, ptr %t65 - %t67 = call ptr @fn_emit_expr(ptr %t66) - store ptr %t67, ptr %t68 - %t69 = load ptr, ptr %t68 - %t70 = getelementptr inbounds %Cmp_Val, ptr %t69, i32 0, i32 1 - %t71 = load ptr, ptr %t70 - %t72 = call ptr @fn_llty(ptr %t71) - %t73 = call i32 @fn_str_eq(ptr %t72, ptr @.str870) - %t74 = icmp ne i32 %t73, 0 - br i1 %t74, label %then30, label %ifend32 -then30: - %t75 = load ptr, ptr %t68 - store ptr %t75, ptr %retval - br label %ret -ifend32: - store i32 1, ptr @g_g_uses_intstr - %t76 = load ptr, ptr %t68 - %t77 = getelementptr inbounds %Cmp_Val, ptr %t76, i32 0, i32 0 - %t78 = load ptr, ptr %t77 - %t79 = call ptr @fn_str_concat(ptr @.str871, ptr %t78) - %t80 = call ptr @fn_str_concat(ptr %t79, ptr @.str872) - %t81 = call ptr @fn_emit_bind(ptr %t80) - %t82 = call ptr @fn_val(ptr %t81, ptr @.str873) - store ptr %t82, ptr %retval + call void @fn_emit(ptr @.str981) + %t98 = call ptr @fn_val(ptr @.str982, ptr @.str983) + store ptr %t98, ptr %retval br label %ret ifend29: - %t83 = load ptr, ptr %t6 - %t84 = call i32 @fn_str_eq(ptr %t83, ptr @.str874) - %t85 = icmp ne i32 %t84, 0 - br i1 %t85, label %then33, label %ifend35 -then33: - %t86 = load ptr, ptr %t0 - %t87 = getelementptr inbounds %Cmp_Node, ptr %t86, i32 0, i32 7 - %t88 = load ptr, ptr %t87 - %t89 = getelementptr inbounds %LSlice, ptr %t88, i32 0, i32 0 - %t90 = load ptr, ptr %t89 - %t91 = getelementptr inbounds ptr, ptr %t90, i32 0 - %t92 = load ptr, ptr %t91 - %t93 = call ptr @fn_emit_expr(ptr %t92) - store ptr %t93, ptr %t94 - %t95 = load ptr, ptr %t94 - %t96 = getelementptr inbounds %Cmp_Val, ptr %t95, i32 0, i32 1 - %t97 = load ptr, ptr %t96 - %t98 = call ptr @fn_llty(ptr %t97) - %t99 = call i32 @fn_str_eq(ptr %t98, ptr @.str875) - %t100 = icmp ne i32 %t99, 0 - br i1 %t100, label %then36, label %else37 -then36: - %t101 = load ptr, ptr %t94 - %t102 = getelementptr inbounds %Cmp_Val, ptr %t101, i32 0, i32 0 - %t103 = load ptr, ptr %t102 - %t104 = call ptr @fn_str_concat(ptr %t103, ptr @.str877) - %t105 = call ptr @fn_str_concat(ptr @.str876, ptr %t104) - call void @fn_emit(ptr %t105) - br label %ifend38 -else37: - %t106 = load ptr, ptr %t94 - %t107 = getelementptr inbounds %Cmp_Val, ptr %t106, i32 0, i32 0 + %t99 = load ptr, ptr %t6 + %t100 = call i32 @fn_str_eq(ptr %t99, ptr @.str984) + %t101 = icmp ne i32 %t100, 0 + br i1 %t101, label %then30, label %ifend32 +then30: + %t102 = load ptr, ptr %t0 + %t103 = getelementptr inbounds %Cmp_Node, ptr %t102, i32 0, i32 7 + %t104 = load ptr, ptr %t103 + %t105 = getelementptr inbounds %LSlice, ptr %t104, i32 0, i32 0 + %t106 = load ptr, ptr %t105 + %t107 = getelementptr inbounds ptr, ptr %t106, i32 0 %t108 = load ptr, ptr %t107 - %t109 = call ptr @fn_str_concat(ptr %t108, ptr @.str879) - %t110 = call ptr @fn_str_concat(ptr @.str878, ptr %t109) - call void @fn_emit(ptr %t110) - br label %ifend38 -ifend38: - %t111 = call ptr @fn_val(ptr @.str880, ptr @.str881) - store ptr %t111, ptr %retval + %t109 = call ptr @fn_emit_expr(ptr %t108) + store ptr %t109, ptr %t110 + %t111 = load ptr, ptr %t0 + %t112 = getelementptr inbounds %Cmp_Node, ptr %t111, i32 0, i32 7 + %t113 = load ptr, ptr %t112 + %t114 = getelementptr inbounds %LSlice, ptr %t113, i32 0, i32 0 + %t115 = load ptr, ptr %t114 + %t116 = getelementptr inbounds ptr, ptr %t115, i32 1 + %t117 = load ptr, ptr %t116 + %t118 = call ptr @fn_emit_expr(ptr %t117) + store ptr %t118, ptr %t119 + %t120 = load ptr, ptr %t110 + %t121 = getelementptr inbounds %Cmp_Val, ptr %t120, i32 0, i32 0 + %t122 = load ptr, ptr %t121 + %t123 = call ptr @fn_str_concat(ptr @.str985, ptr %t122) + %t124 = call ptr @fn_str_concat(ptr %t123, ptr @.str986) + %t125 = load ptr, ptr %t119 + %t126 = getelementptr inbounds %Cmp_Val, ptr %t125, i32 0, i32 0 + %t127 = load ptr, ptr %t126 + %t128 = call ptr @fn_str_concat(ptr %t124, ptr %t127) + %t129 = call ptr @fn_str_concat(ptr %t128, ptr @.str987) + %t130 = call ptr @fn_emit_bind(ptr %t129) + %t131 = call ptr @fn_val(ptr %t130, ptr @.str988) + store ptr %t131, ptr %retval + br label %ret +ifend32: + %t132 = load ptr, ptr %t6 + %t133 = call i32 @fn_str_eq(ptr %t132, ptr @.str989) + %t134 = icmp ne i32 %t133, 0 + br i1 %t134, label %then33, label %ifend35 +then33: + %t135 = load ptr, ptr %t0 + %t136 = getelementptr inbounds %Cmp_Node, ptr %t135, i32 0, i32 7 + %t137 = load ptr, ptr %t136 + %t138 = getelementptr inbounds %LSlice, ptr %t137, i32 0, i32 0 + %t139 = load ptr, ptr %t138 + %t140 = getelementptr inbounds ptr, ptr %t139, i32 0 + %t141 = load ptr, ptr %t140 + %t142 = call ptr @fn_emit_expr(ptr %t141) + store ptr %t142, ptr %t143 + %t144 = load ptr, ptr %t0 + %t145 = getelementptr inbounds %Cmp_Node, ptr %t144, i32 0, i32 7 + %t146 = load ptr, ptr %t145 + %t147 = getelementptr inbounds %LSlice, ptr %t146, i32 0, i32 0 + %t148 = load ptr, ptr %t147 + %t149 = getelementptr inbounds ptr, ptr %t148, i32 1 + %t150 = load ptr, ptr %t149 + %t151 = call ptr @fn_emit_expr(ptr %t150) + store ptr %t151, ptr %t152 + %t153 = load ptr, ptr %t0 + %t154 = getelementptr inbounds %Cmp_Node, ptr %t153, i32 0, i32 7 + %t155 = load ptr, ptr %t154 + %t156 = getelementptr inbounds %LSlice, ptr %t155, i32 0, i32 0 + %t157 = load ptr, ptr %t156 + %t158 = getelementptr inbounds ptr, ptr %t157, i32 2 + %t159 = load ptr, ptr %t158 + %t160 = call ptr @fn_emit_expr(ptr %t159) + store ptr %t160, ptr %t161 + call void @fn_emit(ptr @.str990) + %t162 = load ptr, ptr %t143 + %t163 = getelementptr inbounds %Cmp_Val, ptr %t162, i32 0, i32 0 + %t164 = load ptr, ptr %t163 + call void @fn_emit(ptr %t164) + call void @fn_emit(ptr @.str991) + %t165 = load ptr, ptr %t152 + %t166 = getelementptr inbounds %Cmp_Val, ptr %t165, i32 0, i32 0 + %t167 = load ptr, ptr %t166 + call void @fn_emit(ptr %t167) + call void @fn_emit(ptr @.str992) + %t168 = load ptr, ptr %t161 + %t169 = getelementptr inbounds %Cmp_Val, ptr %t168, i32 0, i32 0 + %t170 = load ptr, ptr %t169 + call void @fn_emit(ptr %t170) + call void @fn_emit(ptr @.str993) + %t171 = call ptr @fn_val(ptr @.str994, ptr @.str995) + store ptr %t171, ptr %retval br label %ret ifend35: - %t112 = load ptr, ptr %t6 - %t113 = call i32 @fn_str_eq(ptr %t112, ptr @.str882) - %t114 = icmp ne i32 %t113, 0 - br i1 %t114, label %then39, label %ifend41 + %t172 = load ptr, ptr %t6 + %t173 = call i32 @fn_str_eq(ptr %t172, ptr @.str996) + %t174 = icmp ne i32 %t173, 0 + br i1 %t174, label %then36, label %ifend38 +then36: + %t175 = load ptr, ptr %t0 + %t176 = getelementptr inbounds %Cmp_Node, ptr %t175, i32 0, i32 7 + %t177 = load ptr, ptr %t176 + %t178 = getelementptr inbounds %LSlice, ptr %t177, i32 0, i32 0 + %t179 = load ptr, ptr %t178 + %t180 = getelementptr inbounds ptr, ptr %t179, i32 0 + %t181 = load ptr, ptr %t180 + %t182 = call ptr @fn_emit_expr(ptr %t181) + store ptr %t182, ptr %t183 + %t184 = load ptr, ptr %t183 + %t185 = getelementptr inbounds %Cmp_Val, ptr %t184, i32 0, i32 0 + %t186 = load ptr, ptr %t185 + %t187 = call ptr @fn_str_concat(ptr @.str997, ptr %t186) + %t188 = call ptr @fn_str_concat(ptr %t187, ptr @.str998) + %t189 = call ptr @fn_emit_bind(ptr %t188) + %t190 = call ptr @fn_val(ptr %t189, ptr @.str999) + store ptr %t190, ptr %retval + br label %ret +ifend38: + %t191 = load ptr, ptr %t6 + %t192 = call i32 @fn_str_eq(ptr %t191, ptr @.str1000) + %t193 = icmp ne i32 %t192, 0 + br i1 %t193, label %then39, label %ifend41 then39: - %t115 = load ptr, ptr %t0 - %t116 = getelementptr inbounds %Cmp_Node, ptr %t115, i32 0, i32 7 - %t117 = load ptr, ptr %t116 - %t118 = getelementptr inbounds %LSlice, ptr %t117, i32 0, i32 0 - %t119 = load ptr, ptr %t118 - %t120 = getelementptr inbounds ptr, ptr %t119, i32 0 - %t121 = load ptr, ptr %t120 - %t122 = call ptr @fn_emit_expr(ptr %t121) - store ptr %t122, ptr %t123 - %t124 = load ptr, ptr %t123 - %t125 = getelementptr inbounds %Cmp_Val, ptr %t124, i32 0, i32 0 - %t126 = load ptr, ptr %t125 - %t127 = call ptr @fn_str_concat(ptr @.str883, ptr %t126) - %t128 = call ptr @fn_str_concat(ptr %t127, ptr @.str884) - %t129 = call ptr @fn_emit_bind(ptr %t128) - store ptr %t129, ptr %t130 - %t131 = load ptr, ptr %t130 - %t132 = call ptr @fn_str_concat(ptr @.str885, ptr %t131) - %t133 = call ptr @fn_str_concat(ptr %t132, ptr @.str886) - %t134 = call ptr @fn_emit_bind(ptr %t133) - %t135 = call ptr @fn_val(ptr %t134, ptr @.str887) - store ptr %t135, ptr %retval + %t194 = load ptr, ptr %t0 + %t195 = getelementptr inbounds %Cmp_Node, ptr %t194, i32 0, i32 7 + %t196 = load ptr, ptr %t195 + %t197 = getelementptr inbounds %LSlice, ptr %t196, i32 0, i32 0 + %t198 = load ptr, ptr %t197 + %t199 = getelementptr inbounds ptr, ptr %t198, i32 0 + %t200 = load ptr, ptr %t199 + %t201 = call ptr @fn_emit_expr(ptr %t200) + store ptr %t201, ptr %t202 + %t203 = load ptr, ptr %t202 + %t204 = getelementptr inbounds %Cmp_Val, ptr %t203, i32 0, i32 0 + %t205 = load ptr, ptr %t204 + %t206 = call ptr @fn_str_concat(ptr @.str1001, ptr %t205) + %t207 = call ptr @fn_str_concat(ptr %t206, ptr @.str1002) + %t208 = call ptr @fn_emit_bind(ptr %t207) + %t209 = call ptr @fn_val(ptr %t208, ptr @.str1003) + store ptr %t209, ptr %retval br label %ret ifend41: - %t136 = load ptr, ptr %t6 - %t137 = call i32 @fn_str_eq(ptr %t136, ptr @.str888) - %t138 = icmp ne i32 %t137, 0 - br i1 %t138, label %then42, label %ifend44 + %t210 = load ptr, ptr %t6 + %t211 = call i32 @fn_str_eq(ptr %t210, ptr @.str1004) + %t212 = icmp ne i32 %t211, 0 + br i1 %t212, label %then42, label %ifend44 then42: - %t139 = load ptr, ptr %t0 - %t140 = getelementptr inbounds %Cmp_Node, ptr %t139, i32 0, i32 7 - %t141 = load ptr, ptr %t140 - %t142 = getelementptr inbounds %LSlice, ptr %t141, i32 0, i32 0 - %t143 = load ptr, ptr %t142 - %t144 = getelementptr inbounds ptr, ptr %t143, i32 0 - %t145 = load ptr, ptr %t144 - %t146 = call ptr @fn_emit_expr(ptr %t145) - store ptr %t146, ptr %t147 - %t148 = load ptr, ptr %t147 - %t149 = getelementptr inbounds %Cmp_Val, ptr %t148, i32 0, i32 0 - %t150 = load ptr, ptr %t149 - %t151 = call ptr @fn_str_concat(ptr @.str889, ptr %t150) - %t152 = call ptr @fn_str_concat(ptr %t151, ptr @.str890) - %t153 = call ptr @fn_emit_bind(ptr %t152) - store ptr %t153, ptr %t154 - %t155 = load ptr, ptr %t154 - %t156 = call ptr @fn_str_concat(ptr @.str891, ptr %t155) - %t157 = call ptr @fn_str_concat(ptr %t156, ptr @.str892) - %t158 = call ptr @fn_emit_bind(ptr %t157) - store ptr %t158, ptr %t159 - %t160 = load ptr, ptr %t159 - %t161 = call ptr @fn_str_concat(ptr @.str893, ptr %t160) - %t162 = call ptr @fn_str_concat(ptr %t161, ptr @.str894) - %t163 = call ptr @fn_emit_bind(ptr %t162) - %t164 = call ptr @fn_val(ptr %t163, ptr @.str895) - store ptr %t164, ptr %retval + %t213 = load ptr, ptr %t0 + %t214 = getelementptr inbounds %Cmp_Node, ptr %t213, i32 0, i32 7 + %t215 = load ptr, ptr %t214 + %t216 = getelementptr inbounds %LSlice, ptr %t215, i32 0, i32 0 + %t217 = load ptr, ptr %t216 + %t218 = getelementptr inbounds ptr, ptr %t217, i32 0 + %t219 = load ptr, ptr %t218 + %t220 = call ptr @fn_emit_expr(ptr %t219) + store ptr %t220, ptr %t221 + %t222 = load ptr, ptr %t0 + %t223 = getelementptr inbounds %Cmp_Node, ptr %t222, i32 0, i32 7 + %t224 = load ptr, ptr %t223 + %t225 = getelementptr inbounds %LSlice, ptr %t224, i32 0, i32 0 + %t226 = load ptr, ptr %t225 + %t227 = getelementptr inbounds ptr, ptr %t226, i32 1 + %t228 = load ptr, ptr %t227 + %t229 = call ptr @fn_emit_expr(ptr %t228) + store ptr %t229, ptr %t230 + call void @fn_emit(ptr @.str1005) + %t231 = load ptr, ptr %t221 + %t232 = getelementptr inbounds %Cmp_Val, ptr %t231, i32 0, i32 0 + %t233 = load ptr, ptr %t232 + call void @fn_emit(ptr %t233) + call void @fn_emit(ptr @.str1006) + %t234 = load ptr, ptr %t230 + %t235 = getelementptr inbounds %Cmp_Val, ptr %t234, i32 0, i32 0 + %t236 = load ptr, ptr %t235 + call void @fn_emit(ptr %t236) + call void @fn_emit(ptr @.str1007) + %t237 = call ptr @fn_val(ptr @.str1008, ptr @.str1009) + store ptr %t237, ptr %retval br label %ret ifend44: - %t165 = load ptr, ptr %t6 - %t166 = call i32 @fn_str_eq(ptr %t165, ptr @.str896) - %t167 = icmp ne i32 %t166, 0 - br i1 %t167, label %then45, label %ifend47 + %t238 = load ptr, ptr %t6 + %t239 = call i32 @fn_str_eq(ptr %t238, ptr @.str1010) + %t240 = icmp ne i32 %t239, 0 + br i1 %t240, label %then45, label %ifend47 then45: - %t168 = load ptr, ptr %t0 - %t169 = getelementptr inbounds %Cmp_Node, ptr %t168, i32 0, i32 7 - %t170 = load ptr, ptr %t169 - %t171 = getelementptr inbounds %LSlice, ptr %t170, i32 0, i32 0 - %t172 = load ptr, ptr %t171 - %t173 = getelementptr inbounds ptr, ptr %t172, i32 0 - %t174 = load ptr, ptr %t173 - %t175 = call ptr @fn_emit_expr(ptr %t174) - store ptr %t175, ptr %t176 - %t177 = load ptr, ptr %t176 - %t178 = getelementptr inbounds %Cmp_Val, ptr %t177, i32 0, i32 0 - %t179 = load ptr, ptr %t178 - %t180 = call ptr @fn_str_concat(ptr @.str897, ptr %t179) - %t181 = call ptr @fn_str_concat(ptr %t180, ptr @.str898) - %t182 = call ptr @fn_emit_bind(ptr %t181) - %t183 = call ptr @fn_val(ptr %t182, ptr @.str899) - store ptr %t183, ptr %retval + %t241 = load ptr, ptr %t0 + %t242 = getelementptr inbounds %Cmp_Node, ptr %t241, i32 0, i32 7 + %t243 = load ptr, ptr %t242 + %t244 = getelementptr inbounds %LSlice, ptr %t243, i32 0, i32 0 + %t245 = load ptr, ptr %t244 + %t246 = getelementptr inbounds ptr, ptr %t245, i32 0 + %t247 = load ptr, ptr %t246 + %t248 = call ptr @fn_emit_expr(ptr %t247) + store ptr %t248, ptr %t249 + %t250 = load ptr, ptr %t249 + %t251 = getelementptr inbounds %Cmp_Val, ptr %t250, i32 0, i32 0 + %t252 = load ptr, ptr %t251 + %t253 = call ptr @fn_str_concat(ptr @.str1011, ptr %t252) + %t254 = call ptr @fn_str_concat(ptr %t253, ptr @.str1012) + %t255 = call ptr @fn_emit_bind(ptr %t254) + %t256 = call ptr @fn_val(ptr %t255, ptr @.str1013) + store ptr %t256, ptr %retval br label %ret ifend47: - %t184 = load ptr, ptr %t6 - %t185 = call i32 @fn_str_eq(ptr %t184, ptr @.str900) - %t186 = icmp ne i32 %t185, 0 - br i1 %t186, label %then48, label %ifend50 + %t257 = load ptr, ptr %t6 + %t258 = call i32 @fn_str_eq(ptr %t257, ptr @.str1014) + %t259 = icmp ne i32 %t258, 0 + br i1 %t259, label %then48, label %ifend50 then48: - %t187 = load ptr, ptr %t0 - %t188 = getelementptr inbounds %Cmp_Node, ptr %t187, i32 0, i32 7 - %t189 = load ptr, ptr %t188 - %t190 = getelementptr inbounds %LSlice, ptr %t189, i32 0, i32 0 - %t191 = load ptr, ptr %t190 - %t192 = getelementptr inbounds ptr, ptr %t191, i32 0 - %t193 = load ptr, ptr %t192 - %t194 = call ptr @fn_emit_expr(ptr %t193) - store ptr %t194, ptr %t195 - %t196 = load ptr, ptr %t195 - %t197 = getelementptr inbounds %Cmp_Val, ptr %t196, i32 0, i32 0 - %t198 = load ptr, ptr %t197 - %t199 = call ptr @fn_str_concat(ptr @.str901, ptr %t198) - %t200 = call ptr @fn_str_concat(ptr %t199, ptr @.str902) - %t201 = call ptr @fn_emit_bind(ptr %t200) - %t202 = call ptr @fn_val(ptr %t201, ptr @.str903) - store ptr %t202, ptr %retval + %t260 = call ptr @fn_emit_bind(ptr @.str1015) + store ptr %t260, ptr %t261 + %t262 = load ptr, ptr %t261 + %t263 = call ptr @fn_str_concat(ptr @.str1016, ptr %t262) + %t264 = call ptr @fn_str_concat(ptr %t263, ptr @.str1017) + %t265 = call ptr @fn_emit_bind(ptr %t264) + store ptr %t265, ptr %t266 + %t267 = load ptr, ptr %t266 + %t268 = call ptr @fn_str_concat(ptr @.str1018, ptr %t267) + %t269 = call ptr @fn_str_concat(ptr %t268, ptr @.str1019) + %t270 = call ptr @fn_emit_bind(ptr %t269) + %t271 = call ptr @fn_val(ptr %t270, ptr @.str1020) + store ptr %t271, ptr %retval br label %ret ifend50: - %t203 = load ptr, ptr %t6 - %t204 = call i32 @fn_is_intrinsic(ptr %t203) - %t205 = icmp ne i32 %t204, 0 - br i1 %t205, label %then51, label %ifend53 + %t272 = load ptr, ptr %t6 + %t273 = call i32 @fn_str_eq(ptr %t272, ptr @.str1021) + %t274 = icmp ne i32 %t273, 0 + br i1 %t274, label %then51, label %ifend53 then51: - %t206 = load ptr, ptr %t6 - %t207 = load ptr, ptr %t0 - %t208 = call ptr @fn_emit_intrinsic(ptr %t206, ptr %t207) - store ptr %t208, ptr %retval + %t275 = call ptr @fn_emit_bind(ptr @.str1022) + %t276 = call ptr @fn_val(ptr %t275, ptr @.str1023) + store ptr %t276, ptr %retval br label %ret ifend53: - %t209 = load ptr, ptr %t6 - %t210 = call i32 @fn_is_intrinsic2(ptr %t209) - %t211 = icmp ne i32 %t210, 0 - br i1 %t211, label %then54, label %ifend56 + %t277 = load ptr, ptr %t6 + %t278 = call i32 @fn_str_eq(ptr %t277, ptr @.str1024) + %t279 = icmp ne i32 %t278, 0 + br i1 %t279, label %then54, label %ifend56 then54: - %t212 = load ptr, ptr %t6 - %t213 = load ptr, ptr %t0 - %t214 = call ptr @fn_emit_intrinsic2(ptr %t212, ptr %t213) - store ptr %t214, ptr %retval + call void @fn_emit(ptr @.str1025) + %t280 = call ptr @fn_val(ptr @.str1026, ptr @.str1027) + store ptr %t280, ptr %retval br label %ret ifend56: - %t215 = load ptr, ptr %t6 - %t216 = call i32 @fn_is_math_builtin(ptr %t215) - %t217 = icmp ne i32 %t216, 0 - br i1 %t217, label %then57, label %ifend59 + %t281 = load ptr, ptr %t6 + %t282 = call i32 @fn_str_eq(ptr %t281, ptr @.str1028) + %t283 = icmp ne i32 %t282, 0 + br i1 %t283, label %then57, label %ifend59 then57: - %t218 = load ptr, ptr %t6 - %t219 = load ptr, ptr %t0 - %t220 = call ptr @fn_emit_math_builtin(ptr %t218, ptr %t219) - store ptr %t220, ptr %retval + call void @fn_emit(ptr @.str1029) + %t284 = call ptr @fn_val(ptr @.str1030, ptr @.str1031) + store ptr %t284, ptr %retval br label %ret ifend59: - %t221 = load ptr, ptr %t6 - %t222 = call ptr @fn_find_fn(ptr %t221) - store ptr %t222, ptr %t223 - %t224 = load ptr, ptr %t6 - store ptr %t224, ptr %t225 - %t226 = load ptr, ptr %t223 - %t227 = icmp eq ptr %t226, null - %t228 = zext i1 %t227 to i32 - %t229 = icmp ne i32 %t228, 0 - br i1 %t229, label %then60, label %ifend62 + %t285 = load ptr, ptr %t6 + %t286 = call i32 @fn_str_eq(ptr %t285, ptr @.str1032) + %t287 = icmp ne i32 %t286, 0 + br i1 %t287, label %then60, label %ifend62 then60: - %t230 = load ptr, ptr %t6 - %t231 = call ptr @fn_str_concat(ptr @.str904, ptr %t230) - store ptr %t231, ptr %t232 - %t233 = load ptr, ptr %t232 - %t234 = call ptr @fn_find_fn(ptr %t233) - store ptr %t234, ptr %t223 - %t235 = load ptr, ptr %t223 - %t236 = icmp eq ptr %t235, null - %t237 = zext i1 %t236 to i32 - %t238 = icmp ne i32 %t237, 0 - br i1 %t238, label %then63, label %ifend65 -then63: - %t239 = load ptr, ptr %t6 - %t240 = call ptr @fn_str_concat(ptr @.str905, ptr %t239) - call void @fn_perr(ptr %t240) - br label %ifend65 -ifend65: - %t241 = load ptr, ptr %t232 - store ptr %t241, ptr %t225 - br label %ifend62 + call void @fn_emit(ptr @.str1033) + %t288 = call ptr @fn_val(ptr @.str1034, ptr @.str1035) + store ptr %t288, ptr %retval + br label %ret ifend62: - %t242 = getelementptr %LSlice, ptr null, i32 1 - %t243 = ptrtoint ptr %t242 to i64 - %t244 = call ptr @malloc(i64 %t243) - %t245 = getelementptr inbounds %LSlice, ptr %t244, i32 0, i32 0 - store ptr null, ptr %t245 - %t246 = getelementptr inbounds %LSlice, ptr %t244, i32 0, i32 1 - store i32 0, ptr %t246 - %t247 = getelementptr inbounds %LSlice, ptr %t244, i32 0, i32 2 - store i32 0, ptr %t247 - store ptr %t244, ptr %t248 - %t249 = getelementptr %LSlice, ptr null, i32 1 - %t250 = ptrtoint ptr %t249 to i64 - %t251 = call ptr @malloc(i64 %t250) - %t252 = getelementptr inbounds %LSlice, ptr %t251, i32 0, i32 0 - store ptr null, ptr %t252 - %t253 = getelementptr inbounds %LSlice, ptr %t251, i32 0, i32 1 - store i32 0, ptr %t253 - %t254 = getelementptr inbounds %LSlice, ptr %t251, i32 0, i32 2 - store i32 0, ptr %t254 - store ptr %t251, ptr %t255 - store i32 0, ptr %t256 - br label %wcond66 -wcond66: - %t257 = load i32, ptr %t256 - %t258 = load ptr, ptr %t0 - %t259 = getelementptr inbounds %Cmp_Node, ptr %t258, i32 0, i32 7 - %t260 = load ptr, ptr %t259 - %t261 = getelementptr inbounds %LSlice, ptr %t260, i32 0, i32 1 - %t262 = load i32, ptr %t261 - %t263 = icmp slt i32 %t257, %t262 - %t264 = zext i1 %t263 to i32 - %t265 = icmp ne i32 %t264, 0 - br i1 %t265, label %wbody67, label %wend68 -wbody67: - %t266 = load ptr, ptr %t0 - %t267 = getelementptr inbounds %Cmp_Node, ptr %t266, i32 0, i32 7 - %t268 = load ptr, ptr %t267 - %t269 = getelementptr inbounds %LSlice, ptr %t268, i32 0, i32 0 - %t270 = load ptr, ptr %t269 - %t271 = load i32, ptr %t256 - %t272 = getelementptr inbounds ptr, ptr %t270, i32 %t271 - %t273 = load ptr, ptr %t272 - %t274 = call ptr @fn_emit_expr(ptr %t273) - store ptr %t274, ptr %t275 - %t276 = load ptr, ptr %t248 - %t277 = getelementptr inbounds %LSlice, ptr %t276, i32 0, i32 1 - %t278 = getelementptr inbounds %LSlice, ptr %t276, i32 0, i32 2 - %t279 = getelementptr inbounds %LSlice, ptr %t276, i32 0, i32 0 - %t280 = load i32, ptr %t277 - %t281 = load i32, ptr %t278 - %t282 = icmp sge i32 %t280, %t281 - br i1 %t282, label %grow69, label %put70 -grow69: - %t283 = mul i32 %t281, 2 - %t284 = icmp eq i32 %t281, 0 - %t285 = select i1 %t284, i32 8, i32 %t283 - %t286 = getelementptr ptr, ptr null, i32 1 - %t287 = ptrtoint ptr %t286 to i64 - %t288 = zext i32 %t285 to i64 - %t289 = mul i64 %t288, %t287 - %t290 = load ptr, ptr %t279 - %t291 = call ptr @realloc(ptr %t290, i64 %t289) - store ptr %t291, ptr %t279 - store i32 %t285, ptr %t278 - br label %put70 -put70: - %t292 = load ptr, ptr %t275 - %t293 = getelementptr inbounds %Cmp_Val, ptr %t292, i32 0, i32 0 + %t289 = load ptr, ptr %t6 + %t290 = call i32 @fn_str_eq(ptr %t289, ptr @.str1036) + %t291 = icmp ne i32 %t290, 0 + br i1 %t291, label %then63, label %ifend65 +then63: + %t292 = load ptr, ptr %t0 + %t293 = getelementptr inbounds %Cmp_Node, ptr %t292, i32 0, i32 7 %t294 = load ptr, ptr %t293 - %t295 = load ptr, ptr %t279 - %t296 = getelementptr inbounds ptr, ptr %t295, i32 %t280 - store ptr %t294, ptr %t296 - %t297 = add i32 %t280, 1 - store i32 %t297, ptr %t277 - %t298 = load ptr, ptr %t255 - %t299 = getelementptr inbounds %LSlice, ptr %t298, i32 0, i32 1 - %t300 = getelementptr inbounds %LSlice, ptr %t298, i32 0, i32 2 - %t301 = getelementptr inbounds %LSlice, ptr %t298, i32 0, i32 0 - %t302 = load i32, ptr %t299 - %t303 = load i32, ptr %t300 - %t304 = icmp sge i32 %t302, %t303 - br i1 %t304, label %grow71, label %put72 -grow71: - %t305 = mul i32 %t303, 2 - %t306 = icmp eq i32 %t303, 0 - %t307 = select i1 %t306, i32 8, i32 %t305 - %t308 = getelementptr ptr, ptr null, i32 1 - %t309 = ptrtoint ptr %t308 to i64 - %t310 = zext i32 %t307 to i64 - %t311 = mul i64 %t310, %t309 - %t312 = load ptr, ptr %t301 - %t313 = call ptr @realloc(ptr %t312, i64 %t311) - store ptr %t313, ptr %t301 - store i32 %t307, ptr %t300 - br label %put72 -put72: - %t314 = load ptr, ptr %t275 - %t315 = getelementptr inbounds %Cmp_Val, ptr %t314, i32 0, i32 1 - %t316 = load ptr, ptr %t315 - %t317 = load ptr, ptr %t301 - %t318 = getelementptr inbounds ptr, ptr %t317, i32 %t302 - store ptr %t316, ptr %t318 - %t319 = add i32 %t302, 1 - store i32 %t319, ptr %t299 - %t320 = load i32, ptr %t256 - %t321 = add i32 %t320, 1 - store i32 %t321, ptr %t256 - br label %wcond66 -wend68: - %t322 = load ptr, ptr %t223 - %t323 = getelementptr inbounds %Cmp_Node, ptr %t322, i32 0, i32 3 - %t324 = load ptr, ptr %t323 - %t325 = call ptr @fn_llty(ptr %t324) - store ptr %t325, ptr %t326 - call void @fn_emit(ptr @.str906) - store ptr @.str907, ptr %t327 - %t328 = load ptr, ptr %t326 - %t329 = call i32 @fn_str_eq(ptr %t328, ptr @.str908) - %t330 = icmp eq i32 %t329, 0 - %t331 = zext i1 %t330 to i32 + %t295 = getelementptr inbounds %LSlice, ptr %t294, i32 0, i32 0 + %t296 = load ptr, ptr %t295 + %t297 = getelementptr inbounds ptr, ptr %t296, i32 0 + %t298 = load ptr, ptr %t297 + %t299 = call ptr @fn_emit_expr(ptr %t298) + store ptr %t299, ptr %t300 + call void @fn_emit(ptr @.str1037) + %t301 = load ptr, ptr %t300 + %t302 = getelementptr inbounds %Cmp_Val, ptr %t301, i32 0, i32 0 + %t303 = load ptr, ptr %t302 + call void @fn_emit(ptr %t303) + call void @fn_emit(ptr @.str1038) + %t304 = call ptr @fn_val(ptr @.str1039, ptr @.str1040) + store ptr %t304, ptr %retval + br label %ret +ifend65: + %t305 = load ptr, ptr %t6 + %t306 = call i32 @fn_str_eq(ptr %t305, ptr @.str1041) + %t307 = icmp ne i32 %t306, 0 + br i1 %t307, label %then66, label %ifend68 +then66: + %t308 = load ptr, ptr %t0 + %t309 = getelementptr inbounds %Cmp_Node, ptr %t308, i32 0, i32 7 + %t310 = load ptr, ptr %t309 + %t311 = getelementptr inbounds %LSlice, ptr %t310, i32 0, i32 0 + %t312 = load ptr, ptr %t311 + %t313 = getelementptr inbounds ptr, ptr %t312, i32 0 + %t314 = load ptr, ptr %t313 + %t315 = call ptr @fn_emit_expr(ptr %t314) + store ptr %t315, ptr %t316 + call void @fn_emit(ptr @.str1042) + %t317 = load ptr, ptr %t316 + %t318 = getelementptr inbounds %Cmp_Val, ptr %t317, i32 0, i32 0 + %t319 = load ptr, ptr %t318 + call void @fn_emit(ptr %t319) + call void @fn_emit(ptr @.str1043) + %t320 = call ptr @fn_val(ptr @.str1044, ptr @.str1045) + store ptr %t320, ptr %retval + br label %ret +ifend68: + %t322 = load ptr, ptr %t6 + %t323 = call i32 @fn_str_eq(ptr %t322, ptr @.str1046) + %t324 = icmp ne i32 %t323, 0 + %t325 = zext i1 %t324 to i32 + store i32 %t325, ptr %t321 + br i1 %t324, label %sc69, label %scend70 +sc69: + %t326 = call ptr @fn_find_extern(ptr @.str1047) + %t327 = icmp eq ptr %t326, null + %t328 = zext i1 %t327 to i32 + %t329 = icmp ne i32 %t328, 0 + %t330 = zext i1 %t329 to i32 + store i32 %t330, ptr %t321 + br label %scend70 +scend70: + %t331 = load i32, ptr %t321 %t332 = icmp ne i32 %t331, 0 - br i1 %t332, label %then73, label %ifend75 -then73: - %t333 = call ptr @fn_nreg() - store ptr %t333, ptr %t327 - %t334 = load ptr, ptr %t327 - call void @fn_emit(ptr %t334) - call void @fn_emit(ptr @.str909) - br label %ifend75 -ifend75: - call void @fn_emit(ptr @.str910) - %t335 = load ptr, ptr %t326 - call void @fn_emit(ptr %t335) - call void @fn_emit(ptr @.str911) - %t336 = load ptr, ptr %t225 - call void @fn_emit(ptr %t336) - call void @fn_emit(ptr @.str912) - store i32 0, ptr %t256 - br label %wcond76 -wcond76: - %t337 = load i32, ptr %t256 - %t338 = load ptr, ptr %t248 - %t339 = getelementptr inbounds %LSlice, ptr %t338, i32 0, i32 1 - %t340 = load i32, ptr %t339 - %t341 = icmp slt i32 %t337, %t340 - %t342 = zext i1 %t341 to i32 - %t343 = icmp ne i32 %t342, 0 - br i1 %t343, label %wbody77, label %wend78 -wbody77: - %t344 = load i32, ptr %t256 - %t345 = icmp sgt i32 %t344, 0 - %t346 = zext i1 %t345 to i32 - %t347 = icmp ne i32 %t346, 0 - br i1 %t347, label %then79, label %ifend81 -then79: - call void @fn_emit(ptr @.str913) - br label %ifend81 -ifend81: - %t348 = load ptr, ptr %t255 - %t349 = getelementptr inbounds %LSlice, ptr %t348, i32 0, i32 0 - %t350 = load ptr, ptr %t349 - %t351 = load i32, ptr %t256 - %t352 = getelementptr inbounds ptr, ptr %t350, i32 %t351 + br i1 %t332, label %then71, label %ifend73 +then71: + store i32 1, ptr @g_g_uses_loopback + %t333 = load ptr, ptr %t0 + %t334 = getelementptr inbounds %Cmp_Node, ptr %t333, i32 0, i32 7 + %t335 = load ptr, ptr %t334 + %t336 = getelementptr inbounds %LSlice, ptr %t335, i32 0, i32 0 + %t337 = load ptr, ptr %t336 + %t338 = getelementptr inbounds ptr, ptr %t337, i32 0 + %t339 = load ptr, ptr %t338 + %t340 = call ptr @fn_emit_expr(ptr %t339) + store ptr %t340, ptr %t341 + %t342 = load ptr, ptr %t0 + %t343 = getelementptr inbounds %Cmp_Node, ptr %t342, i32 0, i32 7 + %t344 = load ptr, ptr %t343 + %t345 = getelementptr inbounds %LSlice, ptr %t344, i32 0, i32 0 + %t346 = load ptr, ptr %t345 + %t347 = getelementptr inbounds ptr, ptr %t346, i32 1 + %t348 = load ptr, ptr %t347 + %t349 = call ptr @fn_emit_expr(ptr %t348) + store ptr %t349, ptr %t350 + %t351 = load ptr, ptr %t0 + %t352 = getelementptr inbounds %Cmp_Node, ptr %t351, i32 0, i32 7 %t353 = load ptr, ptr %t352 - %t354 = call ptr @fn_llty(ptr %t353) - call void @fn_emit(ptr %t354) - call void @fn_emit(ptr @.str914) - %t355 = load ptr, ptr %t248 - %t356 = getelementptr inbounds %LSlice, ptr %t355, i32 0, i32 0 + %t354 = getelementptr inbounds %LSlice, ptr %t353, i32 0, i32 0 + %t355 = load ptr, ptr %t354 + %t356 = getelementptr inbounds ptr, ptr %t355, i32 2 %t357 = load ptr, ptr %t356 - %t358 = load i32, ptr %t256 - %t359 = getelementptr inbounds ptr, ptr %t357, i32 %t358 - %t360 = load ptr, ptr %t359 - call void @fn_emit(ptr %t360) - %t361 = load i32, ptr %t256 - %t362 = add i32 %t361, 1 - store i32 %t362, ptr %t256 - br label %wcond76 -wend78: - call void @fn_emit(ptr @.str915) - %t363 = load ptr, ptr %t327 - %t364 = load ptr, ptr %t223 - %t365 = getelementptr inbounds %Cmp_Node, ptr %t364, i32 0, i32 3 - %t366 = load ptr, ptr %t365 - %t367 = call ptr @fn_val(ptr %t363, ptr %t366) - store ptr %t367, ptr %retval + %t358 = call ptr @fn_emit_expr(ptr %t357) + store ptr %t358, ptr %t359 + call void @fn_emit(ptr @.str1048) + %t360 = load ptr, ptr %t341 + %t361 = getelementptr inbounds %Cmp_Val, ptr %t360, i32 0, i32 0 + %t362 = load ptr, ptr %t361 + call void @fn_emit(ptr %t362) + call void @fn_emit(ptr @.str1049) + %t363 = load ptr, ptr %t350 + %t364 = getelementptr inbounds %Cmp_Val, ptr %t363, i32 0, i32 0 + %t365 = load ptr, ptr %t364 + call void @fn_emit(ptr %t365) + call void @fn_emit(ptr @.str1050) + %t366 = load ptr, ptr %t359 + %t367 = getelementptr inbounds %Cmp_Val, ptr %t366, i32 0, i32 0 + %t368 = load ptr, ptr %t367 + call void @fn_emit(ptr %t368) + call void @fn_emit(ptr @.str1051) + %t369 = call ptr @fn_val(ptr @.str1052, ptr @.str1053) + store ptr %t369, ptr %retval + br label %ret +ifend73: + %t371 = load ptr, ptr %t6 + %t372 = call i32 @fn_str_eq(ptr %t371, ptr @.str1054) + %t373 = icmp ne i32 %t372, 0 + %t374 = zext i1 %t373 to i32 + store i32 %t374, ptr %t370 + br i1 %t373, label %sc74, label %scend75 +sc74: + %t375 = call ptr @fn_find_extern(ptr @.str1055) + %t376 = icmp eq ptr %t375, null + %t377 = zext i1 %t376 to i32 + %t378 = icmp ne i32 %t377, 0 + %t379 = zext i1 %t378 to i32 + store i32 %t379, ptr %t370 + br label %scend75 +scend75: + %t380 = load i32, ptr %t370 + %t381 = icmp ne i32 %t380, 0 + br i1 %t381, label %then76, label %ifend78 +then76: + store i32 1, ptr @g_g_uses_loopback + %t382 = load ptr, ptr %t0 + %t383 = getelementptr inbounds %Cmp_Node, ptr %t382, i32 0, i32 7 + %t384 = load ptr, ptr %t383 + %t385 = getelementptr inbounds %LSlice, ptr %t384, i32 0, i32 0 + %t386 = load ptr, ptr %t385 + %t387 = getelementptr inbounds ptr, ptr %t386, i32 0 + %t388 = load ptr, ptr %t387 + %t389 = call ptr @fn_emit_expr(ptr %t388) + store ptr %t389, ptr %t390 + %t391 = load ptr, ptr %t0 + %t392 = getelementptr inbounds %Cmp_Node, ptr %t391, i32 0, i32 7 + %t393 = load ptr, ptr %t392 + %t394 = getelementptr inbounds %LSlice, ptr %t393, i32 0, i32 0 + %t395 = load ptr, ptr %t394 + %t396 = getelementptr inbounds ptr, ptr %t395, i32 1 + %t397 = load ptr, ptr %t396 + %t398 = call ptr @fn_emit_expr(ptr %t397) + store ptr %t398, ptr %t399 + %t400 = load ptr, ptr %t390 + %t401 = getelementptr inbounds %Cmp_Val, ptr %t400, i32 0, i32 0 + %t402 = load ptr, ptr %t401 + %t403 = call ptr @fn_str_concat(ptr @.str1056, ptr %t402) + %t404 = call ptr @fn_str_concat(ptr %t403, ptr @.str1057) + %t405 = load ptr, ptr %t399 + %t406 = getelementptr inbounds %Cmp_Val, ptr %t405, i32 0, i32 0 + %t407 = load ptr, ptr %t406 + %t408 = call ptr @fn_str_concat(ptr %t404, ptr %t407) + %t409 = call ptr @fn_str_concat(ptr %t408, ptr @.str1058) + %t410 = call ptr @fn_emit_bind(ptr %t409) + %t411 = call ptr @fn_val(ptr %t410, ptr @.str1059) + store ptr %t411, ptr %retval + br label %ret +ifend78: + %t412 = load ptr, ptr %t6 + %t413 = call i32 @fn_str_eq(ptr %t412, ptr @.str1060) + %t414 = icmp ne i32 %t413, 0 + br i1 %t414, label %then79, label %ifend81 +then79: + %t415 = load ptr, ptr %t0 + %t416 = call ptr @fn_emit_len(ptr %t415) + store ptr %t416, ptr %retval + br label %ret +ifend81: + %t417 = load ptr, ptr %t6 + %t418 = call i32 @fn_str_eq(ptr %t417, ptr @.str1061) + %t419 = icmp ne i32 %t418, 0 + br i1 %t419, label %then82, label %ifend84 +then82: + %t420 = load ptr, ptr %t0 + %t421 = call ptr @fn_emit_push(ptr %t420) + store ptr %t421, ptr %retval + br label %ret +ifend84: + %t422 = load ptr, ptr %t6 + %t423 = call i32 @fn_str_eq(ptr %t422, ptr @.str1062) + %t424 = icmp ne i32 %t423, 0 + br i1 %t424, label %then85, label %ifend87 +then85: + %t425 = load ptr, ptr %t0 + %t426 = getelementptr inbounds %Cmp_Node, ptr %t425, i32 0, i32 7 + %t427 = load ptr, ptr %t426 + %t428 = getelementptr inbounds %LSlice, ptr %t427, i32 0, i32 0 + %t429 = load ptr, ptr %t428 + %t430 = getelementptr inbounds ptr, ptr %t429, i32 0 + %t431 = load ptr, ptr %t430 + %t432 = call ptr @fn_emit_expr(ptr %t431) + store ptr %t432, ptr %t433 + %t434 = load ptr, ptr %t433 + %t435 = getelementptr inbounds %Cmp_Val, ptr %t434, i32 0, i32 1 + %t436 = load ptr, ptr %t435 + %t437 = call ptr @fn_llty(ptr %t436) + %t438 = call i32 @fn_str_eq(ptr %t437, ptr @.str1063) + %t439 = icmp ne i32 %t438, 0 + br i1 %t439, label %then88, label %ifend90 +then88: + %t440 = load ptr, ptr %t433 + store ptr %t440, ptr %retval + br label %ret +ifend90: + store i32 1, ptr @g_g_uses_intstr + %t441 = load ptr, ptr %t433 + %t442 = getelementptr inbounds %Cmp_Val, ptr %t441, i32 0, i32 0 + %t443 = load ptr, ptr %t442 + %t444 = call ptr @fn_str_concat(ptr @.str1064, ptr %t443) + %t445 = call ptr @fn_str_concat(ptr %t444, ptr @.str1065) + %t446 = call ptr @fn_emit_bind(ptr %t445) + %t447 = call ptr @fn_val(ptr %t446, ptr @.str1066) + store ptr %t447, ptr %retval + br label %ret +ifend87: + %t448 = load ptr, ptr %t6 + %t449 = call i32 @fn_str_eq(ptr %t448, ptr @.str1067) + %t450 = icmp ne i32 %t449, 0 + br i1 %t450, label %then91, label %ifend93 +then91: + %t451 = load ptr, ptr %t0 + %t452 = getelementptr inbounds %Cmp_Node, ptr %t451, i32 0, i32 7 + %t453 = load ptr, ptr %t452 + %t454 = getelementptr inbounds %LSlice, ptr %t453, i32 0, i32 0 + %t455 = load ptr, ptr %t454 + %t456 = getelementptr inbounds ptr, ptr %t455, i32 0 + %t457 = load ptr, ptr %t456 + %t458 = call ptr @fn_emit_expr(ptr %t457) + store ptr %t458, ptr %t459 + %t460 = load ptr, ptr %t459 + %t461 = getelementptr inbounds %Cmp_Val, ptr %t460, i32 0, i32 1 + %t462 = load ptr, ptr %t461 + %t463 = call ptr @fn_llty(ptr %t462) + %t464 = call i32 @fn_str_eq(ptr %t463, ptr @.str1068) + %t465 = icmp ne i32 %t464, 0 + br i1 %t465, label %then94, label %else95 +then94: + %t466 = load ptr, ptr %t459 + %t467 = getelementptr inbounds %Cmp_Val, ptr %t466, i32 0, i32 0 + %t468 = load ptr, ptr %t467 + %t469 = call ptr @fn_str_concat(ptr %t468, ptr @.str1070) + %t470 = call ptr @fn_str_concat(ptr @.str1069, ptr %t469) + call void @fn_emit(ptr %t470) + br label %ifend96 +else95: + %t471 = load ptr, ptr %t459 + %t472 = getelementptr inbounds %Cmp_Val, ptr %t471, i32 0, i32 0 + %t473 = load ptr, ptr %t472 + %t474 = call ptr @fn_str_concat(ptr %t473, ptr @.str1072) + %t475 = call ptr @fn_str_concat(ptr @.str1071, ptr %t474) + call void @fn_emit(ptr %t475) + br label %ifend96 +ifend96: + %t476 = call ptr @fn_val(ptr @.str1073, ptr @.str1074) + store ptr %t476, ptr %retval + br label %ret +ifend93: + %t477 = load ptr, ptr %t6 + %t478 = call i32 @fn_str_eq(ptr %t477, ptr @.str1075) + %t479 = icmp ne i32 %t478, 0 + br i1 %t479, label %then97, label %ifend99 +then97: + %t480 = load ptr, ptr %t0 + %t481 = getelementptr inbounds %Cmp_Node, ptr %t480, i32 0, i32 7 + %t482 = load ptr, ptr %t481 + %t483 = getelementptr inbounds %LSlice, ptr %t482, i32 0, i32 0 + %t484 = load ptr, ptr %t483 + %t485 = getelementptr inbounds ptr, ptr %t484, i32 0 + %t486 = load ptr, ptr %t485 + %t487 = call ptr @fn_emit_expr(ptr %t486) + store ptr %t487, ptr %t488 + %t489 = load ptr, ptr %t488 + %t490 = getelementptr inbounds %Cmp_Val, ptr %t489, i32 0, i32 0 + %t491 = load ptr, ptr %t490 + %t492 = call ptr @fn_str_concat(ptr @.str1076, ptr %t491) + %t493 = call ptr @fn_str_concat(ptr %t492, ptr @.str1077) + %t494 = call ptr @fn_emit_bind(ptr %t493) + store ptr %t494, ptr %t495 + %t496 = load ptr, ptr %t495 + %t497 = call ptr @fn_str_concat(ptr @.str1078, ptr %t496) + %t498 = call ptr @fn_str_concat(ptr %t497, ptr @.str1079) + %t499 = call ptr @fn_emit_bind(ptr %t498) + %t500 = call ptr @fn_val(ptr %t499, ptr @.str1080) + store ptr %t500, ptr %retval + br label %ret +ifend99: + %t501 = load ptr, ptr %t6 + %t502 = call i32 @fn_str_eq(ptr %t501, ptr @.str1081) + %t503 = icmp ne i32 %t502, 0 + br i1 %t503, label %then100, label %ifend102 +then100: + %t504 = load ptr, ptr %t0 + %t505 = getelementptr inbounds %Cmp_Node, ptr %t504, i32 0, i32 7 + %t506 = load ptr, ptr %t505 + %t507 = getelementptr inbounds %LSlice, ptr %t506, i32 0, i32 0 + %t508 = load ptr, ptr %t507 + %t509 = getelementptr inbounds ptr, ptr %t508, i32 0 + %t510 = load ptr, ptr %t509 + %t511 = call ptr @fn_emit_expr(ptr %t510) + store ptr %t511, ptr %t512 + %t513 = load ptr, ptr %t512 + %t514 = getelementptr inbounds %Cmp_Val, ptr %t513, i32 0, i32 0 + %t515 = load ptr, ptr %t514 + %t516 = call ptr @fn_str_concat(ptr @.str1082, ptr %t515) + %t517 = call ptr @fn_str_concat(ptr %t516, ptr @.str1083) + %t518 = call ptr @fn_emit_bind(ptr %t517) + store ptr %t518, ptr %t519 + %t520 = load ptr, ptr %t519 + %t521 = call ptr @fn_str_concat(ptr @.str1084, ptr %t520) + %t522 = call ptr @fn_str_concat(ptr %t521, ptr @.str1085) + %t523 = call ptr @fn_emit_bind(ptr %t522) + store ptr %t523, ptr %t524 + %t525 = load ptr, ptr %t524 + %t526 = call ptr @fn_str_concat(ptr @.str1086, ptr %t525) + %t527 = call ptr @fn_str_concat(ptr %t526, ptr @.str1087) + %t528 = call ptr @fn_emit_bind(ptr %t527) + %t529 = call ptr @fn_val(ptr %t528, ptr @.str1088) + store ptr %t529, ptr %retval + br label %ret +ifend102: + %t530 = load ptr, ptr %t6 + %t531 = call i32 @fn_str_eq(ptr %t530, ptr @.str1089) + %t532 = icmp ne i32 %t531, 0 + br i1 %t532, label %then103, label %ifend105 +then103: + %t533 = load ptr, ptr %t0 + %t534 = getelementptr inbounds %Cmp_Node, ptr %t533, i32 0, i32 7 + %t535 = load ptr, ptr %t534 + %t536 = getelementptr inbounds %LSlice, ptr %t535, i32 0, i32 0 + %t537 = load ptr, ptr %t536 + %t538 = getelementptr inbounds ptr, ptr %t537, i32 0 + %t539 = load ptr, ptr %t538 + %t540 = call ptr @fn_emit_expr(ptr %t539) + store ptr %t540, ptr %t541 + %t542 = load ptr, ptr %t541 + %t543 = getelementptr inbounds %Cmp_Val, ptr %t542, i32 0, i32 0 + %t544 = load ptr, ptr %t543 + %t545 = call ptr @fn_str_concat(ptr @.str1090, ptr %t544) + %t546 = call ptr @fn_str_concat(ptr %t545, ptr @.str1091) + %t547 = call ptr @fn_emit_bind(ptr %t546) + %t548 = call ptr @fn_val(ptr %t547, ptr @.str1092) + store ptr %t548, ptr %retval + br label %ret +ifend105: + %t549 = load ptr, ptr %t6 + %t550 = call i32 @fn_str_eq(ptr %t549, ptr @.str1093) + %t551 = icmp ne i32 %t550, 0 + br i1 %t551, label %then106, label %ifend108 +then106: + %t552 = load ptr, ptr %t0 + %t553 = getelementptr inbounds %Cmp_Node, ptr %t552, i32 0, i32 7 + %t554 = load ptr, ptr %t553 + %t555 = getelementptr inbounds %LSlice, ptr %t554, i32 0, i32 0 + %t556 = load ptr, ptr %t555 + %t557 = getelementptr inbounds ptr, ptr %t556, i32 0 + %t558 = load ptr, ptr %t557 + %t559 = call ptr @fn_emit_expr(ptr %t558) + store ptr %t559, ptr %t560 + %t561 = load ptr, ptr %t560 + %t562 = getelementptr inbounds %Cmp_Val, ptr %t561, i32 0, i32 0 + %t563 = load ptr, ptr %t562 + %t564 = call ptr @fn_str_concat(ptr @.str1094, ptr %t563) + %t565 = call ptr @fn_str_concat(ptr %t564, ptr @.str1095) + %t566 = call ptr @fn_emit_bind(ptr %t565) + %t567 = call ptr @fn_val(ptr %t566, ptr @.str1096) + store ptr %t567, ptr %retval + br label %ret +ifend108: + %t568 = load ptr, ptr %t6 + %t569 = call i32 @fn_str_eq(ptr %t568, ptr @.str1097) + %t570 = icmp ne i32 %t569, 0 + br i1 %t570, label %then109, label %ifend111 +then109: + %t571 = load ptr, ptr %t0 + %t572 = getelementptr inbounds %Cmp_Node, ptr %t571, i32 0, i32 7 + %t573 = load ptr, ptr %t572 + %t574 = getelementptr inbounds %LSlice, ptr %t573, i32 0, i32 0 + %t575 = load ptr, ptr %t574 + %t576 = getelementptr inbounds ptr, ptr %t575, i32 0 + %t577 = load ptr, ptr %t576 + %t578 = call ptr @fn_emit_expr(ptr %t577) + store ptr %t578, ptr %t579 + %t580 = load ptr, ptr %t579 + %t581 = getelementptr inbounds %Cmp_Val, ptr %t580, i32 0, i32 0 + %t582 = load ptr, ptr %t581 + %t583 = call ptr @fn_str_concat(ptr @.str1098, ptr %t582) + %t584 = call ptr @fn_str_concat(ptr %t583, ptr @.str1099) + %t585 = call ptr @fn_emit_bind(ptr %t584) + %t586 = call ptr @fn_val(ptr %t585, ptr @.str1100) + store ptr %t586, ptr %retval + br label %ret +ifend111: + %t587 = load ptr, ptr %t6 + %t588 = call i32 @fn_str_eq(ptr %t587, ptr @.str1101) + %t589 = icmp ne i32 %t588, 0 + br i1 %t589, label %then112, label %ifend114 +then112: + %t590 = load ptr, ptr %t0 + %t591 = getelementptr inbounds %Cmp_Node, ptr %t590, i32 0, i32 7 + %t592 = load ptr, ptr %t591 + %t593 = getelementptr inbounds %LSlice, ptr %t592, i32 0, i32 0 + %t594 = load ptr, ptr %t593 + %t595 = getelementptr inbounds ptr, ptr %t594, i32 0 + %t596 = load ptr, ptr %t595 + %t597 = call ptr @fn_emit_expr(ptr %t596) + store ptr %t597, ptr %t598 + %t599 = load ptr, ptr %t0 + %t600 = getelementptr inbounds %Cmp_Node, ptr %t599, i32 0, i32 7 + %t601 = load ptr, ptr %t600 + %t602 = getelementptr inbounds %LSlice, ptr %t601, i32 0, i32 0 + %t603 = load ptr, ptr %t602 + %t604 = getelementptr inbounds ptr, ptr %t603, i32 1 + %t605 = load ptr, ptr %t604 + %t606 = call ptr @fn_emit_expr(ptr %t605) + store ptr %t606, ptr %t607 + %t608 = load ptr, ptr %t598 + %t609 = getelementptr inbounds %Cmp_Val, ptr %t608, i32 0, i32 0 + %t610 = load ptr, ptr %t609 + %t611 = call ptr @fn_str_concat(ptr @.str1102, ptr %t610) + %t612 = call ptr @fn_str_concat(ptr %t611, ptr @.str1103) + %t613 = load ptr, ptr %t607 + %t614 = getelementptr inbounds %Cmp_Val, ptr %t613, i32 0, i32 0 + %t615 = load ptr, ptr %t614 + %t616 = call ptr @fn_str_concat(ptr %t612, ptr %t615) + %t617 = call ptr @fn_str_concat(ptr %t616, ptr @.str1104) + %t618 = call ptr @fn_emit_bind(ptr %t617) + %t619 = call ptr @fn_val(ptr %t618, ptr @.str1105) + store ptr %t619, ptr %retval + br label %ret +ifend114: + %t620 = load ptr, ptr %t6 + %t621 = call i32 @fn_str_eq(ptr %t620, ptr @.str1106) + %t622 = icmp ne i32 %t621, 0 + br i1 %t622, label %then115, label %ifend117 +then115: + %t623 = load ptr, ptr %t0 + %t624 = getelementptr inbounds %Cmp_Node, ptr %t623, i32 0, i32 7 + %t625 = load ptr, ptr %t624 + %t626 = getelementptr inbounds %LSlice, ptr %t625, i32 0, i32 0 + %t627 = load ptr, ptr %t626 + %t628 = getelementptr inbounds ptr, ptr %t627, i32 0 + %t629 = load ptr, ptr %t628 + %t630 = call ptr @fn_emit_expr(ptr %t629) + store ptr %t630, ptr %t631 + %t632 = load ptr, ptr %t0 + %t633 = getelementptr inbounds %Cmp_Node, ptr %t632, i32 0, i32 7 + %t634 = load ptr, ptr %t633 + %t635 = getelementptr inbounds %LSlice, ptr %t634, i32 0, i32 0 + %t636 = load ptr, ptr %t635 + %t637 = getelementptr inbounds ptr, ptr %t636, i32 1 + %t638 = load ptr, ptr %t637 + %t639 = call ptr @fn_emit_expr(ptr %t638) + store ptr %t639, ptr %t640 + %t641 = load ptr, ptr %t0 + %t642 = getelementptr inbounds %Cmp_Node, ptr %t641, i32 0, i32 7 + %t643 = load ptr, ptr %t642 + %t644 = getelementptr inbounds %LSlice, ptr %t643, i32 0, i32 0 + %t645 = load ptr, ptr %t644 + %t646 = getelementptr inbounds ptr, ptr %t645, i32 2 + %t647 = load ptr, ptr %t646 + %t648 = call ptr @fn_emit_expr(ptr %t647) + store ptr %t648, ptr %t649 + %t650 = load ptr, ptr %t631 + %t651 = getelementptr inbounds %Cmp_Val, ptr %t650, i32 0, i32 0 + %t652 = load ptr, ptr %t651 + %t653 = call ptr @fn_str_concat(ptr @.str1107, ptr %t652) + %t654 = call ptr @fn_str_concat(ptr %t653, ptr @.str1108) + %t655 = load ptr, ptr %t640 + %t656 = getelementptr inbounds %Cmp_Val, ptr %t655, i32 0, i32 0 + %t657 = load ptr, ptr %t656 + %t658 = call ptr @fn_str_concat(ptr %t654, ptr %t657) + %t659 = call ptr @fn_str_concat(ptr %t658, ptr @.str1109) + %t660 = load ptr, ptr %t649 + %t661 = getelementptr inbounds %Cmp_Val, ptr %t660, i32 0, i32 0 + %t662 = load ptr, ptr %t661 + %t663 = call ptr @fn_str_concat(ptr %t659, ptr %t662) + %t664 = call ptr @fn_str_concat(ptr %t663, ptr @.str1110) + %t665 = call ptr @fn_emit_bind(ptr %t664) + store ptr %t665, ptr %t666 + %t667 = load ptr, ptr %t666 + %t668 = call ptr @fn_str_concat(ptr @.str1111, ptr %t667) + %t669 = call ptr @fn_str_concat(ptr %t668, ptr @.str1112) + %t670 = call ptr @fn_emit_bind(ptr %t669) + %t671 = call ptr @fn_val(ptr %t670, ptr @.str1113) + store ptr %t671, ptr %retval + br label %ret +ifend117: + %t672 = load ptr, ptr %t6 + %t673 = call i32 @fn_str_eq(ptr %t672, ptr @.str1114) + %t674 = icmp ne i32 %t673, 0 + br i1 %t674, label %then118, label %ifend120 +then118: + %t675 = load ptr, ptr %t0 + %t676 = getelementptr inbounds %Cmp_Node, ptr %t675, i32 0, i32 7 + %t677 = load ptr, ptr %t676 + %t678 = getelementptr inbounds %LSlice, ptr %t677, i32 0, i32 0 + %t679 = load ptr, ptr %t678 + %t680 = getelementptr inbounds ptr, ptr %t679, i32 0 + %t681 = load ptr, ptr %t680 + %t682 = call ptr @fn_emit_expr(ptr %t681) + store ptr %t682, ptr %t683 + %t684 = load ptr, ptr %t0 + %t685 = getelementptr inbounds %Cmp_Node, ptr %t684, i32 0, i32 7 + %t686 = load ptr, ptr %t685 + %t687 = getelementptr inbounds %LSlice, ptr %t686, i32 0, i32 0 + %t688 = load ptr, ptr %t687 + %t689 = getelementptr inbounds ptr, ptr %t688, i32 1 + %t690 = load ptr, ptr %t689 + %t691 = call ptr @fn_emit_expr(ptr %t690) + store ptr %t691, ptr %t692 + %t693 = load ptr, ptr %t0 + %t694 = getelementptr inbounds %Cmp_Node, ptr %t693, i32 0, i32 7 + %t695 = load ptr, ptr %t694 + %t696 = getelementptr inbounds %LSlice, ptr %t695, i32 0, i32 0 + %t697 = load ptr, ptr %t696 + %t698 = getelementptr inbounds ptr, ptr %t697, i32 2 + %t699 = load ptr, ptr %t698 + %t700 = call ptr @fn_emit_expr(ptr %t699) + store ptr %t700, ptr %t701 + %t702 = load ptr, ptr %t0 + %t703 = getelementptr inbounds %Cmp_Node, ptr %t702, i32 0, i32 7 + %t704 = load ptr, ptr %t703 + %t705 = getelementptr inbounds %LSlice, ptr %t704, i32 0, i32 0 + %t706 = load ptr, ptr %t705 + %t707 = getelementptr inbounds ptr, ptr %t706, i32 3 + %t708 = load ptr, ptr %t707 + %t709 = call ptr @fn_emit_expr(ptr %t708) + store ptr %t709, ptr %t710 + %t711 = load ptr, ptr %t710 + %t712 = getelementptr inbounds %Cmp_Val, ptr %t711, i32 0, i32 0 + %t713 = load ptr, ptr %t712 + %t714 = call ptr @fn_str_concat(ptr @.str1115, ptr %t713) + %t715 = call ptr @fn_str_concat(ptr %t714, ptr @.str1116) + %t716 = call ptr @fn_emit_bind(ptr %t715) + store ptr %t716, ptr %t717 + call void @fn_emit(ptr @.str1117) + %t718 = load ptr, ptr %t683 + %t719 = getelementptr inbounds %Cmp_Val, ptr %t718, i32 0, i32 0 + %t720 = load ptr, ptr %t719 + call void @fn_emit(ptr %t720) + call void @fn_emit(ptr @.str1118) + %t721 = load ptr, ptr %t692 + %t722 = getelementptr inbounds %Cmp_Val, ptr %t721, i32 0, i32 0 + %t723 = load ptr, ptr %t722 + call void @fn_emit(ptr %t723) + call void @fn_emit(ptr @.str1119) + %t724 = load ptr, ptr %t701 + %t725 = getelementptr inbounds %Cmp_Val, ptr %t724, i32 0, i32 0 + %t726 = load ptr, ptr %t725 + call void @fn_emit(ptr %t726) + call void @fn_emit(ptr @.str1120) + %t727 = load ptr, ptr %t717 + call void @fn_emit(ptr %t727) + call void @fn_emit(ptr @.str1121) + %t728 = call ptr @fn_val(ptr @.str1122, ptr @.str1123) + store ptr %t728, ptr %retval + br label %ret +ifend120: + %t729 = load ptr, ptr %t6 + %t730 = call i32 @fn_str_eq(ptr %t729, ptr @.str1124) + %t731 = icmp ne i32 %t730, 0 + br i1 %t731, label %then121, label %ifend123 +then121: + %t732 = load ptr, ptr %t0 + %t733 = getelementptr inbounds %Cmp_Node, ptr %t732, i32 0, i32 7 + %t734 = load ptr, ptr %t733 + %t735 = getelementptr inbounds %LSlice, ptr %t734, i32 0, i32 0 + %t736 = load ptr, ptr %t735 + %t737 = getelementptr inbounds ptr, ptr %t736, i32 0 + %t738 = load ptr, ptr %t737 + %t739 = call ptr @fn_emit_expr(ptr %t738) + store ptr %t739, ptr %t740 + %t741 = load ptr, ptr %t0 + %t742 = getelementptr inbounds %Cmp_Node, ptr %t741, i32 0, i32 7 + %t743 = load ptr, ptr %t742 + %t744 = getelementptr inbounds %LSlice, ptr %t743, i32 0, i32 0 + %t745 = load ptr, ptr %t744 + %t746 = getelementptr inbounds ptr, ptr %t745, i32 1 + %t747 = load ptr, ptr %t746 + %t748 = call ptr @fn_emit_expr(ptr %t747) + store ptr %t748, ptr %t749 + %t750 = load ptr, ptr %t740 + %t751 = getelementptr inbounds %Cmp_Val, ptr %t750, i32 0, i32 0 + %t752 = load ptr, ptr %t751 + %t753 = call ptr @fn_str_concat(ptr @.str1125, ptr %t752) + %t754 = call ptr @fn_str_concat(ptr %t753, ptr @.str1126) + %t755 = load ptr, ptr %t749 + %t756 = getelementptr inbounds %Cmp_Val, ptr %t755, i32 0, i32 0 + %t757 = load ptr, ptr %t756 + %t758 = call ptr @fn_str_concat(ptr %t754, ptr %t757) + %t759 = call ptr @fn_str_concat(ptr %t758, ptr @.str1127) + %t760 = call ptr @fn_emit_bind(ptr %t759) + %t761 = call ptr @fn_val(ptr %t760, ptr @.str1128) + store ptr %t761, ptr %retval + br label %ret +ifend123: + %t762 = load ptr, ptr %t6 + %t763 = call i32 @fn_str_eq(ptr %t762, ptr @.str1129) + %t764 = icmp ne i32 %t763, 0 + br i1 %t764, label %then124, label %ifend126 +then124: + %t765 = call ptr @fn_emit_bind(ptr @.str1130) + %t766 = call ptr @fn_val(ptr %t765, ptr @.str1131) + store ptr %t766, ptr %retval + br label %ret +ifend126: + %t767 = load ptr, ptr %t6 + %t768 = call i32 @fn_str_eq(ptr %t767, ptr @.str1132) + %t769 = icmp ne i32 %t768, 0 + br i1 %t769, label %then127, label %ifend129 +then127: + %t770 = load ptr, ptr %t0 + %t771 = getelementptr inbounds %Cmp_Node, ptr %t770, i32 0, i32 7 + %t772 = load ptr, ptr %t771 + %t773 = getelementptr inbounds %LSlice, ptr %t772, i32 0, i32 0 + %t774 = load ptr, ptr %t773 + %t775 = getelementptr inbounds ptr, ptr %t774, i32 0 + %t776 = load ptr, ptr %t775 + %t777 = call ptr @fn_emit_expr(ptr %t776) + store ptr %t777, ptr %t778 + %t779 = load ptr, ptr %t778 + %t780 = getelementptr inbounds %Cmp_Val, ptr %t779, i32 0, i32 0 + %t781 = load ptr, ptr %t780 + %t782 = call ptr @fn_str_concat(ptr @.str1133, ptr %t781) + %t783 = call ptr @fn_str_concat(ptr %t782, ptr @.str1134) + %t784 = call ptr @fn_emit_bind(ptr %t783) + %t785 = call ptr @fn_val(ptr %t784, ptr @.str1135) + store ptr %t785, ptr %retval + br label %ret +ifend129: + %t786 = load ptr, ptr %t6 + %t787 = call i32 @fn_str_eq(ptr %t786, ptr @.str1136) + %t788 = icmp ne i32 %t787, 0 + br i1 %t788, label %then130, label %ifend132 +then130: + %t789 = load ptr, ptr %t0 + %t790 = getelementptr inbounds %Cmp_Node, ptr %t789, i32 0, i32 7 + %t791 = load ptr, ptr %t790 + %t792 = getelementptr inbounds %LSlice, ptr %t791, i32 0, i32 0 + %t793 = load ptr, ptr %t792 + %t794 = getelementptr inbounds ptr, ptr %t793, i32 0 + %t795 = load ptr, ptr %t794 + %t796 = call ptr @fn_emit_expr(ptr %t795) + store ptr %t796, ptr %t797 + %t798 = load ptr, ptr %t797 + %t799 = getelementptr inbounds %Cmp_Val, ptr %t798, i32 0, i32 0 + %t800 = load ptr, ptr %t799 + %t801 = call ptr @fn_str_concat(ptr @.str1137, ptr %t800) + %t802 = call ptr @fn_str_concat(ptr %t801, ptr @.str1138) + %t803 = call ptr @fn_emit_bind(ptr %t802) + %t804 = call ptr @fn_val(ptr %t803, ptr @.str1139) + store ptr %t804, ptr %retval + br label %ret +ifend132: + %t805 = load ptr, ptr %t6 + %t806 = call i32 @fn_str_eq(ptr %t805, ptr @.str1140) + %t807 = icmp ne i32 %t806, 0 + br i1 %t807, label %then133, label %ifend135 +then133: + %t808 = load ptr, ptr %t0 + %t809 = getelementptr inbounds %Cmp_Node, ptr %t808, i32 0, i32 7 + %t810 = load ptr, ptr %t809 + %t811 = getelementptr inbounds %LSlice, ptr %t810, i32 0, i32 0 + %t812 = load ptr, ptr %t811 + %t813 = getelementptr inbounds ptr, ptr %t812, i32 0 + %t814 = load ptr, ptr %t813 + %t815 = call ptr @fn_emit_expr(ptr %t814) + store ptr %t815, ptr %t816 + %t817 = load ptr, ptr %t0 + %t818 = getelementptr inbounds %Cmp_Node, ptr %t817, i32 0, i32 7 + %t819 = load ptr, ptr %t818 + %t820 = getelementptr inbounds %LSlice, ptr %t819, i32 0, i32 0 + %t821 = load ptr, ptr %t820 + %t822 = getelementptr inbounds ptr, ptr %t821, i32 1 + %t823 = load ptr, ptr %t822 + %t824 = call ptr @fn_emit_expr(ptr %t823) + store ptr %t824, ptr %t825 + %t826 = load ptr, ptr %t816 + %t827 = getelementptr inbounds %Cmp_Val, ptr %t826, i32 0, i32 0 + %t828 = load ptr, ptr %t827 + %t829 = call ptr @fn_str_concat(ptr @.str1141, ptr %t828) + %t830 = call ptr @fn_str_concat(ptr %t829, ptr @.str1142) + %t831 = load ptr, ptr %t825 + %t832 = getelementptr inbounds %Cmp_Val, ptr %t831, i32 0, i32 0 + %t833 = load ptr, ptr %t832 + %t834 = call ptr @fn_str_concat(ptr %t830, ptr %t833) + %t835 = call ptr @fn_str_concat(ptr %t834, ptr @.str1143) + %t836 = call ptr @fn_emit_bind(ptr %t835) + %t837 = call ptr @fn_val(ptr %t836, ptr @.str1144) + store ptr %t837, ptr %retval + br label %ret +ifend135: + %t838 = load ptr, ptr %t6 + %t839 = call i32 @fn_str_eq(ptr %t838, ptr @.str1145) + %t840 = icmp ne i32 %t839, 0 + br i1 %t840, label %then136, label %ifend138 +then136: + %t841 = load ptr, ptr %t0 + %t842 = getelementptr inbounds %Cmp_Node, ptr %t841, i32 0, i32 7 + %t843 = load ptr, ptr %t842 + %t844 = getelementptr inbounds %LSlice, ptr %t843, i32 0, i32 0 + %t845 = load ptr, ptr %t844 + %t846 = getelementptr inbounds ptr, ptr %t845, i32 0 + %t847 = load ptr, ptr %t846 + %t848 = call ptr @fn_emit_expr(ptr %t847) + store ptr %t848, ptr %t849 + %t850 = load ptr, ptr %t0 + %t851 = getelementptr inbounds %Cmp_Node, ptr %t850, i32 0, i32 7 + %t852 = load ptr, ptr %t851 + %t853 = getelementptr inbounds %LSlice, ptr %t852, i32 0, i32 0 + %t854 = load ptr, ptr %t853 + %t855 = getelementptr inbounds ptr, ptr %t854, i32 1 + %t856 = load ptr, ptr %t855 + %t857 = call ptr @fn_emit_expr(ptr %t856) + store ptr %t857, ptr %t858 + %t859 = load ptr, ptr %t849 + %t860 = getelementptr inbounds %Cmp_Val, ptr %t859, i32 0, i32 0 + %t861 = load ptr, ptr %t860 + %t862 = call ptr @fn_str_concat(ptr @.str1146, ptr %t861) + %t863 = call ptr @fn_str_concat(ptr %t862, ptr @.str1147) + %t864 = load ptr, ptr %t858 + %t865 = getelementptr inbounds %Cmp_Val, ptr %t864, i32 0, i32 0 + %t866 = load ptr, ptr %t865 + %t867 = call ptr @fn_str_concat(ptr %t863, ptr %t866) + %t868 = call ptr @fn_str_concat(ptr %t867, ptr @.str1148) + %t869 = call ptr @fn_emit_bind(ptr %t868) + %t870 = call ptr @fn_val(ptr %t869, ptr @.str1149) + store ptr %t870, ptr %retval + br label %ret +ifend138: + %t871 = load ptr, ptr %t6 + %t872 = call i32 @fn_str_eq(ptr %t871, ptr @.str1150) + %t873 = icmp ne i32 %t872, 0 + br i1 %t873, label %then139, label %ifend141 +then139: + %t874 = load ptr, ptr %t0 + %t875 = getelementptr inbounds %Cmp_Node, ptr %t874, i32 0, i32 7 + %t876 = load ptr, ptr %t875 + %t877 = getelementptr inbounds %LSlice, ptr %t876, i32 0, i32 0 + %t878 = load ptr, ptr %t877 + %t879 = getelementptr inbounds ptr, ptr %t878, i32 0 + %t880 = load ptr, ptr %t879 + %t881 = call ptr @fn_emit_expr(ptr %t880) + store ptr %t881, ptr %t882 + %t883 = load ptr, ptr %t0 + %t884 = getelementptr inbounds %Cmp_Node, ptr %t883, i32 0, i32 7 + %t885 = load ptr, ptr %t884 + %t886 = getelementptr inbounds %LSlice, ptr %t885, i32 0, i32 0 + %t887 = load ptr, ptr %t886 + %t888 = getelementptr inbounds ptr, ptr %t887, i32 1 + %t889 = load ptr, ptr %t888 + %t890 = call ptr @fn_emit_expr(ptr %t889) + store ptr %t890, ptr %t891 + call void @fn_emit(ptr @.str1151) + %t892 = load ptr, ptr %t882 + %t893 = getelementptr inbounds %Cmp_Val, ptr %t892, i32 0, i32 0 + %t894 = load ptr, ptr %t893 + call void @fn_emit(ptr %t894) + call void @fn_emit(ptr @.str1152) + %t895 = load ptr, ptr %t891 + %t896 = getelementptr inbounds %Cmp_Val, ptr %t895, i32 0, i32 0 + %t897 = load ptr, ptr %t896 + call void @fn_emit(ptr %t897) + call void @fn_emit(ptr @.str1153) + %t898 = call ptr @fn_val(ptr @.str1154, ptr @.str1155) + store ptr %t898, ptr %retval + br label %ret +ifend141: + %t899 = load ptr, ptr %t6 + %t900 = call i32 @fn_str_eq(ptr %t899, ptr @.str1156) + %t901 = icmp ne i32 %t900, 0 + br i1 %t901, label %then142, label %ifend144 +then142: + %t902 = load ptr, ptr %t0 + %t903 = getelementptr inbounds %Cmp_Node, ptr %t902, i32 0, i32 7 + %t904 = load ptr, ptr %t903 + %t905 = getelementptr inbounds %LSlice, ptr %t904, i32 0, i32 0 + %t906 = load ptr, ptr %t905 + %t907 = getelementptr inbounds ptr, ptr %t906, i32 0 + %t908 = load ptr, ptr %t907 + %t909 = call ptr @fn_emit_expr(ptr %t908) + store ptr %t909, ptr %t910 + %t911 = load ptr, ptr %t0 + %t912 = getelementptr inbounds %Cmp_Node, ptr %t911, i32 0, i32 7 + %t913 = load ptr, ptr %t912 + %t914 = getelementptr inbounds %LSlice, ptr %t913, i32 0, i32 0 + %t915 = load ptr, ptr %t914 + %t916 = getelementptr inbounds ptr, ptr %t915, i32 1 + %t917 = load ptr, ptr %t916 + %t918 = call ptr @fn_emit_expr(ptr %t917) + store ptr %t918, ptr %t919 + call void @fn_emit(ptr @.str1157) + %t920 = load ptr, ptr %t910 + %t921 = getelementptr inbounds %Cmp_Val, ptr %t920, i32 0, i32 0 + %t922 = load ptr, ptr %t921 + call void @fn_emit(ptr %t922) + call void @fn_emit(ptr @.str1158) + %t923 = load ptr, ptr %t919 + %t924 = getelementptr inbounds %Cmp_Val, ptr %t923, i32 0, i32 0 + %t925 = load ptr, ptr %t924 + call void @fn_emit(ptr %t925) + call void @fn_emit(ptr @.str1159) + %t926 = call ptr @fn_val(ptr @.str1160, ptr @.str1161) + store ptr %t926, ptr %retval + br label %ret +ifend144: + %t927 = load ptr, ptr %t6 + %t928 = call i32 @fn_str_eq(ptr %t927, ptr @.str1162) + %t929 = icmp ne i32 %t928, 0 + br i1 %t929, label %then145, label %ifend147 +then145: + %t930 = load ptr, ptr %t0 + %t931 = getelementptr inbounds %Cmp_Node, ptr %t930, i32 0, i32 7 + %t932 = load ptr, ptr %t931 + %t933 = getelementptr inbounds %LSlice, ptr %t932, i32 0, i32 0 + %t934 = load ptr, ptr %t933 + %t935 = getelementptr inbounds ptr, ptr %t934, i32 0 + %t936 = load ptr, ptr %t935 + %t937 = call ptr @fn_emit_expr(ptr %t936) + store ptr %t937, ptr %t938 + %t939 = load ptr, ptr %t938 + %t940 = getelementptr inbounds %Cmp_Val, ptr %t939, i32 0, i32 0 + %t941 = load ptr, ptr %t940 + %t942 = call ptr @fn_str_concat(ptr @.str1163, ptr %t941) + %t943 = call ptr @fn_str_concat(ptr %t942, ptr @.str1164) + %t944 = call ptr @fn_emit_bind(ptr %t943) + %t945 = call ptr @fn_val(ptr %t944, ptr @.str1165) + store ptr %t945, ptr %retval + br label %ret +ifend147: + %t946 = load ptr, ptr %t6 + %t947 = call i32 @fn_is_intrinsic(ptr %t946) + %t948 = icmp ne i32 %t947, 0 + br i1 %t948, label %then148, label %ifend150 +then148: + %t949 = load ptr, ptr %t6 + %t950 = load ptr, ptr %t0 + %t951 = call ptr @fn_emit_intrinsic(ptr %t949, ptr %t950) + store ptr %t951, ptr %retval + br label %ret +ifend150: + %t952 = load ptr, ptr %t6 + %t953 = call i32 @fn_is_intrinsic2(ptr %t952) + %t954 = icmp ne i32 %t953, 0 + br i1 %t954, label %then151, label %ifend153 +then151: + %t955 = load ptr, ptr %t6 + %t956 = load ptr, ptr %t0 + %t957 = call ptr @fn_emit_intrinsic2(ptr %t955, ptr %t956) + store ptr %t957, ptr %retval + br label %ret +ifend153: + %t958 = load ptr, ptr %t6 + %t959 = call i32 @fn_is_math_builtin(ptr %t958) + %t960 = icmp ne i32 %t959, 0 + br i1 %t960, label %then154, label %ifend156 +then154: + %t961 = load ptr, ptr %t6 + %t962 = load ptr, ptr %t0 + %t963 = call ptr @fn_emit_math_builtin(ptr %t961, ptr %t962) + store ptr %t963, ptr %retval + br label %ret +ifend156: + %t964 = load ptr, ptr %t6 + %t965 = call ptr @fn_find_extern(ptr %t964) + store ptr %t965, ptr %t966 + %t967 = load ptr, ptr %t966 + %t968 = icmp ne ptr %t967, null + %t969 = zext i1 %t968 to i32 + %t970 = icmp ne i32 %t969, 0 + br i1 %t970, label %then157, label %ifend159 +then157: + %t971 = getelementptr %LSlice, ptr null, i32 1 + %t972 = ptrtoint ptr %t971 to i64 + %t973 = call ptr @malloc(i64 %t972) + %t974 = getelementptr inbounds %LSlice, ptr %t973, i32 0, i32 0 + store ptr null, ptr %t974 + %t975 = getelementptr inbounds %LSlice, ptr %t973, i32 0, i32 1 + store i32 0, ptr %t975 + %t976 = getelementptr inbounds %LSlice, ptr %t973, i32 0, i32 2 + store i32 0, ptr %t976 + store ptr %t973, ptr %t977 + %t978 = getelementptr %LSlice, ptr null, i32 1 + %t979 = ptrtoint ptr %t978 to i64 + %t980 = call ptr @malloc(i64 %t979) + %t981 = getelementptr inbounds %LSlice, ptr %t980, i32 0, i32 0 + store ptr null, ptr %t981 + %t982 = getelementptr inbounds %LSlice, ptr %t980, i32 0, i32 1 + store i32 0, ptr %t982 + %t983 = getelementptr inbounds %LSlice, ptr %t980, i32 0, i32 2 + store i32 0, ptr %t983 + store ptr %t980, ptr %t984 + store i32 0, ptr %t985 + br label %wcond160 +wcond160: + %t986 = load i32, ptr %t985 + %t987 = load ptr, ptr %t0 + %t988 = getelementptr inbounds %Cmp_Node, ptr %t987, i32 0, i32 7 + %t989 = load ptr, ptr %t988 + %t990 = getelementptr inbounds %LSlice, ptr %t989, i32 0, i32 1 + %t991 = load i32, ptr %t990 + %t992 = icmp slt i32 %t986, %t991 + %t993 = zext i1 %t992 to i32 + %t994 = icmp ne i32 %t993, 0 + br i1 %t994, label %wbody161, label %wend162 +wbody161: + %t995 = load ptr, ptr %t0 + %t996 = getelementptr inbounds %Cmp_Node, ptr %t995, i32 0, i32 7 + %t997 = load ptr, ptr %t996 + %t998 = getelementptr inbounds %LSlice, ptr %t997, i32 0, i32 0 + %t999 = load ptr, ptr %t998 + %t1000 = load i32, ptr %t985 + %t1001 = getelementptr inbounds ptr, ptr %t999, i32 %t1000 + %t1002 = load ptr, ptr %t1001 + %t1003 = call ptr @fn_emit_expr(ptr %t1002) + store ptr %t1003, ptr %t1004 + %t1005 = load ptr, ptr %t977 + %t1006 = getelementptr inbounds %LSlice, ptr %t1005, i32 0, i32 1 + %t1007 = getelementptr inbounds %LSlice, ptr %t1005, i32 0, i32 2 + %t1008 = getelementptr inbounds %LSlice, ptr %t1005, i32 0, i32 0 + %t1009 = load i32, ptr %t1006 + %t1010 = load i32, ptr %t1007 + %t1011 = icmp sge i32 %t1009, %t1010 + br i1 %t1011, label %grow163, label %put164 +grow163: + %t1012 = mul i32 %t1010, 2 + %t1013 = icmp eq i32 %t1010, 0 + %t1014 = select i1 %t1013, i32 8, i32 %t1012 + %t1015 = getelementptr ptr, ptr null, i32 1 + %t1016 = ptrtoint ptr %t1015 to i64 + %t1017 = zext i32 %t1014 to i64 + %t1018 = mul i64 %t1017, %t1016 + %t1019 = load ptr, ptr %t1008 + %t1020 = call ptr @realloc(ptr %t1019, i64 %t1018) + store ptr %t1020, ptr %t1008 + store i32 %t1014, ptr %t1007 + br label %put164 +put164: + %t1021 = load ptr, ptr %t1004 + %t1022 = getelementptr inbounds %Cmp_Val, ptr %t1021, i32 0, i32 0 + %t1023 = load ptr, ptr %t1022 + %t1024 = load ptr, ptr %t1008 + %t1025 = getelementptr inbounds ptr, ptr %t1024, i32 %t1009 + store ptr %t1023, ptr %t1025 + %t1026 = add i32 %t1009, 1 + store i32 %t1026, ptr %t1006 + %t1027 = load ptr, ptr %t984 + %t1028 = getelementptr inbounds %LSlice, ptr %t1027, i32 0, i32 1 + %t1029 = getelementptr inbounds %LSlice, ptr %t1027, i32 0, i32 2 + %t1030 = getelementptr inbounds %LSlice, ptr %t1027, i32 0, i32 0 + %t1031 = load i32, ptr %t1028 + %t1032 = load i32, ptr %t1029 + %t1033 = icmp sge i32 %t1031, %t1032 + br i1 %t1033, label %grow165, label %put166 +grow165: + %t1034 = mul i32 %t1032, 2 + %t1035 = icmp eq i32 %t1032, 0 + %t1036 = select i1 %t1035, i32 8, i32 %t1034 + %t1037 = getelementptr ptr, ptr null, i32 1 + %t1038 = ptrtoint ptr %t1037 to i64 + %t1039 = zext i32 %t1036 to i64 + %t1040 = mul i64 %t1039, %t1038 + %t1041 = load ptr, ptr %t1030 + %t1042 = call ptr @realloc(ptr %t1041, i64 %t1040) + store ptr %t1042, ptr %t1030 + store i32 %t1036, ptr %t1029 + br label %put166 +put166: + %t1043 = load ptr, ptr %t1004 + %t1044 = getelementptr inbounds %Cmp_Val, ptr %t1043, i32 0, i32 1 + %t1045 = load ptr, ptr %t1044 + %t1046 = load ptr, ptr %t1030 + %t1047 = getelementptr inbounds ptr, ptr %t1046, i32 %t1031 + store ptr %t1045, ptr %t1047 + %t1048 = add i32 %t1031, 1 + store i32 %t1048, ptr %t1028 + %t1049 = load i32, ptr %t985 + %t1050 = add i32 %t1049, 1 + store i32 %t1050, ptr %t985 + br label %wcond160 +wend162: + %t1051 = load ptr, ptr %t966 + %t1052 = getelementptr inbounds %Cmp_Node, ptr %t1051, i32 0, i32 3 + %t1053 = load ptr, ptr %t1052 + %t1054 = call ptr @fn_llty(ptr %t1053) + store ptr %t1054, ptr %t1055 + call void @fn_emit(ptr @.str1166) + store ptr @.str1167, ptr %t1056 + %t1057 = load ptr, ptr %t1055 + %t1058 = call i32 @fn_str_eq(ptr %t1057, ptr @.str1168) + %t1059 = icmp eq i32 %t1058, 0 + %t1060 = zext i1 %t1059 to i32 + %t1061 = icmp ne i32 %t1060, 0 + br i1 %t1061, label %then167, label %ifend169 +then167: + %t1062 = call ptr @fn_nreg() + store ptr %t1062, ptr %t1056 + %t1063 = load ptr, ptr %t1056 + call void @fn_emit(ptr %t1063) + call void @fn_emit(ptr @.str1169) + br label %ifend169 +ifend169: + call void @fn_emit(ptr @.str1170) + %t1064 = load ptr, ptr %t1055 + call void @fn_emit(ptr %t1064) + call void @fn_emit(ptr @.str1171) + %t1065 = load ptr, ptr %t966 + %t1066 = getelementptr inbounds %Cmp_Node, ptr %t1065, i32 0, i32 4 + %t1067 = load ptr, ptr %t1066 + %t1068 = getelementptr inbounds %Cmp_Node, ptr %t1067, i32 0, i32 1 + %t1069 = load ptr, ptr %t1068 + call void @fn_emit(ptr %t1069) + call void @fn_emit(ptr @.str1172) + store i32 0, ptr %t985 + br label %wcond170 +wcond170: + %t1070 = load i32, ptr %t985 + %t1071 = load ptr, ptr %t977 + %t1072 = getelementptr inbounds %LSlice, ptr %t1071, i32 0, i32 1 + %t1073 = load i32, ptr %t1072 + %t1074 = icmp slt i32 %t1070, %t1073 + %t1075 = zext i1 %t1074 to i32 + %t1076 = icmp ne i32 %t1075, 0 + br i1 %t1076, label %wbody171, label %wend172 +wbody171: + %t1077 = load i32, ptr %t985 + %t1078 = icmp sgt i32 %t1077, 0 + %t1079 = zext i1 %t1078 to i32 + %t1080 = icmp ne i32 %t1079, 0 + br i1 %t1080, label %then173, label %ifend175 +then173: + call void @fn_emit(ptr @.str1173) + br label %ifend175 +ifend175: + %t1081 = load ptr, ptr %t984 + %t1082 = getelementptr inbounds %LSlice, ptr %t1081, i32 0, i32 0 + %t1083 = load ptr, ptr %t1082 + %t1084 = load i32, ptr %t985 + %t1085 = getelementptr inbounds ptr, ptr %t1083, i32 %t1084 + %t1086 = load ptr, ptr %t1085 + %t1087 = call ptr @fn_llty(ptr %t1086) + call void @fn_emit(ptr %t1087) + call void @fn_emit(ptr @.str1174) + %t1088 = load ptr, ptr %t977 + %t1089 = getelementptr inbounds %LSlice, ptr %t1088, i32 0, i32 0 + %t1090 = load ptr, ptr %t1089 + %t1091 = load i32, ptr %t985 + %t1092 = getelementptr inbounds ptr, ptr %t1090, i32 %t1091 + %t1093 = load ptr, ptr %t1092 + call void @fn_emit(ptr %t1093) + %t1094 = load i32, ptr %t985 + %t1095 = add i32 %t1094, 1 + store i32 %t1095, ptr %t985 + br label %wcond170 +wend172: + call void @fn_emit(ptr @.str1175) + %t1096 = load ptr, ptr %t1056 + %t1097 = load ptr, ptr %t966 + %t1098 = getelementptr inbounds %Cmp_Node, ptr %t1097, i32 0, i32 3 + %t1099 = load ptr, ptr %t1098 + %t1100 = call ptr @fn_val(ptr %t1096, ptr %t1099) + store ptr %t1100, ptr %retval + br label %ret +ifend159: + %t1101 = load ptr, ptr %t6 + %t1102 = call ptr @fn_find_fn(ptr %t1101) + store ptr %t1102, ptr %t1103 + %t1104 = load ptr, ptr %t6 + store ptr %t1104, ptr %t1105 + %t1106 = load ptr, ptr %t1103 + %t1107 = icmp eq ptr %t1106, null + %t1108 = zext i1 %t1107 to i32 + %t1109 = icmp ne i32 %t1108, 0 + br i1 %t1109, label %then176, label %ifend178 +then176: + %t1110 = load ptr, ptr %t6 + %t1111 = call ptr @fn_str_concat(ptr @.str1176, ptr %t1110) + store ptr %t1111, ptr %t1112 + %t1113 = load ptr, ptr %t1112 + %t1114 = call ptr @fn_find_fn(ptr %t1113) + store ptr %t1114, ptr %t1103 + %t1115 = load ptr, ptr %t1103 + %t1116 = icmp eq ptr %t1115, null + %t1117 = zext i1 %t1116 to i32 + %t1118 = icmp ne i32 %t1117, 0 + br i1 %t1118, label %then179, label %ifend181 +then179: + %t1119 = load ptr, ptr %t6 + %t1120 = call ptr @fn_str_concat(ptr @.str1177, ptr %t1119) + call void @fn_perr(ptr %t1120) + br label %ifend181 +ifend181: + %t1121 = load ptr, ptr %t1112 + store ptr %t1121, ptr %t1105 + br label %ifend178 +ifend178: + %t1122 = getelementptr %LSlice, ptr null, i32 1 + %t1123 = ptrtoint ptr %t1122 to i64 + %t1124 = call ptr @malloc(i64 %t1123) + %t1125 = getelementptr inbounds %LSlice, ptr %t1124, i32 0, i32 0 + store ptr null, ptr %t1125 + %t1126 = getelementptr inbounds %LSlice, ptr %t1124, i32 0, i32 1 + store i32 0, ptr %t1126 + %t1127 = getelementptr inbounds %LSlice, ptr %t1124, i32 0, i32 2 + store i32 0, ptr %t1127 + store ptr %t1124, ptr %t1128 + %t1129 = getelementptr %LSlice, ptr null, i32 1 + %t1130 = ptrtoint ptr %t1129 to i64 + %t1131 = call ptr @malloc(i64 %t1130) + %t1132 = getelementptr inbounds %LSlice, ptr %t1131, i32 0, i32 0 + store ptr null, ptr %t1132 + %t1133 = getelementptr inbounds %LSlice, ptr %t1131, i32 0, i32 1 + store i32 0, ptr %t1133 + %t1134 = getelementptr inbounds %LSlice, ptr %t1131, i32 0, i32 2 + store i32 0, ptr %t1134 + store ptr %t1131, ptr %t1135 + store i32 0, ptr %t1136 + br label %wcond182 +wcond182: + %t1137 = load i32, ptr %t1136 + %t1138 = load ptr, ptr %t0 + %t1139 = getelementptr inbounds %Cmp_Node, ptr %t1138, i32 0, i32 7 + %t1140 = load ptr, ptr %t1139 + %t1141 = getelementptr inbounds %LSlice, ptr %t1140, i32 0, i32 1 + %t1142 = load i32, ptr %t1141 + %t1143 = icmp slt i32 %t1137, %t1142 + %t1144 = zext i1 %t1143 to i32 + %t1145 = icmp ne i32 %t1144, 0 + br i1 %t1145, label %wbody183, label %wend184 +wbody183: + %t1146 = load ptr, ptr %t0 + %t1147 = getelementptr inbounds %Cmp_Node, ptr %t1146, i32 0, i32 7 + %t1148 = load ptr, ptr %t1147 + %t1149 = getelementptr inbounds %LSlice, ptr %t1148, i32 0, i32 0 + %t1150 = load ptr, ptr %t1149 + %t1151 = load i32, ptr %t1136 + %t1152 = getelementptr inbounds ptr, ptr %t1150, i32 %t1151 + %t1153 = load ptr, ptr %t1152 + %t1154 = call ptr @fn_emit_expr(ptr %t1153) + store ptr %t1154, ptr %t1155 + %t1156 = load ptr, ptr %t1128 + %t1157 = getelementptr inbounds %LSlice, ptr %t1156, i32 0, i32 1 + %t1158 = getelementptr inbounds %LSlice, ptr %t1156, i32 0, i32 2 + %t1159 = getelementptr inbounds %LSlice, ptr %t1156, i32 0, i32 0 + %t1160 = load i32, ptr %t1157 + %t1161 = load i32, ptr %t1158 + %t1162 = icmp sge i32 %t1160, %t1161 + br i1 %t1162, label %grow185, label %put186 +grow185: + %t1163 = mul i32 %t1161, 2 + %t1164 = icmp eq i32 %t1161, 0 + %t1165 = select i1 %t1164, i32 8, i32 %t1163 + %t1166 = getelementptr ptr, ptr null, i32 1 + %t1167 = ptrtoint ptr %t1166 to i64 + %t1168 = zext i32 %t1165 to i64 + %t1169 = mul i64 %t1168, %t1167 + %t1170 = load ptr, ptr %t1159 + %t1171 = call ptr @realloc(ptr %t1170, i64 %t1169) + store ptr %t1171, ptr %t1159 + store i32 %t1165, ptr %t1158 + br label %put186 +put186: + %t1172 = load ptr, ptr %t1155 + %t1173 = getelementptr inbounds %Cmp_Val, ptr %t1172, i32 0, i32 0 + %t1174 = load ptr, ptr %t1173 + %t1175 = load ptr, ptr %t1159 + %t1176 = getelementptr inbounds ptr, ptr %t1175, i32 %t1160 + store ptr %t1174, ptr %t1176 + %t1177 = add i32 %t1160, 1 + store i32 %t1177, ptr %t1157 + %t1178 = load ptr, ptr %t1135 + %t1179 = getelementptr inbounds %LSlice, ptr %t1178, i32 0, i32 1 + %t1180 = getelementptr inbounds %LSlice, ptr %t1178, i32 0, i32 2 + %t1181 = getelementptr inbounds %LSlice, ptr %t1178, i32 0, i32 0 + %t1182 = load i32, ptr %t1179 + %t1183 = load i32, ptr %t1180 + %t1184 = icmp sge i32 %t1182, %t1183 + br i1 %t1184, label %grow187, label %put188 +grow187: + %t1185 = mul i32 %t1183, 2 + %t1186 = icmp eq i32 %t1183, 0 + %t1187 = select i1 %t1186, i32 8, i32 %t1185 + %t1188 = getelementptr ptr, ptr null, i32 1 + %t1189 = ptrtoint ptr %t1188 to i64 + %t1190 = zext i32 %t1187 to i64 + %t1191 = mul i64 %t1190, %t1189 + %t1192 = load ptr, ptr %t1181 + %t1193 = call ptr @realloc(ptr %t1192, i64 %t1191) + store ptr %t1193, ptr %t1181 + store i32 %t1187, ptr %t1180 + br label %put188 +put188: + %t1194 = load ptr, ptr %t1155 + %t1195 = getelementptr inbounds %Cmp_Val, ptr %t1194, i32 0, i32 1 + %t1196 = load ptr, ptr %t1195 + %t1197 = load ptr, ptr %t1181 + %t1198 = getelementptr inbounds ptr, ptr %t1197, i32 %t1182 + store ptr %t1196, ptr %t1198 + %t1199 = add i32 %t1182, 1 + store i32 %t1199, ptr %t1179 + %t1200 = load i32, ptr %t1136 + %t1201 = add i32 %t1200, 1 + store i32 %t1201, ptr %t1136 + br label %wcond182 +wend184: + %t1202 = load ptr, ptr %t1103 + %t1203 = getelementptr inbounds %Cmp_Node, ptr %t1202, i32 0, i32 3 + %t1204 = load ptr, ptr %t1203 + %t1205 = call ptr @fn_llty(ptr %t1204) + store ptr %t1205, ptr %t1206 + call void @fn_emit(ptr @.str1178) + store ptr @.str1179, ptr %t1207 + %t1208 = load ptr, ptr %t1206 + %t1209 = call i32 @fn_str_eq(ptr %t1208, ptr @.str1180) + %t1210 = icmp eq i32 %t1209, 0 + %t1211 = zext i1 %t1210 to i32 + %t1212 = icmp ne i32 %t1211, 0 + br i1 %t1212, label %then189, label %ifend191 +then189: + %t1213 = call ptr @fn_nreg() + store ptr %t1213, ptr %t1207 + %t1214 = load ptr, ptr %t1207 + call void @fn_emit(ptr %t1214) + call void @fn_emit(ptr @.str1181) + br label %ifend191 +ifend191: + call void @fn_emit(ptr @.str1182) + %t1215 = load ptr, ptr %t1206 + call void @fn_emit(ptr %t1215) + call void @fn_emit(ptr @.str1183) + %t1216 = load ptr, ptr %t1105 + call void @fn_emit(ptr %t1216) + call void @fn_emit(ptr @.str1184) + store i32 0, ptr %t1136 + br label %wcond192 +wcond192: + %t1217 = load i32, ptr %t1136 + %t1218 = load ptr, ptr %t1128 + %t1219 = getelementptr inbounds %LSlice, ptr %t1218, i32 0, i32 1 + %t1220 = load i32, ptr %t1219 + %t1221 = icmp slt i32 %t1217, %t1220 + %t1222 = zext i1 %t1221 to i32 + %t1223 = icmp ne i32 %t1222, 0 + br i1 %t1223, label %wbody193, label %wend194 +wbody193: + %t1224 = load i32, ptr %t1136 + %t1225 = icmp sgt i32 %t1224, 0 + %t1226 = zext i1 %t1225 to i32 + %t1227 = icmp ne i32 %t1226, 0 + br i1 %t1227, label %then195, label %ifend197 +then195: + call void @fn_emit(ptr @.str1185) + br label %ifend197 +ifend197: + %t1228 = load ptr, ptr %t1135 + %t1229 = getelementptr inbounds %LSlice, ptr %t1228, i32 0, i32 0 + %t1230 = load ptr, ptr %t1229 + %t1231 = load i32, ptr %t1136 + %t1232 = getelementptr inbounds ptr, ptr %t1230, i32 %t1231 + %t1233 = load ptr, ptr %t1232 + %t1234 = call ptr @fn_llty(ptr %t1233) + call void @fn_emit(ptr %t1234) + call void @fn_emit(ptr @.str1186) + %t1235 = load ptr, ptr %t1128 + %t1236 = getelementptr inbounds %LSlice, ptr %t1235, i32 0, i32 0 + %t1237 = load ptr, ptr %t1236 + %t1238 = load i32, ptr %t1136 + %t1239 = getelementptr inbounds ptr, ptr %t1237, i32 %t1238 + %t1240 = load ptr, ptr %t1239 + call void @fn_emit(ptr %t1240) + %t1241 = load i32, ptr %t1136 + %t1242 = add i32 %t1241, 1 + store i32 %t1242, ptr %t1136 + br label %wcond192 +wend194: + call void @fn_emit(ptr @.str1187) + %t1243 = load ptr, ptr %t1207 + %t1244 = load ptr, ptr %t1103 + %t1245 = getelementptr inbounds %Cmp_Node, ptr %t1244, i32 0, i32 3 + %t1246 = load ptr, ptr %t1245 + %t1247 = call ptr @fn_val(ptr %t1243, ptr %t1246) + store ptr %t1247, ptr %retval br label %ret ret: - %t368 = load ptr, ptr %retval - ret ptr %t368 + %t1248 = load ptr, ptr %retval + ret ptr %t1248 } define ptr @fn_emit_expr(ptr %arg_e) { @@ -15316,8 +19659,8 @@ entry: %t254 = alloca ptr %t266 = alloca ptr %t273 = alloca ptr - %t308 = alloca ptr - %t338 = alloca ptr + %t316 = alloca ptr + %t346 = alloca ptr store ptr %arg_e, ptr %t0 %t1 = load ptr, ptr %t0 %t2 = icmp eq ptr %t1, null @@ -15325,7 +19668,7 @@ entry: %t4 = icmp ne i32 %t3, 0 br i1 %t4, label %then0, label %ifend2 then0: - %t5 = call ptr @fn_val(ptr @.str916, ptr @.str917) + %t5 = call ptr @fn_val(ptr @.str1188, ptr @.str1189) store ptr %t5, ptr %retval br label %ret ifend2: @@ -15341,7 +19684,7 @@ then3: %t13 = getelementptr inbounds %Cmp_Node, ptr %t12, i32 0, i32 2 %t14 = load i32, ptr %t13 %t15 = call ptr @fn_itoa(i32 %t14) - %t16 = call ptr @fn_val(ptr %t15, ptr @.str918) + %t16 = call ptr @fn_val(ptr %t15, ptr @.str1190) store ptr %t16, ptr %retval br label %ret ifend5: @@ -15357,7 +19700,7 @@ then6: %t24 = getelementptr inbounds %Cmp_Node, ptr %t23, i32 0, i32 2 %t25 = load i32, ptr %t24 %t26 = call ptr @fn_itoa(i32 %t25) - %t27 = call ptr @fn_val(ptr %t26, ptr @.str919) + %t27 = call ptr @fn_val(ptr %t26, ptr @.str1191) store ptr %t27, ptr %retval br label %ret ifend8: @@ -15373,7 +19716,7 @@ then9: %t35 = getelementptr inbounds %Cmp_Node, ptr %t34, i32 0, i32 2 %t36 = load i32, ptr %t35 %t37 = call ptr @fn_itoa(i32 %t36) - %t38 = call ptr @fn_val(ptr %t37, ptr @.str920) + %t38 = call ptr @fn_val(ptr %t37, ptr @.str1192) store ptr %t38, ptr %retval br label %ret ifend11: @@ -15385,7 +19728,7 @@ ifend11: %t44 = icmp ne i32 %t43, 0 br i1 %t44, label %then12, label %ifend14 then12: - %t45 = call ptr @fn_val(ptr @.str921, ptr @.str922) + %t45 = call ptr @fn_val(ptr @.str1193, ptr @.str1194) store ptr %t45, ptr %retval br label %ret ifend14: @@ -15416,20 +19759,20 @@ then15: %t67 = load ptr, ptr %t56 %t68 = getelementptr inbounds %Cmp_Val, ptr %t67, i32 0, i32 0 %t69 = load ptr, ptr %t68 - %t70 = call ptr @fn_str_concat(ptr @.str923, ptr %t69) - %t71 = call ptr @fn_str_concat(ptr %t70, ptr @.str924) + %t70 = call ptr @fn_str_concat(ptr @.str1195, ptr %t69) + %t71 = call ptr @fn_str_concat(ptr %t70, ptr @.str1196) %t72 = load ptr, ptr %t61 %t73 = getelementptr inbounds %Cmp_Val, ptr %t72, i32 0, i32 0 %t74 = load ptr, ptr %t73 %t75 = call ptr @fn_str_concat(ptr %t71, ptr %t74) - %t76 = call ptr @fn_str_concat(ptr %t75, ptr @.str925) + %t76 = call ptr @fn_str_concat(ptr %t75, ptr @.str1197) %t77 = load ptr, ptr %t66 %t78 = getelementptr inbounds %Cmp_Val, ptr %t77, i32 0, i32 0 %t79 = load ptr, ptr %t78 %t80 = call ptr @fn_str_concat(ptr %t76, ptr %t79) - %t81 = call ptr @fn_str_concat(ptr %t80, ptr @.str926) + %t81 = call ptr @fn_str_concat(ptr %t80, ptr @.str1198) %t82 = call ptr @fn_emit_bind(ptr %t81) - %t83 = call ptr @fn_val(ptr %t82, ptr @.str927) + %t83 = call ptr @fn_val(ptr %t82, ptr @.str1199) store ptr %t83, ptr %retval br label %ret ifend17: @@ -15445,7 +19788,7 @@ then18: %t91 = getelementptr inbounds %Cmp_Node, ptr %t90, i32 0, i32 1 %t92 = load ptr, ptr %t91 %t93 = call ptr @fn_emit_str_const(ptr %t92) - %t94 = call ptr @fn_val(ptr %t93, ptr @.str928) + %t94 = call ptr @fn_val(ptr %t93, ptr @.str1200) store ptr %t94, ptr %retval br label %ret ifend20: @@ -15538,7 +19881,7 @@ then36: %t160 = getelementptr inbounds %Cmp_Node, ptr %t159, i32 0, i32 2 %t161 = load i32, ptr %t160 %t162 = call ptr @fn_itoa(i32 %t161) - %t163 = call ptr @fn_val(ptr %t162, ptr @.str929) + %t163 = call ptr @fn_val(ptr %t162, ptr @.str1201) store ptr %t163, ptr %retval br label %ret ifend38: @@ -15546,8 +19889,8 @@ ifend38: %t165 = getelementptr inbounds %Cmp_Node, ptr %t164, i32 0, i32 3 %t166 = load ptr, ptr %t165 %t167 = call ptr @fn_llty(ptr %t166) - %t168 = call ptr @fn_str_concat(ptr @.str930, ptr %t167) - %t169 = call ptr @fn_str_concat(ptr %t168, ptr @.str931) + %t168 = call ptr @fn_str_concat(ptr @.str1202, ptr %t167) + %t169 = call ptr @fn_str_concat(ptr %t168, ptr @.str1203) %t170 = load ptr, ptr %t0 %t171 = getelementptr inbounds %Cmp_Node, ptr %t170, i32 0, i32 1 %t172 = load ptr, ptr %t171 @@ -15574,14 +19917,14 @@ then39: %t188 = load ptr, ptr %t187 %t189 = call i32 @fn_ui_index_of(ptr %t188) %t190 = call ptr @fn_itoa(i32 %t189) - %t191 = call ptr @fn_val(ptr %t190, ptr @.str932) + %t191 = call ptr @fn_val(ptr %t190, ptr @.str1204) store ptr %t191, ptr %retval br label %ret ifend41: %t192 = load ptr, ptr %t0 %t193 = getelementptr inbounds %Cmp_Node, ptr %t192, i32 0, i32 1 %t194 = load ptr, ptr %t193 - %t195 = call ptr @fn_str_concat(ptr @.str933, ptr %t194) + %t195 = call ptr @fn_str_concat(ptr @.str1205, ptr %t194) call void @fn_perr(ptr %t195) br label %ifend29 ifend29: @@ -15621,7 +19964,7 @@ then45: then48: %t224 = load i32, ptr %t219 %t225 = call ptr @fn_itoa(i32 %t224) - %t226 = call ptr @fn_val(ptr %t225, ptr @.str934) + %t226 = call ptr @fn_val(ptr %t225, ptr @.str1206) store ptr %t226, ptr %retval br label %ret ifend50: @@ -15682,19 +20025,19 @@ then57: %t265 = call ptr @fn_emit_index_addr(ptr %t264) store ptr %t265, ptr %t266 %t267 = load ptr, ptr @g_g_addr_ty - %t268 = call i32 @fn_str_eq(ptr %t267, ptr @.str935) + %t268 = call i32 @fn_str_eq(ptr %t267, ptr @.str1207) %t269 = icmp ne i32 %t268, 0 br i1 %t269, label %then60, label %ifend62 then60: %t270 = load ptr, ptr %t266 - %t271 = call ptr @fn_str_concat(ptr @.str936, ptr %t270) + %t271 = call ptr @fn_str_concat(ptr @.str1208, ptr %t270) %t272 = call ptr @fn_emit_bind(ptr %t271) store ptr %t272, ptr %t273 %t274 = load ptr, ptr %t273 - %t275 = call ptr @fn_str_concat(ptr @.str937, ptr %t274) - %t276 = call ptr @fn_str_concat(ptr %t275, ptr @.str938) + %t275 = call ptr @fn_str_concat(ptr @.str1209, ptr %t274) + %t276 = call ptr @fn_str_concat(ptr %t275, ptr @.str1210) %t277 = call ptr @fn_emit_bind(ptr %t276) - %t278 = call ptr @fn_val(ptr %t277, ptr @.str939) + %t278 = call ptr @fn_val(ptr %t277, ptr @.str1211) store ptr %t278, ptr %retval br label %ret ifend62: @@ -15707,97 +20050,110 @@ ifend59: %t282 = load ptr, ptr %t0 %t283 = getelementptr inbounds %Cmp_Node, ptr %t282, i32 0, i32 0 %t284 = load i32, ptr %t283 - %t285 = icmp eq i32 %t284, 34 + %t285 = icmp eq i32 %t284, 49 %t286 = zext i1 %t285 to i32 %t287 = icmp ne i32 %t286, 0 br i1 %t287, label %then63, label %ifend65 then63: %t288 = load ptr, ptr %t0 - %t289 = call ptr @fn_emit_call(ptr %t288) + %t289 = call ptr @fn_emit_emit(ptr %t288) store ptr %t289, ptr %retval br label %ret ifend65: %t290 = load ptr, ptr %t0 %t291 = getelementptr inbounds %Cmp_Node, ptr %t290, i32 0, i32 0 %t292 = load i32, ptr %t291 - %t293 = icmp eq i32 %t292, 37 + %t293 = icmp eq i32 %t292, 34 %t294 = zext i1 %t293 to i32 %t295 = icmp ne i32 %t294, 0 br i1 %t295, label %then66, label %ifend68 then66: %t296 = load ptr, ptr %t0 - %t297 = call ptr @fn_emit_bin(ptr %t296) + %t297 = call ptr @fn_emit_call(ptr %t296) store ptr %t297, ptr %retval br label %ret ifend68: %t298 = load ptr, ptr %t0 %t299 = getelementptr inbounds %Cmp_Node, ptr %t298, i32 0, i32 0 %t300 = load i32, ptr %t299 - %t301 = icmp eq i32 %t300, 38 + %t301 = icmp eq i32 %t300, 37 %t302 = zext i1 %t301 to i32 %t303 = icmp ne i32 %t302, 0 br i1 %t303, label %then69, label %ifend71 then69: %t304 = load ptr, ptr %t0 - %t305 = getelementptr inbounds %Cmp_Node, ptr %t304, i32 0, i32 4 - %t306 = load ptr, ptr %t305 - %t307 = call ptr @fn_emit_expr(ptr %t306) - store ptr %t307, ptr %t308 - %t309 = load ptr, ptr %t0 - %t310 = getelementptr inbounds %Cmp_Node, ptr %t309, i32 0, i32 1 - %t311 = load ptr, ptr %t310 - %t312 = call i32 @fn_str_eq(ptr %t311, ptr @.str940) - %t313 = icmp ne i32 %t312, 0 - br i1 %t313, label %then72, label %ifend74 -then72: - %t314 = load ptr, ptr %t308 - %t315 = getelementptr inbounds %Cmp_Val, ptr %t314, i32 0, i32 0 - %t316 = load ptr, ptr %t315 - %t317 = call ptr @fn_str_concat(ptr @.str941, ptr %t316) - %t318 = call ptr @fn_emit_bind(ptr %t317) - %t319 = call ptr @fn_val(ptr %t318, ptr @.str942) - store ptr %t319, ptr %retval - br label %ret -ifend74: - %t320 = load ptr, ptr %t0 - %t321 = getelementptr inbounds %Cmp_Node, ptr %t320, i32 0, i32 1 - %t322 = load ptr, ptr %t321 - %t323 = call i32 @fn_str_eq(ptr %t322, ptr @.str943) - %t324 = icmp ne i32 %t323, 0 - br i1 %t324, label %then75, label %ifend77 -then75: - %t325 = load ptr, ptr %t308 - %t326 = getelementptr inbounds %Cmp_Val, ptr %t325, i32 0, i32 0 - %t327 = load ptr, ptr %t326 - %t328 = call ptr @fn_str_concat(ptr @.str944, ptr %t327) - %t329 = call ptr @fn_str_concat(ptr %t328, ptr @.str945) - %t330 = call ptr @fn_emit_bind(ptr %t329) - %t331 = call ptr @fn_val(ptr %t330, ptr @.str946) - store ptr %t331, ptr %retval - br label %ret -ifend77: - %t332 = load ptr, ptr %t308 - %t333 = getelementptr inbounds %Cmp_Val, ptr %t332, i32 0, i32 0 - %t334 = load ptr, ptr %t333 - %t335 = call ptr @fn_str_concat(ptr @.str947, ptr %t334) - %t336 = call ptr @fn_str_concat(ptr %t335, ptr @.str948) - %t337 = call ptr @fn_emit_bind(ptr %t336) - store ptr %t337, ptr %t338 - %t339 = load ptr, ptr %t338 - %t340 = call ptr @fn_str_concat(ptr @.str949, ptr %t339) - %t341 = call ptr @fn_str_concat(ptr %t340, ptr @.str950) - %t342 = call ptr @fn_emit_bind(ptr %t341) - %t343 = call ptr @fn_val(ptr %t342, ptr @.str951) - store ptr %t343, ptr %retval + %t305 = call ptr @fn_emit_bin(ptr %t304) + store ptr %t305, ptr %retval br label %ret ifend71: - call void @fn_perr(ptr @.str952) - %t344 = call ptr @fn_val(ptr @.str953, ptr @.str954) - store ptr %t344, ptr %retval + %t306 = load ptr, ptr %t0 + %t307 = getelementptr inbounds %Cmp_Node, ptr %t306, i32 0, i32 0 + %t308 = load i32, ptr %t307 + %t309 = icmp eq i32 %t308, 38 + %t310 = zext i1 %t309 to i32 + %t311 = icmp ne i32 %t310, 0 + br i1 %t311, label %then72, label %ifend74 +then72: + %t312 = load ptr, ptr %t0 + %t313 = getelementptr inbounds %Cmp_Node, ptr %t312, i32 0, i32 4 + %t314 = load ptr, ptr %t313 + %t315 = call ptr @fn_emit_expr(ptr %t314) + store ptr %t315, ptr %t316 + %t317 = load ptr, ptr %t0 + %t318 = getelementptr inbounds %Cmp_Node, ptr %t317, i32 0, i32 1 + %t319 = load ptr, ptr %t318 + %t320 = call i32 @fn_str_eq(ptr %t319, ptr @.str1212) + %t321 = icmp ne i32 %t320, 0 + br i1 %t321, label %then75, label %ifend77 +then75: + %t322 = load ptr, ptr %t316 + %t323 = getelementptr inbounds %Cmp_Val, ptr %t322, i32 0, i32 0 + %t324 = load ptr, ptr %t323 + %t325 = call ptr @fn_str_concat(ptr @.str1213, ptr %t324) + %t326 = call ptr @fn_emit_bind(ptr %t325) + %t327 = call ptr @fn_val(ptr %t326, ptr @.str1214) + store ptr %t327, ptr %retval + br label %ret +ifend77: + %t328 = load ptr, ptr %t0 + %t329 = getelementptr inbounds %Cmp_Node, ptr %t328, i32 0, i32 1 + %t330 = load ptr, ptr %t329 + %t331 = call i32 @fn_str_eq(ptr %t330, ptr @.str1215) + %t332 = icmp ne i32 %t331, 0 + br i1 %t332, label %then78, label %ifend80 +then78: + %t333 = load ptr, ptr %t316 + %t334 = getelementptr inbounds %Cmp_Val, ptr %t333, i32 0, i32 0 + %t335 = load ptr, ptr %t334 + %t336 = call ptr @fn_str_concat(ptr @.str1216, ptr %t335) + %t337 = call ptr @fn_str_concat(ptr %t336, ptr @.str1217) + %t338 = call ptr @fn_emit_bind(ptr %t337) + %t339 = call ptr @fn_val(ptr %t338, ptr @.str1218) + store ptr %t339, ptr %retval + br label %ret +ifend80: + %t340 = load ptr, ptr %t316 + %t341 = getelementptr inbounds %Cmp_Val, ptr %t340, i32 0, i32 0 + %t342 = load ptr, ptr %t341 + %t343 = call ptr @fn_str_concat(ptr @.str1219, ptr %t342) + %t344 = call ptr @fn_str_concat(ptr %t343, ptr @.str1220) + %t345 = call ptr @fn_emit_bind(ptr %t344) + store ptr %t345, ptr %t346 + %t347 = load ptr, ptr %t346 + %t348 = call ptr @fn_str_concat(ptr @.str1221, ptr %t347) + %t349 = call ptr @fn_str_concat(ptr %t348, ptr @.str1222) + %t350 = call ptr @fn_emit_bind(ptr %t349) + %t351 = call ptr @fn_val(ptr %t350, ptr @.str1223) + store ptr %t351, ptr %retval + br label %ret +ifend74: + call void @fn_perr(ptr @.str1224) + %t352 = call ptr @fn_val(ptr @.str1225, ptr @.str1226) + store ptr %t352, ptr %retval br label %ret ret: - %t345 = load ptr, ptr %retval - ret ptr %t345 + %t353 = load ptr, ptr %retval + ret ptr %t353 } define void @fn_emit_block(ptr %arg_b) { @@ -15852,16 +20208,16 @@ entry: store ptr %arg_lt, ptr %t0 store ptr %arg_v, ptr %t1 store ptr %arg_addr, ptr %t2 - call void @fn_emit(ptr @.str955) + call void @fn_emit(ptr @.str1227) %t3 = load ptr, ptr %t0 call void @fn_emit(ptr %t3) - call void @fn_emit(ptr @.str956) + call void @fn_emit(ptr @.str1228) %t4 = load ptr, ptr %t1 call void @fn_emit(ptr %t4) - call void @fn_emit(ptr @.str957) + call void @fn_emit(ptr @.str1229) %t5 = load ptr, ptr %t2 call void @fn_emit(ptr %t5) - call void @fn_emit(ptr @.str958) + call void @fn_emit(ptr @.str1230) br label %ret ret: ret void @@ -15885,8 +20241,8 @@ entry: %t2 = getelementptr inbounds %Cmp_Node, ptr %t1, i32 0, i32 4 %t3 = load ptr, ptr %t2 store ptr %t3, ptr %t4 - store ptr @.str959, ptr %t5 - store ptr @.str960, ptr %t6 + store ptr @.str1231, ptr %t5 + store ptr @.str1232, ptr %t6 %t7 = load ptr, ptr %t4 %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 0 %t9 = load i32, ptr %t8 @@ -15920,8 +20276,8 @@ then6: %t31 = load ptr, ptr %t4 %t32 = getelementptr inbounds %Cmp_Node, ptr %t31, i32 0, i32 1 %t33 = load ptr, ptr %t32 - %t34 = call ptr @fn_str_concat(ptr @.str961, ptr %t33) - %t35 = call ptr @fn_str_concat(ptr %t34, ptr @.str962) + %t34 = call ptr @fn_str_concat(ptr @.str1233, ptr %t33) + %t35 = call ptr @fn_str_concat(ptr %t34, ptr @.str1234) %t36 = load ptr, ptr %t0 %t37 = getelementptr inbounds %Cmp_Node, ptr %t36, i32 0, i32 8 %t38 = load i32, ptr %t37 @@ -15960,14 +20316,14 @@ then9: %t62 = load ptr, ptr %t4 %t63 = getelementptr inbounds %Cmp_Node, ptr %t62, i32 0, i32 1 %t64 = load ptr, ptr %t63 - %t65 = call ptr @fn_str_concat(ptr @.str963, ptr %t64) + %t65 = call ptr @fn_str_concat(ptr @.str1235, ptr %t64) call void @fn_perr(ptr %t65) br label %ifend11 ifend11: %t66 = load ptr, ptr %t4 %t67 = getelementptr inbounds %Cmp_Node, ptr %t66, i32 0, i32 1 %t68 = load ptr, ptr %t67 - %t69 = call ptr @fn_str_concat(ptr @.str964, ptr %t68) + %t69 = call ptr @fn_str_concat(ptr @.str1236, ptr %t68) store ptr %t69, ptr %t5 %t70 = load ptr, ptr %t57 %t71 = getelementptr inbounds %Cmp_Node, ptr %t70, i32 0, i32 3 @@ -16007,7 +20363,7 @@ then15: store ptr %t90, ptr %t6 br label %ifend17 else16: - call void @fn_perr(ptr @.str965) + call void @fn_perr(ptr @.str1237) br label %ifend17 ifend17: br label %ifend14 @@ -16029,55 +20385,55 @@ ifend2: %t103 = load ptr, ptr %t0 %t104 = getelementptr inbounds %Cmp_Node, ptr %t103, i32 0, i32 1 %t105 = load ptr, ptr %t104 - %t106 = call i32 @fn_str_eq(ptr %t105, ptr @.str966) + %t106 = call i32 @fn_str_eq(ptr %t105, ptr @.str1238) %t107 = icmp eq i32 %t106, 0 %t108 = zext i1 %t107 to i32 %t109 = icmp ne i32 %t108, 0 br i1 %t109, label %then18, label %ifend20 then18: %t110 = load ptr, ptr %t93 - %t111 = call ptr @fn_str_concat(ptr @.str967, ptr %t110) - %t112 = call ptr @fn_str_concat(ptr %t111, ptr @.str968) + %t111 = call ptr @fn_str_concat(ptr @.str1239, ptr %t110) + %t112 = call ptr @fn_str_concat(ptr %t111, ptr @.str1240) %t113 = load ptr, ptr %t5 %t114 = call ptr @fn_str_concat(ptr %t112, ptr %t113) %t115 = call ptr @fn_emit_bind(ptr %t114) store ptr %t115, ptr %t116 - store ptr @.str969, ptr %t117 + store ptr @.str1241, ptr %t117 %t118 = load ptr, ptr %t0 %t119 = getelementptr inbounds %Cmp_Node, ptr %t118, i32 0, i32 1 %t120 = load ptr, ptr %t119 - %t121 = call i32 @fn_str_eq(ptr %t120, ptr @.str970) + %t121 = call i32 @fn_str_eq(ptr %t120, ptr @.str1242) %t122 = icmp ne i32 %t121, 0 br i1 %t122, label %then21, label %ifend23 then21: - store ptr @.str971, ptr %t117 + store ptr @.str1243, ptr %t117 br label %ifend23 ifend23: %t123 = load ptr, ptr %t0 %t124 = getelementptr inbounds %Cmp_Node, ptr %t123, i32 0, i32 1 %t125 = load ptr, ptr %t124 - %t126 = call i32 @fn_str_eq(ptr %t125, ptr @.str972) + %t126 = call i32 @fn_str_eq(ptr %t125, ptr @.str1244) %t127 = icmp ne i32 %t126, 0 br i1 %t127, label %then24, label %ifend26 then24: - store ptr @.str973, ptr %t117 + store ptr @.str1245, ptr %t117 br label %ifend26 ifend26: %t128 = load ptr, ptr %t0 %t129 = getelementptr inbounds %Cmp_Node, ptr %t128, i32 0, i32 1 %t130 = load ptr, ptr %t129 - %t131 = call i32 @fn_str_eq(ptr %t130, ptr @.str974) + %t131 = call i32 @fn_str_eq(ptr %t130, ptr @.str1246) %t132 = icmp ne i32 %t131, 0 br i1 %t132, label %then27, label %ifend29 then27: - store ptr @.str975, ptr %t117 + store ptr @.str1247, ptr %t117 br label %ifend29 ifend29: %t133 = load ptr, ptr %t117 - %t134 = call ptr @fn_str_concat(ptr %t133, ptr @.str976) + %t134 = call ptr @fn_str_concat(ptr %t133, ptr @.str1248) %t135 = load ptr, ptr %t116 %t136 = call ptr @fn_str_concat(ptr %t134, ptr %t135) - %t137 = call ptr @fn_str_concat(ptr %t136, ptr @.str977) + %t137 = call ptr @fn_str_concat(ptr %t136, ptr @.str1249) %t138 = load ptr, ptr %t102 %t139 = call ptr @fn_str_concat(ptr %t137, ptr %t138) %t140 = call ptr @fn_emit_bind(ptr %t139) @@ -16085,13 +20441,13 @@ ifend29: br label %ifend20 ifend20: %t141 = load ptr, ptr %t93 - %t142 = call i32 @fn_str_eq(ptr %t141, ptr @.str978) + %t142 = call i32 @fn_str_eq(ptr %t141, ptr @.str1250) %t143 = icmp ne i32 %t142, 0 br i1 %t143, label %then30, label %ifend32 then30: %t144 = load ptr, ptr %t102 - %t145 = call ptr @fn_str_concat(ptr @.str979, ptr %t144) - %t146 = call ptr @fn_str_concat(ptr %t145, ptr @.str980) + %t145 = call ptr @fn_str_concat(ptr @.str1251, ptr %t144) + %t146 = call ptr @fn_str_concat(ptr %t145, ptr @.str1252) %t147 = call ptr @fn_emit_bind(ptr %t146) store ptr %t147, ptr %t102 br label %ifend32 @@ -16123,8 +20479,8 @@ entry: %t6 = load ptr, ptr %t5 %t7 = getelementptr inbounds %Cmp_Val, ptr %t6, i32 0, i32 0 %t8 = load ptr, ptr %t7 - %t9 = call ptr @fn_str_concat(ptr @.str981, ptr %t8) - %t10 = call ptr @fn_str_concat(ptr %t9, ptr @.str982) + %t9 = call ptr @fn_str_concat(ptr @.str1253, ptr %t8) + %t10 = call ptr @fn_str_concat(ptr %t9, ptr @.str1254) %t11 = call ptr @fn_emit_bind(ptr %t10) store ptr %t11, ptr %t12 %t13 = load ptr, ptr %t0 @@ -16133,43 +20489,43 @@ entry: %t16 = icmp ne ptr %t15, null %t17 = zext i1 %t16 to i32 store i32 %t17, ptr %t18 - %t19 = call ptr @fn_lbl(ptr @.str983) + %t19 = call ptr @fn_lbl(ptr @.str1255) store ptr %t19, ptr %t20 - %t21 = call ptr @fn_lbl(ptr @.str984) + %t21 = call ptr @fn_lbl(ptr @.str1256) store ptr %t21, ptr %t22 - %t23 = call ptr @fn_lbl(ptr @.str985) + %t23 = call ptr @fn_lbl(ptr @.str1257) store ptr %t23, ptr %t24 %t25 = load i32, ptr %t18 %t26 = icmp ne i32 %t25, 0 br i1 %t26, label %then0, label %else1 then0: - call void @fn_emit(ptr @.str986) + call void @fn_emit(ptr @.str1258) %t27 = load ptr, ptr %t12 call void @fn_emit(ptr %t27) - call void @fn_emit(ptr @.str987) + call void @fn_emit(ptr @.str1259) %t28 = load ptr, ptr %t20 call void @fn_emit(ptr %t28) - call void @fn_emit(ptr @.str988) + call void @fn_emit(ptr @.str1260) %t29 = load ptr, ptr %t22 call void @fn_emit(ptr %t29) - call void @fn_emit(ptr @.str989) + call void @fn_emit(ptr @.str1261) br label %ifend2 else1: - call void @fn_emit(ptr @.str990) + call void @fn_emit(ptr @.str1262) %t30 = load ptr, ptr %t12 call void @fn_emit(ptr %t30) - call void @fn_emit(ptr @.str991) + call void @fn_emit(ptr @.str1263) %t31 = load ptr, ptr %t20 call void @fn_emit(ptr %t31) - call void @fn_emit(ptr @.str992) + call void @fn_emit(ptr @.str1264) %t32 = load ptr, ptr %t24 call void @fn_emit(ptr %t32) - call void @fn_emit(ptr @.str993) + call void @fn_emit(ptr @.str1265) br label %ifend2 ifend2: %t33 = load ptr, ptr %t20 call void @fn_emit(ptr %t33) - call void @fn_emit(ptr @.str994) + call void @fn_emit(ptr @.str1266) store i32 0, ptr @g_g_term %t34 = load ptr, ptr %t0 %t35 = getelementptr inbounds %Cmp_Node, ptr %t34, i32 0, i32 5 @@ -16181,10 +20537,10 @@ ifend2: %t40 = icmp ne i32 %t39, 0 br i1 %t40, label %then3, label %ifend5 then3: - call void @fn_emit(ptr @.str995) + call void @fn_emit(ptr @.str1267) %t41 = load ptr, ptr %t24 call void @fn_emit(ptr %t41) - call void @fn_emit(ptr @.str996) + call void @fn_emit(ptr @.str1268) br label %ifend5 ifend5: %t42 = load i32, ptr %t18 @@ -16193,7 +20549,7 @@ ifend5: then6: %t44 = load ptr, ptr %t22 call void @fn_emit(ptr %t44) - call void @fn_emit(ptr @.str997) + call void @fn_emit(ptr @.str1269) store i32 0, ptr @g_g_term %t45 = load ptr, ptr %t0 %t46 = getelementptr inbounds %Cmp_Node, ptr %t45, i32 0, i32 6 @@ -16223,17 +20579,17 @@ ifend11: %t62 = icmp ne i32 %t61, 0 br i1 %t62, label %then12, label %ifend14 then12: - call void @fn_emit(ptr @.str998) + call void @fn_emit(ptr @.str1270) %t63 = load ptr, ptr %t24 call void @fn_emit(ptr %t63) - call void @fn_emit(ptr @.str999) + call void @fn_emit(ptr @.str1271) br label %ifend14 ifend14: br label %ifend8 ifend8: %t64 = load ptr, ptr %t24 call void @fn_emit(ptr %t64) - call void @fn_emit(ptr @.str1000) + call void @fn_emit(ptr @.str1272) store i32 0, ptr @g_g_term br label %ret ret: @@ -16249,19 +20605,19 @@ entry: %t13 = alloca ptr %t20 = alloca ptr store ptr %arg_st, ptr %t0 - %t1 = call ptr @fn_lbl(ptr @.str1001) + %t1 = call ptr @fn_lbl(ptr @.str1273) store ptr %t1, ptr %t2 - %t3 = call ptr @fn_lbl(ptr @.str1002) + %t3 = call ptr @fn_lbl(ptr @.str1274) store ptr %t3, ptr %t4 - %t5 = call ptr @fn_lbl(ptr @.str1003) + %t5 = call ptr @fn_lbl(ptr @.str1275) store ptr %t5, ptr %t6 - call void @fn_emit(ptr @.str1004) + call void @fn_emit(ptr @.str1276) %t7 = load ptr, ptr %t2 call void @fn_emit(ptr %t7) - call void @fn_emit(ptr @.str1005) + call void @fn_emit(ptr @.str1277) %t8 = load ptr, ptr %t2 call void @fn_emit(ptr %t8) - call void @fn_emit(ptr @.str1006) + call void @fn_emit(ptr @.str1278) %t9 = load ptr, ptr %t0 %t10 = getelementptr inbounds %Cmp_Node, ptr %t9, i32 0, i32 4 %t11 = load ptr, ptr %t10 @@ -16270,23 +20626,23 @@ entry: %t14 = load ptr, ptr %t13 %t15 = getelementptr inbounds %Cmp_Val, ptr %t14, i32 0, i32 0 %t16 = load ptr, ptr %t15 - %t17 = call ptr @fn_str_concat(ptr @.str1007, ptr %t16) - %t18 = call ptr @fn_str_concat(ptr %t17, ptr @.str1008) + %t17 = call ptr @fn_str_concat(ptr @.str1279, ptr %t16) + %t18 = call ptr @fn_str_concat(ptr %t17, ptr @.str1280) %t19 = call ptr @fn_emit_bind(ptr %t18) store ptr %t19, ptr %t20 - call void @fn_emit(ptr @.str1009) + call void @fn_emit(ptr @.str1281) %t21 = load ptr, ptr %t20 call void @fn_emit(ptr %t21) - call void @fn_emit(ptr @.str1010) + call void @fn_emit(ptr @.str1282) %t22 = load ptr, ptr %t4 call void @fn_emit(ptr %t22) - call void @fn_emit(ptr @.str1011) + call void @fn_emit(ptr @.str1283) %t23 = load ptr, ptr %t6 call void @fn_emit(ptr %t23) - call void @fn_emit(ptr @.str1012) + call void @fn_emit(ptr @.str1284) %t24 = load ptr, ptr %t4 call void @fn_emit(ptr %t24) - call void @fn_emit(ptr @.str1013) + call void @fn_emit(ptr @.str1285) store i32 0, ptr @g_g_term %t25 = load ptr, ptr %t2 %t26 = load ptr, ptr %t6 @@ -16302,15 +20658,15 @@ entry: %t33 = icmp ne i32 %t32, 0 br i1 %t33, label %then0, label %ifend2 then0: - call void @fn_emit(ptr @.str1014) + call void @fn_emit(ptr @.str1286) %t34 = load ptr, ptr %t2 call void @fn_emit(ptr %t34) - call void @fn_emit(ptr @.str1015) + call void @fn_emit(ptr @.str1287) br label %ifend2 ifend2: %t35 = load ptr, ptr %t6 call void @fn_emit(ptr %t35) - call void @fn_emit(ptr @.str1016) + call void @fn_emit(ptr @.str1288) store i32 0, ptr @g_g_term br label %ret ret: @@ -16332,7 +20688,7 @@ entry: %t62 = alloca ptr %t67 = alloca ptr store ptr %arg_st, ptr %t0 - %t1 = call ptr @fn_emit_alloca(ptr @.str1017) + %t1 = call ptr @fn_emit_alloca(ptr @.str1289) store ptr %t1, ptr %t2 %t3 = load ptr, ptr %t0 %t4 = getelementptr inbounds %Cmp_Node, ptr %t3, i32 0, i32 4 @@ -16343,29 +20699,29 @@ entry: %t9 = getelementptr inbounds %Cmp_Val, ptr %t8, i32 0, i32 0 %t10 = load ptr, ptr %t9 %t11 = load ptr, ptr %t2 - call void @fn_store_at(ptr @.str1018, ptr %t10, ptr %t11) + call void @fn_store_at(ptr @.str1290, ptr %t10, ptr %t11) %t12 = load ptr, ptr %t0 %t13 = getelementptr inbounds %Cmp_Node, ptr %t12, i32 0, i32 1 %t14 = load ptr, ptr %t13 %t15 = load ptr, ptr %t2 - call void @fn_loc_push(ptr %t14, ptr %t15, ptr @.str1019) - %t16 = call ptr @fn_lbl(ptr @.str1020) + call void @fn_loc_push(ptr %t14, ptr %t15, ptr @.str1291) + %t16 = call ptr @fn_lbl(ptr @.str1292) store ptr %t16, ptr %t17 - %t18 = call ptr @fn_lbl(ptr @.str1021) + %t18 = call ptr @fn_lbl(ptr @.str1293) store ptr %t18, ptr %t19 - %t20 = call ptr @fn_lbl(ptr @.str1022) + %t20 = call ptr @fn_lbl(ptr @.str1294) store ptr %t20, ptr %t21 - %t22 = call ptr @fn_lbl(ptr @.str1023) + %t22 = call ptr @fn_lbl(ptr @.str1295) store ptr %t22, ptr %t23 - call void @fn_emit(ptr @.str1024) + call void @fn_emit(ptr @.str1296) %t24 = load ptr, ptr %t17 call void @fn_emit(ptr %t24) - call void @fn_emit(ptr @.str1025) + call void @fn_emit(ptr @.str1297) %t25 = load ptr, ptr %t17 call void @fn_emit(ptr %t25) - call void @fn_emit(ptr @.str1026) + call void @fn_emit(ptr @.str1298) %t26 = load ptr, ptr %t2 - %t27 = call ptr @fn_str_concat(ptr @.str1027, ptr %t26) + %t27 = call ptr @fn_str_concat(ptr @.str1299, ptr %t26) %t28 = call ptr @fn_emit_bind(ptr %t27) store ptr %t28, ptr %t29 %t30 = load ptr, ptr %t0 @@ -16374,27 +20730,27 @@ entry: %t33 = call ptr @fn_emit_expr(ptr %t32) store ptr %t33, ptr %t34 %t35 = load ptr, ptr %t29 - %t36 = call ptr @fn_str_concat(ptr @.str1028, ptr %t35) - %t37 = call ptr @fn_str_concat(ptr %t36, ptr @.str1029) + %t36 = call ptr @fn_str_concat(ptr @.str1300, ptr %t35) + %t37 = call ptr @fn_str_concat(ptr %t36, ptr @.str1301) %t38 = load ptr, ptr %t34 %t39 = getelementptr inbounds %Cmp_Val, ptr %t38, i32 0, i32 0 %t40 = load ptr, ptr %t39 %t41 = call ptr @fn_str_concat(ptr %t37, ptr %t40) %t42 = call ptr @fn_emit_bind(ptr %t41) store ptr %t42, ptr %t43 - call void @fn_emit(ptr @.str1030) + call void @fn_emit(ptr @.str1302) %t44 = load ptr, ptr %t43 call void @fn_emit(ptr %t44) - call void @fn_emit(ptr @.str1031) + call void @fn_emit(ptr @.str1303) %t45 = load ptr, ptr %t19 call void @fn_emit(ptr %t45) - call void @fn_emit(ptr @.str1032) + call void @fn_emit(ptr @.str1304) %t46 = load ptr, ptr %t23 call void @fn_emit(ptr %t46) - call void @fn_emit(ptr @.str1033) + call void @fn_emit(ptr @.str1305) %t47 = load ptr, ptr %t19 call void @fn_emit(ptr %t47) - call void @fn_emit(ptr @.str1034) + call void @fn_emit(ptr @.str1306) store i32 0, ptr @g_g_term %t48 = load ptr, ptr %t21 %t49 = load ptr, ptr %t23 @@ -16410,34 +20766,34 @@ entry: %t56 = icmp ne i32 %t55, 0 br i1 %t56, label %then0, label %ifend2 then0: - call void @fn_emit(ptr @.str1035) + call void @fn_emit(ptr @.str1307) %t57 = load ptr, ptr %t21 call void @fn_emit(ptr %t57) - call void @fn_emit(ptr @.str1036) + call void @fn_emit(ptr @.str1308) br label %ifend2 ifend2: %t58 = load ptr, ptr %t21 call void @fn_emit(ptr %t58) - call void @fn_emit(ptr @.str1037) + call void @fn_emit(ptr @.str1309) %t59 = load ptr, ptr %t2 - %t60 = call ptr @fn_str_concat(ptr @.str1038, ptr %t59) + %t60 = call ptr @fn_str_concat(ptr @.str1310, ptr %t59) %t61 = call ptr @fn_emit_bind(ptr %t60) store ptr %t61, ptr %t62 %t63 = load ptr, ptr %t62 - %t64 = call ptr @fn_str_concat(ptr @.str1039, ptr %t63) - %t65 = call ptr @fn_str_concat(ptr %t64, ptr @.str1040) + %t64 = call ptr @fn_str_concat(ptr @.str1311, ptr %t63) + %t65 = call ptr @fn_str_concat(ptr %t64, ptr @.str1312) %t66 = call ptr @fn_emit_bind(ptr %t65) store ptr %t66, ptr %t67 %t68 = load ptr, ptr %t67 %t69 = load ptr, ptr %t2 - call void @fn_store_at(ptr @.str1041, ptr %t68, ptr %t69) - call void @fn_emit(ptr @.str1042) + call void @fn_store_at(ptr @.str1313, ptr %t68, ptr %t69) + call void @fn_emit(ptr @.str1314) %t70 = load ptr, ptr %t17 call void @fn_emit(ptr %t70) - call void @fn_emit(ptr @.str1043) + call void @fn_emit(ptr @.str1315) %t71 = load ptr, ptr %t23 call void @fn_emit(ptr %t71) - call void @fn_emit(ptr @.str1044) + call void @fn_emit(ptr @.str1316) store i32 0, ptr @g_g_term br label %ret ret: @@ -16467,10 +20823,10 @@ then0: %t14 = load ptr, ptr %t11 %t15 = getelementptr inbounds %Cmp_Val, ptr %t14, i32 0, i32 0 %t16 = load ptr, ptr %t15 - call void @fn_store_at(ptr %t13, ptr %t16, ptr @.str1045) + call void @fn_store_at(ptr %t13, ptr %t16, ptr @.str1317) br label %ifend2 ifend2: - call void @fn_emit(ptr @.str1046) + call void @fn_emit(ptr @.str1318) store i32 1, ptr @g_g_term br label %ret ret: @@ -16525,7 +20881,7 @@ sc3: %t33 = load ptr, ptr %t32 %t34 = getelementptr inbounds %Cmp_Node, ptr %t33, i32 0, i32 1 %t35 = load ptr, ptr %t34 - %t36 = call i32 @fn_str_eq(ptr %t35, ptr @.str1047) + %t36 = call i32 @fn_str_eq(ptr %t35, ptr @.str1319) %t37 = icmp ne i32 %t36, 0 %t38 = zext i1 %t37 to i32 store i32 %t38, ptr %t11 @@ -16571,7 +20927,7 @@ entry: %t3 = load ptr, ptr %t2 %t4 = call ptr @fn_emit_expr(ptr %t3) store ptr %t4, ptr %t5 - %t6 = call ptr @fn_lbl(ptr @.str1048) + %t6 = call ptr @fn_lbl(ptr @.str1320) store ptr %t6, ptr %t7 store ptr null, ptr %t8 store i32 0, ptr %t9 @@ -16606,7 +20962,7 @@ then3: store ptr %t31, ptr %t8 br label %ifend5 else4: - store ptr @.str1049, ptr %t32 + store ptr @.str1321, ptr %t32 store i32 1, ptr %t33 store i32 0, ptr %t34 br label %wcond6 @@ -16635,8 +20991,8 @@ wbody7: %t54 = load ptr, ptr %t5 %t55 = getelementptr inbounds %Cmp_Val, ptr %t54, i32 0, i32 0 %t56 = load ptr, ptr %t55 - %t57 = call ptr @fn_str_concat(ptr @.str1050, ptr %t56) - %t58 = call ptr @fn_str_concat(ptr %t57, ptr @.str1051) + %t57 = call ptr @fn_str_concat(ptr @.str1322, ptr %t56) + %t58 = call ptr @fn_str_concat(ptr %t57, ptr @.str1323) %t59 = load ptr, ptr %t53 %t60 = getelementptr inbounds %Cmp_Val, ptr %t59, i32 0, i32 0 %t61 = load ptr, ptr %t60 @@ -16653,8 +21009,8 @@ then9: br label %ifend11 else10: %t68 = load ptr, ptr %t32 - %t69 = call ptr @fn_str_concat(ptr @.str1052, ptr %t68) - %t70 = call ptr @fn_str_concat(ptr %t69, ptr @.str1053) + %t69 = call ptr @fn_str_concat(ptr @.str1324, ptr %t68) + %t70 = call ptr @fn_str_concat(ptr %t69, ptr @.str1325) %t71 = load ptr, ptr %t64 %t72 = call ptr @fn_str_concat(ptr %t70, ptr %t71) %t73 = call ptr @fn_emit_bind(ptr %t72) @@ -16666,23 +21022,23 @@ ifend11: store i32 %t75, ptr %t34 br label %wcond6 wend8: - %t76 = call ptr @fn_lbl(ptr @.str1054) + %t76 = call ptr @fn_lbl(ptr @.str1326) store ptr %t76, ptr %t77 - %t78 = call ptr @fn_lbl(ptr @.str1055) + %t78 = call ptr @fn_lbl(ptr @.str1327) store ptr %t78, ptr %t79 - call void @fn_emit(ptr @.str1056) + call void @fn_emit(ptr @.str1328) %t80 = load ptr, ptr %t32 call void @fn_emit(ptr %t80) - call void @fn_emit(ptr @.str1057) + call void @fn_emit(ptr @.str1329) %t81 = load ptr, ptr %t77 call void @fn_emit(ptr %t81) - call void @fn_emit(ptr @.str1058) + call void @fn_emit(ptr @.str1330) %t82 = load ptr, ptr %t79 call void @fn_emit(ptr %t82) - call void @fn_emit(ptr @.str1059) + call void @fn_emit(ptr @.str1331) %t83 = load ptr, ptr %t77 call void @fn_emit(ptr %t83) - call void @fn_emit(ptr @.str1060) + call void @fn_emit(ptr @.str1332) store i32 0, ptr @g_g_term %t84 = load ptr, ptr %t27 %t85 = getelementptr inbounds %Cmp_Node, ptr %t84, i32 0, i32 4 @@ -16694,15 +21050,15 @@ wend8: %t90 = icmp ne i32 %t89, 0 br i1 %t90, label %then12, label %ifend14 then12: - call void @fn_emit(ptr @.str1061) + call void @fn_emit(ptr @.str1333) %t91 = load ptr, ptr %t7 call void @fn_emit(ptr %t91) - call void @fn_emit(ptr @.str1062) + call void @fn_emit(ptr @.str1334) br label %ifend14 ifend14: %t92 = load ptr, ptr %t79 call void @fn_emit(ptr %t92) - call void @fn_emit(ptr @.str1063) + call void @fn_emit(ptr @.str1335) store i32 0, ptr @g_g_term br label %ifend5 ifend5: @@ -16729,21 +21085,490 @@ ifend17: %t105 = icmp ne i32 %t104, 0 br i1 %t105, label %then18, label %ifend20 then18: - call void @fn_emit(ptr @.str1064) + call void @fn_emit(ptr @.str1336) %t106 = load ptr, ptr %t7 call void @fn_emit(ptr %t106) - call void @fn_emit(ptr @.str1065) + call void @fn_emit(ptr @.str1337) br label %ifend20 ifend20: %t107 = load ptr, ptr %t7 call void @fn_emit(ptr %t107) - call void @fn_emit(ptr @.str1066) + call void @fn_emit(ptr @.str1338) store i32 0, ptr @g_g_term br label %ret ret: ret void } +define ptr @fn_emit_emit(ptr %arg_st) { +entry: + %retval = alloca ptr + %t0 = alloca ptr + %t5 = alloca ptr + %t20 = alloca ptr + %t27 = alloca ptr + %t28 = alloca i32 + %t46 = alloca ptr + %t47 = alloca ptr + %t48 = alloca i32 + %t95 = alloca ptr + %t96 = alloca ptr + %t106 = alloca ptr + %t120 = alloca ptr + %t173 = alloca ptr + %t181 = alloca i32 + %t182 = alloca i32 + %t193 = alloca ptr + %t225 = alloca ptr + %t241 = alloca ptr + %t242 = alloca i32 + %t279 = alloca ptr + store ptr %arg_st, ptr %t0 + %t1 = load ptr, ptr %t0 + %t2 = getelementptr inbounds %Cmp_Node, ptr %t1, i32 0, i32 1 + %t3 = load ptr, ptr %t2 + %t4 = call ptr @fn_find_event(ptr %t3) + store ptr %t4, ptr %t5 + %t6 = load ptr, ptr %t5 + %t7 = icmp eq ptr %t6, null + %t8 = zext i1 %t7 to i32 + %t9 = icmp ne i32 %t8, 0 + br i1 %t9, label %then0, label %ifend2 +then0: + %t10 = load ptr, ptr %t0 + %t11 = getelementptr inbounds %Cmp_Node, ptr %t10, i32 0, i32 1 + %t12 = load ptr, ptr %t11 + %t13 = call ptr @fn_str_concat(ptr @.str1339, ptr %t12) + call void @fn_perr(ptr %t13) + br label %ifend2 +ifend2: + %t14 = getelementptr %LSlice, ptr null, i32 1 + %t15 = ptrtoint ptr %t14 to i64 + %t16 = call ptr @malloc(i64 %t15) + %t17 = getelementptr inbounds %LSlice, ptr %t16, i32 0, i32 0 + store ptr null, ptr %t17 + %t18 = getelementptr inbounds %LSlice, ptr %t16, i32 0, i32 1 + store i32 0, ptr %t18 + %t19 = getelementptr inbounds %LSlice, ptr %t16, i32 0, i32 2 + store i32 0, ptr %t19 + store ptr %t16, ptr %t20 + %t21 = getelementptr %LSlice, ptr null, i32 1 + %t22 = ptrtoint ptr %t21 to i64 + %t23 = call ptr @malloc(i64 %t22) + %t24 = getelementptr inbounds %LSlice, ptr %t23, i32 0, i32 0 + store ptr null, ptr %t24 + %t25 = getelementptr inbounds %LSlice, ptr %t23, i32 0, i32 1 + store i32 0, ptr %t25 + %t26 = getelementptr inbounds %LSlice, ptr %t23, i32 0, i32 2 + store i32 0, ptr %t26 + store ptr %t23, ptr %t27 + store i32 0, ptr %t28 + br label %wcond3 +wcond3: + %t29 = load i32, ptr %t28 + %t30 = load ptr, ptr %t5 + %t31 = getelementptr inbounds %Cmp_Node, ptr %t30, i32 0, i32 7 + %t32 = load ptr, ptr %t31 + %t33 = getelementptr inbounds %LSlice, ptr %t32, i32 0, i32 1 + %t34 = load i32, ptr %t33 + %t35 = icmp slt i32 %t29, %t34 + %t36 = zext i1 %t35 to i32 + %t37 = icmp ne i32 %t36, 0 + br i1 %t37, label %wbody4, label %wend5 +wbody4: + %t38 = load ptr, ptr %t5 + %t39 = getelementptr inbounds %Cmp_Node, ptr %t38, i32 0, i32 7 + %t40 = load ptr, ptr %t39 + %t41 = getelementptr inbounds %LSlice, ptr %t40, i32 0, i32 0 + %t42 = load ptr, ptr %t41 + %t43 = load i32, ptr %t28 + %t44 = getelementptr inbounds ptr, ptr %t42, i32 %t43 + %t45 = load ptr, ptr %t44 + store ptr %t45, ptr %t46 + store ptr null, ptr %t47 + store i32 0, ptr %t48 + br label %wcond6 +wcond6: + %t49 = load i32, ptr %t48 + %t50 = load ptr, ptr %t0 + %t51 = getelementptr inbounds %Cmp_Node, ptr %t50, i32 0, i32 4 + %t52 = load ptr, ptr %t51 + %t53 = getelementptr inbounds %Cmp_Node, ptr %t52, i32 0, i32 7 + %t54 = load ptr, ptr %t53 + %t55 = getelementptr inbounds %LSlice, ptr %t54, i32 0, i32 1 + %t56 = load i32, ptr %t55 + %t57 = icmp slt i32 %t49, %t56 + %t58 = zext i1 %t57 to i32 + %t59 = icmp ne i32 %t58, 0 + br i1 %t59, label %wbody7, label %wend8 +wbody7: + %t60 = load ptr, ptr %t0 + %t61 = getelementptr inbounds %Cmp_Node, ptr %t60, i32 0, i32 4 + %t62 = load ptr, ptr %t61 + %t63 = getelementptr inbounds %Cmp_Node, ptr %t62, i32 0, i32 7 + %t64 = load ptr, ptr %t63 + %t65 = getelementptr inbounds %LSlice, ptr %t64, i32 0, i32 0 + %t66 = load ptr, ptr %t65 + %t67 = load i32, ptr %t48 + %t68 = getelementptr inbounds ptr, ptr %t66, i32 %t67 + %t69 = load ptr, ptr %t68 + %t70 = getelementptr inbounds %Cmp_Node, ptr %t69, i32 0, i32 1 + %t71 = load ptr, ptr %t70 + %t72 = load ptr, ptr %t46 + %t73 = getelementptr inbounds %Cmp_Node, ptr %t72, i32 0, i32 1 + %t74 = load ptr, ptr %t73 + %t75 = call i32 @fn_str_eq(ptr %t71, ptr %t74) + %t76 = icmp ne i32 %t75, 0 + br i1 %t76, label %then9, label %ifend11 +then9: + %t77 = load ptr, ptr %t0 + %t78 = getelementptr inbounds %Cmp_Node, ptr %t77, i32 0, i32 4 + %t79 = load ptr, ptr %t78 + %t80 = getelementptr inbounds %Cmp_Node, ptr %t79, i32 0, i32 7 + %t81 = load ptr, ptr %t80 + %t82 = getelementptr inbounds %LSlice, ptr %t81, i32 0, i32 0 + %t83 = load ptr, ptr %t82 + %t84 = load i32, ptr %t48 + %t85 = getelementptr inbounds ptr, ptr %t83, i32 %t84 + %t86 = load ptr, ptr %t85 + %t87 = getelementptr inbounds %Cmp_Node, ptr %t86, i32 0, i32 4 + %t88 = load ptr, ptr %t87 + store ptr %t88, ptr %t47 + br label %ifend11 +ifend11: + %t89 = load i32, ptr %t48 + %t90 = add i32 %t89, 1 + store i32 %t90, ptr %t48 + br label %wcond6 +wend8: + %t91 = load ptr, ptr %t46 + %t92 = getelementptr inbounds %Cmp_Node, ptr %t91, i32 0, i32 3 + %t93 = load ptr, ptr %t92 + %t94 = call ptr @fn_llty(ptr %t93) + store ptr %t94, ptr %t95 + store ptr @.str1340, ptr %t96 + %t97 = load ptr, ptr %t95 + %t98 = call i32 @fn_str_eq(ptr %t97, ptr @.str1341) + %t99 = icmp ne i32 %t98, 0 + br i1 %t99, label %then12, label %ifend14 +then12: + store ptr @.str1342, ptr %t96 + br label %ifend14 +ifend14: + %t100 = load ptr, ptr %t47 + %t101 = icmp ne ptr %t100, null + %t102 = zext i1 %t101 to i32 + %t103 = icmp ne i32 %t102, 0 + br i1 %t103, label %then15, label %else16 +then15: + %t104 = load ptr, ptr %t47 + %t105 = call ptr @fn_emit_expr(ptr %t104) + store ptr %t105, ptr %t106 + %t107 = load ptr, ptr %t106 + %t108 = getelementptr inbounds %Cmp_Val, ptr %t107, i32 0, i32 0 + %t109 = load ptr, ptr %t108 + store ptr %t109, ptr %t96 + br label %ifend17 +else16: + %t110 = load ptr, ptr %t46 + %t111 = getelementptr inbounds %Cmp_Node, ptr %t110, i32 0, i32 4 + %t112 = load ptr, ptr %t111 + %t113 = icmp ne ptr %t112, null + %t114 = zext i1 %t113 to i32 + %t115 = icmp ne i32 %t114, 0 + br i1 %t115, label %then18, label %ifend20 +then18: + %t116 = load ptr, ptr %t46 + %t117 = getelementptr inbounds %Cmp_Node, ptr %t116, i32 0, i32 4 + %t118 = load ptr, ptr %t117 + %t119 = call ptr @fn_emit_expr(ptr %t118) + store ptr %t119, ptr %t120 + %t121 = load ptr, ptr %t120 + %t122 = getelementptr inbounds %Cmp_Val, ptr %t121, i32 0, i32 0 + %t123 = load ptr, ptr %t122 + store ptr %t123, ptr %t96 + br label %ifend20 +ifend20: + br label %ifend17 +ifend17: + %t124 = load ptr, ptr %t20 + %t125 = getelementptr inbounds %LSlice, ptr %t124, i32 0, i32 1 + %t126 = getelementptr inbounds %LSlice, ptr %t124, i32 0, i32 2 + %t127 = getelementptr inbounds %LSlice, ptr %t124, i32 0, i32 0 + %t128 = load i32, ptr %t125 + %t129 = load i32, ptr %t126 + %t130 = icmp sge i32 %t128, %t129 + br i1 %t130, label %grow21, label %put22 +grow21: + %t131 = mul i32 %t129, 2 + %t132 = icmp eq i32 %t129, 0 + %t133 = select i1 %t132, i32 8, i32 %t131 + %t134 = getelementptr ptr, ptr null, i32 1 + %t135 = ptrtoint ptr %t134 to i64 + %t136 = zext i32 %t133 to i64 + %t137 = mul i64 %t136, %t135 + %t138 = load ptr, ptr %t127 + %t139 = call ptr @realloc(ptr %t138, i64 %t137) + store ptr %t139, ptr %t127 + store i32 %t133, ptr %t126 + br label %put22 +put22: + %t140 = load ptr, ptr %t96 + %t141 = load ptr, ptr %t127 + %t142 = getelementptr inbounds ptr, ptr %t141, i32 %t128 + store ptr %t140, ptr %t142 + %t143 = add i32 %t128, 1 + store i32 %t143, ptr %t125 + %t144 = load ptr, ptr %t27 + %t145 = getelementptr inbounds %LSlice, ptr %t144, i32 0, i32 1 + %t146 = getelementptr inbounds %LSlice, ptr %t144, i32 0, i32 2 + %t147 = getelementptr inbounds %LSlice, ptr %t144, i32 0, i32 0 + %t148 = load i32, ptr %t145 + %t149 = load i32, ptr %t146 + %t150 = icmp sge i32 %t148, %t149 + br i1 %t150, label %grow23, label %put24 +grow23: + %t151 = mul i32 %t149, 2 + %t152 = icmp eq i32 %t149, 0 + %t153 = select i1 %t152, i32 8, i32 %t151 + %t154 = getelementptr ptr, ptr null, i32 1 + %t155 = ptrtoint ptr %t154 to i64 + %t156 = zext i32 %t153 to i64 + %t157 = mul i64 %t156, %t155 + %t158 = load ptr, ptr %t147 + %t159 = call ptr @realloc(ptr %t158, i64 %t157) + store ptr %t159, ptr %t147 + store i32 %t153, ptr %t146 + br label %put24 +put24: + %t160 = load ptr, ptr %t95 + %t161 = load ptr, ptr %t147 + %t162 = getelementptr inbounds ptr, ptr %t161, i32 %t148 + store ptr %t160, ptr %t162 + %t163 = add i32 %t148, 1 + store i32 %t163, ptr %t145 + %t164 = load i32, ptr %t28 + %t165 = add i32 %t164, 1 + store i32 %t165, ptr %t28 + br label %wcond3 +wend5: + %t166 = load ptr, ptr %t5 + %t167 = getelementptr inbounds %Cmp_Node, ptr %t166, i32 0, i32 3 + %t168 = load ptr, ptr %t167 + %t169 = icmp ne ptr %t168, null + %t170 = zext i1 %t169 to i32 + %t171 = icmp ne i32 %t170, 0 + br i1 %t171, label %then25, label %ifend27 +then25: + %t172 = call ptr @fn_nreg() + store ptr %t172, ptr %t173 + call void @fn_emit(ptr @.str1343) + %t174 = load ptr, ptr %t173 + call void @fn_emit(ptr %t174) + call void @fn_emit(ptr @.str1344) + call void @fn_emit(ptr @.str1345) + %t175 = load ptr, ptr %t0 + %t176 = getelementptr inbounds %Cmp_Node, ptr %t175, i32 0, i32 1 + %t177 = load ptr, ptr %t176 + %t178 = call i32 @fn_net_event_id(ptr %t177) + %t179 = call ptr @fn_itoa(i32 %t178) + call void @fn_emit(ptr %t179) + call void @fn_emit(ptr @.str1346) + %t180 = load ptr, ptr %t173 + call void @fn_emit(ptr %t180) + call void @fn_emit(ptr @.str1347) + store i32 4, ptr %t181 + store i32 0, ptr %t182 + br label %wcond28 +wcond28: + %t183 = load i32, ptr %t182 + %t184 = load ptr, ptr %t5 + %t185 = getelementptr inbounds %Cmp_Node, ptr %t184, i32 0, i32 7 + %t186 = load ptr, ptr %t185 + %t187 = getelementptr inbounds %LSlice, ptr %t186, i32 0, i32 1 + %t188 = load i32, ptr %t187 + %t189 = icmp slt i32 %t183, %t188 + %t190 = zext i1 %t189 to i32 + %t191 = icmp ne i32 %t190, 0 + br i1 %t191, label %wbody29, label %wend30 +wbody29: + %t192 = call ptr @fn_nreg() + store ptr %t192, ptr %t193 + call void @fn_emit(ptr @.str1348) + %t194 = load ptr, ptr %t193 + call void @fn_emit(ptr %t194) + call void @fn_emit(ptr @.str1349) + %t195 = load i32, ptr %t181 + %t196 = call ptr @fn_itoa(i32 %t195) + call void @fn_emit(ptr %t196) + call void @fn_emit(ptr @.str1350) + call void @fn_emit(ptr @.str1351) + %t197 = load ptr, ptr %t27 + %t198 = getelementptr inbounds %LSlice, ptr %t197, i32 0, i32 0 + %t199 = load ptr, ptr %t198 + %t200 = load i32, ptr %t182 + %t201 = getelementptr inbounds ptr, ptr %t199, i32 %t200 + %t202 = load ptr, ptr %t201 + call void @fn_emit(ptr %t202) + call void @fn_emit(ptr @.str1352) + %t203 = load ptr, ptr %t20 + %t204 = getelementptr inbounds %LSlice, ptr %t203, i32 0, i32 0 + %t205 = load ptr, ptr %t204 + %t206 = load i32, ptr %t182 + %t207 = getelementptr inbounds ptr, ptr %t205, i32 %t206 + %t208 = load ptr, ptr %t207 + call void @fn_emit(ptr %t208) + call void @fn_emit(ptr @.str1353) + %t209 = load ptr, ptr %t193 + call void @fn_emit(ptr %t209) + call void @fn_emit(ptr @.str1354) + %t210 = load i32, ptr %t181 + %t211 = load ptr, ptr %t5 + %t212 = getelementptr inbounds %Cmp_Node, ptr %t211, i32 0, i32 7 + %t213 = load ptr, ptr %t212 + %t214 = getelementptr inbounds %LSlice, ptr %t213, i32 0, i32 0 + %t215 = load ptr, ptr %t214 + %t216 = load i32, ptr %t182 + %t217 = getelementptr inbounds ptr, ptr %t215, i32 %t216 + %t218 = load ptr, ptr %t217 + %t219 = getelementptr inbounds %Cmp_Node, ptr %t218, i32 0, i32 3 + %t220 = load ptr, ptr %t219 + %t221 = call i32 @fn_net_field_ibytes(ptr %t220) + %t222 = add i32 %t210, %t221 + store i32 %t222, ptr %t181 + %t223 = load i32, ptr %t182 + %t224 = add i32 %t223, 1 + store i32 %t224, ptr %t182 + br label %wcond28 +wend30: + store ptr @.str1355, ptr %t225 + %t226 = load ptr, ptr %t5 + %t227 = getelementptr inbounds %Cmp_Node, ptr %t226, i32 0, i32 3 + %t228 = load ptr, ptr %t227 + %t229 = call i32 @fn_str_eq(ptr %t228, ptr @.str1356) + %t230 = icmp ne i32 %t229, 0 + br i1 %t230, label %then31, label %ifend33 +then31: + store ptr @.str1357, ptr %t225 + br label %ifend33 +ifend33: + %t231 = call ptr @fn_find_extern(ptr @.str1358) + %t232 = icmp eq ptr %t231, null + %t233 = zext i1 %t232 to i32 + %t234 = icmp ne i32 %t233, 0 + br i1 %t234, label %then34, label %ifend36 +then34: + store i32 1, ptr @g_g_uses_loopback + br label %ifend36 +ifend36: + call void @fn_emit(ptr @.str1359) + %t235 = call ptr @fn_net_send_sym() + call void @fn_emit(ptr %t235) + call void @fn_emit(ptr @.str1360) + %t236 = load ptr, ptr %t225 + call void @fn_emit(ptr %t236) + call void @fn_emit(ptr @.str1361) + %t237 = load i32, ptr %t181 + %t238 = call ptr @fn_itoa(i32 %t237) + call void @fn_emit(ptr %t238) + call void @fn_emit(ptr @.str1362) + %t239 = call ptr @fn_val(ptr @.str1363, ptr @.str1364) + store ptr %t239, ptr %retval + br label %ret +ifend27: + %t240 = call ptr @fn_buf_new() + store ptr %t240, ptr %t241 + store i32 0, ptr %t242 + br label %wcond37 +wcond37: + %t243 = load i32, ptr %t242 + %t244 = load ptr, ptr %t20 + %t245 = getelementptr inbounds %LSlice, ptr %t244, i32 0, i32 1 + %t246 = load i32, ptr %t245 + %t247 = icmp slt i32 %t243, %t246 + %t248 = zext i1 %t247 to i32 + %t249 = icmp ne i32 %t248, 0 + br i1 %t249, label %wbody38, label %wend39 +wbody38: + %t250 = load i32, ptr %t242 + %t251 = icmp sgt i32 %t250, 0 + %t252 = zext i1 %t251 to i32 + %t253 = icmp ne i32 %t252, 0 + br i1 %t253, label %then40, label %ifend42 +then40: + %t254 = load ptr, ptr %t241 + call void @fn_buf_puts(ptr %t254, ptr @.str1365) + br label %ifend42 +ifend42: + %t255 = load ptr, ptr %t241 + %t256 = load ptr, ptr %t27 + %t257 = getelementptr inbounds %LSlice, ptr %t256, i32 0, i32 0 + %t258 = load ptr, ptr %t257 + %t259 = load i32, ptr %t242 + %t260 = getelementptr inbounds ptr, ptr %t258, i32 %t259 + %t261 = load ptr, ptr %t260 + call void @fn_buf_puts(ptr %t255, ptr %t261) + %t262 = load ptr, ptr %t241 + call void @fn_buf_puts(ptr %t262, ptr @.str1366) + %t263 = load ptr, ptr %t241 + %t264 = load ptr, ptr %t20 + %t265 = getelementptr inbounds %LSlice, ptr %t264, i32 0, i32 0 + %t266 = load ptr, ptr %t265 + %t267 = load i32, ptr %t242 + %t268 = getelementptr inbounds ptr, ptr %t266, i32 %t267 + %t269 = load ptr, ptr %t268 + call void @fn_buf_puts(ptr %t263, ptr %t269) + %t270 = load i32, ptr %t242 + %t271 = add i32 %t270, 1 + store i32 %t271, ptr %t242 + br label %wcond37 +wend39: + %t272 = load ptr, ptr %t5 + %t273 = getelementptr inbounds %Cmp_Node, ptr %t272, i32 0, i32 2 + %t274 = load i32, ptr %t273 + %t275 = icmp eq i32 %t274, 1 + %t276 = zext i1 %t275 to i32 + %t277 = icmp ne i32 %t276, 0 + br i1 %t277, label %then43, label %ifend45 +then43: + %t278 = call ptr @fn_nreg() + store ptr %t278, ptr %t279 + call void @fn_emit(ptr @.str1367) + %t280 = load ptr, ptr %t279 + call void @fn_emit(ptr %t280) + call void @fn_emit(ptr @.str1368) + %t281 = load ptr, ptr %t0 + %t282 = getelementptr inbounds %Cmp_Node, ptr %t281, i32 0, i32 1 + %t283 = load ptr, ptr %t282 + call void @fn_emit(ptr %t283) + call void @fn_emit(ptr @.str1369) + %t284 = load ptr, ptr %t241 + %t285 = call ptr @fn_buf_str(ptr %t284) + call void @fn_emit(ptr %t285) + call void @fn_emit(ptr @.str1370) + %t286 = load ptr, ptr %t279 + %t287 = call ptr @fn_val(ptr %t286, ptr @.str1371) + store ptr %t287, ptr %retval + br label %ret +ifend45: + call void @fn_emit(ptr @.str1372) + %t288 = load ptr, ptr %t0 + %t289 = getelementptr inbounds %Cmp_Node, ptr %t288, i32 0, i32 1 + %t290 = load ptr, ptr %t289 + call void @fn_emit(ptr %t290) + call void @fn_emit(ptr @.str1373) + %t291 = load ptr, ptr %t241 + %t292 = call ptr @fn_buf_str(ptr %t291) + call void @fn_emit(ptr %t292) + call void @fn_emit(ptr @.str1374) + %t293 = call ptr @fn_val(ptr @.str1375, ptr @.str1376) + store ptr %t293, ptr %retval + br label %ret +ret: + %t294 = load ptr, ptr %retval + ret ptr %t294 +} + define void @fn_emit_stmt(ptr %arg_st) { entry: %t0 = alloca ptr @@ -16753,7 +21578,9 @@ entry: %t44 = alloca ptr %t51 = alloca ptr %t64 = alloca ptr + %t162 = alloca ptr %t199 = alloca ptr + %t235 = alloca ptr store ptr %arg_st, ptr %t0 %t1 = load ptr, ptr %t0 %t2 = getelementptr inbounds %Cmp_Node, ptr %t1, i32 0, i32 0 @@ -16817,14 +21644,14 @@ ifend5: %t50 = icmp ne i32 %t49, 0 br i1 %t50, label %then6, label %else7 then6: - store ptr @.str1067, ptr %t51 + store ptr @.str1377, ptr %t51 %t52 = load ptr, ptr %t10 %t53 = call ptr @fn_llty(ptr %t52) - %t54 = call i32 @fn_str_eq(ptr %t53, ptr @.str1068) + %t54 = call i32 @fn_str_eq(ptr %t53, ptr @.str1378) %t55 = icmp ne i32 %t54, 0 br i1 %t55, label %then9, label %ifend11 then9: - store ptr @.str1069, ptr %t51 + store ptr @.str1379, ptr %t51 br label %ifend11 ifend11: %t56 = load ptr, ptr %t10 @@ -16928,7 +21755,7 @@ ifend26: %t119 = icmp ne i32 %t118, 0 br i1 %t119, label %then27, label %ifend29 then27: - call void @fn_emit(ptr @.str1070) + call void @fn_emit(ptr @.str1380) %t120 = load ptr, ptr @g_brk_lbl %t121 = getelementptr inbounds %LSlice, ptr %t120, i32 0, i32 0 %t122 = load ptr, ptr %t121 @@ -16937,7 +21764,7 @@ then27: %t125 = getelementptr inbounds ptr, ptr %t122, i32 %t124 %t126 = load ptr, ptr %t125 call void @fn_emit(ptr %t126) - call void @fn_emit(ptr @.str1071) + call void @fn_emit(ptr @.str1381) store i32 1, ptr @g_g_term br label %ret ifend29: @@ -16949,7 +21776,7 @@ ifend29: %t132 = icmp ne i32 %t131, 0 br i1 %t132, label %then30, label %ifend32 then30: - call void @fn_emit(ptr @.str1072) + call void @fn_emit(ptr @.str1382) %t133 = load ptr, ptr @g_cnt_lbl %t134 = getelementptr inbounds %LSlice, ptr %t133, i32 0, i32 0 %t135 = load ptr, ptr %t134 @@ -16958,7 +21785,7 @@ then30: %t138 = getelementptr inbounds ptr, ptr %t135, i32 %t137 %t139 = load ptr, ptr %t138 call void @fn_emit(ptr %t139) - call void @fn_emit(ptr @.str1073) + call void @fn_emit(ptr @.str1383) store i32 1, ptr @g_g_term br label %ret ifend32: @@ -16995,73 +21822,134 @@ ifend38: br i1 %t159, label %then39, label %ifend41 then39: %t160 = load ptr, ptr %t0 - call void @fn_emit_spawn(ptr %t160) + %t161 = call ptr @fn_emit_spawn(ptr %t160) + store ptr %t161, ptr %t162 br label %ret ifend41: - %t161 = load ptr, ptr %t0 - %t162 = getelementptr inbounds %Cmp_Node, ptr %t161, i32 0, i32 0 - %t163 = load i32, ptr %t162 - %t164 = icmp eq i32 %t163, 23 - %t165 = zext i1 %t164 to i32 - %t166 = icmp ne i32 %t165, 0 - br i1 %t166, label %then42, label %ifend44 + %t163 = load ptr, ptr %t0 + %t164 = getelementptr inbounds %Cmp_Node, ptr %t163, i32 0, i32 0 + %t165 = load i32, ptr %t164 + %t166 = icmp eq i32 %t165, 23 + %t167 = zext i1 %t166 to i32 + %t168 = icmp ne i32 %t167, 0 + br i1 %t168, label %then42, label %ifend44 then42: - %t167 = load ptr, ptr %t0 - call void @fn_emit_despawn(ptr %t167) + %t169 = load ptr, ptr %t0 + call void @fn_emit_despawn(ptr %t169) br label %ret ifend44: - %t168 = load ptr, ptr %t0 - %t169 = getelementptr inbounds %Cmp_Node, ptr %t168, i32 0, i32 0 - %t170 = load i32, ptr %t169 - %t171 = icmp eq i32 %t170, 28 - %t172 = zext i1 %t171 to i32 - %t173 = icmp ne i32 %t172, 0 - br i1 %t173, label %then45, label %ifend47 + %t170 = load ptr, ptr %t0 + %t171 = getelementptr inbounds %Cmp_Node, ptr %t170, i32 0, i32 0 + %t172 = load i32, ptr %t171 + %t173 = icmp eq i32 %t172, 28 + %t174 = zext i1 %t173 to i32 + %t175 = icmp ne i32 %t174, 0 + br i1 %t175, label %then45, label %ifend47 then45: - %t174 = load ptr, ptr %t0 - call void @fn_emit_toggle(ptr %t174) + %t176 = load ptr, ptr %t0 + call void @fn_emit_toggle(ptr %t176) br label %ret ifend47: - %t175 = load ptr, ptr %t0 - %t176 = getelementptr inbounds %Cmp_Node, ptr %t175, i32 0, i32 0 - %t177 = load i32, ptr %t176 - %t178 = icmp eq i32 %t177, 24 - %t179 = zext i1 %t178 to i32 - %t180 = icmp ne i32 %t179, 0 - br i1 %t180, label %then48, label %ifend50 + %t177 = load ptr, ptr %t0 + %t178 = getelementptr inbounds %Cmp_Node, ptr %t177, i32 0, i32 0 + %t179 = load i32, ptr %t178 + %t180 = icmp eq i32 %t179, 46 + %t181 = zext i1 %t180 to i32 + %t182 = icmp ne i32 %t181, 0 + br i1 %t182, label %then48, label %ifend50 then48: - %t181 = load ptr, ptr %t0 - call void @fn_emit_machine(ptr %t181) + %t183 = load ptr, ptr %t0 + call void @fn_emit_attach(ptr %t183) br label %ret ifend50: - %t182 = load ptr, ptr %t0 - %t183 = getelementptr inbounds %Cmp_Node, ptr %t182, i32 0, i32 0 - %t184 = load i32, ptr %t183 - %t185 = icmp eq i32 %t184, 26 - %t186 = zext i1 %t185 to i32 - %t187 = icmp ne i32 %t186, 0 - br i1 %t187, label %then51, label %ifend53 + %t184 = load ptr, ptr %t0 + %t185 = getelementptr inbounds %Cmp_Node, ptr %t184, i32 0, i32 0 + %t186 = load i32, ptr %t185 + %t187 = icmp eq i32 %t186, 47 + %t188 = zext i1 %t187 to i32 + %t189 = icmp ne i32 %t188, 0 + br i1 %t189, label %then51, label %ifend53 then51: - %t188 = load ptr, ptr %t0 - call void @fn_emit_become(ptr %t188) + %t190 = load ptr, ptr %t0 + call void @fn_emit_detach(ptr %t190) br label %ret ifend53: - %t189 = load ptr, ptr %t0 - %t190 = getelementptr inbounds %Cmp_Node, ptr %t189, i32 0, i32 0 - %t191 = load i32, ptr %t190 - %t192 = icmp eq i32 %t191, 16 - %t193 = zext i1 %t192 to i32 - %t194 = icmp ne i32 %t193, 0 - br i1 %t194, label %then54, label %ifend56 + %t191 = load ptr, ptr %t0 + %t192 = getelementptr inbounds %Cmp_Node, ptr %t191, i32 0, i32 0 + %t193 = load i32, ptr %t192 + %t194 = icmp eq i32 %t193, 49 + %t195 = zext i1 %t194 to i32 + %t196 = icmp ne i32 %t195, 0 + br i1 %t196, label %then54, label %ifend56 then54: - %t195 = load ptr, ptr %t0 - %t196 = getelementptr inbounds %Cmp_Node, ptr %t195, i32 0, i32 4 - %t197 = load ptr, ptr %t196 - %t198 = call ptr @fn_emit_expr(ptr %t197) + %t197 = load ptr, ptr %t0 + %t198 = call ptr @fn_emit_emit(ptr %t197) store ptr %t198, ptr %t199 br label %ret ifend56: - call void @fn_perr(ptr @.str1074) + %t200 = load ptr, ptr %t0 + %t201 = getelementptr inbounds %Cmp_Node, ptr %t200, i32 0, i32 0 + %t202 = load i32, ptr %t201 + %t203 = icmp eq i32 %t202, 50 + %t204 = zext i1 %t203 to i32 + %t205 = icmp ne i32 %t204, 0 + br i1 %t205, label %then57, label %ifend59 +then57: + %t206 = load ptr, ptr @g_g_cancel_addr + %t207 = icmp eq ptr %t206, null + %t208 = zext i1 %t207 to i32 + %t209 = icmp ne i32 %t208, 0 + br i1 %t209, label %then60, label %ifend62 +then60: + call void @fn_perr(ptr @.str1384) + br label %ifend62 +ifend62: + call void @fn_emit(ptr @.str1385) + %t210 = load ptr, ptr @g_g_cancel_addr + call void @fn_emit(ptr %t210) + call void @fn_emit(ptr @.str1386) + br label %ret +ifend59: + %t211 = load ptr, ptr %t0 + %t212 = getelementptr inbounds %Cmp_Node, ptr %t211, i32 0, i32 0 + %t213 = load i32, ptr %t212 + %t214 = icmp eq i32 %t213, 24 + %t215 = zext i1 %t214 to i32 + %t216 = icmp ne i32 %t215, 0 + br i1 %t216, label %then63, label %ifend65 +then63: + %t217 = load ptr, ptr %t0 + call void @fn_emit_machine(ptr %t217) + br label %ret +ifend65: + %t218 = load ptr, ptr %t0 + %t219 = getelementptr inbounds %Cmp_Node, ptr %t218, i32 0, i32 0 + %t220 = load i32, ptr %t219 + %t221 = icmp eq i32 %t220, 26 + %t222 = zext i1 %t221 to i32 + %t223 = icmp ne i32 %t222, 0 + br i1 %t223, label %then66, label %ifend68 +then66: + %t224 = load ptr, ptr %t0 + call void @fn_emit_become(ptr %t224) + br label %ret +ifend68: + %t225 = load ptr, ptr %t0 + %t226 = getelementptr inbounds %Cmp_Node, ptr %t225, i32 0, i32 0 + %t227 = load i32, ptr %t226 + %t228 = icmp eq i32 %t227, 16 + %t229 = zext i1 %t228 to i32 + %t230 = icmp ne i32 %t229, 0 + br i1 %t230, label %then69, label %ifend71 +then69: + %t231 = load ptr, ptr %t0 + %t232 = getelementptr inbounds %Cmp_Node, ptr %t231, i32 0, i32 4 + %t233 = load ptr, ptr %t232 + %t234 = call ptr @fn_emit_expr(ptr %t233) + store ptr %t234, ptr %t235 + br label %ret +ifend71: + call void @fn_perr(ptr @.str1387) br label %ret ret: ret void @@ -17262,6 +22150,50 @@ ret: ret i32 %t21 } +define i32 @fn_has_entry() { +entry: + %retval = alloca i32 + %t0 = alloca i32 + store i32 0, ptr %t0 + br label %wcond0 +wcond0: + %t1 = load i32, ptr %t0 + %t2 = load ptr, ptr @g_prog + %t3 = getelementptr inbounds %LSlice, ptr %t2, i32 0, i32 1 + %t4 = load i32, ptr %t3 + %t5 = icmp slt i32 %t1, %t4 + %t6 = zext i1 %t5 to i32 + %t7 = icmp ne i32 %t6, 0 + br i1 %t7, label %wbody1, label %wend2 +wbody1: + %t8 = load ptr, ptr @g_prog + %t9 = getelementptr inbounds %LSlice, ptr %t8, i32 0, i32 0 + %t10 = load ptr, ptr %t9 + %t11 = load i32, ptr %t0 + %t12 = getelementptr inbounds ptr, ptr %t10, i32 %t11 + %t13 = load ptr, ptr %t12 + %t14 = getelementptr inbounds %Cmp_Node, ptr %t13, i32 0, i32 0 + %t15 = load i32, ptr %t14 + %t16 = icmp eq i32 %t15, 6 + %t17 = zext i1 %t16 to i32 + %t18 = icmp ne i32 %t17, 0 + br i1 %t18, label %then3, label %ifend5 +then3: + store i32 1, ptr %retval + br label %ret +ifend5: + %t19 = load i32, ptr %t0 + %t20 = add i32 %t19, 1 + store i32 %t20, ptr %t0 + br label %wcond0 +wend2: + store i32 0, ptr %retval + br label %ret +ret: + %t21 = load i32, ptr %retval + ret i32 %t21 +} + define i32 @fn_has_ecs() { entry: %retval = alloca i32 @@ -17288,116 +22220,172 @@ ret: define void @fn_emit_ecs_storage() { entry: - %t1 = alloca ptr - %t11 = alloca i32 - %t25 = alloca ptr - call void @fn_emith(ptr @.str1075) - call void @fn_emith(ptr @.str1076) - call void @fn_emith(ptr @.str1077) - %t0 = call ptr @fn_itoa(i32 1024) - store ptr %t0, ptr %t1 - %t2 = load ptr, ptr %t1 - %t3 = call ptr @fn_str_concat(ptr @.str1078, ptr %t2) - %t4 = call ptr @fn_str_concat(ptr %t3, ptr @.str1079) - call void @fn_emith(ptr %t4) - %t5 = load ptr, ptr %t1 - %t6 = call ptr @fn_str_concat(ptr @.str1080, ptr %t5) - %t7 = call ptr @fn_str_concat(ptr %t6, ptr @.str1081) - call void @fn_emith(ptr %t7) - %t8 = load ptr, ptr %t1 - %t9 = call ptr @fn_str_concat(ptr @.str1082, ptr %t8) - %t10 = call ptr @fn_str_concat(ptr %t9, ptr @.str1083) + %t7 = alloca ptr + %t24 = alloca i32 + %t38 = alloca ptr + %t90 = alloca i32 + call void @fn_emith(ptr @.str1388) + call void @fn_emith(ptr @.str1389) + %t0 = load ptr, ptr @g_g_scenes + %t1 = getelementptr inbounds %LSlice, ptr %t0, i32 0, i32 1 + %t2 = load i32, ptr %t1 + %t3 = icmp sgt i32 %t2, 0 + %t4 = zext i1 %t3 to i32 + %t5 = icmp ne i32 %t4, 0 + br i1 %t5, label %then0, label %ifend2 +then0: + call void @fn_emith(ptr @.str1390) + br label %ifend2 +ifend2: + call void @fn_emith(ptr @.str1391) + %t6 = call ptr @fn_itoa(i32 1024) + store ptr %t6, ptr %t7 + %t8 = load ptr, ptr %t7 + %t9 = call ptr @fn_str_concat(ptr @.str1392, ptr %t8) + %t10 = call ptr @fn_str_concat(ptr %t9, ptr @.str1393) call void @fn_emith(ptr %t10) - call void @fn_emith(ptr @.str1084) - store i32 0, ptr %t11 - br label %wcond0 -wcond0: - %t12 = load i32, ptr %t11 - %t13 = load ptr, ptr @g_prog - %t14 = getelementptr inbounds %LSlice, ptr %t13, i32 0, i32 1 - %t15 = load i32, ptr %t14 - %t16 = icmp slt i32 %t12, %t15 - %t17 = zext i1 %t16 to i32 + %t11 = load ptr, ptr %t7 + %t12 = call ptr @fn_str_concat(ptr @.str1394, ptr %t11) + %t13 = call ptr @fn_str_concat(ptr %t12, ptr @.str1395) + call void @fn_emith(ptr %t13) + %t14 = load ptr, ptr %t7 + %t15 = call ptr @fn_str_concat(ptr @.str1396, ptr %t14) + %t16 = call ptr @fn_str_concat(ptr %t15, ptr @.str1397) + call void @fn_emith(ptr %t16) + call void @fn_emith(ptr @.str1398) + %t17 = call i32 @fn_net_any() %t18 = icmp ne i32 %t17, 0 - br i1 %t18, label %wbody1, label %wend2 -wbody1: - %t19 = load ptr, ptr @g_prog - %t20 = getelementptr inbounds %LSlice, ptr %t19, i32 0, i32 0 - %t21 = load ptr, ptr %t20 - %t22 = load i32, ptr %t11 - %t23 = getelementptr inbounds ptr, ptr %t21, i32 %t22 - %t24 = load ptr, ptr %t23 - store ptr %t24, ptr %t25 - %t26 = load ptr, ptr %t25 - %t27 = getelementptr inbounds %Cmp_Node, ptr %t26, i32 0, i32 0 - %t28 = load i32, ptr %t27 - %t29 = icmp eq i32 %t28, 8 - %t30 = zext i1 %t29 to i32 - %t31 = icmp ne i32 %t30, 0 - br i1 %t31, label %then3, label %ifend5 + br i1 %t18, label %then3, label %ifend5 then3: - %t32 = load ptr, ptr %t25 - %t33 = getelementptr inbounds %Cmp_Node, ptr %t32, i32 0, i32 1 - %t34 = load ptr, ptr %t33 - %t35 = call ptr @fn_str_concat(ptr @.str1085, ptr %t34) - %t36 = call ptr @fn_str_concat(ptr %t35, ptr @.str1086) - %t37 = load ptr, ptr %t1 - %t38 = call ptr @fn_str_concat(ptr %t36, ptr %t37) - %t39 = call ptr @fn_str_concat(ptr %t38, ptr @.str1087) - %t40 = load ptr, ptr %t25 - %t41 = getelementptr inbounds %Cmp_Node, ptr %t40, i32 0, i32 1 - %t42 = load ptr, ptr %t41 - %t43 = call ptr @fn_str_concat(ptr %t39, ptr %t42) - %t44 = call ptr @fn_str_concat(ptr %t43, ptr @.str1088) - call void @fn_emith(ptr %t44) - %t45 = load ptr, ptr %t25 - %t46 = getelementptr inbounds %Cmp_Node, ptr %t45, i32 0, i32 1 - %t47 = load ptr, ptr %t46 - %t48 = call ptr @fn_str_concat(ptr @.str1089, ptr %t47) - %t49 = call ptr @fn_str_concat(ptr %t48, ptr @.str1090) - %t50 = load ptr, ptr %t1 - %t51 = call ptr @fn_str_concat(ptr %t49, ptr %t50) - %t52 = call ptr @fn_str_concat(ptr %t51, ptr @.str1091) - call void @fn_emith(ptr %t52) + call void @fn_emith(ptr @.str1399) + call void @fn_emith(ptr @.str1400) br label %ifend5 ifend5: - %t53 = load ptr, ptr %t25 - %t54 = getelementptr inbounds %Cmp_Node, ptr %t53, i32 0, i32 0 - %t55 = load i32, ptr %t54 - %t56 = icmp eq i32 %t55, 10 - %t57 = zext i1 %t56 to i32 - %t58 = icmp ne i32 %t57, 0 - br i1 %t58, label %then6, label %ifend8 + %t19 = call i32 @fn_net_has_owned() + %t20 = icmp ne i32 %t19, 0 + br i1 %t20, label %then6, label %ifend8 then6: - %t59 = load ptr, ptr %t25 - %t60 = getelementptr inbounds %Cmp_Node, ptr %t59, i32 0, i32 1 - %t61 = load ptr, ptr %t60 - %t62 = call ptr @fn_str_concat(ptr @.str1092, ptr %t61) - %t63 = call ptr @fn_str_concat(ptr %t62, ptr @.str1093) - call void @fn_emith(ptr %t63) + %t21 = load ptr, ptr %t7 + %t22 = call ptr @fn_str_concat(ptr @.str1401, ptr %t21) + %t23 = call ptr @fn_str_concat(ptr %t22, ptr @.str1402) + call void @fn_emith(ptr %t23) br label %ifend8 ifend8: - %t64 = load ptr, ptr %t25 - %t65 = getelementptr inbounds %Cmp_Node, ptr %t64, i32 0, i32 0 - %t66 = load i32, ptr %t65 - %t67 = icmp eq i32 %t66, 9 - %t68 = zext i1 %t67 to i32 - %t69 = icmp ne i32 %t68, 0 - br i1 %t69, label %then9, label %ifend11 -then9: - %t70 = load ptr, ptr %t25 - %t71 = getelementptr inbounds %Cmp_Node, ptr %t70, i32 0, i32 1 - %t72 = load ptr, ptr %t71 - %t73 = call ptr @fn_str_concat(ptr @.str1094, ptr %t72) - %t74 = call ptr @fn_str_concat(ptr %t73, ptr @.str1095) - call void @fn_emith(ptr %t74) - br label %ifend11 -ifend11: - %t75 = load i32, ptr %t11 - %t76 = add i32 %t75, 1 - store i32 %t76, ptr %t11 - br label %wcond0 -wend2: + store i32 0, ptr %t24 + br label %wcond9 +wcond9: + %t25 = load i32, ptr %t24 + %t26 = load ptr, ptr @g_prog + %t27 = getelementptr inbounds %LSlice, ptr %t26, i32 0, i32 1 + %t28 = load i32, ptr %t27 + %t29 = icmp slt i32 %t25, %t28 + %t30 = zext i1 %t29 to i32 + %t31 = icmp ne i32 %t30, 0 + br i1 %t31, label %wbody10, label %wend11 +wbody10: + %t32 = load ptr, ptr @g_prog + %t33 = getelementptr inbounds %LSlice, ptr %t32, i32 0, i32 0 + %t34 = load ptr, ptr %t33 + %t35 = load i32, ptr %t24 + %t36 = getelementptr inbounds ptr, ptr %t34, i32 %t35 + %t37 = load ptr, ptr %t36 + store ptr %t37, ptr %t38 + %t39 = load ptr, ptr %t38 + %t40 = getelementptr inbounds %Cmp_Node, ptr %t39, i32 0, i32 0 + %t41 = load i32, ptr %t40 + %t42 = icmp eq i32 %t41, 8 + %t43 = zext i1 %t42 to i32 + %t44 = icmp ne i32 %t43, 0 + br i1 %t44, label %then12, label %ifend14 +then12: + %t45 = load ptr, ptr %t38 + %t46 = getelementptr inbounds %Cmp_Node, ptr %t45, i32 0, i32 1 + %t47 = load ptr, ptr %t46 + %t48 = call ptr @fn_str_concat(ptr @.str1403, ptr %t47) + %t49 = call ptr @fn_str_concat(ptr %t48, ptr @.str1404) + %t50 = load ptr, ptr %t7 + %t51 = call ptr @fn_str_concat(ptr %t49, ptr %t50) + %t52 = call ptr @fn_str_concat(ptr %t51, ptr @.str1405) + %t53 = load ptr, ptr %t38 + %t54 = getelementptr inbounds %Cmp_Node, ptr %t53, i32 0, i32 1 + %t55 = load ptr, ptr %t54 + %t56 = call ptr @fn_str_concat(ptr %t52, ptr %t55) + %t57 = call ptr @fn_str_concat(ptr %t56, ptr @.str1406) + call void @fn_emith(ptr %t57) + %t58 = load ptr, ptr %t38 + %t59 = getelementptr inbounds %Cmp_Node, ptr %t58, i32 0, i32 1 + %t60 = load ptr, ptr %t59 + %t61 = call ptr @fn_str_concat(ptr @.str1407, ptr %t60) + %t62 = call ptr @fn_str_concat(ptr %t61, ptr @.str1408) + %t63 = load ptr, ptr %t7 + %t64 = call ptr @fn_str_concat(ptr %t62, ptr %t63) + %t65 = call ptr @fn_str_concat(ptr %t64, ptr @.str1409) + call void @fn_emith(ptr %t65) + br label %ifend14 +ifend14: + %t66 = load ptr, ptr %t38 + %t67 = getelementptr inbounds %Cmp_Node, ptr %t66, i32 0, i32 0 + %t68 = load i32, ptr %t67 + %t69 = icmp eq i32 %t68, 10 + %t70 = zext i1 %t69 to i32 + %t71 = icmp ne i32 %t70, 0 + br i1 %t71, label %then15, label %ifend17 +then15: + %t72 = load ptr, ptr %t38 + %t73 = getelementptr inbounds %Cmp_Node, ptr %t72, i32 0, i32 1 + %t74 = load ptr, ptr %t73 + %t75 = call ptr @fn_str_concat(ptr @.str1410, ptr %t74) + %t76 = call ptr @fn_str_concat(ptr %t75, ptr @.str1411) + call void @fn_emith(ptr %t76) + br label %ifend17 +ifend17: + %t77 = load ptr, ptr %t38 + %t78 = getelementptr inbounds %Cmp_Node, ptr %t77, i32 0, i32 0 + %t79 = load i32, ptr %t78 + %t80 = icmp eq i32 %t79, 9 + %t81 = zext i1 %t80 to i32 + %t82 = icmp ne i32 %t81, 0 + br i1 %t82, label %then18, label %ifend20 +then18: + %t83 = load ptr, ptr %t38 + %t84 = getelementptr inbounds %Cmp_Node, ptr %t83, i32 0, i32 1 + %t85 = load ptr, ptr %t84 + %t86 = call ptr @fn_str_concat(ptr @.str1412, ptr %t85) + %t87 = call ptr @fn_str_concat(ptr %t86, ptr @.str1413) + call void @fn_emith(ptr %t87) + br label %ifend20 +ifend20: + %t88 = load i32, ptr %t24 + %t89 = add i32 %t88, 1 + store i32 %t89, ptr %t24 + br label %wcond9 +wend11: + store i32 0, ptr %t90 + br label %wcond21 +wcond21: + %t91 = load i32, ptr %t90 + %t92 = load ptr, ptr @g_g_toggled_layers + %t93 = getelementptr inbounds %LSlice, ptr %t92, i32 0, i32 1 + %t94 = load i32, ptr %t93 + %t95 = icmp slt i32 %t91, %t94 + %t96 = zext i1 %t95 to i32 + %t97 = icmp ne i32 %t96, 0 + br i1 %t97, label %wbody22, label %wend23 +wbody22: + %t98 = load ptr, ptr @g_g_toggled_layers + %t99 = getelementptr inbounds %LSlice, ptr %t98, i32 0, i32 0 + %t100 = load ptr, ptr %t99 + %t101 = load i32, ptr %t90 + %t102 = getelementptr inbounds ptr, ptr %t100, i32 %t101 + %t103 = load ptr, ptr %t102 + %t104 = call ptr @fn_str_concat(ptr @.str1414, ptr %t103) + %t105 = call ptr @fn_str_concat(ptr %t104, ptr @.str1415) + call void @fn_emith(ptr %t105) + %t106 = load i32, ptr %t90 + %t107 = add i32 %t106, 1 + store i32 %t107, ptr %t90 + br label %wcond21 +wend23: br label %ret ret: ret void @@ -17410,7 +22398,7 @@ entry: %t24 = alloca ptr %t0 = call ptr @fn_itoa(i32 1024) store ptr %t0, ptr %t1 - call void @fn_emit(ptr @.str1096) + call void @fn_emit(ptr @.str1416) store i32 0, ptr %t2 br label %wcond0 wcond0: @@ -17438,15 +22426,15 @@ wbody1: then3: %t21 = load i32, ptr %t2 %t22 = call ptr @fn_itoa(i32 %t21) - %t23 = call ptr @fn_str_concat(ptr @.str1097, ptr %t22) + %t23 = call ptr @fn_str_concat(ptr @.str1417, ptr %t22) store ptr %t23, ptr %t24 - call void @fn_emit(ptr @.str1098) + call void @fn_emit(ptr @.str1418) %t25 = load ptr, ptr %t24 call void @fn_emit(ptr %t25) - call void @fn_emit(ptr @.str1099) + call void @fn_emit(ptr @.str1419) %t26 = load ptr, ptr %t1 call void @fn_emit(ptr %t26) - call void @fn_emit(ptr @.str1100) + call void @fn_emit(ptr @.str1420) %t27 = load ptr, ptr @g_prog %t28 = getelementptr inbounds %LSlice, ptr %t27, i32 0, i32 0 %t29 = load ptr, ptr %t28 @@ -17456,11 +22444,11 @@ then3: %t33 = getelementptr inbounds %Cmp_Node, ptr %t32, i32 0, i32 1 %t34 = load ptr, ptr %t33 call void @fn_emit(ptr %t34) - call void @fn_emit(ptr @.str1101) - call void @fn_emit(ptr @.str1102) + call void @fn_emit(ptr @.str1421) + call void @fn_emit(ptr @.str1422) %t35 = load ptr, ptr %t24 call void @fn_emit(ptr %t35) - call void @fn_emit(ptr @.str1103) + call void @fn_emit(ptr @.str1423) br label %ifend5 ifend5: %t36 = load i32, ptr %t2 @@ -17468,54 +22456,66 @@ ifend5: store i32 %t37, ptr %t2 br label %wcond0 wend2: - call void @fn_emit(ptr @.str1104) + call void @fn_emit(ptr @.str1424) %t38 = load ptr, ptr %t1 call void @fn_emit(ptr %t38) - call void @fn_emit(ptr @.str1105) - call void @fn_emit(ptr @.str1106) - call void @fn_emit(ptr @.str1107) - call void @fn_emit(ptr @.str1108) - call void @fn_emit(ptr @.str1109) - call void @fn_emit(ptr @.str1110) - call void @fn_emit(ptr @.str1111) - call void @fn_emit(ptr @.str1112) - call void @fn_emit(ptr @.str1113) - call void @fn_emit(ptr @.str1114) - %t39 = load ptr, ptr %t1 - call void @fn_emit(ptr %t39) - call void @fn_emit(ptr @.str1115) - call void @fn_emit(ptr @.str1116) - call void @fn_emit(ptr @.str1117) - call void @fn_emit(ptr @.str1118) - call void @fn_emit(ptr @.str1119) - call void @fn_emit(ptr @.str1120) - call void @fn_emit(ptr @.str1121) - call void @fn_emit(ptr @.str1122) - call void @fn_emit(ptr @.str1123) - call void @fn_emit(ptr @.str1124) - call void @fn_emit(ptr @.str1125) - call void @fn_emit(ptr @.str1126) - %t40 = load ptr, ptr %t1 - call void @fn_emit(ptr %t40) - call void @fn_emit(ptr @.str1127) - call void @fn_emit(ptr @.str1128) - call void @fn_emit(ptr @.str1129) - call void @fn_emit(ptr @.str1130) - call void @fn_emit(ptr @.str1131) + call void @fn_emit(ptr @.str1425) + call void @fn_emit(ptr @.str1426) + %t39 = call i32 @fn_net_has_owned() + %t40 = icmp ne i32 %t39, 0 + br i1 %t40, label %then6, label %ifend8 +then6: + call void @fn_emit(ptr @.str1427) %t41 = load ptr, ptr %t1 call void @fn_emit(ptr %t41) - call void @fn_emit(ptr @.str1132) - call void @fn_emit(ptr @.str1133) - call void @fn_emit(ptr @.str1134) - call void @fn_emit(ptr @.str1135) - call void @fn_emit(ptr @.str1136) + call void @fn_emit(ptr @.str1428) + call void @fn_emit(ptr @.str1429) + br label %ifend8 +ifend8: + call void @fn_emit(ptr @.str1430) + call void @fn_emit(ptr @.str1431) + call void @fn_emit(ptr @.str1432) + call void @fn_emit(ptr @.str1433) + call void @fn_emit(ptr @.str1434) + call void @fn_emit(ptr @.str1435) + call void @fn_emit(ptr @.str1436) + call void @fn_emit(ptr @.str1437) + call void @fn_emit(ptr @.str1438) %t42 = load ptr, ptr %t1 call void @fn_emit(ptr %t42) - call void @fn_emit(ptr @.str1137) - call void @fn_emit(ptr @.str1138) - call void @fn_emit(ptr @.str1139) - call void @fn_emit(ptr @.str1140) - call void @fn_emit(ptr @.str1141) + call void @fn_emit(ptr @.str1439) + call void @fn_emit(ptr @.str1440) + call void @fn_emit(ptr @.str1441) + call void @fn_emit(ptr @.str1442) + call void @fn_emit(ptr @.str1443) + call void @fn_emit(ptr @.str1444) + call void @fn_emit(ptr @.str1445) + call void @fn_emit(ptr @.str1446) + call void @fn_emit(ptr @.str1447) + call void @fn_emit(ptr @.str1448) + call void @fn_emit(ptr @.str1449) + call void @fn_emit(ptr @.str1450) + %t43 = load ptr, ptr %t1 + call void @fn_emit(ptr %t43) + call void @fn_emit(ptr @.str1451) + call void @fn_emit(ptr @.str1452) + call void @fn_emit(ptr @.str1453) + call void @fn_emit(ptr @.str1454) + call void @fn_emit(ptr @.str1455) + %t44 = load ptr, ptr %t1 + call void @fn_emit(ptr %t44) + call void @fn_emit(ptr @.str1456) + call void @fn_emit(ptr @.str1457) + call void @fn_emit(ptr @.str1458) + call void @fn_emit(ptr @.str1459) + call void @fn_emit(ptr @.str1460) + %t45 = load ptr, ptr %t1 + call void @fn_emit(ptr %t45) + call void @fn_emit(ptr @.str1461) + call void @fn_emit(ptr @.str1462) + call void @fn_emit(ptr @.str1463) + call void @fn_emit(ptr @.str1464) + call void @fn_emit(ptr @.str1465) br label %ret ret: ret void @@ -17632,10 +22632,10 @@ entry: store ptr %arg_st, ptr %t0 %t1 = call ptr @fn_itoa(i32 1024) store ptr %t1, ptr %t2 - %t3 = call ptr @fn_emit_alloca(ptr @.str1142) + %t3 = call ptr @fn_emit_alloca(ptr @.str1466) store ptr %t3, ptr %t4 %t5 = load ptr, ptr %t4 - call void @fn_store_at(ptr @.str1143, ptr @.str1144, ptr %t5) + call void @fn_store_at(ptr @.str1467, ptr @.str1468, ptr %t5) %t6 = load i32, ptr @g_nself %t7 = load ptr, ptr @g_self_stk %t8 = getelementptr inbounds %LSlice, ptr %t7, i32 0, i32 1 @@ -17687,88 +22687,88 @@ ifend2: %t39 = load i32, ptr @g_nself %t40 = add i32 %t39, 1 store i32 %t40, ptr @g_nself - %t41 = call ptr @fn_lbl(ptr @.str1145) + %t41 = call ptr @fn_lbl(ptr @.str1469) store ptr %t41, ptr %t42 - %t43 = call ptr @fn_lbl(ptr @.str1146) + %t43 = call ptr @fn_lbl(ptr @.str1470) store ptr %t43, ptr %t44 - %t45 = call ptr @fn_lbl(ptr @.str1147) + %t45 = call ptr @fn_lbl(ptr @.str1471) store ptr %t45, ptr %t46 - %t47 = call ptr @fn_lbl(ptr @.str1148) + %t47 = call ptr @fn_lbl(ptr @.str1472) store ptr %t47, ptr %t48 - call void @fn_emit(ptr @.str1149) + call void @fn_emit(ptr @.str1473) %t49 = load ptr, ptr %t42 call void @fn_emit(ptr %t49) - call void @fn_emit(ptr @.str1150) + call void @fn_emit(ptr @.str1474) %t50 = load ptr, ptr %t42 call void @fn_emit(ptr %t50) - call void @fn_emit(ptr @.str1151) + call void @fn_emit(ptr @.str1475) %t51 = load ptr, ptr %t4 - %t52 = call ptr @fn_str_concat(ptr @.str1152, ptr %t51) + %t52 = call ptr @fn_str_concat(ptr @.str1476, ptr %t51) %t53 = call ptr @fn_emit_bind(ptr %t52) store ptr %t53, ptr %t54 - %t55 = call ptr @fn_emit_bind(ptr @.str1153) + %t55 = call ptr @fn_emit_bind(ptr @.str1477) store ptr %t55, ptr %t56 %t57 = load ptr, ptr %t54 - %t58 = call ptr @fn_str_concat(ptr @.str1154, ptr %t57) - %t59 = call ptr @fn_str_concat(ptr %t58, ptr @.str1155) + %t58 = call ptr @fn_str_concat(ptr @.str1478, ptr %t57) + %t59 = call ptr @fn_str_concat(ptr %t58, ptr @.str1479) %t60 = load ptr, ptr %t56 %t61 = call ptr @fn_str_concat(ptr %t59, ptr %t60) %t62 = call ptr @fn_emit_bind(ptr %t61) store ptr %t62, ptr %t63 - call void @fn_emit(ptr @.str1156) + call void @fn_emit(ptr @.str1480) %t64 = load ptr, ptr %t63 call void @fn_emit(ptr %t64) - call void @fn_emit(ptr @.str1157) + call void @fn_emit(ptr @.str1481) %t65 = load ptr, ptr %t44 call void @fn_emit(ptr %t65) - call void @fn_emit(ptr @.str1158) + call void @fn_emit(ptr @.str1482) %t66 = load ptr, ptr %t48 call void @fn_emit(ptr %t66) - call void @fn_emit(ptr @.str1159) + call void @fn_emit(ptr @.str1483) %t67 = load ptr, ptr %t44 call void @fn_emit(ptr %t67) - call void @fn_emit(ptr @.str1160) + call void @fn_emit(ptr @.str1484) store i32 0, ptr @g_g_term %t68 = load ptr, ptr %t4 - %t69 = call ptr @fn_str_concat(ptr @.str1161, ptr %t68) + %t69 = call ptr @fn_str_concat(ptr @.str1485, ptr %t68) %t70 = call ptr @fn_emit_bind(ptr %t69) store ptr %t70, ptr %t71 %t72 = call ptr @fn_nreg() store ptr %t72, ptr %t73 - call void @fn_emit(ptr @.str1162) + call void @fn_emit(ptr @.str1486) %t74 = load ptr, ptr %t73 call void @fn_emit(ptr %t74) - call void @fn_emit(ptr @.str1163) + call void @fn_emit(ptr @.str1487) %t75 = load ptr, ptr %t2 call void @fn_emit(ptr %t75) - call void @fn_emit(ptr @.str1164) + call void @fn_emit(ptr @.str1488) %t76 = load ptr, ptr %t71 call void @fn_emit(ptr %t76) - call void @fn_emit(ptr @.str1165) + call void @fn_emit(ptr @.str1489) %t77 = load ptr, ptr %t73 - %t78 = call ptr @fn_str_concat(ptr @.str1166, ptr %t77) + %t78 = call ptr @fn_str_concat(ptr @.str1490, ptr %t77) %t79 = call ptr @fn_emit_bind(ptr %t78) store ptr %t79, ptr %t80 %t81 = load ptr, ptr %t80 - %t82 = call ptr @fn_str_concat(ptr @.str1167, ptr %t81) - %t83 = call ptr @fn_str_concat(ptr %t82, ptr @.str1168) + %t82 = call ptr @fn_str_concat(ptr @.str1491, ptr %t81) + %t83 = call ptr @fn_str_concat(ptr %t82, ptr @.str1492) %t84 = call ptr @fn_emit_bind(ptr %t83) store ptr %t84, ptr %t85 - %t86 = call ptr @fn_lbl(ptr @.str1169) + %t86 = call ptr @fn_lbl(ptr @.str1493) store ptr %t86, ptr %t87 - call void @fn_emit(ptr @.str1170) + call void @fn_emit(ptr @.str1494) %t88 = load ptr, ptr %t85 call void @fn_emit(ptr %t88) - call void @fn_emit(ptr @.str1171) + call void @fn_emit(ptr @.str1495) %t89 = load ptr, ptr %t87 call void @fn_emit(ptr %t89) - call void @fn_emit(ptr @.str1172) + call void @fn_emit(ptr @.str1496) %t90 = load ptr, ptr %t46 call void @fn_emit(ptr %t90) - call void @fn_emit(ptr @.str1173) + call void @fn_emit(ptr @.str1497) %t91 = load ptr, ptr %t87 call void @fn_emit(ptr %t91) - call void @fn_emit(ptr @.str1174) + call void @fn_emit(ptr @.str1498) %t92 = load ptr, ptr %t0 %t93 = getelementptr inbounds %Cmp_Node, ptr %t92, i32 0, i32 6 %t94 = load ptr, ptr %t93 @@ -17801,7 +22801,7 @@ wbody6: %t117 = load ptr, ptr %t116 %t118 = call i32 @fn_find_arch_id(ptr %t117) store i32 %t118, ptr %t119 - store ptr @.str1175, ptr %t120 + store ptr @.str1499, ptr %t120 %t121 = load i32, ptr %t119 %t122 = icmp sgt i32 %t121, 0 %t123 = zext i1 %t122 to i32 @@ -17810,23 +22810,23 @@ wbody6: then8: %t125 = call ptr @fn_nreg() store ptr %t125, ptr %t126 - call void @fn_emit(ptr @.str1176) + call void @fn_emit(ptr @.str1500) %t127 = load ptr, ptr %t126 call void @fn_emit(ptr %t127) - call void @fn_emit(ptr @.str1177) + call void @fn_emit(ptr @.str1501) %t128 = load ptr, ptr %t2 call void @fn_emit(ptr %t128) - call void @fn_emit(ptr @.str1178) + call void @fn_emit(ptr @.str1502) %t129 = load ptr, ptr %t71 call void @fn_emit(ptr %t129) - call void @fn_emit(ptr @.str1179) + call void @fn_emit(ptr @.str1503) %t130 = load ptr, ptr %t126 - %t131 = call ptr @fn_str_concat(ptr @.str1180, ptr %t130) + %t131 = call ptr @fn_str_concat(ptr @.str1504, ptr %t130) %t132 = call ptr @fn_emit_bind(ptr %t131) store ptr %t132, ptr %t133 %t134 = load ptr, ptr %t133 - %t135 = call ptr @fn_str_concat(ptr @.str1181, ptr %t134) - %t136 = call ptr @fn_str_concat(ptr %t135, ptr @.str1182) + %t135 = call ptr @fn_str_concat(ptr @.str1505, ptr %t134) + %t136 = call ptr @fn_str_concat(ptr %t135, ptr @.str1506) %t137 = load i32, ptr %t119 %t138 = call ptr @fn_itoa(i32 %t137) %t139 = call ptr @fn_str_concat(ptr %t136, ptr %t138) @@ -17835,17 +22835,17 @@ then8: %t142 = load ptr, ptr %t114 %t143 = getelementptr inbounds %Cmp_Node, ptr %t142, i32 0, i32 1 %t144 = load ptr, ptr %t143 - %t145 = call ptr @fn_str_concat(ptr @.str1183, ptr %t144) + %t145 = call ptr @fn_str_concat(ptr @.str1507, ptr %t144) %t146 = call ptr @fn_emit_bind(ptr %t145) store ptr %t146, ptr %t147 %t148 = load ptr, ptr %t147 - %t149 = call ptr @fn_str_concat(ptr @.str1184, ptr %t148) - %t150 = call ptr @fn_str_concat(ptr %t149, ptr @.str1185) + %t149 = call ptr @fn_str_concat(ptr @.str1508, ptr %t148) + %t150 = call ptr @fn_str_concat(ptr %t149, ptr @.str1509) %t151 = call ptr @fn_emit_bind(ptr %t150) store ptr %t151, ptr %t152 %t153 = load ptr, ptr %t141 - %t154 = call ptr @fn_str_concat(ptr @.str1186, ptr %t153) - %t155 = call ptr @fn_str_concat(ptr %t154, ptr @.str1187) + %t154 = call ptr @fn_str_concat(ptr @.str1510, ptr %t153) + %t155 = call ptr @fn_str_concat(ptr %t154, ptr @.str1511) %t156 = load ptr, ptr %t152 %t157 = call ptr @fn_str_concat(ptr %t155, ptr %t156) %t158 = call ptr @fn_emit_bind(ptr %t157) @@ -17854,47 +22854,47 @@ then8: else9: %t159 = call ptr @fn_nreg() store ptr %t159, ptr %t160 - call void @fn_emit(ptr @.str1188) + call void @fn_emit(ptr @.str1512) %t161 = load ptr, ptr %t160 call void @fn_emit(ptr %t161) - call void @fn_emit(ptr @.str1189) + call void @fn_emit(ptr @.str1513) %t162 = load ptr, ptr %t2 call void @fn_emit(ptr %t162) - call void @fn_emit(ptr @.str1190) + call void @fn_emit(ptr @.str1514) %t163 = load ptr, ptr %t114 %t164 = getelementptr inbounds %Cmp_Node, ptr %t163, i32 0, i32 1 %t165 = load ptr, ptr %t164 call void @fn_emit(ptr %t165) - call void @fn_emit(ptr @.str1191) + call void @fn_emit(ptr @.str1515) %t166 = load ptr, ptr %t71 call void @fn_emit(ptr %t166) - call void @fn_emit(ptr @.str1192) + call void @fn_emit(ptr @.str1516) %t167 = load ptr, ptr %t160 - %t168 = call ptr @fn_str_concat(ptr @.str1193, ptr %t167) + %t168 = call ptr @fn_str_concat(ptr @.str1517, ptr %t167) %t169 = call ptr @fn_emit_bind(ptr %t168) store ptr %t169, ptr %t170 %t171 = load ptr, ptr %t170 - %t172 = call ptr @fn_str_concat(ptr @.str1194, ptr %t171) - %t173 = call ptr @fn_str_concat(ptr %t172, ptr @.str1195) + %t172 = call ptr @fn_str_concat(ptr @.str1518, ptr %t171) + %t173 = call ptr @fn_str_concat(ptr %t172, ptr @.str1519) %t174 = call ptr @fn_emit_bind(ptr %t173) store ptr %t174, ptr %t120 br label %ifend10 ifend10: - %t175 = call ptr @fn_lbl(ptr @.str1196) + %t175 = call ptr @fn_lbl(ptr @.str1520) store ptr %t175, ptr %t176 - call void @fn_emit(ptr @.str1197) + call void @fn_emit(ptr @.str1521) %t177 = load ptr, ptr %t120 call void @fn_emit(ptr %t177) - call void @fn_emit(ptr @.str1198) + call void @fn_emit(ptr @.str1522) %t178 = load ptr, ptr %t176 call void @fn_emit(ptr %t178) - call void @fn_emit(ptr @.str1199) + call void @fn_emit(ptr @.str1523) %t179 = load ptr, ptr %t46 call void @fn_emit(ptr %t179) - call void @fn_emit(ptr @.str1200) + call void @fn_emit(ptr @.str1524) %t180 = load ptr, ptr %t176 call void @fn_emit(ptr %t180) - call void @fn_emit(ptr @.str1201) + call void @fn_emit(ptr @.str1525) %t181 = load i32, ptr %t96 %t182 = add i32 %t181, 1 store i32 %t182, ptr %t96 @@ -17964,35 +22964,35 @@ then16: then19: %t231 = call ptr @fn_nreg() store ptr %t231, ptr %t232 - call void @fn_emit(ptr @.str1202) + call void @fn_emit(ptr @.str1526) %t233 = load ptr, ptr %t232 call void @fn_emit(ptr %t233) - call void @fn_emit(ptr @.str1203) + call void @fn_emit(ptr @.str1527) %t234 = load ptr, ptr %t2 call void @fn_emit(ptr %t234) - call void @fn_emit(ptr @.str1204) + call void @fn_emit(ptr @.str1528) %t235 = load ptr, ptr %t203 %t236 = getelementptr inbounds %Cmp_Node, ptr %t235, i32 0, i32 1 %t237 = load ptr, ptr %t236 call void @fn_emit(ptr %t237) - call void @fn_emit(ptr @.str1205) + call void @fn_emit(ptr @.str1529) %t238 = load ptr, ptr %t203 %t239 = getelementptr inbounds %Cmp_Node, ptr %t238, i32 0, i32 1 %t240 = load ptr, ptr %t239 call void @fn_emit(ptr %t240) - call void @fn_emit(ptr @.str1206) + call void @fn_emit(ptr @.str1530) %t241 = load ptr, ptr %t71 call void @fn_emit(ptr %t241) - call void @fn_emit(ptr @.str1207) - %t242 = call ptr @fn_emit_alloca(ptr @.str1208) + call void @fn_emit(ptr @.str1531) + %t242 = call ptr @fn_emit_alloca(ptr @.str1532) store ptr %t242, ptr %t243 - call void @fn_emit(ptr @.str1209) + call void @fn_emit(ptr @.str1533) %t244 = load ptr, ptr %t232 call void @fn_emit(ptr %t244) - call void @fn_emit(ptr @.str1210) + call void @fn_emit(ptr @.str1534) %t245 = load ptr, ptr %t243 call void @fn_emit(ptr %t245) - call void @fn_emit(ptr @.str1211) + call void @fn_emit(ptr @.str1535) %t246 = load ptr, ptr %t0 %t247 = getelementptr inbounds %Cmp_Node, ptr %t246, i32 0, i32 7 %t248 = load ptr, ptr %t247 @@ -18036,25 +23036,25 @@ then22: %t275 = load ptr, ptr %t274 %t276 = getelementptr inbounds %Cmp_Val, ptr %t275, i32 0, i32 0 %t277 = load ptr, ptr %t276 - %t278 = call ptr @fn_str_concat(ptr @.str1212, ptr %t277) - %t279 = call ptr @fn_str_concat(ptr %t278, ptr @.str1213) + %t278 = call ptr @fn_str_concat(ptr @.str1536, ptr %t277) + %t279 = call ptr @fn_str_concat(ptr %t278, ptr @.str1537) %t280 = call ptr @fn_emit_bind(ptr %t279) store ptr %t280, ptr %t281 - %t282 = call ptr @fn_lbl(ptr @.str1214) + %t282 = call ptr @fn_lbl(ptr @.str1538) store ptr %t282, ptr %t283 - call void @fn_emit(ptr @.str1215) + call void @fn_emit(ptr @.str1539) %t284 = load ptr, ptr %t281 call void @fn_emit(ptr %t284) - call void @fn_emit(ptr @.str1216) + call void @fn_emit(ptr @.str1540) %t285 = load ptr, ptr %t283 call void @fn_emit(ptr %t285) - call void @fn_emit(ptr @.str1217) + call void @fn_emit(ptr @.str1541) %t286 = load ptr, ptr %t46 call void @fn_emit(ptr %t286) - call void @fn_emit(ptr @.str1218) + call void @fn_emit(ptr @.str1542) %t287 = load ptr, ptr %t283 call void @fn_emit(ptr %t287) - call void @fn_emit(ptr @.str1219) + call void @fn_emit(ptr @.str1543) br label %ifend24 ifend24: %t288 = load ptr, ptr %t46 @@ -18073,34 +23073,34 @@ ifend24: %t297 = icmp ne i32 %t296, 0 br i1 %t297, label %then25, label %ifend27 then25: - call void @fn_emit(ptr @.str1220) + call void @fn_emit(ptr @.str1544) %t298 = load ptr, ptr %t46 call void @fn_emit(ptr %t298) - call void @fn_emit(ptr @.str1221) + call void @fn_emit(ptr @.str1545) br label %ifend27 ifend27: %t299 = load ptr, ptr %t46 call void @fn_emit(ptr %t299) - call void @fn_emit(ptr @.str1222) + call void @fn_emit(ptr @.str1546) %t300 = load ptr, ptr %t4 - %t301 = call ptr @fn_str_concat(ptr @.str1223, ptr %t300) + %t301 = call ptr @fn_str_concat(ptr @.str1547, ptr %t300) %t302 = call ptr @fn_emit_bind(ptr %t301) store ptr %t302, ptr %t303 %t304 = load ptr, ptr %t303 - %t305 = call ptr @fn_str_concat(ptr @.str1224, ptr %t304) - %t306 = call ptr @fn_str_concat(ptr %t305, ptr @.str1225) + %t305 = call ptr @fn_str_concat(ptr @.str1548, ptr %t304) + %t306 = call ptr @fn_str_concat(ptr %t305, ptr @.str1549) %t307 = call ptr @fn_emit_bind(ptr %t306) store ptr %t307, ptr %t308 %t309 = load ptr, ptr %t308 %t310 = load ptr, ptr %t4 - call void @fn_store_at(ptr @.str1226, ptr %t309, ptr %t310) - call void @fn_emit(ptr @.str1227) + call void @fn_store_at(ptr @.str1550, ptr %t309, ptr %t310) + call void @fn_emit(ptr @.str1551) %t311 = load ptr, ptr %t42 call void @fn_emit(ptr %t311) - call void @fn_emit(ptr @.str1228) + call void @fn_emit(ptr @.str1552) %t312 = load ptr, ptr %t48 call void @fn_emit(ptr %t312) - call void @fn_emit(ptr @.str1229) + call void @fn_emit(ptr @.str1553) store i32 0, ptr @g_g_term %t313 = load i32, ptr @g_nself %t314 = sub i32 %t313, 1 @@ -18133,6 +23133,7 @@ entry: %t141 = alloca ptr %t147 = alloca i32 %t149 = alloca ptr + %t160 = alloca ptr store ptr %arg_e, ptr %t0 store ptr %arg_comp, ptr %t1 store ptr %arg_rec, ptr %t2 @@ -18148,47 +23149,47 @@ entry: br i1 %t11, label %then0, label %ifend2 then0: %t12 = load ptr, ptr %t1 - %t13 = call ptr @fn_str_concat(ptr @.str1230, ptr %t12) + %t13 = call ptr @fn_str_concat(ptr @.str1554, ptr %t12) call void @fn_perr(ptr %t13) br label %ifend2 ifend2: %t14 = call ptr @fn_nreg() store ptr %t14, ptr %t15 - call void @fn_emit(ptr @.str1231) + call void @fn_emit(ptr @.str1555) %t16 = load ptr, ptr %t15 call void @fn_emit(ptr %t16) - call void @fn_emit(ptr @.str1232) + call void @fn_emit(ptr @.str1556) %t17 = load ptr, ptr %t4 call void @fn_emit(ptr %t17) - call void @fn_emit(ptr @.str1233) + call void @fn_emit(ptr @.str1557) %t18 = load ptr, ptr %t1 call void @fn_emit(ptr %t18) - call void @fn_emit(ptr @.str1234) + call void @fn_emit(ptr @.str1558) %t19 = load ptr, ptr %t0 call void @fn_emit(ptr %t19) - call void @fn_emit(ptr @.str1235) - call void @fn_emit(ptr @.str1236) + call void @fn_emit(ptr @.str1559) + call void @fn_emit(ptr @.str1560) %t20 = load ptr, ptr %t15 call void @fn_emit(ptr %t20) - call void @fn_emit(ptr @.str1237) + call void @fn_emit(ptr @.str1561) %t21 = call ptr @fn_nreg() store ptr %t21, ptr %t22 - call void @fn_emit(ptr @.str1238) + call void @fn_emit(ptr @.str1562) %t23 = load ptr, ptr %t22 call void @fn_emit(ptr %t23) - call void @fn_emit(ptr @.str1239) + call void @fn_emit(ptr @.str1563) %t24 = load ptr, ptr %t4 call void @fn_emit(ptr %t24) - call void @fn_emit(ptr @.str1240) + call void @fn_emit(ptr @.str1564) %t25 = load ptr, ptr %t1 call void @fn_emit(ptr %t25) - call void @fn_emit(ptr @.str1241) + call void @fn_emit(ptr @.str1565) %t26 = load ptr, ptr %t1 call void @fn_emit(ptr %t26) - call void @fn_emit(ptr @.str1242) + call void @fn_emit(ptr @.str1566) %t27 = load ptr, ptr %t0 call void @fn_emit(ptr %t27) - call void @fn_emit(ptr @.str1243) + call void @fn_emit(ptr @.str1567) store i32 0, ptr %t28 br label %wcond3 wcond3: @@ -18214,32 +23215,32 @@ wbody4: store ptr %t45, ptr %t46 %t47 = call ptr @fn_nreg() store ptr %t47, ptr %t48 - call void @fn_emit(ptr @.str1244) + call void @fn_emit(ptr @.str1568) %t49 = load ptr, ptr %t48 call void @fn_emit(ptr %t49) - call void @fn_emit(ptr @.str1245) + call void @fn_emit(ptr @.str1569) %t50 = load ptr, ptr %t1 call void @fn_emit(ptr %t50) - call void @fn_emit(ptr @.str1246) + call void @fn_emit(ptr @.str1570) %t51 = load ptr, ptr %t22 call void @fn_emit(ptr %t51) - call void @fn_emit(ptr @.str1247) + call void @fn_emit(ptr @.str1571) %t52 = load i32, ptr %t28 %t53 = call ptr @fn_itoa(i32 %t52) call void @fn_emit(ptr %t53) - call void @fn_emit(ptr @.str1248) + call void @fn_emit(ptr @.str1572) %t54 = load ptr, ptr %t46 %t55 = getelementptr inbounds %Cmp_Node, ptr %t54, i32 0, i32 3 %t56 = load ptr, ptr %t55 %t57 = call ptr @fn_llty(ptr %t56) store ptr %t57, ptr %t58 - store ptr @.str1249, ptr %t59 + store ptr @.str1573, ptr %t59 %t60 = load ptr, ptr %t58 - %t61 = call i32 @fn_str_eq(ptr %t60, ptr @.str1250) + %t61 = call i32 @fn_str_eq(ptr %t60, ptr @.str1574) %t62 = icmp ne i32 %t61, 0 br i1 %t62, label %then6, label %ifend8 then6: - store ptr @.str1251, ptr %t59 + store ptr @.str1575, ptr %t59 br label %ifend8 ifend8: %t63 = load ptr, ptr %t46 @@ -18261,16 +23262,16 @@ then9: store ptr %t76, ptr %t59 br label %ifend11 ifend11: - call void @fn_emit(ptr @.str1252) + call void @fn_emit(ptr @.str1576) %t77 = load ptr, ptr %t58 call void @fn_emit(ptr %t77) - call void @fn_emit(ptr @.str1253) + call void @fn_emit(ptr @.str1577) %t78 = load ptr, ptr %t59 call void @fn_emit(ptr %t78) - call void @fn_emit(ptr @.str1254) + call void @fn_emit(ptr @.str1578) %t79 = load ptr, ptr %t48 call void @fn_emit(ptr %t79) - call void @fn_emit(ptr @.str1255) + call void @fn_emit(ptr @.str1579) %t80 = load i32, ptr %t28 %t81 = add i32 %t80, 1 store i32 %t81, ptr %t28 @@ -18319,26 +23320,26 @@ wbody16: then18: %t115 = call ptr @fn_nreg() store ptr %t115, ptr %t116 - call void @fn_emit(ptr @.str1256) + call void @fn_emit(ptr @.str1580) %t117 = load ptr, ptr %t116 call void @fn_emit(ptr %t117) - call void @fn_emit(ptr @.str1257) + call void @fn_emit(ptr @.str1581) %t118 = load ptr, ptr %t1 call void @fn_emit(ptr %t118) - call void @fn_emit(ptr @.str1258) + call void @fn_emit(ptr @.str1582) %t119 = load ptr, ptr %t22 call void @fn_emit(ptr %t119) - call void @fn_emit(ptr @.str1259) + call void @fn_emit(ptr @.str1583) %t120 = load i32, ptr %t110 %t121 = call ptr @fn_itoa(i32 %t120) call void @fn_emit(ptr %t121) - call void @fn_emit(ptr @.str1260) + call void @fn_emit(ptr @.str1584) %t122 = load ptr, ptr %t104 %t123 = getelementptr inbounds %Cmp_Node, ptr %t122, i32 0, i32 4 %t124 = load ptr, ptr %t123 %t125 = call ptr @fn_emit_expr(ptr %t124) store ptr %t125, ptr %t126 - call void @fn_emit(ptr @.str1261) + call void @fn_emit(ptr @.str1585) %t127 = load ptr, ptr %t7 %t128 = load ptr, ptr %t104 %t129 = getelementptr inbounds %Cmp_Node, ptr %t128, i32 0, i32 1 @@ -18346,15 +23347,15 @@ then18: %t131 = call ptr @fn_field_type(ptr %t127, ptr %t130) %t132 = call ptr @fn_llty(ptr %t131) call void @fn_emit(ptr %t132) - call void @fn_emit(ptr @.str1262) + call void @fn_emit(ptr @.str1586) %t133 = load ptr, ptr %t126 %t134 = getelementptr inbounds %Cmp_Val, ptr %t133, i32 0, i32 0 %t135 = load ptr, ptr %t134 call void @fn_emit(ptr %t135) - call void @fn_emit(ptr @.str1263) + call void @fn_emit(ptr @.str1587) %t136 = load ptr, ptr %t116 call void @fn_emit(ptr %t136) - call void @fn_emit(ptr @.str1264) + call void @fn_emit(ptr @.str1588) br label %ifend20 ifend20: %t137 = load i32, ptr %t86 @@ -18375,15 +23376,15 @@ ifend14: then21: %t146 = load i32, ptr @g_nloc store i32 %t146, ptr %t147 - %t148 = call ptr @fn_emit_alloca(ptr @.str1265) + %t148 = call ptr @fn_emit_alloca(ptr @.str1589) store ptr %t148, ptr %t149 - call void @fn_emit(ptr @.str1266) + call void @fn_emit(ptr @.str1590) %t150 = load ptr, ptr %t22 call void @fn_emit(ptr %t150) - call void @fn_emit(ptr @.str1267) + call void @fn_emit(ptr @.str1591) %t151 = load ptr, ptr %t149 call void @fn_emit(ptr %t151) - call void @fn_emit(ptr @.str1268) + call void @fn_emit(ptr @.str1592) %t152 = load ptr, ptr %t1 %t153 = load ptr, ptr %t149 %t154 = load ptr, ptr %t1 @@ -18394,6 +23395,26 @@ then21: store i32 %t156, ptr @g_nloc br label %ifend23 ifend23: + %t157 = load ptr, ptr %t1 + %t158 = call ptr @fn_str_concat(ptr @.str1593, ptr %t157) + %t159 = call ptr @fn_str_concat(ptr %t158, ptr @.str1594) + store ptr %t159, ptr %t160 + %t161 = load ptr, ptr %t160 + %t162 = call ptr @fn_find_event(ptr %t161) + %t163 = icmp ne ptr %t162, null + %t164 = zext i1 %t163 to i32 + %t165 = icmp ne i32 %t164, 0 + br i1 %t165, label %then24, label %ifend26 +then24: + call void @fn_emit(ptr @.str1595) + %t166 = load ptr, ptr %t160 + call void @fn_emit(ptr %t166) + call void @fn_emit(ptr @.str1596) + %t167 = load ptr, ptr %t0 + call void @fn_emit(ptr %t167) + call void @fn_emit(ptr @.str1597) + br label %ifend26 +ifend26: br label %ret ret: ret void @@ -18439,31 +23460,31 @@ wbody1: store ptr %t23, ptr %t24 %t25 = call ptr @fn_nreg() store ptr %t25, ptr %t26 - call void @fn_emit(ptr @.str1269) + call void @fn_emit(ptr @.str1598) %t27 = load ptr, ptr %t26 call void @fn_emit(ptr %t27) - call void @fn_emit(ptr @.str1270) + call void @fn_emit(ptr @.str1599) %t28 = load ptr, ptr %t3 call void @fn_emit(ptr %t28) - call void @fn_emit(ptr @.str1271) + call void @fn_emit(ptr @.str1600) %t29 = load ptr, ptr %t24 call void @fn_emit(ptr %t29) - call void @fn_emit(ptr @.str1272) + call void @fn_emit(ptr @.str1601) %t30 = load ptr, ptr %t24 call void @fn_emit(ptr %t30) - call void @fn_emit(ptr @.str1273) + call void @fn_emit(ptr @.str1602) %t31 = load ptr, ptr %t1 call void @fn_emit(ptr %t31) - call void @fn_emit(ptr @.str1274) - %t32 = call ptr @fn_emit_alloca(ptr @.str1275) + call void @fn_emit(ptr @.str1603) + %t32 = call ptr @fn_emit_alloca(ptr @.str1604) store ptr %t32, ptr %t33 - call void @fn_emit(ptr @.str1276) + call void @fn_emit(ptr @.str1605) %t34 = load ptr, ptr %t26 call void @fn_emit(ptr %t34) - call void @fn_emit(ptr @.str1277) + call void @fn_emit(ptr @.str1606) %t35 = load ptr, ptr %t33 call void @fn_emit(ptr %t35) - call void @fn_emit(ptr @.str1278) + call void @fn_emit(ptr @.str1607) %t36 = load ptr, ptr %t24 %t37 = load ptr, ptr %t33 %t38 = load ptr, ptr %t24 @@ -18478,8 +23499,9 @@ ret: ret void } -define void @fn_emit_spawn(ptr %arg_st) { +define ptr @fn_emit_spawn(ptr %arg_st) { entry: + %retval = alloca ptr %t0 = alloca ptr %t2 = alloca ptr %t7 = alloca i32 @@ -18492,9 +23514,10 @@ entry: %t49 = alloca i32 %t93 = alloca ptr %t99 = alloca i32 - %t104 = alloca i32 + %t109 = alloca ptr + %t117 = alloca i32 store ptr %arg_st, ptr %t0 - %t1 = call ptr @fn_emit_bind(ptr @.str1279) + %t1 = call ptr @fn_emit_bind(ptr @.str1608) store ptr %t1, ptr %t2 %t3 = load ptr, ptr %t0 %t4 = getelementptr inbounds %Cmp_Node, ptr %t3, i32 0, i32 1 @@ -18511,24 +23534,24 @@ then0: store ptr %t12, ptr %t13 %t14 = call ptr @fn_nreg() store ptr %t14, ptr %t15 - call void @fn_emit(ptr @.str1280) + call void @fn_emit(ptr @.str1609) %t16 = load ptr, ptr %t15 call void @fn_emit(ptr %t16) - call void @fn_emit(ptr @.str1281) + call void @fn_emit(ptr @.str1610) %t17 = load ptr, ptr %t13 call void @fn_emit(ptr %t17) - call void @fn_emit(ptr @.str1282) + call void @fn_emit(ptr @.str1611) %t18 = load ptr, ptr %t2 call void @fn_emit(ptr %t18) - call void @fn_emit(ptr @.str1283) - call void @fn_emit(ptr @.str1284) + call void @fn_emit(ptr @.str1612) + call void @fn_emit(ptr @.str1613) %t19 = load i32, ptr %t7 %t20 = call ptr @fn_itoa(i32 %t19) call void @fn_emit(ptr %t20) - call void @fn_emit(ptr @.str1285) + call void @fn_emit(ptr @.str1614) %t21 = load ptr, ptr %t15 call void @fn_emit(ptr %t21) - call void @fn_emit(ptr @.str1286) + call void @fn_emit(ptr @.str1615) %t22 = load ptr, ptr %t0 %t23 = getelementptr inbounds %Cmp_Node, ptr %t22, i32 0, i32 1 %t24 = load ptr, ptr %t23 @@ -18638,54 +23661,79 @@ then12: store i32 %t103, ptr @g_nloc br label %ifend14 ifend14: + %t104 = load ptr, ptr %t0 + %t105 = getelementptr inbounds %Cmp_Node, ptr %t104, i32 0, i32 1 + %t106 = load ptr, ptr %t105 + %t107 = call ptr @fn_str_concat(ptr @.str1616, ptr %t106) + %t108 = call ptr @fn_str_concat(ptr %t107, ptr @.str1617) + store ptr %t108, ptr %t109 + %t110 = load ptr, ptr %t109 + %t111 = call ptr @fn_find_event(ptr %t110) + %t112 = icmp ne ptr %t111, null + %t113 = zext i1 %t112 to i32 + %t114 = icmp ne i32 %t113, 0 + br i1 %t114, label %then15, label %ifend17 +then15: + call void @fn_emit(ptr @.str1618) + %t115 = load ptr, ptr %t109 + call void @fn_emit(ptr %t115) + call void @fn_emit(ptr @.str1619) + %t116 = load ptr, ptr %t2 + call void @fn_emit(ptr %t116) + call void @fn_emit(ptr @.str1620) + br label %ifend17 +ifend17: br label %ifend2 else1: - store i32 0, ptr %t104 - br label %wcond15 -wcond15: - %t105 = load i32, ptr %t104 - %t106 = load ptr, ptr %t0 - %t107 = getelementptr inbounds %Cmp_Node, ptr %t106, i32 0, i32 7 - %t108 = load ptr, ptr %t107 - %t109 = getelementptr inbounds %LSlice, ptr %t108, i32 0, i32 1 - %t110 = load i32, ptr %t109 - %t111 = icmp slt i32 %t105, %t110 - %t112 = zext i1 %t111 to i32 - %t113 = icmp ne i32 %t112, 0 - br i1 %t113, label %wbody16, label %wend17 -wbody16: - %t114 = load ptr, ptr %t2 - %t115 = load ptr, ptr %t0 - %t116 = getelementptr inbounds %Cmp_Node, ptr %t115, i32 0, i32 7 - %t117 = load ptr, ptr %t116 - %t118 = getelementptr inbounds %LSlice, ptr %t117, i32 0, i32 0 - %t119 = load ptr, ptr %t118 - %t120 = load i32, ptr %t104 - %t121 = getelementptr inbounds ptr, ptr %t119, i32 %t120 - %t122 = load ptr, ptr %t121 - %t123 = getelementptr inbounds %Cmp_Node, ptr %t122, i32 0, i32 1 - %t124 = load ptr, ptr %t123 - %t125 = load ptr, ptr %t0 - %t126 = getelementptr inbounds %Cmp_Node, ptr %t125, i32 0, i32 7 - %t127 = load ptr, ptr %t126 - %t128 = getelementptr inbounds %LSlice, ptr %t127, i32 0, i32 0 - %t129 = load ptr, ptr %t128 - %t130 = load i32, ptr %t104 - %t131 = getelementptr inbounds ptr, ptr %t129, i32 %t130 + store i32 0, ptr %t117 + br label %wcond18 +wcond18: + %t118 = load i32, ptr %t117 + %t119 = load ptr, ptr %t0 + %t120 = getelementptr inbounds %Cmp_Node, ptr %t119, i32 0, i32 7 + %t121 = load ptr, ptr %t120 + %t122 = getelementptr inbounds %LSlice, ptr %t121, i32 0, i32 1 + %t123 = load i32, ptr %t122 + %t124 = icmp slt i32 %t118, %t123 + %t125 = zext i1 %t124 to i32 + %t126 = icmp ne i32 %t125, 0 + br i1 %t126, label %wbody19, label %wend20 +wbody19: + %t127 = load ptr, ptr %t2 + %t128 = load ptr, ptr %t0 + %t129 = getelementptr inbounds %Cmp_Node, ptr %t128, i32 0, i32 7 + %t130 = load ptr, ptr %t129 + %t131 = getelementptr inbounds %LSlice, ptr %t130, i32 0, i32 0 %t132 = load ptr, ptr %t131 - %t133 = getelementptr inbounds %Cmp_Node, ptr %t132, i32 0, i32 4 - %t134 = load ptr, ptr %t133 - call void @fn_emit_init_component(ptr %t114, ptr %t124, ptr %t134) - %t135 = load i32, ptr %t104 - %t136 = add i32 %t135, 1 - store i32 %t136, ptr %t104 - br label %wcond15 -wend17: + %t133 = load i32, ptr %t117 + %t134 = getelementptr inbounds ptr, ptr %t132, i32 %t133 + %t135 = load ptr, ptr %t134 + %t136 = getelementptr inbounds %Cmp_Node, ptr %t135, i32 0, i32 1 + %t137 = load ptr, ptr %t136 + %t138 = load ptr, ptr %t0 + %t139 = getelementptr inbounds %Cmp_Node, ptr %t138, i32 0, i32 7 + %t140 = load ptr, ptr %t139 + %t141 = getelementptr inbounds %LSlice, ptr %t140, i32 0, i32 0 + %t142 = load ptr, ptr %t141 + %t143 = load i32, ptr %t117 + %t144 = getelementptr inbounds ptr, ptr %t142, i32 %t143 + %t145 = load ptr, ptr %t144 + %t146 = getelementptr inbounds %Cmp_Node, ptr %t145, i32 0, i32 4 + %t147 = load ptr, ptr %t146 + call void @fn_emit_init_component(ptr %t127, ptr %t137, ptr %t147) + %t148 = load i32, ptr %t117 + %t149 = add i32 %t148, 1 + store i32 %t149, ptr %t117 + br label %wcond18 +wend20: br label %ifend2 ifend2: + %t150 = load ptr, ptr %t2 + store ptr %t150, ptr %retval br label %ret ret: - ret void + %t151 = load ptr, ptr %retval + ret ptr %t151 } define void @fn_emit_despawn(ptr %arg_st) { @@ -18700,6 +23748,7 @@ entry: %t50 = alloca ptr %t52 = alloca ptr %t54 = alloca ptr + %t66 = alloca ptr store ptr %arg_st, ptr %t0 %t1 = load ptr, ptr %t0 %t2 = getelementptr inbounds %Cmp_Node, ptr %t1, i32 0, i32 4 @@ -18718,20 +23767,20 @@ then0: store ptr %t12, ptr %t13 %t14 = call ptr @fn_nreg() store ptr %t14, ptr %t15 - call void @fn_emit(ptr @.str1287) + call void @fn_emit(ptr @.str1621) %t16 = load ptr, ptr %t15 call void @fn_emit(ptr %t16) - call void @fn_emit(ptr @.str1288) + call void @fn_emit(ptr @.str1622) %t17 = load ptr, ptr %t13 call void @fn_emit(ptr %t17) - call void @fn_emit(ptr @.str1289) + call void @fn_emit(ptr @.str1623) %t18 = load ptr, ptr %t5 %t19 = getelementptr inbounds %Cmp_Val, ptr %t18, i32 0, i32 0 %t20 = load ptr, ptr %t19 call void @fn_emit(ptr %t20) - call void @fn_emit(ptr @.str1290) + call void @fn_emit(ptr @.str1624) %t21 = load ptr, ptr %t15 - %t22 = call ptr @fn_str_concat(ptr @.str1291, ptr %t21) + %t22 = call ptr @fn_str_concat(ptr @.str1625, ptr %t21) %t23 = call ptr @fn_emit_bind(ptr %t22) store ptr %t23, ptr %t24 store i32 0, ptr %t25 @@ -18756,59 +23805,370 @@ wbody4: %t40 = load ptr, ptr %t39 store ptr %t40, ptr %t41 %t42 = load ptr, ptr %t24 - %t43 = call ptr @fn_str_concat(ptr @.str1292, ptr %t42) - %t44 = call ptr @fn_str_concat(ptr %t43, ptr @.str1293) + %t43 = call ptr @fn_str_concat(ptr @.str1626, ptr %t42) + %t44 = call ptr @fn_str_concat(ptr %t43, ptr @.str1627) %t45 = load ptr, ptr %t41 %t46 = call i32 @fn_find_arch_id(ptr %t45) %t47 = call ptr @fn_itoa(i32 %t46) %t48 = call ptr @fn_str_concat(ptr %t44, ptr %t47) %t49 = call ptr @fn_emit_bind(ptr %t48) store ptr %t49, ptr %t50 - %t51 = call ptr @fn_lbl(ptr @.str1294) + %t51 = call ptr @fn_lbl(ptr @.str1628) store ptr %t51, ptr %t52 - %t53 = call ptr @fn_lbl(ptr @.str1295) + %t53 = call ptr @fn_lbl(ptr @.str1629) store ptr %t53, ptr %t54 - call void @fn_emit(ptr @.str1296) + call void @fn_emit(ptr @.str1630) %t55 = load ptr, ptr %t50 call void @fn_emit(ptr %t55) - call void @fn_emit(ptr @.str1297) + call void @fn_emit(ptr @.str1631) %t56 = load ptr, ptr %t52 call void @fn_emit(ptr %t56) - call void @fn_emit(ptr @.str1298) + call void @fn_emit(ptr @.str1632) %t57 = load ptr, ptr %t54 call void @fn_emit(ptr %t57) - call void @fn_emit(ptr @.str1299) + call void @fn_emit(ptr @.str1633) %t58 = load ptr, ptr %t52 call void @fn_emit(ptr %t58) - call void @fn_emit(ptr @.str1300) + call void @fn_emit(ptr @.str1634) %t59 = load ptr, ptr %t41 call void @fn_emit(ptr %t59) - call void @fn_emit(ptr @.str1301) + call void @fn_emit(ptr @.str1635) %t60 = load ptr, ptr %t5 %t61 = getelementptr inbounds %Cmp_Val, ptr %t60, i32 0, i32 0 %t62 = load ptr, ptr %t61 call void @fn_emit(ptr %t62) - call void @fn_emit(ptr @.str1302) - call void @fn_emit(ptr @.str1303) - %t63 = load ptr, ptr %t54 - call void @fn_emit(ptr %t63) - call void @fn_emit(ptr @.str1304) - %t64 = load ptr, ptr %t54 - call void @fn_emit(ptr %t64) - call void @fn_emit(ptr @.str1305) - %t65 = load i32, ptr %t25 - %t66 = add i32 %t65, 1 - store i32 %t66, ptr %t25 + call void @fn_emit(ptr @.str1636) + %t63 = load ptr, ptr %t41 + %t64 = call ptr @fn_str_concat(ptr @.str1637, ptr %t63) + %t65 = call ptr @fn_str_concat(ptr %t64, ptr @.str1638) + store ptr %t65, ptr %t66 + %t67 = load ptr, ptr %t66 + %t68 = call ptr @fn_find_event(ptr %t67) + %t69 = icmp ne ptr %t68, null + %t70 = zext i1 %t69 to i32 + %t71 = icmp ne i32 %t70, 0 + br i1 %t71, label %then6, label %ifend8 +then6: + call void @fn_emit(ptr @.str1639) + %t72 = load ptr, ptr %t66 + call void @fn_emit(ptr %t72) + call void @fn_emit(ptr @.str1640) + %t73 = load ptr, ptr %t5 + %t74 = getelementptr inbounds %Cmp_Val, ptr %t73, i32 0, i32 0 + %t75 = load ptr, ptr %t74 + call void @fn_emit(ptr %t75) + call void @fn_emit(ptr @.str1641) + br label %ifend8 +ifend8: + call void @fn_emit(ptr @.str1642) + %t76 = load ptr, ptr %t54 + call void @fn_emit(ptr %t76) + call void @fn_emit(ptr @.str1643) + %t77 = load ptr, ptr %t54 + call void @fn_emit(ptr %t77) + call void @fn_emit(ptr @.str1644) + %t78 = load i32, ptr %t25 + %t79 = add i32 %t78, 1 + store i32 %t79, ptr %t25 br label %wcond3 wend5: br label %ifend2 ifend2: - call void @fn_emit(ptr @.str1306) - %t67 = load ptr, ptr %t5 - %t68 = getelementptr inbounds %Cmp_Val, ptr %t67, i32 0, i32 0 - %t69 = load ptr, ptr %t68 - call void @fn_emit(ptr %t69) - call void @fn_emit(ptr @.str1307) + %t80 = load ptr, ptr @g_g_events + %t81 = getelementptr inbounds %LSlice, ptr %t80, i32 0, i32 1 + %t82 = load i32, ptr %t81 + %t83 = icmp sgt i32 %t82, 0 + %t84 = zext i1 %t83 to i32 + %t85 = icmp ne i32 %t84, 0 + br i1 %t85, label %then9, label %ifend11 +then9: + call void @fn_emit(ptr @.str1645) + %t86 = load ptr, ptr %t5 + %t87 = getelementptr inbounds %Cmp_Val, ptr %t86, i32 0, i32 0 + %t88 = load ptr, ptr %t87 + call void @fn_emit(ptr %t88) + call void @fn_emit(ptr @.str1646) + br label %ifend11 +ifend11: + call void @fn_emit(ptr @.str1647) + %t89 = load ptr, ptr %t5 + %t90 = getelementptr inbounds %Cmp_Val, ptr %t89, i32 0, i32 0 + %t91 = load ptr, ptr %t90 + call void @fn_emit(ptr %t91) + call void @fn_emit(ptr @.str1648) + br label %ret +ret: + ret void +} + +define void @fn_emit_attach(ptr %arg_st) { +entry: + %t0 = alloca ptr + %t5 = alloca ptr + %t7 = alloca ptr + %t9 = alloca ptr + %t21 = alloca ptr + %t26 = alloca ptr + %t28 = alloca ptr + %t30 = alloca ptr + store ptr %arg_st, ptr %t0 + %t1 = load ptr, ptr %t0 + %t2 = getelementptr inbounds %Cmp_Node, ptr %t1, i32 0, i32 4 + %t3 = load ptr, ptr %t2 + %t4 = call ptr @fn_emit_expr(ptr %t3) + store ptr %t4, ptr %t5 + %t6 = call ptr @fn_itoa(i32 1024) + store ptr %t6, ptr %t7 + %t8 = call ptr @fn_nreg() + store ptr %t8, ptr %t9 + call void @fn_emit(ptr @.str1649) + %t10 = load ptr, ptr %t9 + call void @fn_emit(ptr %t10) + call void @fn_emit(ptr @.str1650) + %t11 = load ptr, ptr %t7 + call void @fn_emit(ptr %t11) + call void @fn_emit(ptr @.str1651) + %t12 = load ptr, ptr %t0 + %t13 = getelementptr inbounds %Cmp_Node, ptr %t12, i32 0, i32 1 + %t14 = load ptr, ptr %t13 + call void @fn_emit(ptr %t14) + call void @fn_emit(ptr @.str1652) + %t15 = load ptr, ptr %t5 + %t16 = getelementptr inbounds %Cmp_Val, ptr %t15, i32 0, i32 0 + %t17 = load ptr, ptr %t16 + call void @fn_emit(ptr %t17) + call void @fn_emit(ptr @.str1653) + %t18 = load ptr, ptr %t9 + %t19 = call ptr @fn_str_concat(ptr @.str1654, ptr %t18) + %t20 = call ptr @fn_emit_bind(ptr %t19) + store ptr %t20, ptr %t21 + %t22 = load ptr, ptr %t21 + %t23 = call ptr @fn_str_concat(ptr @.str1655, ptr %t22) + %t24 = call ptr @fn_str_concat(ptr %t23, ptr @.str1656) + %t25 = call ptr @fn_emit_bind(ptr %t24) + store ptr %t25, ptr %t26 + %t27 = call ptr @fn_lbl(ptr @.str1657) + store ptr %t27, ptr %t28 + %t29 = call ptr @fn_lbl(ptr @.str1658) + store ptr %t29, ptr %t30 + call void @fn_emit(ptr @.str1659) + %t31 = load ptr, ptr %t26 + call void @fn_emit(ptr %t31) + call void @fn_emit(ptr @.str1660) + %t32 = load ptr, ptr %t28 + call void @fn_emit(ptr %t32) + call void @fn_emit(ptr @.str1661) + %t33 = load ptr, ptr %t30 + call void @fn_emit(ptr %t33) + call void @fn_emit(ptr @.str1662) + %t34 = load ptr, ptr %t28 + call void @fn_emit(ptr %t34) + call void @fn_emit(ptr @.str1663) + store i32 0, ptr @g_g_term + %t35 = load ptr, ptr %t5 + %t36 = getelementptr inbounds %Cmp_Val, ptr %t35, i32 0, i32 0 + %t37 = load ptr, ptr %t36 + %t38 = load ptr, ptr %t0 + %t39 = getelementptr inbounds %Cmp_Node, ptr %t38, i32 0, i32 1 + %t40 = load ptr, ptr %t39 + %t41 = load ptr, ptr %t0 + %t42 = getelementptr inbounds %Cmp_Node, ptr %t41, i32 0, i32 5 + %t43 = load ptr, ptr %t42 + call void @fn_emit_init_component(ptr %t37, ptr %t40, ptr %t43) + %t44 = load i32, ptr @g_g_term + %t45 = icmp eq i32 %t44, 0 + %t46 = zext i1 %t45 to i32 + %t47 = icmp ne i32 %t46, 0 + br i1 %t47, label %then0, label %ifend2 +then0: + call void @fn_emit(ptr @.str1664) + %t48 = load ptr, ptr %t30 + call void @fn_emit(ptr %t48) + call void @fn_emit(ptr @.str1665) + br label %ifend2 +ifend2: + %t49 = load ptr, ptr %t30 + call void @fn_emit(ptr %t49) + call void @fn_emit(ptr @.str1666) + store i32 0, ptr @g_g_term + br label %ret +ret: + ret void +} + +define void @fn_emit_detach(ptr %arg_st) { +entry: + %t0 = alloca ptr + %t5 = alloca ptr + %t7 = alloca ptr + %t9 = alloca ptr + %t21 = alloca ptr + %t26 = alloca ptr + %t28 = alloca ptr + %t30 = alloca ptr + %t40 = alloca ptr + %t46 = alloca i32 + %t48 = alloca ptr + %t61 = alloca ptr + %t78 = alloca ptr + store ptr %arg_st, ptr %t0 + %t1 = load ptr, ptr %t0 + %t2 = getelementptr inbounds %Cmp_Node, ptr %t1, i32 0, i32 4 + %t3 = load ptr, ptr %t2 + %t4 = call ptr @fn_emit_expr(ptr %t3) + store ptr %t4, ptr %t5 + %t6 = call ptr @fn_itoa(i32 1024) + store ptr %t6, ptr %t7 + %t8 = call ptr @fn_nreg() + store ptr %t8, ptr %t9 + call void @fn_emit(ptr @.str1667) + %t10 = load ptr, ptr %t9 + call void @fn_emit(ptr %t10) + call void @fn_emit(ptr @.str1668) + %t11 = load ptr, ptr %t7 + call void @fn_emit(ptr %t11) + call void @fn_emit(ptr @.str1669) + %t12 = load ptr, ptr %t0 + %t13 = getelementptr inbounds %Cmp_Node, ptr %t12, i32 0, i32 1 + %t14 = load ptr, ptr %t13 + call void @fn_emit(ptr %t14) + call void @fn_emit(ptr @.str1670) + %t15 = load ptr, ptr %t5 + %t16 = getelementptr inbounds %Cmp_Val, ptr %t15, i32 0, i32 0 + %t17 = load ptr, ptr %t16 + call void @fn_emit(ptr %t17) + call void @fn_emit(ptr @.str1671) + %t18 = load ptr, ptr %t9 + %t19 = call ptr @fn_str_concat(ptr @.str1672, ptr %t18) + %t20 = call ptr @fn_emit_bind(ptr %t19) + store ptr %t20, ptr %t21 + %t22 = load ptr, ptr %t21 + %t23 = call ptr @fn_str_concat(ptr @.str1673, ptr %t22) + %t24 = call ptr @fn_str_concat(ptr %t23, ptr @.str1674) + %t25 = call ptr @fn_emit_bind(ptr %t24) + store ptr %t25, ptr %t26 + %t27 = call ptr @fn_lbl(ptr @.str1675) + store ptr %t27, ptr %t28 + %t29 = call ptr @fn_lbl(ptr @.str1676) + store ptr %t29, ptr %t30 + call void @fn_emit(ptr @.str1677) + %t31 = load ptr, ptr %t26 + call void @fn_emit(ptr %t31) + call void @fn_emit(ptr @.str1678) + %t32 = load ptr, ptr %t28 + call void @fn_emit(ptr %t32) + call void @fn_emit(ptr @.str1679) + %t33 = load ptr, ptr %t30 + call void @fn_emit(ptr %t33) + call void @fn_emit(ptr @.str1680) + %t34 = load ptr, ptr %t28 + call void @fn_emit(ptr %t34) + call void @fn_emit(ptr @.str1681) + store i32 0, ptr @g_g_term + call void @fn_emit(ptr @.str1682) + %t35 = load ptr, ptr %t9 + call void @fn_emit(ptr %t35) + call void @fn_emit(ptr @.str1683) + %t36 = load ptr, ptr %t0 + %t37 = getelementptr inbounds %Cmp_Node, ptr %t36, i32 0, i32 1 + %t38 = load ptr, ptr %t37 + %t39 = call ptr @fn_ondetach_body(ptr %t38) + store ptr %t39, ptr %t40 + %t41 = load ptr, ptr %t40 + %t42 = icmp ne ptr %t41, null + %t43 = zext i1 %t42 to i32 + %t44 = icmp ne i32 %t43, 0 + br i1 %t44, label %then0, label %ifend2 +then0: + %t45 = load i32, ptr @g_nloc + store i32 %t45, ptr %t46 + %t47 = call ptr @fn_nreg() + store ptr %t47, ptr %t48 + call void @fn_emit(ptr @.str1684) + %t49 = load ptr, ptr %t48 + call void @fn_emit(ptr %t49) + call void @fn_emit(ptr @.str1685) + %t50 = load ptr, ptr %t7 + call void @fn_emit(ptr %t50) + call void @fn_emit(ptr @.str1686) + %t51 = load ptr, ptr %t0 + %t52 = getelementptr inbounds %Cmp_Node, ptr %t51, i32 0, i32 1 + %t53 = load ptr, ptr %t52 + call void @fn_emit(ptr %t53) + call void @fn_emit(ptr @.str1687) + %t54 = load ptr, ptr %t0 + %t55 = getelementptr inbounds %Cmp_Node, ptr %t54, i32 0, i32 1 + %t56 = load ptr, ptr %t55 + call void @fn_emit(ptr %t56) + call void @fn_emit(ptr @.str1688) + %t57 = load ptr, ptr %t5 + %t58 = getelementptr inbounds %Cmp_Val, ptr %t57, i32 0, i32 0 + %t59 = load ptr, ptr %t58 + call void @fn_emit(ptr %t59) + call void @fn_emit(ptr @.str1689) + %t60 = call ptr @fn_emit_alloca(ptr @.str1690) + store ptr %t60, ptr %t61 + call void @fn_emit(ptr @.str1691) + %t62 = load ptr, ptr %t48 + call void @fn_emit(ptr %t62) + call void @fn_emit(ptr @.str1692) + %t63 = load ptr, ptr %t61 + call void @fn_emit(ptr %t63) + call void @fn_emit(ptr @.str1693) + %t64 = load ptr, ptr %t0 + %t65 = getelementptr inbounds %Cmp_Node, ptr %t64, i32 0, i32 1 + %t66 = load ptr, ptr %t65 + %t67 = load ptr, ptr %t61 + %t68 = load ptr, ptr %t0 + %t69 = getelementptr inbounds %Cmp_Node, ptr %t68, i32 0, i32 1 + %t70 = load ptr, ptr %t69 + call void @fn_loc_push(ptr %t66, ptr %t67, ptr %t70) + %t71 = load ptr, ptr %t40 + call void @fn_emit_block(ptr %t71) + %t72 = load i32, ptr %t46 + store i32 %t72, ptr @g_nloc + br label %ifend2 +ifend2: + %t73 = load ptr, ptr %t0 + %t74 = getelementptr inbounds %Cmp_Node, ptr %t73, i32 0, i32 1 + %t75 = load ptr, ptr %t74 + %t76 = call ptr @fn_str_concat(ptr @.str1694, ptr %t75) + %t77 = call ptr @fn_str_concat(ptr %t76, ptr @.str1695) + store ptr %t77, ptr %t78 + %t79 = load ptr, ptr %t78 + %t80 = call ptr @fn_find_event(ptr %t79) + %t81 = icmp ne ptr %t80, null + %t82 = zext i1 %t81 to i32 + %t83 = icmp ne i32 %t82, 0 + br i1 %t83, label %then3, label %ifend5 +then3: + call void @fn_emit(ptr @.str1696) + %t84 = load ptr, ptr %t78 + call void @fn_emit(ptr %t84) + call void @fn_emit(ptr @.str1697) + %t85 = load ptr, ptr %t5 + %t86 = getelementptr inbounds %Cmp_Val, ptr %t85, i32 0, i32 0 + %t87 = load ptr, ptr %t86 + call void @fn_emit(ptr %t87) + call void @fn_emit(ptr @.str1698) + br label %ifend5 +ifend5: + %t88 = load i32, ptr @g_g_term + %t89 = icmp eq i32 %t88, 0 + %t90 = zext i1 %t89 to i32 + %t91 = icmp ne i32 %t90, 0 + br i1 %t91, label %then6, label %ifend8 +then6: + call void @fn_emit(ptr @.str1699) + %t92 = load ptr, ptr %t30 + call void @fn_emit(ptr %t92) + call void @fn_emit(ptr @.str1700) + br label %ifend8 +ifend8: + %t93 = load ptr, ptr %t30 + call void @fn_emit(ptr %t93) + call void @fn_emit(ptr @.str1701) + store i32 0, ptr @g_g_term br label %ret ret: ret void @@ -18818,16 +24178,19 @@ define void @fn_emit_toggle(ptr %arg_st) { entry: %t0 = alloca ptr %t1 = alloca ptr - %t18 = alloca ptr - %t20 = alloca ptr - %t22 = alloca ptr + %t8 = alloca i32 %t33 = alloca ptr - %t53 = alloca i32 - %t55 = alloca ptr - %t68 = alloca ptr - %t80 = alloca ptr + %t61 = alloca ptr + %t63 = alloca ptr + %t65 = alloca ptr + %t76 = alloca ptr + %t96 = alloca i32 + %t98 = alloca ptr + %t111 = alloca ptr + %t128 = alloca ptr + %t149 = alloca ptr store ptr %arg_st, ptr %t0 - store ptr @.str1308, ptr %t1 + store ptr @.str1702, ptr %t1 %t2 = load ptr, ptr %t0 %t3 = getelementptr inbounds %Cmp_Node, ptr %t2, i32 0, i32 2 %t4 = load i32, ptr %t3 @@ -18836,154 +24199,263 @@ entry: %t7 = icmp ne i32 %t6, 0 br i1 %t7, label %then0, label %ifend2 then0: - store ptr @.str1309, ptr %t1 + store ptr @.str1703, ptr %t1 br label %ifend2 ifend2: - %t8 = load ptr, ptr %t0 - %t9 = getelementptr inbounds %Cmp_Node, ptr %t8, i32 0, i32 4 - %t10 = load ptr, ptr %t9 - %t11 = icmp ne ptr %t10, null - %t12 = zext i1 %t11 to i32 - %t13 = icmp ne i32 %t12, 0 - br i1 %t13, label %then3, label %else4 -then3: - %t14 = load ptr, ptr %t0 - %t15 = getelementptr inbounds %Cmp_Node, ptr %t14, i32 0, i32 4 - %t16 = load ptr, ptr %t15 - %t17 = call ptr @fn_emit_expr(ptr %t16) - store ptr %t17, ptr %t18 - %t19 = call ptr @fn_itoa(i32 1024) - store ptr %t19, ptr %t20 - %t21 = call ptr @fn_nreg() - store ptr %t21, ptr %t22 - call void @fn_emit(ptr @.str1310) - %t23 = load ptr, ptr %t22 - call void @fn_emit(ptr %t23) - call void @fn_emit(ptr @.str1311) - %t24 = load ptr, ptr %t20 + %t9 = load ptr, ptr %t0 + %t10 = getelementptr inbounds %Cmp_Node, ptr %t9, i32 0, i32 3 + %t11 = load ptr, ptr %t10 + %t12 = icmp ne ptr %t11, null + %t13 = zext i1 %t12 to i32 + %t14 = icmp ne i32 %t13, 0 + %t15 = zext i1 %t14 to i32 + store i32 %t15, ptr %t8 + br i1 %t14, label %sc3, label %scend4 +sc3: + %t16 = load ptr, ptr %t0 + %t17 = getelementptr inbounds %Cmp_Node, ptr %t16, i32 0, i32 3 + %t18 = load ptr, ptr %t17 + %t19 = call i32 @fn_str_eq(ptr %t18, ptr @.str1704) + %t20 = icmp ne i32 %t19, 0 + %t21 = zext i1 %t20 to i32 + store i32 %t21, ptr %t8 + br label %scend4 +scend4: + %t22 = load i32, ptr %t8 + %t23 = icmp ne i32 %t22, 0 + br i1 %t23, label %then5, label %ifend7 +then5: + call void @fn_emit(ptr @.str1705) + %t24 = load ptr, ptr %t1 call void @fn_emit(ptr %t24) - call void @fn_emit(ptr @.str1312) + call void @fn_emit(ptr @.str1706) %t25 = load ptr, ptr %t0 %t26 = getelementptr inbounds %Cmp_Node, ptr %t25, i32 0, i32 1 %t27 = load ptr, ptr %t26 call void @fn_emit(ptr %t27) - call void @fn_emit(ptr @.str1313) - %t28 = load ptr, ptr %t18 - %t29 = getelementptr inbounds %Cmp_Val, ptr %t28, i32 0, i32 0 + call void @fn_emit(ptr @.str1707) + %t28 = load ptr, ptr %t0 + %t29 = getelementptr inbounds %Cmp_Node, ptr %t28, i32 0, i32 1 %t30 = load ptr, ptr %t29 - call void @fn_emit(ptr %t30) - call void @fn_emit(ptr @.str1314) - call void @fn_emit(ptr @.str1315) - %t31 = load ptr, ptr %t1 - call void @fn_emit(ptr %t31) - call void @fn_emit(ptr @.str1316) - %t32 = load ptr, ptr %t22 - call void @fn_emit(ptr %t32) - call void @fn_emit(ptr @.str1317) - store ptr null, ptr %t33 + %t31 = call ptr @fn_str_concat(ptr @.str1708, ptr %t30) + %t32 = call ptr @fn_str_concat(ptr %t31, ptr @.str1709) + store ptr %t32, ptr %t33 %t34 = load ptr, ptr %t0 %t35 = getelementptr inbounds %Cmp_Node, ptr %t34, i32 0, i32 2 %t36 = load i32, ptr %t35 %t37 = icmp eq i32 %t36, 1 %t38 = zext i1 %t37 to i32 %t39 = icmp ne i32 %t38, 0 - br i1 %t39, label %then6, label %else7 -then6: + br i1 %t39, label %then8, label %ifend10 +then8: %t40 = load ptr, ptr %t0 %t41 = getelementptr inbounds %Cmp_Node, ptr %t40, i32 0, i32 1 %t42 = load ptr, ptr %t41 - %t43 = call ptr @fn_onenable_body(ptr %t42) - store ptr %t43, ptr %t33 - br label %ifend8 -else7: - %t44 = load ptr, ptr %t0 - %t45 = getelementptr inbounds %Cmp_Node, ptr %t44, i32 0, i32 1 - %t46 = load ptr, ptr %t45 - %t47 = call ptr @fn_ondisable_body(ptr %t46) - store ptr %t47, ptr %t33 - br label %ifend8 -ifend8: - %t48 = load ptr, ptr %t33 - %t49 = icmp ne ptr %t48, null - %t50 = zext i1 %t49 to i32 - %t51 = icmp ne i32 %t50, 0 - br i1 %t51, label %then9, label %ifend11 -then9: - %t52 = load i32, ptr @g_nloc - store i32 %t52, ptr %t53 - %t54 = call ptr @fn_nreg() - store ptr %t54, ptr %t55 - call void @fn_emit(ptr @.str1318) - %t56 = load ptr, ptr %t55 - call void @fn_emit(ptr %t56) - call void @fn_emit(ptr @.str1319) - %t57 = load ptr, ptr %t20 - call void @fn_emit(ptr %t57) - call void @fn_emit(ptr @.str1320) - %t58 = load ptr, ptr %t0 - %t59 = getelementptr inbounds %Cmp_Node, ptr %t58, i32 0, i32 1 - %t60 = load ptr, ptr %t59 - call void @fn_emit(ptr %t60) - call void @fn_emit(ptr @.str1321) - %t61 = load ptr, ptr %t0 - %t62 = getelementptr inbounds %Cmp_Node, ptr %t61, i32 0, i32 1 - %t63 = load ptr, ptr %t62 - call void @fn_emit(ptr %t63) - call void @fn_emit(ptr @.str1322) - %t64 = load ptr, ptr %t18 - %t65 = getelementptr inbounds %Cmp_Val, ptr %t64, i32 0, i32 0 + %t43 = call ptr @fn_str_concat(ptr @.str1710, ptr %t42) + %t44 = call ptr @fn_str_concat(ptr %t43, ptr @.str1711) + store ptr %t44, ptr %t33 + br label %ifend10 +ifend10: + %t45 = load ptr, ptr %t33 + %t46 = call ptr @fn_find_event(ptr %t45) + %t47 = icmp ne ptr %t46, null + %t48 = zext i1 %t47 to i32 + %t49 = icmp ne i32 %t48, 0 + br i1 %t49, label %then11, label %ifend13 +then11: + call void @fn_emit(ptr @.str1712) + %t50 = load ptr, ptr %t33 + call void @fn_emit(ptr %t50) + call void @fn_emit(ptr @.str1713) + br label %ifend13 +ifend13: + br label %ret +ifend7: + %t51 = load ptr, ptr %t0 + %t52 = getelementptr inbounds %Cmp_Node, ptr %t51, i32 0, i32 4 + %t53 = load ptr, ptr %t52 + %t54 = icmp ne ptr %t53, null + %t55 = zext i1 %t54 to i32 + %t56 = icmp ne i32 %t55, 0 + br i1 %t56, label %then14, label %else15 +then14: + %t57 = load ptr, ptr %t0 + %t58 = getelementptr inbounds %Cmp_Node, ptr %t57, i32 0, i32 4 + %t59 = load ptr, ptr %t58 + %t60 = call ptr @fn_emit_expr(ptr %t59) + store ptr %t60, ptr %t61 + %t62 = call ptr @fn_itoa(i32 1024) + store ptr %t62, ptr %t63 + %t64 = call ptr @fn_nreg() + store ptr %t64, ptr %t65 + call void @fn_emit(ptr @.str1714) %t66 = load ptr, ptr %t65 call void @fn_emit(ptr %t66) - call void @fn_emit(ptr @.str1323) - %t67 = call ptr @fn_emit_alloca(ptr @.str1324) - store ptr %t67, ptr %t68 - call void @fn_emit(ptr @.str1325) - %t69 = load ptr, ptr %t55 - call void @fn_emit(ptr %t69) - call void @fn_emit(ptr @.str1326) - %t70 = load ptr, ptr %t68 + call void @fn_emit(ptr @.str1715) + %t67 = load ptr, ptr %t63 + call void @fn_emit(ptr %t67) + call void @fn_emit(ptr @.str1716) + %t68 = load ptr, ptr %t0 + %t69 = getelementptr inbounds %Cmp_Node, ptr %t68, i32 0, i32 1 + %t70 = load ptr, ptr %t69 call void @fn_emit(ptr %t70) - call void @fn_emit(ptr @.str1327) - %t71 = load ptr, ptr %t0 - %t72 = getelementptr inbounds %Cmp_Node, ptr %t71, i32 0, i32 1 + call void @fn_emit(ptr @.str1717) + %t71 = load ptr, ptr %t61 + %t72 = getelementptr inbounds %Cmp_Val, ptr %t71, i32 0, i32 0 %t73 = load ptr, ptr %t72 - %t74 = load ptr, ptr %t68 - %t75 = load ptr, ptr %t0 - %t76 = getelementptr inbounds %Cmp_Node, ptr %t75, i32 0, i32 1 - %t77 = load ptr, ptr %t76 - call void @fn_loc_push(ptr %t73, ptr %t74, ptr %t77) - %t78 = load ptr, ptr %t33 - call void @fn_emit_block(ptr %t78) - %t79 = load i32, ptr %t53 - store i32 %t79, ptr @g_nloc - br label %ifend11 -ifend11: - br label %ifend5 -else4: - store ptr @.str1328, ptr %t80 - %t81 = load ptr, ptr %t0 - %t82 = getelementptr inbounds %Cmp_Node, ptr %t81, i32 0, i32 1 - %t83 = load ptr, ptr %t82 - %t84 = call i32 @fn_is_model(ptr %t83) - %t85 = icmp ne i32 %t84, 0 - br i1 %t85, label %then12, label %ifend14 -then12: - store ptr @.str1329, ptr %t80 - br label %ifend14 -ifend14: - call void @fn_emit(ptr @.str1330) - %t86 = load ptr, ptr %t1 - call void @fn_emit(ptr %t86) - call void @fn_emit(ptr @.str1331) - %t87 = load ptr, ptr %t80 - call void @fn_emit(ptr %t87) - %t88 = load ptr, ptr %t0 - %t89 = getelementptr inbounds %Cmp_Node, ptr %t88, i32 0, i32 1 - %t90 = load ptr, ptr %t89 - call void @fn_emit(ptr %t90) - call void @fn_emit(ptr @.str1332) - br label %ifend5 -ifend5: + call void @fn_emit(ptr %t73) + call void @fn_emit(ptr @.str1718) + call void @fn_emit(ptr @.str1719) + %t74 = load ptr, ptr %t1 + call void @fn_emit(ptr %t74) + call void @fn_emit(ptr @.str1720) + %t75 = load ptr, ptr %t65 + call void @fn_emit(ptr %t75) + call void @fn_emit(ptr @.str1721) + store ptr null, ptr %t76 + %t77 = load ptr, ptr %t0 + %t78 = getelementptr inbounds %Cmp_Node, ptr %t77, i32 0, i32 2 + %t79 = load i32, ptr %t78 + %t80 = icmp eq i32 %t79, 1 + %t81 = zext i1 %t80 to i32 + %t82 = icmp ne i32 %t81, 0 + br i1 %t82, label %then17, label %else18 +then17: + %t83 = load ptr, ptr %t0 + %t84 = getelementptr inbounds %Cmp_Node, ptr %t83, i32 0, i32 1 + %t85 = load ptr, ptr %t84 + %t86 = call ptr @fn_onenable_body(ptr %t85) + store ptr %t86, ptr %t76 + br label %ifend19 +else18: + %t87 = load ptr, ptr %t0 + %t88 = getelementptr inbounds %Cmp_Node, ptr %t87, i32 0, i32 1 + %t89 = load ptr, ptr %t88 + %t90 = call ptr @fn_ondisable_body(ptr %t89) + store ptr %t90, ptr %t76 + br label %ifend19 +ifend19: + %t91 = load ptr, ptr %t76 + %t92 = icmp ne ptr %t91, null + %t93 = zext i1 %t92 to i32 + %t94 = icmp ne i32 %t93, 0 + br i1 %t94, label %then20, label %ifend22 +then20: + %t95 = load i32, ptr @g_nloc + store i32 %t95, ptr %t96 + %t97 = call ptr @fn_nreg() + store ptr %t97, ptr %t98 + call void @fn_emit(ptr @.str1722) + %t99 = load ptr, ptr %t98 + call void @fn_emit(ptr %t99) + call void @fn_emit(ptr @.str1723) + %t100 = load ptr, ptr %t63 + call void @fn_emit(ptr %t100) + call void @fn_emit(ptr @.str1724) + %t101 = load ptr, ptr %t0 + %t102 = getelementptr inbounds %Cmp_Node, ptr %t101, i32 0, i32 1 + %t103 = load ptr, ptr %t102 + call void @fn_emit(ptr %t103) + call void @fn_emit(ptr @.str1725) + %t104 = load ptr, ptr %t0 + %t105 = getelementptr inbounds %Cmp_Node, ptr %t104, i32 0, i32 1 + %t106 = load ptr, ptr %t105 + call void @fn_emit(ptr %t106) + call void @fn_emit(ptr @.str1726) + %t107 = load ptr, ptr %t61 + %t108 = getelementptr inbounds %Cmp_Val, ptr %t107, i32 0, i32 0 + %t109 = load ptr, ptr %t108 + call void @fn_emit(ptr %t109) + call void @fn_emit(ptr @.str1727) + %t110 = call ptr @fn_emit_alloca(ptr @.str1728) + store ptr %t110, ptr %t111 + call void @fn_emit(ptr @.str1729) + %t112 = load ptr, ptr %t98 + call void @fn_emit(ptr %t112) + call void @fn_emit(ptr @.str1730) + %t113 = load ptr, ptr %t111 + call void @fn_emit(ptr %t113) + call void @fn_emit(ptr @.str1731) + %t114 = load ptr, ptr %t0 + %t115 = getelementptr inbounds %Cmp_Node, ptr %t114, i32 0, i32 1 + %t116 = load ptr, ptr %t115 + %t117 = load ptr, ptr %t111 + %t118 = load ptr, ptr %t0 + %t119 = getelementptr inbounds %Cmp_Node, ptr %t118, i32 0, i32 1 + %t120 = load ptr, ptr %t119 + call void @fn_loc_push(ptr %t116, ptr %t117, ptr %t120) + %t121 = load ptr, ptr %t76 + call void @fn_emit_block(ptr %t121) + %t122 = load i32, ptr %t96 + store i32 %t122, ptr @g_nloc + br label %ifend22 +ifend22: + %t123 = load ptr, ptr %t0 + %t124 = getelementptr inbounds %Cmp_Node, ptr %t123, i32 0, i32 1 + %t125 = load ptr, ptr %t124 + %t126 = call ptr @fn_str_concat(ptr @.str1732, ptr %t125) + %t127 = call ptr @fn_str_concat(ptr %t126, ptr @.str1733) + store ptr %t127, ptr %t128 + %t129 = load ptr, ptr %t0 + %t130 = getelementptr inbounds %Cmp_Node, ptr %t129, i32 0, i32 2 + %t131 = load i32, ptr %t130 + %t132 = icmp eq i32 %t131, 1 + %t133 = zext i1 %t132 to i32 + %t134 = icmp ne i32 %t133, 0 + br i1 %t134, label %then23, label %ifend25 +then23: + %t135 = load ptr, ptr %t0 + %t136 = getelementptr inbounds %Cmp_Node, ptr %t135, i32 0, i32 1 + %t137 = load ptr, ptr %t136 + %t138 = call ptr @fn_str_concat(ptr @.str1734, ptr %t137) + %t139 = call ptr @fn_str_concat(ptr %t138, ptr @.str1735) + store ptr %t139, ptr %t128 + br label %ifend25 +ifend25: + %t140 = load ptr, ptr %t128 + %t141 = call ptr @fn_find_event(ptr %t140) + %t142 = icmp ne ptr %t141, null + %t143 = zext i1 %t142 to i32 + %t144 = icmp ne i32 %t143, 0 + br i1 %t144, label %then26, label %ifend28 +then26: + call void @fn_emit(ptr @.str1736) + %t145 = load ptr, ptr %t128 + call void @fn_emit(ptr %t145) + call void @fn_emit(ptr @.str1737) + %t146 = load ptr, ptr %t61 + %t147 = getelementptr inbounds %Cmp_Val, ptr %t146, i32 0, i32 0 + %t148 = load ptr, ptr %t147 + call void @fn_emit(ptr %t148) + call void @fn_emit(ptr @.str1738) + br label %ifend28 +ifend28: + br label %ifend16 +else15: + store ptr @.str1739, ptr %t149 + %t150 = load ptr, ptr %t0 + %t151 = getelementptr inbounds %Cmp_Node, ptr %t150, i32 0, i32 1 + %t152 = load ptr, ptr %t151 + %t153 = call i32 @fn_is_model(ptr %t152) + %t154 = icmp ne i32 %t153, 0 + br i1 %t154, label %then29, label %ifend31 +then29: + store ptr @.str1740, ptr %t149 + br label %ifend31 +ifend31: + call void @fn_emit(ptr @.str1741) + %t155 = load ptr, ptr %t1 + call void @fn_emit(ptr %t155) + call void @fn_emit(ptr @.str1742) + %t156 = load ptr, ptr %t149 + call void @fn_emit(ptr %t156) + %t157 = load ptr, ptr %t0 + %t158 = getelementptr inbounds %Cmp_Node, ptr %t157, i32 0, i32 1 + %t159 = load ptr, ptr %t158 + call void @fn_emit(ptr %t159) + call void @fn_emit(ptr @.str1743) + br label %ifend16 +ifend16: br label %ret ret: ret void @@ -18992,53 +24464,186 @@ ret: define void @fn_emit_system_fn(ptr %arg_sys) { entry: %t0 = alloca ptr - %t2 = alloca ptr %t5 = alloca ptr + %t8 = alloca ptr store ptr %arg_sys, ptr %t0 + %t1 = load ptr, ptr %t0 + %t2 = getelementptr inbounds %Cmp_Node, ptr %t1, i32 0, i32 6 + %t3 = load ptr, ptr %t2 + store ptr %t3, ptr @g_g_cur_scene store i32 0, ptr @g_ll_t store i32 0, ptr @g_ll_lbl store i32 0, ptr @g_g_term call void @fn_loc_reset() store i32 0, ptr @g_nloop store i32 0, ptr @g_nself - store ptr @.str1333, ptr @g_ret_ty - %t1 = call ptr @fn_buf_new() - store ptr %t1, ptr %t2 - %t3 = call ptr @fn_buf_new() - store ptr %t3, ptr @g_falloc - %t4 = load ptr, ptr @g_code + store ptr @.str1744, ptr @g_ret_ty + %t4 = call ptr @fn_buf_new() store ptr %t4, ptr %t5 - %t6 = load ptr, ptr %t2 - store ptr %t6, ptr @g_code - %t7 = load ptr, ptr %t0 - %t8 = getelementptr inbounds %Cmp_Node, ptr %t7, i32 0, i32 4 - %t9 = load ptr, ptr %t8 - call void @fn_emit_block(ptr %t9) - %t10 = load i32, ptr @g_g_term - %t11 = icmp eq i32 %t10, 0 - %t12 = zext i1 %t11 to i32 - %t13 = icmp ne i32 %t12, 0 - br i1 %t13, label %then0, label %ifend2 + %t6 = call ptr @fn_buf_new() + store ptr %t6, ptr @g_falloc + %t7 = load ptr, ptr @g_code + store ptr %t7, ptr %t8 + %t9 = load ptr, ptr %t5 + store ptr %t9, ptr @g_code + %t10 = load ptr, ptr %t0 + %t11 = getelementptr inbounds %Cmp_Node, ptr %t10, i32 0, i32 4 + %t12 = load ptr, ptr %t11 + call void @fn_emit_block(ptr %t12) + %t13 = load i32, ptr @g_g_term + %t14 = icmp eq i32 %t13, 0 + %t15 = zext i1 %t14 to i32 + %t16 = icmp ne i32 %t15, 0 + br i1 %t16, label %then0, label %ifend2 then0: - call void @fn_emit(ptr @.str1334) + call void @fn_emit(ptr @.str1745) br label %ifend2 ifend2: - call void @fn_emit(ptr @.str1335) - %t14 = load ptr, ptr %t5 - store ptr %t14, ptr @g_code - call void @fn_emit(ptr @.str1336) - %t15 = load ptr, ptr %t0 - %t16 = getelementptr inbounds %Cmp_Node, ptr %t15, i32 0, i32 1 - %t17 = load ptr, ptr %t16 - call void @fn_emit(ptr %t17) - call void @fn_emit(ptr @.str1337) - %t18 = load ptr, ptr @g_falloc - %t19 = call ptr @fn_buf_str(ptr %t18) - call void @fn_emit(ptr %t19) - %t20 = load ptr, ptr %t2 - %t21 = call ptr @fn_buf_str(ptr %t20) - call void @fn_emit(ptr %t21) - call void @fn_emit(ptr @.str1338) + call void @fn_emit(ptr @.str1746) + %t17 = load ptr, ptr %t8 + store ptr %t17, ptr @g_code + call void @fn_emit(ptr @.str1747) + %t18 = load ptr, ptr %t0 + %t19 = getelementptr inbounds %Cmp_Node, ptr %t18, i32 0, i32 1 + %t20 = load ptr, ptr %t19 + call void @fn_emit(ptr %t20) + call void @fn_emit(ptr @.str1748) + %t21 = load ptr, ptr @g_falloc + %t22 = call ptr @fn_buf_str(ptr %t21) + call void @fn_emit(ptr %t22) + %t23 = load ptr, ptr %t5 + %t24 = call ptr @fn_buf_str(ptr %t23) + call void @fn_emit(ptr %t24) + call void @fn_emit(ptr @.str1749) + br label %ret +ret: + ret void +} + +define void @fn_emit_call_one(ptr %arg_d) { +entry: + %t0 = alloca ptr + %t6 = alloca ptr + %t11 = alloca ptr + %t12 = alloca i32 + %t37 = alloca ptr + %t42 = alloca ptr + %t56 = alloca ptr + %t61 = alloca ptr + %t69 = alloca ptr + %t71 = alloca ptr + store ptr %arg_d, ptr %t0 + %t1 = load ptr, ptr %t0 + %t2 = getelementptr inbounds %Cmp_Node, ptr %t1, i32 0, i32 1 + %t3 = load ptr, ptr %t2 + %t4 = call ptr @fn_str_concat(ptr @.str1750, ptr %t3) + %t5 = call ptr @fn_emit_bind(ptr %t4) + store ptr %t5, ptr %t6 + %t7 = load ptr, ptr %t6 + %t8 = call ptr @fn_str_concat(ptr @.str1751, ptr %t7) + %t9 = call ptr @fn_str_concat(ptr %t8, ptr @.str1752) + %t10 = call ptr @fn_emit_bind(ptr %t9) + store ptr %t10, ptr %t11 + %t13 = load ptr, ptr %t0 + %t14 = getelementptr inbounds %Cmp_Node, ptr %t13, i32 0, i32 5 + %t15 = load ptr, ptr %t14 + %t16 = icmp ne ptr %t15, null + %t17 = zext i1 %t16 to i32 + %t18 = icmp ne i32 %t17, 0 + %t19 = zext i1 %t18 to i32 + store i32 %t19, ptr %t12 + br i1 %t18, label %sc0, label %scend1 +sc0: + %t20 = load ptr, ptr %t0 + %t21 = getelementptr inbounds %Cmp_Node, ptr %t20, i32 0, i32 5 + %t22 = load ptr, ptr %t21 + %t23 = getelementptr inbounds %Cmp_Node, ptr %t22, i32 0, i32 1 + %t24 = load ptr, ptr %t23 + %t25 = call i32 @fn_is_toggled_layer(ptr %t24) + %t26 = icmp ne i32 %t25, 0 + %t27 = zext i1 %t26 to i32 + store i32 %t27, ptr %t12 + br label %scend1 +scend1: + %t28 = load i32, ptr %t12 + %t29 = icmp ne i32 %t28, 0 + br i1 %t29, label %then2, label %ifend4 +then2: + %t30 = load ptr, ptr %t0 + %t31 = getelementptr inbounds %Cmp_Node, ptr %t30, i32 0, i32 5 + %t32 = load ptr, ptr %t31 + %t33 = getelementptr inbounds %Cmp_Node, ptr %t32, i32 0, i32 1 + %t34 = load ptr, ptr %t33 + %t35 = call ptr @fn_str_concat(ptr @.str1753, ptr %t34) + %t36 = call ptr @fn_emit_bind(ptr %t35) + store ptr %t36, ptr %t37 + %t38 = load ptr, ptr %t37 + %t39 = call ptr @fn_str_concat(ptr @.str1754, ptr %t38) + %t40 = call ptr @fn_str_concat(ptr %t39, ptr @.str1755) + %t41 = call ptr @fn_emit_bind(ptr %t40) + store ptr %t41, ptr %t42 + %t43 = load ptr, ptr %t11 + %t44 = call ptr @fn_str_concat(ptr @.str1756, ptr %t43) + %t45 = call ptr @fn_str_concat(ptr %t44, ptr @.str1757) + %t46 = load ptr, ptr %t42 + %t47 = call ptr @fn_str_concat(ptr %t45, ptr %t46) + %t48 = call ptr @fn_emit_bind(ptr %t47) + store ptr %t48, ptr %t11 + br label %ifend4 +ifend4: + %t49 = load ptr, ptr %t0 + %t50 = getelementptr inbounds %Cmp_Node, ptr %t49, i32 0, i32 2 + %t51 = load i32, ptr %t50 + %t52 = icmp eq i32 %t51, 1 + %t53 = zext i1 %t52 to i32 + %t54 = icmp ne i32 %t53, 0 + br i1 %t54, label %then5, label %ifend7 +then5: + %t55 = call ptr @fn_emit_bind(ptr @.str1758) + store ptr %t55, ptr %t56 + %t57 = load ptr, ptr %t56 + %t58 = call ptr @fn_str_concat(ptr @.str1759, ptr %t57) + %t59 = call ptr @fn_str_concat(ptr %t58, ptr @.str1760) + %t60 = call ptr @fn_emit_bind(ptr %t59) + store ptr %t60, ptr %t61 + %t62 = load ptr, ptr %t11 + %t63 = call ptr @fn_str_concat(ptr @.str1761, ptr %t62) + %t64 = call ptr @fn_str_concat(ptr %t63, ptr @.str1762) + %t65 = load ptr, ptr %t61 + %t66 = call ptr @fn_str_concat(ptr %t64, ptr %t65) + %t67 = call ptr @fn_emit_bind(ptr %t66) + store ptr %t67, ptr %t11 + br label %ifend7 +ifend7: + %t68 = call ptr @fn_lbl(ptr @.str1763) + store ptr %t68, ptr %t69 + %t70 = call ptr @fn_lbl(ptr @.str1764) + store ptr %t70, ptr %t71 + call void @fn_emit(ptr @.str1765) + %t72 = load ptr, ptr %t11 + call void @fn_emit(ptr %t72) + call void @fn_emit(ptr @.str1766) + %t73 = load ptr, ptr %t69 + call void @fn_emit(ptr %t73) + call void @fn_emit(ptr @.str1767) + %t74 = load ptr, ptr %t71 + call void @fn_emit(ptr %t74) + call void @fn_emit(ptr @.str1768) + %t75 = load ptr, ptr %t69 + call void @fn_emit(ptr %t75) + call void @fn_emit(ptr @.str1769) + %t76 = load ptr, ptr %t0 + %t77 = getelementptr inbounds %Cmp_Node, ptr %t76, i32 0, i32 1 + %t78 = load ptr, ptr %t77 + call void @fn_emit(ptr %t78) + call void @fn_emit(ptr @.str1770) + call void @fn_emit(ptr @.str1771) + %t79 = load ptr, ptr %t71 + call void @fn_emit(ptr %t79) + call void @fn_emit(ptr @.str1772) + %t80 = load ptr, ptr %t71 + call void @fn_emit(ptr %t80) + call void @fn_emit(ptr @.str1773) br label %ret ret: ret void @@ -19050,10 +24655,18 @@ entry: %t1 = alloca i32 %t15 = alloca ptr %t16 = alloca i32 - %t38 = alloca ptr - %t43 = alloca ptr - %t45 = alloca ptr - %t47 = alloca ptr + %t17 = alloca i32 + %t47 = alloca i32 + %t61 = alloca ptr + %t62 = alloca i32 + %t63 = alloca i32 + %t97 = alloca ptr + %t111 = alloca ptr + %t112 = alloca i32 + %t113 = alloca i32 + %t151 = alloca ptr + %t153 = alloca ptr + %t155 = alloca ptr store ptr %arg_phase, ptr %t0 store i32 0, ptr %t1 br label %wcond0 @@ -19074,75 +24687,385 @@ wbody1: %t13 = getelementptr inbounds ptr, ptr %t11, i32 %t12 %t14 = load ptr, ptr %t13 store ptr %t14, ptr %t15 - %t17 = load ptr, ptr %t15 - %t18 = getelementptr inbounds %Cmp_Node, ptr %t17, i32 0, i32 0 - %t19 = load i32, ptr %t18 - %t20 = icmp eq i32 %t19, 9 - %t21 = zext i1 %t20 to i32 - %t22 = icmp ne i32 %t21, 0 - %t23 = zext i1 %t22 to i32 - store i32 %t23, ptr %t16 - br i1 %t22, label %sc3, label %scend4 + %t18 = load ptr, ptr %t15 + %t19 = getelementptr inbounds %Cmp_Node, ptr %t18, i32 0, i32 0 + %t20 = load i32, ptr %t19 + %t21 = icmp eq i32 %t20, 9 + %t22 = zext i1 %t21 to i32 + %t23 = icmp ne i32 %t22, 0 + %t24 = zext i1 %t23 to i32 + store i32 %t24, ptr %t17 + br i1 %t23, label %sc3, label %scend4 sc3: - %t24 = load ptr, ptr %t15 - %t25 = getelementptr inbounds %Cmp_Node, ptr %t24, i32 0, i32 3 - %t26 = load ptr, ptr %t25 - %t27 = load ptr, ptr %t0 - %t28 = call i32 @fn_str_eq(ptr %t26, ptr %t27) - %t29 = icmp ne i32 %t28, 0 - %t30 = zext i1 %t29 to i32 - store i32 %t30, ptr %t16 + %t25 = load ptr, ptr %t15 + %t26 = getelementptr inbounds %Cmp_Node, ptr %t25, i32 0, i32 3 + %t27 = load ptr, ptr %t26 + %t28 = load ptr, ptr %t0 + %t29 = call i32 @fn_str_eq(ptr %t27, ptr %t28) + %t30 = icmp ne i32 %t29, 0 + %t31 = zext i1 %t30 to i32 + store i32 %t31, ptr %t17 br label %scend4 scend4: - %t31 = load i32, ptr %t16 - %t32 = icmp ne i32 %t31, 0 - br i1 %t32, label %then5, label %ifend7 + %t32 = load i32, ptr %t17 + %t33 = icmp ne i32 %t32, 0 + %t34 = zext i1 %t33 to i32 + store i32 %t34, ptr %t16 + br i1 %t33, label %sc5, label %scend6 +sc5: + %t35 = load ptr, ptr %t15 + %t36 = getelementptr inbounds %Cmp_Node, ptr %t35, i32 0, i32 6 + %t37 = load ptr, ptr %t36 + %t38 = icmp eq ptr %t37, null + %t39 = zext i1 %t38 to i32 + %t40 = icmp ne i32 %t39, 0 + %t41 = zext i1 %t40 to i32 + store i32 %t41, ptr %t16 + br label %scend6 +scend6: + %t42 = load i32, ptr %t16 + %t43 = icmp ne i32 %t42, 0 + br i1 %t43, label %then7, label %ifend9 +then7: + %t44 = load ptr, ptr %t15 + call void @fn_emit_call_one(ptr %t44) + br label %ifend9 +ifend9: + %t45 = load i32, ptr %t1 + %t46 = add i32 %t45, 1 + store i32 %t46, ptr %t1 + br label %wcond0 +wend2: + store i32 0, ptr %t47 + store i32 0, ptr %t1 + br label %wcond10 +wcond10: + %t48 = load i32, ptr %t1 + %t49 = load ptr, ptr @g_prog + %t50 = getelementptr inbounds %LSlice, ptr %t49, i32 0, i32 1 + %t51 = load i32, ptr %t50 + %t52 = icmp slt i32 %t48, %t51 + %t53 = zext i1 %t52 to i32 + %t54 = icmp ne i32 %t53, 0 + br i1 %t54, label %wbody11, label %wend12 +wbody11: + %t55 = load ptr, ptr @g_prog + %t56 = getelementptr inbounds %LSlice, ptr %t55, i32 0, i32 0 + %t57 = load ptr, ptr %t56 + %t58 = load i32, ptr %t1 + %t59 = getelementptr inbounds ptr, ptr %t57, i32 %t58 + %t60 = load ptr, ptr %t59 + store ptr %t60, ptr %t61 + %t64 = load ptr, ptr %t61 + %t65 = getelementptr inbounds %Cmp_Node, ptr %t64, i32 0, i32 0 + %t66 = load i32, ptr %t65 + %t67 = icmp eq i32 %t66, 9 + %t68 = zext i1 %t67 to i32 + %t69 = icmp ne i32 %t68, 0 + %t70 = zext i1 %t69 to i32 + store i32 %t70, ptr %t63 + br i1 %t69, label %sc13, label %scend14 +sc13: + %t71 = load ptr, ptr %t61 + %t72 = getelementptr inbounds %Cmp_Node, ptr %t71, i32 0, i32 3 + %t73 = load ptr, ptr %t72 + %t74 = load ptr, ptr %t0 + %t75 = call i32 @fn_str_eq(ptr %t73, ptr %t74) + %t76 = icmp ne i32 %t75, 0 + %t77 = zext i1 %t76 to i32 + store i32 %t77, ptr %t63 + br label %scend14 +scend14: + %t78 = load i32, ptr %t63 + %t79 = icmp ne i32 %t78, 0 + %t80 = zext i1 %t79 to i32 + store i32 %t80, ptr %t62 + br i1 %t79, label %sc15, label %scend16 +sc15: + %t81 = load ptr, ptr %t61 + %t82 = getelementptr inbounds %Cmp_Node, ptr %t81, i32 0, i32 6 + %t83 = load ptr, ptr %t82 + %t84 = icmp ne ptr %t83, null + %t85 = zext i1 %t84 to i32 + %t86 = icmp ne i32 %t85, 0 + %t87 = zext i1 %t86 to i32 + store i32 %t87, ptr %t62 + br label %scend16 +scend16: + %t88 = load i32, ptr %t62 + %t89 = icmp ne i32 %t88, 0 + br i1 %t89, label %then17, label %ifend19 +then17: + store i32 1, ptr %t47 + br label %ifend19 +ifend19: + %t90 = load i32, ptr %t1 + %t91 = add i32 %t90, 1 + store i32 %t91, ptr %t1 + br label %wcond10 +wend12: + %t92 = load i32, ptr %t47 + %t93 = icmp eq i32 %t92, 0 + %t94 = zext i1 %t93 to i32 + %t95 = icmp ne i32 %t94, 0 + br i1 %t95, label %then20, label %ifend22 +then20: + br label %ret +ifend22: + %t96 = call ptr @fn_emit_bind(ptr @.str1774) + store ptr %t96, ptr %t97 + store i32 0, ptr %t1 + br label %wcond23 +wcond23: + %t98 = load i32, ptr %t1 + %t99 = load ptr, ptr @g_prog + %t100 = getelementptr inbounds %LSlice, ptr %t99, i32 0, i32 1 + %t101 = load i32, ptr %t100 + %t102 = icmp slt i32 %t98, %t101 + %t103 = zext i1 %t102 to i32 + %t104 = icmp ne i32 %t103, 0 + br i1 %t104, label %wbody24, label %wend25 +wbody24: + %t105 = load ptr, ptr @g_prog + %t106 = getelementptr inbounds %LSlice, ptr %t105, i32 0, i32 0 + %t107 = load ptr, ptr %t106 + %t108 = load i32, ptr %t1 + %t109 = getelementptr inbounds ptr, ptr %t107, i32 %t108 + %t110 = load ptr, ptr %t109 + store ptr %t110, ptr %t111 + %t114 = load ptr, ptr %t111 + %t115 = getelementptr inbounds %Cmp_Node, ptr %t114, i32 0, i32 0 + %t116 = load i32, ptr %t115 + %t117 = icmp eq i32 %t116, 9 + %t118 = zext i1 %t117 to i32 + %t119 = icmp ne i32 %t118, 0 + %t120 = zext i1 %t119 to i32 + store i32 %t120, ptr %t113 + br i1 %t119, label %sc26, label %scend27 +sc26: + %t121 = load ptr, ptr %t111 + %t122 = getelementptr inbounds %Cmp_Node, ptr %t121, i32 0, i32 3 + %t123 = load ptr, ptr %t122 + %t124 = load ptr, ptr %t0 + %t125 = call i32 @fn_str_eq(ptr %t123, ptr %t124) + %t126 = icmp ne i32 %t125, 0 + %t127 = zext i1 %t126 to i32 + store i32 %t127, ptr %t113 + br label %scend27 +scend27: + %t128 = load i32, ptr %t113 + %t129 = icmp ne i32 %t128, 0 + %t130 = zext i1 %t129 to i32 + store i32 %t130, ptr %t112 + br i1 %t129, label %sc28, label %scend29 +sc28: + %t131 = load ptr, ptr %t111 + %t132 = getelementptr inbounds %Cmp_Node, ptr %t131, i32 0, i32 6 + %t133 = load ptr, ptr %t132 + %t134 = icmp ne ptr %t133, null + %t135 = zext i1 %t134 to i32 + %t136 = icmp ne i32 %t135, 0 + %t137 = zext i1 %t136 to i32 + store i32 %t137, ptr %t112 + br label %scend29 +scend29: + %t138 = load i32, ptr %t112 + %t139 = icmp ne i32 %t138, 0 + br i1 %t139, label %then30, label %ifend32 +then30: + %t140 = load ptr, ptr %t97 + %t141 = call ptr @fn_str_concat(ptr @.str1775, ptr %t140) + %t142 = call ptr @fn_str_concat(ptr %t141, ptr @.str1776) + %t143 = load ptr, ptr %t111 + %t144 = getelementptr inbounds %Cmp_Node, ptr %t143, i32 0, i32 6 + %t145 = load ptr, ptr %t144 + %t146 = getelementptr inbounds %Cmp_Node, ptr %t145, i32 0, i32 2 + %t147 = load i32, ptr %t146 + %t148 = call ptr @fn_itoa(i32 %t147) + %t149 = call ptr @fn_str_concat(ptr %t142, ptr %t148) + %t150 = call ptr @fn_emit_bind(ptr %t149) + store ptr %t150, ptr %t151 + %t152 = call ptr @fn_lbl(ptr @.str1777) + store ptr %t152, ptr %t153 + %t154 = call ptr @fn_lbl(ptr @.str1778) + store ptr %t154, ptr %t155 + call void @fn_emit(ptr @.str1779) + %t156 = load ptr, ptr %t151 + call void @fn_emit(ptr %t156) + call void @fn_emit(ptr @.str1780) + %t157 = load ptr, ptr %t153 + call void @fn_emit(ptr %t157) + call void @fn_emit(ptr @.str1781) + %t158 = load ptr, ptr %t155 + call void @fn_emit(ptr %t158) + call void @fn_emit(ptr @.str1782) + %t159 = load ptr, ptr %t153 + call void @fn_emit(ptr %t159) + call void @fn_emit(ptr @.str1783) + %t160 = load ptr, ptr %t111 + call void @fn_emit_call_one(ptr %t160) + call void @fn_emit(ptr @.str1784) + %t161 = load ptr, ptr %t155 + call void @fn_emit(ptr %t161) + call void @fn_emit(ptr @.str1785) + %t162 = load ptr, ptr %t155 + call void @fn_emit(ptr %t162) + call void @fn_emit(ptr @.str1786) + br label %ifend32 +ifend32: + %t163 = load i32, ptr %t1 + %t164 = add i32 %t163, 1 + store i32 %t164, ptr %t1 + br label %wcond23 +wend25: + br label %ret +ret: + ret void +} + +define void @fn_emit_scene_fn(ptr %arg_name, ptr %arg_kind, ptr %arg_body) { +entry: + %t0 = alloca ptr + %t1 = alloca ptr + %t2 = alloca ptr + %t4 = alloca ptr + %t7 = alloca ptr + %t19 = alloca ptr + %t20 = alloca i32 + store ptr %arg_name, ptr %t0 + store ptr %arg_kind, ptr %t1 + store ptr %arg_body, ptr %t2 + store i32 0, ptr @g_ll_t + store i32 0, ptr @g_ll_lbl + store i32 0, ptr @g_g_term + call void @fn_loc_reset() + store i32 0, ptr @g_nloop + store i32 0, ptr @g_nself + store ptr @.str1787, ptr @g_ret_ty + %t3 = call ptr @fn_buf_new() + store ptr %t3, ptr %t4 + %t5 = call ptr @fn_buf_new() + store ptr %t5, ptr @g_falloc + %t6 = load ptr, ptr @g_code + store ptr %t6, ptr %t7 + %t8 = load ptr, ptr %t4 + store ptr %t8, ptr @g_code + %t9 = load ptr, ptr %t2 + %t10 = icmp ne ptr %t9, null + %t11 = zext i1 %t10 to i32 + %t12 = icmp ne i32 %t11, 0 + br i1 %t12, label %then0, label %ifend2 +then0: + %t13 = load ptr, ptr %t2 + call void @fn_emit_block(ptr %t13) + br label %ifend2 +ifend2: + %t14 = load ptr, ptr %t0 + %t15 = call ptr @fn_str_concat(ptr @.str1788, ptr %t14) + %t16 = call ptr @fn_str_concat(ptr %t15, ptr @.str1789) + %t17 = load ptr, ptr %t1 + %t18 = call ptr @fn_str_concat(ptr %t16, ptr %t17) + store ptr %t18, ptr %t19 + %t21 = load i32, ptr @g_g_term + %t22 = icmp eq i32 %t21, 0 + %t23 = zext i1 %t22 to i32 + %t24 = icmp ne i32 %t23, 0 + %t25 = zext i1 %t24 to i32 + store i32 %t25, ptr %t20 + br i1 %t24, label %sc3, label %scend4 +sc3: + %t26 = load ptr, ptr %t19 + %t27 = call ptr @fn_find_event(ptr %t26) + %t28 = icmp ne ptr %t27, null + %t29 = zext i1 %t28 to i32 + %t30 = icmp ne i32 %t29, 0 + %t31 = zext i1 %t30 to i32 + store i32 %t31, ptr %t20 + br label %scend4 +scend4: + %t32 = load i32, ptr %t20 + %t33 = icmp ne i32 %t32, 0 + br i1 %t33, label %then5, label %ifend7 then5: - %t33 = load ptr, ptr %t15 - %t34 = getelementptr inbounds %Cmp_Node, ptr %t33, i32 0, i32 1 - %t35 = load ptr, ptr %t34 - %t36 = call ptr @fn_str_concat(ptr @.str1339, ptr %t35) - %t37 = call ptr @fn_emit_bind(ptr %t36) - store ptr %t37, ptr %t38 - %t39 = load ptr, ptr %t38 - %t40 = call ptr @fn_str_concat(ptr @.str1340, ptr %t39) - %t41 = call ptr @fn_str_concat(ptr %t40, ptr @.str1341) - %t42 = call ptr @fn_emit_bind(ptr %t41) - store ptr %t42, ptr %t43 - %t44 = call ptr @fn_lbl(ptr @.str1342) - store ptr %t44, ptr %t45 - %t46 = call ptr @fn_lbl(ptr @.str1343) - store ptr %t46, ptr %t47 - call void @fn_emit(ptr @.str1344) - %t48 = load ptr, ptr %t43 - call void @fn_emit(ptr %t48) - call void @fn_emit(ptr @.str1345) - %t49 = load ptr, ptr %t45 - call void @fn_emit(ptr %t49) - call void @fn_emit(ptr @.str1346) - %t50 = load ptr, ptr %t47 - call void @fn_emit(ptr %t50) - call void @fn_emit(ptr @.str1347) - %t51 = load ptr, ptr %t45 - call void @fn_emit(ptr %t51) - call void @fn_emit(ptr @.str1348) - %t52 = load ptr, ptr %t15 - %t53 = getelementptr inbounds %Cmp_Node, ptr %t52, i32 0, i32 1 - %t54 = load ptr, ptr %t53 - call void @fn_emit(ptr %t54) - call void @fn_emit(ptr @.str1349) - call void @fn_emit(ptr @.str1350) - %t55 = load ptr, ptr %t47 - call void @fn_emit(ptr %t55) - call void @fn_emit(ptr @.str1351) - %t56 = load ptr, ptr %t47 - call void @fn_emit(ptr %t56) - call void @fn_emit(ptr @.str1352) + call void @fn_emit(ptr @.str1790) + %t34 = load ptr, ptr %t19 + call void @fn_emit(ptr %t34) + call void @fn_emit(ptr @.str1791) br label %ifend7 ifend7: - %t57 = load i32, ptr %t1 - %t58 = add i32 %t57, 1 - store i32 %t58, ptr %t1 + %t35 = load i32, ptr @g_g_term + %t36 = icmp eq i32 %t35, 0 + %t37 = zext i1 %t36 to i32 + %t38 = icmp ne i32 %t37, 0 + br i1 %t38, label %then8, label %ifend10 +then8: + call void @fn_emit(ptr @.str1792) + br label %ifend10 +ifend10: + call void @fn_emit(ptr @.str1793) + %t39 = load ptr, ptr %t7 + store ptr %t39, ptr @g_code + call void @fn_emit(ptr @.str1794) + %t40 = load ptr, ptr %t1 + call void @fn_emit(ptr %t40) + call void @fn_emit(ptr @.str1795) + %t41 = load ptr, ptr %t0 + call void @fn_emit(ptr %t41) + call void @fn_emit(ptr @.str1796) + %t42 = load ptr, ptr @g_falloc + %t43 = call ptr @fn_buf_str(ptr %t42) + call void @fn_emit(ptr %t43) + %t44 = load ptr, ptr %t4 + %t45 = call ptr @fn_buf_str(ptr %t44) + call void @fn_emit(ptr %t45) + call void @fn_emit(ptr @.str1797) + br label %ret +ret: + ret void +} + +define void @fn_emit_scene_hooks() { +entry: + %t0 = alloca i32 + %t14 = alloca ptr + store i32 0, ptr %t0 + br label %wcond0 +wcond0: + %t1 = load i32, ptr %t0 + %t2 = load ptr, ptr @g_g_scenes + %t3 = getelementptr inbounds %LSlice, ptr %t2, i32 0, i32 1 + %t4 = load i32, ptr %t3 + %t5 = icmp slt i32 %t1, %t4 + %t6 = zext i1 %t5 to i32 + %t7 = icmp ne i32 %t6, 0 + br i1 %t7, label %wbody1, label %wend2 +wbody1: + %t8 = load ptr, ptr @g_g_scenes + %t9 = getelementptr inbounds %LSlice, ptr %t8, i32 0, i32 0 + %t10 = load ptr, ptr %t9 + %t11 = load i32, ptr %t0 + %t12 = getelementptr inbounds ptr, ptr %t10, i32 %t11 + %t13 = load ptr, ptr %t12 + store ptr %t13, ptr %t14 + %t15 = load ptr, ptr %t14 + store ptr %t15, ptr @g_g_cur_scene + %t16 = load ptr, ptr %t14 + %t17 = getelementptr inbounds %Cmp_Node, ptr %t16, i32 0, i32 1 + %t18 = load ptr, ptr %t17 + %t19 = load ptr, ptr %t14 + %t20 = getelementptr inbounds %Cmp_Node, ptr %t19, i32 0, i32 4 + %t21 = load ptr, ptr %t20 + call void @fn_emit_scene_fn(ptr %t18, ptr @.str1798, ptr %t21) + %t22 = load ptr, ptr %t14 + %t23 = getelementptr inbounds %Cmp_Node, ptr %t22, i32 0, i32 1 + %t24 = load ptr, ptr %t23 + %t25 = load ptr, ptr %t14 + %t26 = getelementptr inbounds %Cmp_Node, ptr %t25, i32 0, i32 5 + %t27 = load ptr, ptr %t26 + call void @fn_emit_scene_fn(ptr %t24, ptr @.str1799, ptr %t27) + %t28 = load i32, ptr %t0 + %t29 = add i32 %t28, 1 + store i32 %t29, ptr %t0 br label %wcond0 wend2: br label %ret @@ -19157,6 +25080,7 @@ entry: %t19 = alloca ptr %t21 = alloca ptr %t24 = alloca ptr + %t33 = alloca ptr store i32 0, ptr %t0 br label %wcond0 wcond0: @@ -19187,7 +25111,7 @@ wbody1: call void @fn_loc_reset() store i32 0, ptr @g_nloop store i32 0, ptr @g_nself - store ptr @.str1353, ptr @g_ret_ty + store ptr @.str1800, ptr @g_ret_ty %t20 = call ptr @fn_buf_new() store ptr %t20, ptr %t21 %t22 = call ptr @fn_buf_new() @@ -19196,56 +25120,2298 @@ wbody1: store ptr %t23, ptr %t24 %t25 = load ptr, ptr %t21 store ptr %t25, ptr @g_code - %t26 = load ptr, ptr %t19 - call void @fn_emit_bind_props(ptr %t26, ptr @.str1354) - %t27 = load ptr, ptr %t14 - %t28 = getelementptr inbounds %Cmp_Node, ptr %t27, i32 0, i32 4 - %t29 = load ptr, ptr %t28 - call void @fn_emit_block(ptr %t29) - %t30 = load i32, ptr @g_g_term - %t31 = icmp eq i32 %t30, 0 - %t32 = zext i1 %t31 to i32 - %t33 = icmp ne i32 %t32, 0 - br i1 %t33, label %then3, label %ifend5 + %t26 = load ptr, ptr %t14 + %t27 = getelementptr inbounds %Cmp_Node, ptr %t26, i32 0, i32 3 + %t28 = load ptr, ptr %t27 + %t29 = icmp ne ptr %t28, null + %t30 = zext i1 %t29 to i32 + %t31 = icmp ne i32 %t30, 0 + br i1 %t31, label %then3, label %ifend5 then3: - call void @fn_emit(ptr @.str1355) + %t32 = call ptr @fn_emit_alloca(ptr @.str1801) + store ptr %t32, ptr %t33 + call void @fn_emit(ptr @.str1802) + %t34 = load ptr, ptr %t33 + call void @fn_emit(ptr %t34) + call void @fn_emit(ptr @.str1803) + %t35 = load ptr, ptr %t14 + %t36 = getelementptr inbounds %Cmp_Node, ptr %t35, i32 0, i32 3 + %t37 = load ptr, ptr %t36 + %t38 = load ptr, ptr %t33 + call void @fn_loc_push(ptr %t37, ptr %t38, ptr @.str1804) br label %ifend5 ifend5: - call void @fn_emit(ptr @.str1356) - %t34 = load ptr, ptr %t24 - store ptr %t34, ptr @g_code - call void @fn_emit(ptr @.str1357) - %t35 = load ptr, ptr %t14 - %t36 = getelementptr inbounds %Cmp_Node, ptr %t35, i32 0, i32 1 - %t37 = load ptr, ptr %t36 - call void @fn_emit(ptr %t37) - call void @fn_emit(ptr @.str1358) - %t38 = load ptr, ptr @g_falloc - %t39 = call ptr @fn_buf_str(ptr %t38) - call void @fn_emit(ptr %t39) - %t40 = load ptr, ptr %t21 - %t41 = call ptr @fn_buf_str(ptr %t40) - call void @fn_emit(ptr %t41) - call void @fn_emit(ptr @.str1359) - %t42 = load i32, ptr %t0 - %t43 = add i32 %t42, 1 - store i32 %t43, ptr %t0 + %t39 = load ptr, ptr %t19 + call void @fn_emit_bind_props(ptr %t39, ptr @.str1805) + %t40 = load ptr, ptr %t14 + %t41 = getelementptr inbounds %Cmp_Node, ptr %t40, i32 0, i32 4 + %t42 = load ptr, ptr %t41 + call void @fn_emit_block(ptr %t42) + %t43 = load i32, ptr @g_g_term + %t44 = icmp eq i32 %t43, 0 + %t45 = zext i1 %t44 to i32 + %t46 = icmp ne i32 %t45, 0 + br i1 %t46, label %then6, label %ifend8 +then6: + call void @fn_emit(ptr @.str1806) + br label %ifend8 +ifend8: + call void @fn_emit(ptr @.str1807) + %t47 = load ptr, ptr %t24 + store ptr %t47, ptr @g_code + call void @fn_emit(ptr @.str1808) + %t48 = load ptr, ptr %t14 + %t49 = getelementptr inbounds %Cmp_Node, ptr %t48, i32 0, i32 1 + %t50 = load ptr, ptr %t49 + call void @fn_emit(ptr %t50) + call void @fn_emit(ptr @.str1809) + %t51 = load ptr, ptr @g_falloc + %t52 = call ptr @fn_buf_str(ptr %t51) + call void @fn_emit(ptr %t52) + %t53 = load ptr, ptr %t21 + %t54 = call ptr @fn_buf_str(ptr %t53) + call void @fn_emit(ptr %t54) + call void @fn_emit(ptr @.str1810) + %t55 = load i32, ptr %t0 + %t56 = add i32 %t55, 1 + store i32 %t56, ptr %t0 br label %wcond0 wend2: + call void @fn_emit_despawn_all_fn() br label %ret ret: ret void } -define void @fn_emit_game_main() { +define void @fn_emit_despawn_all_fn() { +entry: + %t7 = alloca ptr + %t10 = alloca i32 + %t26 = alloca ptr + %t29 = alloca ptr + %t42 = alloca ptr + %t0 = load ptr, ptr @g_g_ondespawn + %t1 = getelementptr inbounds %LSlice, ptr %t0, i32 0, i32 1 + %t2 = load i32, ptr %t1 + %t3 = icmp eq i32 %t2, 0 + %t4 = zext i1 %t3 to i32 + %t5 = icmp ne i32 %t4, 0 + br i1 %t5, label %then0, label %ifend2 +then0: + br label %ret +ifend2: + %t6 = call ptr @fn_itoa(i32 1024) + store ptr %t6, ptr %t7 + call void @fn_emit(ptr @.str1811) + call void @fn_emit(ptr @.str1812) + call void @fn_emit(ptr @.str1813) + call void @fn_emit(ptr @.str1814) + call void @fn_emit(ptr @.str1815) + %t8 = load ptr, ptr %t7 + call void @fn_emit(ptr %t8) + call void @fn_emit(ptr @.str1816) + call void @fn_emit(ptr @.str1817) + call void @fn_emit(ptr @.str1818) + call void @fn_emit(ptr @.str1819) + %t9 = load ptr, ptr %t7 + call void @fn_emit(ptr %t9) + call void @fn_emit(ptr @.str1820) + call void @fn_emit(ptr @.str1821) + store i32 0, ptr %t10 + br label %wcond3 +wcond3: + %t11 = load i32, ptr %t10 + %t12 = load ptr, ptr @g_g_ondespawn + %t13 = getelementptr inbounds %LSlice, ptr %t12, i32 0, i32 1 + %t14 = load i32, ptr %t13 + %t15 = icmp slt i32 %t11, %t14 + %t16 = zext i1 %t15 to i32 + %t17 = icmp ne i32 %t16, 0 + br i1 %t17, label %wbody4, label %wend5 +wbody4: + %t18 = load ptr, ptr @g_g_ondespawn + %t19 = getelementptr inbounds %LSlice, ptr %t18, i32 0, i32 0 + %t20 = load ptr, ptr %t19 + %t21 = load i32, ptr %t10 + %t22 = getelementptr inbounds ptr, ptr %t20, i32 %t21 + %t23 = load ptr, ptr %t22 + %t24 = getelementptr inbounds %Cmp_Node, ptr %t23, i32 0, i32 1 + %t25 = load ptr, ptr %t24 + store ptr %t25, ptr %t26 + %t27 = load i32, ptr %t10 + %t28 = call ptr @fn_itoa(i32 %t27) + store ptr %t28, ptr %t29 + call void @fn_emit(ptr @.str1822) + %t30 = load ptr, ptr %t29 + call void @fn_emit(ptr %t30) + call void @fn_emit(ptr @.str1823) + %t31 = load ptr, ptr %t26 + %t32 = call i32 @fn_find_arch_id(ptr %t31) + %t33 = call ptr @fn_itoa(i32 %t32) + call void @fn_emit(ptr %t33) + call void @fn_emit(ptr @.str1824) + call void @fn_emit(ptr @.str1825) + %t34 = load ptr, ptr %t29 + call void @fn_emit(ptr %t34) + call void @fn_emit(ptr @.str1826) + %t35 = load ptr, ptr %t29 + call void @fn_emit(ptr %t35) + call void @fn_emit(ptr @.str1827) + %t36 = load ptr, ptr %t29 + call void @fn_emit(ptr %t36) + call void @fn_emit(ptr @.str1828) + call void @fn_emit(ptr @.str1829) + %t37 = load ptr, ptr %t29 + call void @fn_emit(ptr %t37) + call void @fn_emit(ptr @.str1830) + %t38 = load ptr, ptr %t26 + call void @fn_emit(ptr %t38) + call void @fn_emit(ptr @.str1831) + %t39 = load ptr, ptr %t26 + %t40 = call ptr @fn_str_concat(ptr @.str1832, ptr %t39) + %t41 = call ptr @fn_str_concat(ptr %t40, ptr @.str1833) + store ptr %t41, ptr %t42 + %t43 = load ptr, ptr %t42 + %t44 = call ptr @fn_find_event(ptr %t43) + %t45 = icmp ne ptr %t44, null + %t46 = zext i1 %t45 to i32 + %t47 = icmp ne i32 %t46, 0 + br i1 %t47, label %then6, label %ifend8 +then6: + call void @fn_emit(ptr @.str1834) + %t48 = load ptr, ptr %t42 + call void @fn_emit(ptr %t48) + call void @fn_emit(ptr @.str1835) + br label %ifend8 +ifend8: + call void @fn_emit(ptr @.str1836) + %t49 = load ptr, ptr %t29 + call void @fn_emit(ptr %t49) + call void @fn_emit(ptr @.str1837) + call void @fn_emit(ptr @.str1838) + %t50 = load ptr, ptr %t29 + call void @fn_emit(ptr %t50) + call void @fn_emit(ptr @.str1839) + %t51 = load i32, ptr %t10 + %t52 = add i32 %t51, 1 + store i32 %t52, ptr %t10 + br label %wcond3 +wend5: + call void @fn_emit(ptr @.str1840) + call void @fn_emit(ptr @.str1841) + call void @fn_emit(ptr @.str1842) + br label %ret +ret: + ret void +} + +define void @fn_emit_event_fns() { +entry: + %t0 = alloca i32 + %t14 = alloca ptr + %t18 = alloca ptr + %t20 = alloca ptr + %t22 = alloca i32 + %t89 = alloca ptr + %t92 = alloca ptr + %t104 = alloca ptr + %t105 = alloca i32 + %t123 = alloca ptr + %t128 = alloca ptr + %t130 = alloca ptr + %t142 = alloca ptr + %t156 = alloca ptr + %t176 = alloca i32 + %t177 = alloca i32 + %t212 = alloca ptr + %t215 = alloca ptr + %t217 = alloca ptr + %t219 = alloca ptr + %t225 = alloca ptr + %t229 = alloca ptr + %t236 = alloca ptr + %t242 = alloca ptr + %t250 = alloca ptr + %t255 = alloca ptr + %t257 = alloca ptr + %t259 = alloca ptr + %t272 = alloca ptr + %t286 = alloca ptr + %t289 = alloca ptr + %t298 = alloca i32 + %t334 = alloca ptr + %t335 = alloca i32 + %t351 = alloca ptr + %t354 = alloca ptr + call void @fn_emith(ptr @.str1843) + store i32 0, ptr %t0 + br label %wcond0 +wcond0: + %t1 = load i32, ptr %t0 + %t2 = load ptr, ptr @g_g_events + %t3 = getelementptr inbounds %LSlice, ptr %t2, i32 0, i32 1 + %t4 = load i32, ptr %t3 + %t5 = icmp slt i32 %t1, %t4 + %t6 = zext i1 %t5 to i32 + %t7 = icmp ne i32 %t6, 0 + br i1 %t7, label %wbody1, label %wend2 +wbody1: + %t8 = load ptr, ptr @g_g_events + %t9 = getelementptr inbounds %LSlice, ptr %t8, i32 0, i32 0 + %t10 = load ptr, ptr %t9 + %t11 = load i32, ptr %t0 + %t12 = getelementptr inbounds ptr, ptr %t10, i32 %t11 + %t13 = load ptr, ptr %t12 + store ptr %t13, ptr %t14 + %t15 = load ptr, ptr %t14 + %t16 = getelementptr inbounds %Cmp_Node, ptr %t15, i32 0, i32 1 + %t17 = load ptr, ptr %t16 + store ptr %t17, ptr %t18 + %t19 = call ptr @fn_itoa(i32 16) + store ptr %t19, ptr %t20 + call void @fn_emith(ptr @.str1844) + %t21 = load ptr, ptr %t18 + call void @fn_emith(ptr %t21) + call void @fn_emith(ptr @.str1845) + store i32 0, ptr %t22 + br label %wcond3 +wcond3: + %t23 = load i32, ptr %t22 + %t24 = load ptr, ptr %t14 + %t25 = getelementptr inbounds %Cmp_Node, ptr %t24, i32 0, i32 7 + %t26 = load ptr, ptr %t25 + %t27 = getelementptr inbounds %LSlice, ptr %t26, i32 0, i32 1 + %t28 = load i32, ptr %t27 + %t29 = icmp slt i32 %t23, %t28 + %t30 = zext i1 %t29 to i32 + %t31 = icmp ne i32 %t30, 0 + br i1 %t31, label %wbody4, label %wend5 +wbody4: + %t32 = load i32, ptr %t22 + %t33 = icmp sgt i32 %t32, 0 + %t34 = zext i1 %t33 to i32 + %t35 = icmp ne i32 %t34, 0 + br i1 %t35, label %then6, label %ifend8 +then6: + call void @fn_emith(ptr @.str1846) + br label %ifend8 +ifend8: + %t36 = load ptr, ptr %t14 + %t37 = getelementptr inbounds %Cmp_Node, ptr %t36, i32 0, i32 7 + %t38 = load ptr, ptr %t37 + %t39 = getelementptr inbounds %LSlice, ptr %t38, i32 0, i32 0 + %t40 = load ptr, ptr %t39 + %t41 = load i32, ptr %t22 + %t42 = getelementptr inbounds ptr, ptr %t40, i32 %t41 + %t43 = load ptr, ptr %t42 + %t44 = getelementptr inbounds %Cmp_Node, ptr %t43, i32 0, i32 3 + %t45 = load ptr, ptr %t44 + %t46 = call ptr @fn_llty(ptr %t45) + call void @fn_emith(ptr %t46) + %t47 = load i32, ptr %t22 + %t48 = add i32 %t47, 1 + store i32 %t48, ptr %t22 + br label %wcond3 +wend5: + %t49 = load ptr, ptr %t14 + %t50 = getelementptr inbounds %Cmp_Node, ptr %t49, i32 0, i32 2 + %t51 = load i32, ptr %t50 + %t52 = icmp eq i32 %t51, 1 + %t53 = zext i1 %t52 to i32 + %t54 = icmp ne i32 %t53, 0 + br i1 %t54, label %then9, label %ifend11 +then9: + %t55 = load ptr, ptr %t14 + %t56 = getelementptr inbounds %Cmp_Node, ptr %t55, i32 0, i32 7 + %t57 = load ptr, ptr %t56 + %t58 = getelementptr inbounds %LSlice, ptr %t57, i32 0, i32 1 + %t59 = load i32, ptr %t58 + %t60 = icmp sgt i32 %t59, 0 + %t61 = zext i1 %t60 to i32 + %t62 = icmp ne i32 %t61, 0 + br i1 %t62, label %then12, label %ifend14 +then12: + call void @fn_emith(ptr @.str1847) + br label %ifend14 +ifend14: + call void @fn_emith(ptr @.str1848) + br label %ifend11 +ifend11: + call void @fn_emith(ptr @.str1849) + call void @fn_emith(ptr @.str1850) + %t63 = load ptr, ptr %t18 + call void @fn_emith(ptr %t63) + call void @fn_emith(ptr @.str1851) + %t64 = load ptr, ptr %t20 + call void @fn_emith(ptr %t64) + call void @fn_emith(ptr @.str1852) + call void @fn_emith(ptr @.str1853) + %t65 = load ptr, ptr %t18 + call void @fn_emith(ptr %t65) + call void @fn_emith(ptr @.str1854) + call void @fn_emith(ptr @.str1855) + %t66 = load ptr, ptr %t18 + call void @fn_emith(ptr %t66) + call void @fn_emith(ptr @.str1856) + %t67 = load ptr, ptr %t20 + call void @fn_emith(ptr %t67) + call void @fn_emith(ptr @.str1857) + call void @fn_emit(ptr @.str1858) + %t68 = load ptr, ptr %t18 + call void @fn_emit(ptr %t68) + call void @fn_emit(ptr @.str1859) + call void @fn_emit(ptr @.str1860) + %t69 = load ptr, ptr %t18 + call void @fn_emit(ptr %t69) + call void @fn_emit(ptr @.str1861) + call void @fn_emit(ptr @.str1862) + %t70 = load ptr, ptr %t20 + call void @fn_emit(ptr %t70) + call void @fn_emit(ptr @.str1863) + call void @fn_emit(ptr @.str1864) + call void @fn_emit(ptr @.str1865) + %t71 = load ptr, ptr %t20 + call void @fn_emit(ptr %t71) + call void @fn_emit(ptr @.str1866) + %t72 = load ptr, ptr %t18 + call void @fn_emit(ptr %t72) + call void @fn_emit(ptr @.str1867) + call void @fn_emit(ptr @.str1868) + call void @fn_emit(ptr @.str1869) + %t73 = load ptr, ptr %t20 + call void @fn_emit(ptr %t73) + call void @fn_emit(ptr @.str1870) + %t74 = load ptr, ptr %t18 + call void @fn_emit(ptr %t74) + call void @fn_emit(ptr @.str1871) + call void @fn_emit(ptr @.str1872) + call void @fn_emit(ptr @.str1873) + %t75 = load ptr, ptr %t18 + call void @fn_emit(ptr %t75) + call void @fn_emit(ptr @.str1874) + call void @fn_emit(ptr @.str1875) + call void @fn_emit(ptr @.str1876) + %t76 = load ptr, ptr %t18 + call void @fn_emit(ptr %t76) + call void @fn_emit(ptr @.str1877) + call void @fn_emit(ptr @.str1878) + %t77 = load ptr, ptr %t18 + call void @fn_emit(ptr %t77) + call void @fn_emit(ptr @.str1879) + call void @fn_emit(ptr @.str1880) + %t78 = load ptr, ptr %t20 + call void @fn_emit(ptr %t78) + call void @fn_emit(ptr @.str1881) + call void @fn_emit(ptr @.str1882) + call void @fn_emit(ptr @.str1883) + %t79 = load ptr, ptr %t20 + call void @fn_emit(ptr %t79) + call void @fn_emit(ptr @.str1884) + %t80 = load ptr, ptr %t18 + call void @fn_emit(ptr %t80) + call void @fn_emit(ptr @.str1885) + call void @fn_emit(ptr @.str1886) + call void @fn_emit(ptr @.str1887) + %t81 = load ptr, ptr %t20 + call void @fn_emit(ptr %t81) + call void @fn_emit(ptr @.str1888) + %t82 = load ptr, ptr %t18 + call void @fn_emit(ptr %t82) + call void @fn_emit(ptr @.str1889) + call void @fn_emit(ptr @.str1890) + call void @fn_emit(ptr @.str1891) + %t83 = load ptr, ptr %t18 + call void @fn_emit(ptr %t83) + call void @fn_emit(ptr @.str1892) + call void @fn_emit(ptr @.str1893) + call void @fn_emit(ptr @.str1894) + %t84 = load ptr, ptr %t18 + call void @fn_emit(ptr %t84) + call void @fn_emit(ptr @.str1895) + call void @fn_emit(ptr @.str1896) + %t85 = load ptr, ptr %t18 + call void @fn_emit(ptr %t85) + call void @fn_emit(ptr @.str1897) + call void @fn_emit(ptr @.str1898) + call void @fn_emit(ptr @.str1899) + call void @fn_emit(ptr @.str1900) + %t86 = load ptr, ptr %t20 + call void @fn_emit(ptr %t86) + call void @fn_emit(ptr @.str1901) + %t87 = load ptr, ptr %t18 + call void @fn_emit(ptr %t87) + call void @fn_emit(ptr @.str1902) + call void @fn_emit(ptr @.str1903) + call void @fn_emit(ptr @.str1904) + store i32 0, ptr @g_ll_t + store i32 0, ptr @g_ll_lbl + store i32 0, ptr @g_g_term + call void @fn_loc_reset() + store i32 0, ptr @g_nloop + store i32 0, ptr @g_nself + store ptr @.str1905, ptr @g_ret_ty + %t88 = call ptr @fn_buf_new() + store ptr %t88, ptr %t89 + %t90 = call ptr @fn_buf_new() + store ptr %t90, ptr @g_falloc + %t91 = load ptr, ptr @g_code + store ptr %t91, ptr %t92 + %t93 = load ptr, ptr %t89 + store ptr %t93, ptr @g_code + call void @fn_emit(ptr @.str1906) + call void @fn_emit(ptr @.str1907) + %t94 = call ptr @fn_itoa(i32 32) + call void @fn_emit(ptr %t94) + call void @fn_emit(ptr @.str1908) + call void @fn_emit(ptr @.str1909) + call void @fn_emit(ptr @.str1910) + %t95 = load ptr, ptr %t14 + %t96 = getelementptr inbounds %Cmp_Node, ptr %t95, i32 0, i32 2 + %t97 = load i32, ptr %t96 + %t98 = icmp eq i32 %t97, 1 + %t99 = zext i1 %t98 to i32 + %t100 = icmp ne i32 %t99, 0 + br i1 %t100, label %then15, label %else16 +then15: + call void @fn_emit(ptr @.str1911) + br label %ifend17 +else16: + call void @fn_emit(ptr @.str1912) + br label %ifend17 +ifend17: + call void @fn_emit(ptr @.str1913) + call void @fn_emit(ptr @.str1914) + %t101 = load ptr, ptr %t18 + %t102 = call ptr @fn_str_concat(ptr @.str1915, ptr %t101) + %t103 = call ptr @fn_emit_alloca(ptr %t102) + store ptr %t103, ptr %t104 + store i32 0, ptr %t105 + br label %wcond18 +wcond18: + %t106 = load i32, ptr %t105 + %t107 = load ptr, ptr %t14 + %t108 = getelementptr inbounds %Cmp_Node, ptr %t107, i32 0, i32 7 + %t109 = load ptr, ptr %t108 + %t110 = getelementptr inbounds %LSlice, ptr %t109, i32 0, i32 1 + %t111 = load i32, ptr %t110 + %t112 = icmp slt i32 %t106, %t111 + %t113 = zext i1 %t112 to i32 + %t114 = icmp ne i32 %t113, 0 + br i1 %t114, label %wbody19, label %wend20 +wbody19: + %t115 = load ptr, ptr %t14 + %t116 = getelementptr inbounds %Cmp_Node, ptr %t115, i32 0, i32 7 + %t117 = load ptr, ptr %t116 + %t118 = getelementptr inbounds %LSlice, ptr %t117, i32 0, i32 0 + %t119 = load ptr, ptr %t118 + %t120 = load i32, ptr %t105 + %t121 = getelementptr inbounds ptr, ptr %t119, i32 %t120 + %t122 = load ptr, ptr %t121 + store ptr %t122, ptr %t123 + %t124 = load ptr, ptr %t123 + %t125 = getelementptr inbounds %Cmp_Node, ptr %t124, i32 0, i32 3 + %t126 = load ptr, ptr %t125 + %t127 = call ptr @fn_llty(ptr %t126) + store ptr %t127, ptr %t128 + %t129 = call ptr @fn_nreg() + store ptr %t129, ptr %t130 + call void @fn_emit(ptr @.str1916) + %t131 = load ptr, ptr %t130 + call void @fn_emit(ptr %t131) + call void @fn_emit(ptr @.str1917) + %t132 = load ptr, ptr %t18 + call void @fn_emit(ptr %t132) + call void @fn_emit(ptr @.str1918) + %t133 = load ptr, ptr %t104 + call void @fn_emit(ptr %t133) + call void @fn_emit(ptr @.str1919) + %t134 = load i32, ptr %t105 + %t135 = call ptr @fn_itoa(i32 %t134) + call void @fn_emit(ptr %t135) + call void @fn_emit(ptr @.str1920) + call void @fn_emit(ptr @.str1921) + %t136 = load ptr, ptr %t128 + call void @fn_emit(ptr %t136) + call void @fn_emit(ptr @.str1922) + %t137 = load i32, ptr %t105 + %t138 = call ptr @fn_itoa(i32 %t137) + call void @fn_emit(ptr %t138) + call void @fn_emit(ptr @.str1923) + %t139 = load ptr, ptr %t130 + call void @fn_emit(ptr %t139) + call void @fn_emit(ptr @.str1924) + %t140 = load ptr, ptr %t128 + %t141 = call ptr @fn_emit_alloca(ptr %t140) + store ptr %t141, ptr %t142 + call void @fn_emit(ptr @.str1925) + %t143 = load ptr, ptr %t128 + call void @fn_emit(ptr %t143) + call void @fn_emit(ptr @.str1926) + %t144 = load i32, ptr %t105 + %t145 = call ptr @fn_itoa(i32 %t144) + call void @fn_emit(ptr %t145) + call void @fn_emit(ptr @.str1927) + %t146 = load ptr, ptr %t142 + call void @fn_emit(ptr %t146) + call void @fn_emit(ptr @.str1928) + %t147 = load ptr, ptr %t123 + %t148 = getelementptr inbounds %Cmp_Node, ptr %t147, i32 0, i32 1 + %t149 = load ptr, ptr %t148 + %t150 = load ptr, ptr %t142 + %t151 = load ptr, ptr %t123 + %t152 = getelementptr inbounds %Cmp_Node, ptr %t151, i32 0, i32 3 + %t153 = load ptr, ptr %t152 + call void @fn_loc_push(ptr %t149, ptr %t150, ptr %t153) + %t154 = load i32, ptr %t105 + %t155 = add i32 %t154, 1 + store i32 %t155, ptr %t105 + br label %wcond18 +wend20: + store ptr null, ptr %t156 + %t157 = load ptr, ptr %t14 + %t158 = getelementptr inbounds %Cmp_Node, ptr %t157, i32 0, i32 2 + %t159 = load i32, ptr %t158 + %t160 = icmp eq i32 %t159, 1 + %t161 = zext i1 %t160 to i32 + %t162 = icmp ne i32 %t161, 0 + br i1 %t162, label %then21, label %ifend23 +then21: + %t163 = call ptr @fn_nreg() + store ptr %t163, ptr %t156 + call void @fn_emit(ptr @.str1929) + %t164 = load ptr, ptr %t156 + call void @fn_emit(ptr %t164) + call void @fn_emit(ptr @.str1930) + %t165 = load ptr, ptr %t18 + call void @fn_emit(ptr %t165) + call void @fn_emit(ptr @.str1931) + %t166 = load ptr, ptr %t104 + call void @fn_emit(ptr %t166) + call void @fn_emit(ptr @.str1932) + %t167 = load ptr, ptr %t14 + %t168 = getelementptr inbounds %Cmp_Node, ptr %t167, i32 0, i32 7 + %t169 = load ptr, ptr %t168 + %t170 = getelementptr inbounds %LSlice, ptr %t169, i32 0, i32 1 + %t171 = load i32, ptr %t170 + %t172 = call ptr @fn_itoa(i32 %t171) + call void @fn_emit(ptr %t172) + call void @fn_emit(ptr @.str1933) + call void @fn_emit(ptr @.str1934) + %t173 = load ptr, ptr %t156 + call void @fn_emit(ptr %t173) + call void @fn_emit(ptr @.str1935) + %t174 = load ptr, ptr %t156 + store ptr %t174, ptr @g_g_cancel_addr + br label %ifend23 +ifend23: + %t175 = load i32, ptr @g_nloc + store i32 %t175, ptr %t176 + store i32 0, ptr %t177 + br label %wcond24 +wcond24: + %t178 = load i32, ptr %t177 + %t179 = load ptr, ptr @g_g_onlisten + %t180 = getelementptr inbounds %LSlice, ptr %t179, i32 0, i32 1 + %t181 = load i32, ptr %t180 + %t182 = icmp slt i32 %t178, %t181 + %t183 = zext i1 %t182 to i32 + %t184 = icmp ne i32 %t183, 0 + br i1 %t184, label %wbody25, label %wend26 +wbody25: + %t185 = load ptr, ptr @g_g_onlisten + %t186 = getelementptr inbounds %LSlice, ptr %t185, i32 0, i32 0 + %t187 = load ptr, ptr %t186 + %t188 = load i32, ptr %t177 + %t189 = getelementptr inbounds ptr, ptr %t187, i32 %t188 + %t190 = load ptr, ptr %t189 + %t191 = getelementptr inbounds %Cmp_Node, ptr %t190, i32 0, i32 1 + %t192 = load ptr, ptr %t191 + %t193 = load ptr, ptr %t18 + %t194 = call i32 @fn_str_eq(ptr %t192, ptr %t193) + %t195 = icmp ne i32 %t194, 0 + br i1 %t195, label %then27, label %ifend29 +then27: + %t196 = load i32, ptr %t176 + store i32 %t196, ptr @g_nloc + store i32 0, ptr @g_g_term + %t197 = load ptr, ptr @g_g_onlisten + %t198 = getelementptr inbounds %LSlice, ptr %t197, i32 0, i32 0 + %t199 = load ptr, ptr %t198 + %t200 = load i32, ptr %t177 + %t201 = getelementptr inbounds ptr, ptr %t199, i32 %t200 + %t202 = load ptr, ptr %t201 + %t203 = getelementptr inbounds %Cmp_Node, ptr %t202, i32 0, i32 4 + %t204 = load ptr, ptr %t203 + call void @fn_emit_block(ptr %t204) + br label %ifend29 +ifend29: + %t205 = load i32, ptr %t177 + %t206 = add i32 %t205, 1 + store i32 %t206, ptr %t177 + br label %wcond24 +wend26: + %t207 = load i32, ptr @g_g_term + %t208 = icmp eq i32 %t207, 0 + %t209 = zext i1 %t208 to i32 + %t210 = icmp ne i32 %t209, 0 + br i1 %t210, label %then30, label %ifend32 +then30: + %t211 = call ptr @fn_emit_alloca(ptr @.str1936) + store ptr %t211, ptr %t212 + call void @fn_emit(ptr @.str1937) + %t213 = load ptr, ptr %t212 + call void @fn_emit(ptr %t213) + call void @fn_emit(ptr @.str1938) + %t214 = call ptr @fn_lbl(ptr @.str1939) + store ptr %t214, ptr %t215 + %t216 = call ptr @fn_lbl(ptr @.str1940) + store ptr %t216, ptr %t217 + %t218 = call ptr @fn_lbl(ptr @.str1941) + store ptr %t218, ptr %t219 + call void @fn_emit(ptr @.str1942) + %t220 = load ptr, ptr %t215 + call void @fn_emit(ptr %t220) + call void @fn_emit(ptr @.str1943) + %t221 = load ptr, ptr %t215 + call void @fn_emit(ptr %t221) + call void @fn_emit(ptr @.str1944) + %t222 = load ptr, ptr %t212 + %t223 = call ptr @fn_str_concat(ptr @.str1945, ptr %t222) + %t224 = call ptr @fn_emit_bind(ptr %t223) + store ptr %t224, ptr %t225 + %t226 = load ptr, ptr %t18 + %t227 = call ptr @fn_str_concat(ptr @.str1946, ptr %t226) + %t228 = call ptr @fn_emit_bind(ptr %t227) + store ptr %t228, ptr %t229 + %t230 = load ptr, ptr %t225 + %t231 = call ptr @fn_str_concat(ptr @.str1947, ptr %t230) + %t232 = call ptr @fn_str_concat(ptr %t231, ptr @.str1948) + %t233 = load ptr, ptr %t229 + %t234 = call ptr @fn_str_concat(ptr %t232, ptr %t233) + %t235 = call ptr @fn_emit_bind(ptr %t234) + store ptr %t235, ptr %t236 + call void @fn_emit(ptr @.str1949) + %t237 = load ptr, ptr %t236 + call void @fn_emit(ptr %t237) + call void @fn_emit(ptr @.str1950) + %t238 = load ptr, ptr %t217 + call void @fn_emit(ptr %t238) + call void @fn_emit(ptr @.str1951) + %t239 = load ptr, ptr %t219 + call void @fn_emit(ptr %t239) + call void @fn_emit(ptr @.str1952) + %t240 = load ptr, ptr %t217 + call void @fn_emit(ptr %t240) + call void @fn_emit(ptr @.str1953) + %t241 = call ptr @fn_nreg() + store ptr %t241, ptr %t242 + call void @fn_emit(ptr @.str1954) + %t243 = load ptr, ptr %t242 + call void @fn_emit(ptr %t243) + call void @fn_emit(ptr @.str1955) + %t244 = load ptr, ptr %t20 + call void @fn_emit(ptr %t244) + call void @fn_emit(ptr @.str1956) + %t245 = load ptr, ptr %t18 + call void @fn_emit(ptr %t245) + call void @fn_emit(ptr @.str1957) + %t246 = load ptr, ptr %t225 + call void @fn_emit(ptr %t246) + call void @fn_emit(ptr @.str1958) + %t247 = load ptr, ptr %t242 + %t248 = call ptr @fn_str_concat(ptr @.str1959, ptr %t247) + %t249 = call ptr @fn_emit_bind(ptr %t248) + store ptr %t249, ptr %t250 + %t251 = load ptr, ptr %t250 + %t252 = call ptr @fn_str_concat(ptr @.str1960, ptr %t251) + %t253 = call ptr @fn_str_concat(ptr %t252, ptr @.str1961) + %t254 = call ptr @fn_emit_bind(ptr %t253) + store ptr %t254, ptr %t255 + %t256 = call ptr @fn_lbl(ptr @.str1962) + store ptr %t256, ptr %t257 + %t258 = call ptr @fn_lbl(ptr @.str1963) + store ptr %t258, ptr %t259 + call void @fn_emit(ptr @.str1964) + %t260 = load ptr, ptr %t255 + call void @fn_emit(ptr %t260) + call void @fn_emit(ptr @.str1965) + %t261 = load ptr, ptr %t259 + call void @fn_emit(ptr %t261) + call void @fn_emit(ptr @.str1966) + %t262 = load ptr, ptr %t257 + call void @fn_emit(ptr %t262) + call void @fn_emit(ptr @.str1967) + %t263 = load ptr, ptr %t257 + call void @fn_emit(ptr %t263) + call void @fn_emit(ptr @.str1968) + call void @fn_emit(ptr @.str1969) + %t264 = load ptr, ptr %t250 + call void @fn_emit(ptr %t264) + call void @fn_emit(ptr @.str1970) + %t265 = load ptr, ptr %t104 + call void @fn_emit(ptr %t265) + call void @fn_emit(ptr @.str1971) + call void @fn_emit(ptr @.str1972) + %t266 = load ptr, ptr %t259 + call void @fn_emit(ptr %t266) + call void @fn_emit(ptr @.str1973) + %t267 = load ptr, ptr %t259 + call void @fn_emit(ptr %t267) + call void @fn_emit(ptr @.str1974) + %t268 = load ptr, ptr %t225 + %t269 = call ptr @fn_str_concat(ptr @.str1975, ptr %t268) + %t270 = call ptr @fn_str_concat(ptr %t269, ptr @.str1976) + %t271 = call ptr @fn_emit_bind(ptr %t270) + store ptr %t271, ptr %t272 + call void @fn_emit(ptr @.str1977) + %t273 = load ptr, ptr %t272 + call void @fn_emit(ptr %t273) + call void @fn_emit(ptr @.str1978) + %t274 = load ptr, ptr %t212 + call void @fn_emit(ptr %t274) + call void @fn_emit(ptr @.str1979) + call void @fn_emit(ptr @.str1980) + %t275 = load ptr, ptr %t215 + call void @fn_emit(ptr %t275) + call void @fn_emit(ptr @.str1981) + %t276 = load ptr, ptr %t219 + call void @fn_emit(ptr %t276) + call void @fn_emit(ptr @.str1982) + call void @fn_emit(ptr @.str1983) + br label %ifend32 +ifend32: + call void @fn_emit(ptr @.str1984) + call void @fn_emit(ptr @.str1985) + %t277 = load ptr, ptr %t14 + %t278 = getelementptr inbounds %Cmp_Node, ptr %t277, i32 0, i32 2 + %t279 = load i32, ptr %t278 + %t280 = icmp eq i32 %t279, 1 + %t281 = zext i1 %t280 to i32 + %t282 = icmp ne i32 %t281, 0 + br i1 %t282, label %then33, label %else34 +then33: + %t283 = load ptr, ptr %t156 + %t284 = call ptr @fn_str_concat(ptr @.str1986, ptr %t283) + %t285 = call ptr @fn_emit_bind(ptr %t284) + store ptr %t285, ptr %t286 + call void @fn_emit(ptr @.str1987) + %t287 = load ptr, ptr %t286 + call void @fn_emit(ptr %t287) + call void @fn_emit(ptr @.str1988) + br label %ifend35 +else34: + call void @fn_emit(ptr @.str1989) + br label %ifend35 +ifend35: + store ptr null, ptr @g_g_cancel_addr + %t288 = load ptr, ptr %t92 + store ptr %t288, ptr @g_code + store ptr @.str1990, ptr %t289 + %t290 = load ptr, ptr %t14 + %t291 = getelementptr inbounds %Cmp_Node, ptr %t290, i32 0, i32 2 + %t292 = load i32, ptr %t291 + %t293 = icmp eq i32 %t292, 1 + %t294 = zext i1 %t293 to i32 + %t295 = icmp ne i32 %t294, 0 + br i1 %t295, label %then36, label %ifend38 +then36: + store ptr @.str1991, ptr %t289 + br label %ifend38 +ifend38: + call void @fn_emit(ptr @.str1992) + %t296 = load ptr, ptr %t289 + call void @fn_emit(ptr %t296) + call void @fn_emit(ptr @.str1993) + %t297 = load ptr, ptr %t18 + call void @fn_emit(ptr %t297) + call void @fn_emit(ptr @.str1994) + store i32 0, ptr %t298 + br label %wcond39 +wcond39: + %t299 = load i32, ptr %t298 + %t300 = load ptr, ptr %t14 + %t301 = getelementptr inbounds %Cmp_Node, ptr %t300, i32 0, i32 7 + %t302 = load ptr, ptr %t301 + %t303 = getelementptr inbounds %LSlice, ptr %t302, i32 0, i32 1 + %t304 = load i32, ptr %t303 + %t305 = icmp slt i32 %t299, %t304 + %t306 = zext i1 %t305 to i32 + %t307 = icmp ne i32 %t306, 0 + br i1 %t307, label %wbody40, label %wend41 +wbody40: + %t308 = load i32, ptr %t298 + %t309 = icmp sgt i32 %t308, 0 + %t310 = zext i1 %t309 to i32 + %t311 = icmp ne i32 %t310, 0 + br i1 %t311, label %then42, label %ifend44 +then42: + call void @fn_emit(ptr @.str1995) + br label %ifend44 +ifend44: + %t312 = load ptr, ptr %t14 + %t313 = getelementptr inbounds %Cmp_Node, ptr %t312, i32 0, i32 7 + %t314 = load ptr, ptr %t313 + %t315 = getelementptr inbounds %LSlice, ptr %t314, i32 0, i32 0 + %t316 = load ptr, ptr %t315 + %t317 = load i32, ptr %t298 + %t318 = getelementptr inbounds ptr, ptr %t316, i32 %t317 + %t319 = load ptr, ptr %t318 + %t320 = getelementptr inbounds %Cmp_Node, ptr %t319, i32 0, i32 3 + %t321 = load ptr, ptr %t320 + %t322 = call ptr @fn_llty(ptr %t321) + call void @fn_emit(ptr %t322) + call void @fn_emit(ptr @.str1996) + %t323 = load i32, ptr %t298 + %t324 = call ptr @fn_itoa(i32 %t323) + call void @fn_emit(ptr %t324) + %t325 = load i32, ptr %t298 + %t326 = add i32 %t325, 1 + store i32 %t326, ptr %t298 + br label %wcond39 +wend41: + call void @fn_emit(ptr @.str1997) + %t327 = load ptr, ptr @g_falloc + %t328 = call ptr @fn_buf_str(ptr %t327) + call void @fn_emit(ptr %t328) + %t329 = load ptr, ptr %t89 + %t330 = call ptr @fn_buf_str(ptr %t329) + call void @fn_emit(ptr %t330) + call void @fn_emit(ptr @.str1998) + %t331 = load i32, ptr %t0 + %t332 = add i32 %t331, 1 + store i32 %t332, ptr %t0 + br label %wcond0 +wend2: + %t333 = call ptr @fn_itoa(i32 16) + store ptr %t333, ptr %t334 + call void @fn_emit(ptr @.str1999) + store i32 0, ptr %t335 + br label %wcond45 +wcond45: + %t336 = load i32, ptr %t335 + %t337 = load ptr, ptr @g_g_events + %t338 = getelementptr inbounds %LSlice, ptr %t337, i32 0, i32 1 + %t339 = load i32, ptr %t338 + %t340 = icmp slt i32 %t336, %t339 + %t341 = zext i1 %t340 to i32 + %t342 = icmp ne i32 %t341, 0 + br i1 %t342, label %wbody46, label %wend47 +wbody46: + %t343 = load ptr, ptr @g_g_events + %t344 = getelementptr inbounds %LSlice, ptr %t343, i32 0, i32 0 + %t345 = load ptr, ptr %t344 + %t346 = load i32, ptr %t335 + %t347 = getelementptr inbounds ptr, ptr %t345, i32 %t346 + %t348 = load ptr, ptr %t347 + %t349 = getelementptr inbounds %Cmp_Node, ptr %t348, i32 0, i32 1 + %t350 = load ptr, ptr %t349 + store ptr %t350, ptr %t351 + %t352 = load i32, ptr %t335 + %t353 = call ptr @fn_itoa(i32 %t352) + store ptr %t353, ptr %t354 + call void @fn_emit(ptr @.str2000) + %t355 = load ptr, ptr %t354 + call void @fn_emit(ptr %t355) + call void @fn_emit(ptr @.str2001) + call void @fn_emit(ptr @.str2002) + %t356 = load ptr, ptr %t354 + call void @fn_emit(ptr %t356) + call void @fn_emit(ptr @.str2003) + call void @fn_emit(ptr @.str2004) + %t357 = load ptr, ptr %t354 + call void @fn_emit(ptr %t357) + call void @fn_emit(ptr @.str2005) + %t358 = load ptr, ptr %t351 + call void @fn_emit(ptr %t358) + call void @fn_emit(ptr @.str2006) + call void @fn_emit(ptr @.str2007) + %t359 = load ptr, ptr %t354 + call void @fn_emit(ptr %t359) + call void @fn_emit(ptr @.str2008) + %t360 = load ptr, ptr %t354 + call void @fn_emit(ptr %t360) + call void @fn_emit(ptr @.str2009) + %t361 = load ptr, ptr %t354 + call void @fn_emit(ptr %t361) + call void @fn_emit(ptr @.str2010) + call void @fn_emit(ptr @.str2011) + %t362 = load ptr, ptr %t354 + call void @fn_emit(ptr %t362) + call void @fn_emit(ptr @.str2012) + %t363 = load ptr, ptr %t354 + call void @fn_emit(ptr %t363) + call void @fn_emit(ptr @.str2013) + %t364 = load ptr, ptr %t354 + call void @fn_emit(ptr %t364) + call void @fn_emit(ptr @.str2014) + call void @fn_emit(ptr @.str2015) + %t365 = load ptr, ptr %t354 + call void @fn_emit(ptr %t365) + call void @fn_emit(ptr @.str2016) + call void @fn_emit(ptr @.str2017) + %t366 = load ptr, ptr %t354 + call void @fn_emit(ptr %t366) + call void @fn_emit(ptr @.str2018) + %t367 = load ptr, ptr %t334 + call void @fn_emit(ptr %t367) + call void @fn_emit(ptr @.str2019) + %t368 = load ptr, ptr %t351 + call void @fn_emit(ptr %t368) + call void @fn_emit(ptr @.str2020) + %t369 = load ptr, ptr %t354 + call void @fn_emit(ptr %t369) + call void @fn_emit(ptr @.str2021) + call void @fn_emit(ptr @.str2022) + %t370 = load ptr, ptr %t354 + call void @fn_emit(ptr %t370) + call void @fn_emit(ptr @.str2023) + %t371 = load ptr, ptr %t354 + call void @fn_emit(ptr %t371) + call void @fn_emit(ptr @.str2024) + call void @fn_emit(ptr @.str2025) + %t372 = load ptr, ptr %t354 + call void @fn_emit(ptr %t372) + call void @fn_emit(ptr @.str2026) + %t373 = load ptr, ptr %t354 + call void @fn_emit(ptr %t373) + call void @fn_emit(ptr @.str2027) + call void @fn_emit(ptr @.str2028) + %t374 = load ptr, ptr %t354 + call void @fn_emit(ptr %t374) + call void @fn_emit(ptr @.str2029) + %t375 = load ptr, ptr %t354 + call void @fn_emit(ptr %t375) + call void @fn_emit(ptr @.str2030) + %t376 = load ptr, ptr %t354 + call void @fn_emit(ptr %t376) + call void @fn_emit(ptr @.str2031) + call void @fn_emit(ptr @.str2032) + %t377 = load ptr, ptr %t354 + call void @fn_emit(ptr %t377) + call void @fn_emit(ptr @.str2033) + call void @fn_emit(ptr @.str2034) + %t378 = load ptr, ptr %t354 + call void @fn_emit(ptr %t378) + call void @fn_emit(ptr @.str2035) + %t379 = load ptr, ptr %t334 + call void @fn_emit(ptr %t379) + call void @fn_emit(ptr @.str2036) + %t380 = load ptr, ptr %t351 + call void @fn_emit(ptr %t380) + call void @fn_emit(ptr @.str2037) + %t381 = load ptr, ptr %t354 + call void @fn_emit(ptr %t381) + call void @fn_emit(ptr @.str2038) + call void @fn_emit(ptr @.str2039) + %t382 = load ptr, ptr %t354 + call void @fn_emit(ptr %t382) + call void @fn_emit(ptr @.str2040) + %t383 = load ptr, ptr %t354 + call void @fn_emit(ptr %t383) + call void @fn_emit(ptr @.str2041) + call void @fn_emit(ptr @.str2042) + %t384 = load ptr, ptr %t354 + call void @fn_emit(ptr %t384) + call void @fn_emit(ptr @.str2043) + call void @fn_emit(ptr @.str2044) + %t385 = load ptr, ptr %t354 + call void @fn_emit(ptr %t385) + call void @fn_emit(ptr @.str2045) + %t386 = load ptr, ptr %t354 + call void @fn_emit(ptr %t386) + call void @fn_emit(ptr @.str2046) + %t387 = load ptr, ptr %t354 + call void @fn_emit(ptr %t387) + call void @fn_emit(ptr @.str2047) + %t388 = load ptr, ptr %t354 + call void @fn_emit(ptr %t388) + call void @fn_emit(ptr @.str2048) + call void @fn_emit(ptr @.str2049) + %t389 = load ptr, ptr %t354 + call void @fn_emit(ptr %t389) + call void @fn_emit(ptr @.str2050) + %t390 = load i32, ptr %t335 + %t391 = add i32 %t390, 1 + %t392 = load ptr, ptr @g_g_events + %t393 = getelementptr inbounds %LSlice, ptr %t392, i32 0, i32 1 + %t394 = load i32, ptr %t393 + %t395 = icmp slt i32 %t391, %t394 + %t396 = zext i1 %t395 to i32 + %t397 = icmp ne i32 %t396, 0 + br i1 %t397, label %then48, label %else49 +then48: + call void @fn_emit(ptr @.str2051) + %t398 = load i32, ptr %t335 + %t399 = add i32 %t398, 1 + %t400 = call ptr @fn_itoa(i32 %t399) + call void @fn_emit(ptr %t400) + call void @fn_emit(ptr @.str2052) + br label %ifend50 +else49: + call void @fn_emit(ptr @.str2053) + br label %ifend50 +ifend50: + %t401 = load i32, ptr %t335 + %t402 = add i32 %t401, 1 + store i32 %t402, ptr %t335 + br label %wcond45 +wend47: + call void @fn_emit(ptr @.str2054) + br label %ret +ret: + ret void +} + +define void @fn_emit_world_table() { +entry: + %t1 = alloca ptr + %t2 = alloca i32 + %t3 = alloca i32 + %t28 = alloca ptr + %t29 = alloca i32 + %t30 = alloca i32 + %t58 = alloca ptr + %t61 = alloca ptr + %t101 = alloca ptr + %t104 = alloca ptr + %t111 = alloca i32 + %t132 = alloca ptr + %t138 = alloca ptr + %t181 = alloca ptr + %t185 = alloca ptr + %t188 = alloca ptr + %t199 = alloca i32 + %t220 = alloca ptr + %t226 = alloca ptr + %t293 = alloca ptr + %t297 = alloca ptr + %t300 = alloca ptr + %t311 = alloca i32 + %t332 = alloca ptr + %t338 = alloca ptr + %t401 = alloca ptr + %t404 = alloca ptr + %t459 = alloca ptr + %t462 = alloca ptr + %t512 = alloca ptr + %t514 = alloca ptr + %t517 = alloca ptr + %t520 = alloca ptr + %t526 = alloca ptr + %t562 = alloca ptr + %t565 = alloca ptr + %t0 = call ptr @fn_itoa(i32 1024) + store ptr %t0, ptr %t1 + call void @fn_emith(ptr @.str2055) + store i32 0, ptr %t2 + store i32 0, ptr %t3 + br label %wcond0 +wcond0: + %t4 = load i32, ptr %t3 + %t5 = load ptr, ptr @g_prog + %t6 = getelementptr inbounds %LSlice, ptr %t5, i32 0, i32 1 + %t7 = load i32, ptr %t6 + %t8 = icmp slt i32 %t4, %t7 + %t9 = zext i1 %t8 to i32 + %t10 = icmp ne i32 %t9, 0 + br i1 %t10, label %wbody1, label %wend2 +wbody1: + %t11 = load ptr, ptr @g_prog + %t12 = getelementptr inbounds %LSlice, ptr %t11, i32 0, i32 0 + %t13 = load ptr, ptr %t12 + %t14 = load i32, ptr %t3 + %t15 = getelementptr inbounds ptr, ptr %t13, i32 %t14 + %t16 = load ptr, ptr %t15 + %t17 = getelementptr inbounds %Cmp_Node, ptr %t16, i32 0, i32 0 + %t18 = load i32, ptr %t17 + %t19 = icmp eq i32 %t18, 8 + %t20 = zext i1 %t19 to i32 + %t21 = icmp ne i32 %t20, 0 + br i1 %t21, label %then3, label %ifend5 +then3: + %t22 = load i32, ptr %t2 + %t23 = add i32 %t22, 1 + store i32 %t23, ptr %t2 + br label %ifend5 +ifend5: + %t24 = load i32, ptr %t3 + %t25 = add i32 %t24, 1 + store i32 %t25, ptr %t3 + br label %wcond0 +wend2: + %t26 = load i32, ptr %t2 + %t27 = call ptr @fn_itoa(i32 %t26) + store ptr %t27, ptr %t28 + call void @fn_emith(ptr @.str2056) + call void @fn_emith(ptr @.str2057) + call void @fn_emith(ptr @.str2058) + call void @fn_emith(ptr @.str2059) + call void @fn_emith(ptr @.str2060) + call void @fn_emit(ptr @.str2061) + store i32 0, ptr %t29 + store i32 0, ptr %t30 + br label %wcond6 +wcond6: + %t31 = load i32, ptr %t30 + %t32 = load ptr, ptr @g_prog + %t33 = getelementptr inbounds %LSlice, ptr %t32, i32 0, i32 1 + %t34 = load i32, ptr %t33 + %t35 = icmp slt i32 %t31, %t34 + %t36 = zext i1 %t35 to i32 + %t37 = icmp ne i32 %t36, 0 + br i1 %t37, label %wbody7, label %wend8 +wbody7: + %t38 = load ptr, ptr @g_prog + %t39 = getelementptr inbounds %LSlice, ptr %t38, i32 0, i32 0 + %t40 = load ptr, ptr %t39 + %t41 = load i32, ptr %t30 + %t42 = getelementptr inbounds ptr, ptr %t40, i32 %t41 + %t43 = load ptr, ptr %t42 + %t44 = getelementptr inbounds %Cmp_Node, ptr %t43, i32 0, i32 0 + %t45 = load i32, ptr %t44 + %t46 = icmp eq i32 %t45, 8 + %t47 = zext i1 %t46 to i32 + %t48 = icmp ne i32 %t47, 0 + br i1 %t48, label %then9, label %ifend11 +then9: + %t49 = load ptr, ptr @g_prog + %t50 = getelementptr inbounds %LSlice, ptr %t49, i32 0, i32 0 + %t51 = load ptr, ptr %t50 + %t52 = load i32, ptr %t30 + %t53 = getelementptr inbounds ptr, ptr %t51, i32 %t52 + %t54 = load ptr, ptr %t53 + %t55 = getelementptr inbounds %Cmp_Node, ptr %t54, i32 0, i32 1 + %t56 = load ptr, ptr %t55 + %t57 = call ptr @fn_emit_str_const(ptr %t56) + store ptr %t57, ptr %t58 + %t59 = load i32, ptr %t29 + %t60 = call ptr @fn_itoa(i32 %t59) + store ptr %t60, ptr %t61 + call void @fn_emit(ptr @.str2062) + %t62 = load ptr, ptr %t61 + call void @fn_emit(ptr %t62) + call void @fn_emit(ptr @.str2063) + %t63 = load ptr, ptr %t58 + call void @fn_emit(ptr %t63) + call void @fn_emit(ptr @.str2064) + call void @fn_emit(ptr @.str2065) + %t64 = load ptr, ptr %t61 + call void @fn_emit(ptr %t64) + call void @fn_emit(ptr @.str2066) + %t65 = load ptr, ptr %t61 + call void @fn_emit(ptr %t65) + call void @fn_emit(ptr @.str2067) + call void @fn_emit(ptr @.str2068) + %t66 = load ptr, ptr %t61 + call void @fn_emit(ptr %t66) + call void @fn_emit(ptr @.str2069) + %t67 = load ptr, ptr %t61 + call void @fn_emit(ptr %t67) + call void @fn_emit(ptr @.str2070) + %t68 = load ptr, ptr %t61 + call void @fn_emit(ptr %t68) + call void @fn_emit(ptr @.str2071) + call void @fn_emit(ptr @.str2072) + %t69 = load ptr, ptr %t61 + call void @fn_emit(ptr %t69) + call void @fn_emit(ptr @.str2073) + %t70 = load ptr, ptr %t61 + call void @fn_emit(ptr %t70) + call void @fn_emit(ptr @.str2074) + call void @fn_emit(ptr @.str2075) + %t71 = load ptr, ptr %t61 + call void @fn_emit(ptr %t71) + call void @fn_emit(ptr @.str2076) + %t72 = load i32, ptr %t29 + %t73 = add i32 %t72, 1 + store i32 %t73, ptr %t29 + br label %ifend11 +ifend11: + %t74 = load i32, ptr %t30 + %t75 = add i32 %t74, 1 + store i32 %t75, ptr %t30 + br label %wcond6 +wend8: + call void @fn_emit(ptr @.str2077) + call void @fn_emit(ptr @.str2078) + call void @fn_emit(ptr @.str2079) + call void @fn_emit(ptr @.str2080) + %t76 = load ptr, ptr %t28 + call void @fn_emit(ptr %t76) + call void @fn_emit(ptr @.str2081) + call void @fn_emit(ptr @.str2082) + call void @fn_emit(ptr @.str2083) + call void @fn_emit(ptr @.str2084) + store i32 0, ptr %t29 + store i32 0, ptr %t30 + br label %wcond12 +wcond12: + %t77 = load i32, ptr %t30 + %t78 = load ptr, ptr @g_prog + %t79 = getelementptr inbounds %LSlice, ptr %t78, i32 0, i32 1 + %t80 = load i32, ptr %t79 + %t81 = icmp slt i32 %t77, %t80 + %t82 = zext i1 %t81 to i32 + %t83 = icmp ne i32 %t82, 0 + br i1 %t83, label %wbody13, label %wend14 +wbody13: + %t84 = load ptr, ptr @g_prog + %t85 = getelementptr inbounds %LSlice, ptr %t84, i32 0, i32 0 + %t86 = load ptr, ptr %t85 + %t87 = load i32, ptr %t30 + %t88 = getelementptr inbounds ptr, ptr %t86, i32 %t87 + %t89 = load ptr, ptr %t88 + %t90 = getelementptr inbounds %Cmp_Node, ptr %t89, i32 0, i32 0 + %t91 = load i32, ptr %t90 + %t92 = icmp eq i32 %t91, 8 + %t93 = zext i1 %t92 to i32 + %t94 = icmp ne i32 %t93, 0 + br i1 %t94, label %then15, label %ifend17 +then15: + %t95 = load ptr, ptr @g_prog + %t96 = getelementptr inbounds %LSlice, ptr %t95, i32 0, i32 0 + %t97 = load ptr, ptr %t96 + %t98 = load i32, ptr %t30 + %t99 = getelementptr inbounds ptr, ptr %t97, i32 %t98 + %t100 = load ptr, ptr %t99 + store ptr %t100, ptr %t101 + %t102 = load i32, ptr %t29 + %t103 = call ptr @fn_itoa(i32 %t102) + store ptr %t103, ptr %t104 + call void @fn_emit(ptr @.str2085) + %t105 = load ptr, ptr %t104 + call void @fn_emit(ptr %t105) + call void @fn_emit(ptr @.str2086) + %t106 = load ptr, ptr %t104 + call void @fn_emit(ptr %t106) + call void @fn_emit(ptr @.str2087) + call void @fn_emit(ptr @.str2088) + %t107 = load ptr, ptr %t104 + call void @fn_emit(ptr %t107) + call void @fn_emit(ptr @.str2089) + %t108 = load ptr, ptr %t104 + call void @fn_emit(ptr %t108) + call void @fn_emit(ptr @.str2090) + %t109 = load ptr, ptr %t104 + call void @fn_emit(ptr %t109) + call void @fn_emit(ptr @.str2091) + call void @fn_emit(ptr @.str2092) + %t110 = load ptr, ptr %t104 + call void @fn_emit(ptr %t110) + call void @fn_emit(ptr @.str2093) + store i32 0, ptr %t111 + br label %wcond18 +wcond18: + %t112 = load i32, ptr %t111 + %t113 = load ptr, ptr %t101 + %t114 = getelementptr inbounds %Cmp_Node, ptr %t113, i32 0, i32 7 + %t115 = load ptr, ptr %t114 + %t116 = getelementptr inbounds %LSlice, ptr %t115, i32 0, i32 1 + %t117 = load i32, ptr %t116 + %t118 = icmp slt i32 %t112, %t117 + %t119 = zext i1 %t118 to i32 + %t120 = icmp ne i32 %t119, 0 + br i1 %t120, label %wbody19, label %wend20 +wbody19: + %t121 = load ptr, ptr %t101 + %t122 = getelementptr inbounds %Cmp_Node, ptr %t121, i32 0, i32 7 + %t123 = load ptr, ptr %t122 + %t124 = getelementptr inbounds %LSlice, ptr %t123, i32 0, i32 0 + %t125 = load ptr, ptr %t124 + %t126 = load i32, ptr %t111 + %t127 = getelementptr inbounds ptr, ptr %t125, i32 %t126 + %t128 = load ptr, ptr %t127 + %t129 = getelementptr inbounds %Cmp_Node, ptr %t128, i32 0, i32 1 + %t130 = load ptr, ptr %t129 + %t131 = call ptr @fn_emit_str_const(ptr %t130) + store ptr %t131, ptr %t132 + %t133 = load ptr, ptr %t104 + %t134 = call ptr @fn_str_concat(ptr %t133, ptr @.str2094) + %t135 = load i32, ptr %t111 + %t136 = call ptr @fn_itoa(i32 %t135) + %t137 = call ptr @fn_str_concat(ptr %t134, ptr %t136) + store ptr %t137, ptr %t138 + call void @fn_emit(ptr @.str2095) + %t139 = load ptr, ptr %t138 + call void @fn_emit(ptr %t139) + call void @fn_emit(ptr @.str2096) + %t140 = load ptr, ptr %t132 + call void @fn_emit(ptr %t140) + call void @fn_emit(ptr @.str2097) + call void @fn_emit(ptr @.str2098) + %t141 = load ptr, ptr %t138 + call void @fn_emit(ptr %t141) + call void @fn_emit(ptr @.str2099) + %t142 = load ptr, ptr %t138 + call void @fn_emit(ptr %t142) + call void @fn_emit(ptr @.str2100) + call void @fn_emit(ptr @.str2101) + %t143 = load ptr, ptr %t138 + call void @fn_emit(ptr %t143) + call void @fn_emit(ptr @.str2102) + %t144 = load ptr, ptr %t138 + call void @fn_emit(ptr %t144) + call void @fn_emit(ptr @.str2103) + %t145 = load ptr, ptr %t138 + call void @fn_emit(ptr %t145) + call void @fn_emit(ptr @.str2104) + call void @fn_emit(ptr @.str2105) + %t146 = load ptr, ptr %t138 + call void @fn_emit(ptr %t146) + call void @fn_emit(ptr @.str2106) + %t147 = load i32, ptr %t111 + %t148 = call ptr @fn_itoa(i32 %t147) + call void @fn_emit(ptr %t148) + call void @fn_emit(ptr @.str2107) + call void @fn_emit(ptr @.str2108) + %t149 = load ptr, ptr %t138 + call void @fn_emit(ptr %t149) + call void @fn_emit(ptr @.str2109) + %t150 = load i32, ptr %t111 + %t151 = add i32 %t150, 1 + store i32 %t151, ptr %t111 + br label %wcond18 +wend20: + call void @fn_emit(ptr @.str2110) + call void @fn_emit(ptr @.str2111) + %t152 = load ptr, ptr %t104 + call void @fn_emit(ptr %t152) + call void @fn_emit(ptr @.str2112) + %t153 = load i32, ptr %t29 + %t154 = add i32 %t153, 1 + store i32 %t154, ptr %t29 + br label %ifend17 +ifend17: + %t155 = load i32, ptr %t30 + %t156 = add i32 %t155, 1 + store i32 %t156, ptr %t30 + br label %wcond12 +wend14: + call void @fn_emit(ptr @.str2113) + call void @fn_emit(ptr @.str2114) + store i32 0, ptr %t29 + store i32 0, ptr %t30 + br label %wcond21 +wcond21: + %t157 = load i32, ptr %t30 + %t158 = load ptr, ptr @g_prog + %t159 = getelementptr inbounds %LSlice, ptr %t158, i32 0, i32 1 + %t160 = load i32, ptr %t159 + %t161 = icmp slt i32 %t157, %t160 + %t162 = zext i1 %t161 to i32 + %t163 = icmp ne i32 %t162, 0 + br i1 %t163, label %wbody22, label %wend23 +wbody22: + %t164 = load ptr, ptr @g_prog + %t165 = getelementptr inbounds %LSlice, ptr %t164, i32 0, i32 0 + %t166 = load ptr, ptr %t165 + %t167 = load i32, ptr %t30 + %t168 = getelementptr inbounds ptr, ptr %t166, i32 %t167 + %t169 = load ptr, ptr %t168 + %t170 = getelementptr inbounds %Cmp_Node, ptr %t169, i32 0, i32 0 + %t171 = load i32, ptr %t170 + %t172 = icmp eq i32 %t171, 8 + %t173 = zext i1 %t172 to i32 + %t174 = icmp ne i32 %t173, 0 + br i1 %t174, label %then24, label %ifend26 +then24: + %t175 = load ptr, ptr @g_prog + %t176 = getelementptr inbounds %LSlice, ptr %t175, i32 0, i32 0 + %t177 = load ptr, ptr %t176 + %t178 = load i32, ptr %t30 + %t179 = getelementptr inbounds ptr, ptr %t177, i32 %t178 + %t180 = load ptr, ptr %t179 + store ptr %t180, ptr %t181 + %t182 = load ptr, ptr %t181 + %t183 = getelementptr inbounds %Cmp_Node, ptr %t182, i32 0, i32 1 + %t184 = load ptr, ptr %t183 + store ptr %t184, ptr %t185 + %t186 = load i32, ptr %t29 + %t187 = call ptr @fn_itoa(i32 %t186) + store ptr %t187, ptr %t188 + call void @fn_emit(ptr @.str2115) + %t189 = load ptr, ptr %t188 + call void @fn_emit(ptr %t189) + call void @fn_emit(ptr @.str2116) + %t190 = load ptr, ptr %t188 + call void @fn_emit(ptr %t190) + call void @fn_emit(ptr @.str2117) + call void @fn_emit(ptr @.str2118) + %t191 = load ptr, ptr %t188 + call void @fn_emit(ptr %t191) + call void @fn_emit(ptr @.str2119) + %t192 = load ptr, ptr %t188 + call void @fn_emit(ptr %t192) + call void @fn_emit(ptr @.str2120) + %t193 = load ptr, ptr %t188 + call void @fn_emit(ptr %t193) + call void @fn_emit(ptr @.str2121) + call void @fn_emit(ptr @.str2122) + %t194 = load ptr, ptr %t188 + call void @fn_emit(ptr %t194) + call void @fn_emit(ptr @.str2123) + call void @fn_emit(ptr @.str2124) + %t195 = load ptr, ptr %t188 + call void @fn_emit(ptr %t195) + call void @fn_emit(ptr @.str2125) + %t196 = load ptr, ptr %t1 + call void @fn_emit(ptr %t196) + call void @fn_emit(ptr @.str2126) + %t197 = load ptr, ptr %t185 + call void @fn_emit(ptr %t197) + call void @fn_emit(ptr @.str2127) + %t198 = load ptr, ptr %t185 + call void @fn_emit(ptr %t198) + call void @fn_emit(ptr @.str2128) + store i32 0, ptr %t199 + br label %wcond27 +wcond27: + %t200 = load i32, ptr %t199 + %t201 = load ptr, ptr %t181 + %t202 = getelementptr inbounds %Cmp_Node, ptr %t201, i32 0, i32 7 + %t203 = load ptr, ptr %t202 + %t204 = getelementptr inbounds %LSlice, ptr %t203, i32 0, i32 1 + %t205 = load i32, ptr %t204 + %t206 = icmp slt i32 %t200, %t205 + %t207 = zext i1 %t206 to i32 + %t208 = icmp ne i32 %t207, 0 + br i1 %t208, label %wbody28, label %wend29 +wbody28: + %t209 = load ptr, ptr %t181 + %t210 = getelementptr inbounds %Cmp_Node, ptr %t209, i32 0, i32 7 + %t211 = load ptr, ptr %t210 + %t212 = getelementptr inbounds %LSlice, ptr %t211, i32 0, i32 0 + %t213 = load ptr, ptr %t212 + %t214 = load i32, ptr %t199 + %t215 = getelementptr inbounds ptr, ptr %t213, i32 %t214 + %t216 = load ptr, ptr %t215 + %t217 = getelementptr inbounds %Cmp_Node, ptr %t216, i32 0, i32 3 + %t218 = load ptr, ptr %t217 + %t219 = call ptr @fn_llty(ptr %t218) + store ptr %t219, ptr %t220 + %t221 = load ptr, ptr %t188 + %t222 = call ptr @fn_str_concat(ptr %t221, ptr @.str2129) + %t223 = load i32, ptr %t199 + %t224 = call ptr @fn_itoa(i32 %t223) + %t225 = call ptr @fn_str_concat(ptr %t222, ptr %t224) + store ptr %t225, ptr %t226 + call void @fn_emit(ptr @.str2130) + %t227 = load ptr, ptr %t226 + call void @fn_emit(ptr %t227) + call void @fn_emit(ptr @.str2131) + %t228 = load i32, ptr %t199 + %t229 = call ptr @fn_itoa(i32 %t228) + call void @fn_emit(ptr %t229) + call void @fn_emit(ptr @.str2132) + call void @fn_emit(ptr @.str2133) + %t230 = load ptr, ptr %t226 + call void @fn_emit(ptr %t230) + call void @fn_emit(ptr @.str2134) + %t231 = load ptr, ptr %t226 + call void @fn_emit(ptr %t231) + call void @fn_emit(ptr @.str2135) + %t232 = load ptr, ptr %t226 + call void @fn_emit(ptr %t232) + call void @fn_emit(ptr @.str2136) + call void @fn_emit(ptr @.str2137) + %t233 = load ptr, ptr %t226 + call void @fn_emit(ptr %t233) + call void @fn_emit(ptr @.str2138) + call void @fn_emit(ptr @.str2139) + %t234 = load ptr, ptr %t226 + call void @fn_emit(ptr %t234) + call void @fn_emit(ptr @.str2140) + %t235 = load ptr, ptr %t185 + call void @fn_emit(ptr %t235) + call void @fn_emit(ptr @.str2141) + %t236 = load ptr, ptr %t188 + call void @fn_emit(ptr %t236) + call void @fn_emit(ptr @.str2142) + %t237 = load i32, ptr %t199 + %t238 = call ptr @fn_itoa(i32 %t237) + call void @fn_emit(ptr %t238) + call void @fn_emit(ptr @.str2143) + %t239 = load ptr, ptr %t220 + %t240 = call i32 @fn_str_eq(ptr %t239, ptr @.str2144) + %t241 = icmp ne i32 %t240, 0 + br i1 %t241, label %then30, label %else31 +then30: + call void @fn_emit(ptr @.str2145) + %t242 = load ptr, ptr %t226 + call void @fn_emit(ptr %t242) + call void @fn_emit(ptr @.str2146) + %t243 = load ptr, ptr %t226 + call void @fn_emit(ptr %t243) + call void @fn_emit(ptr @.str2147) + call void @fn_emit(ptr @.str2148) + %t244 = load ptr, ptr %t226 + call void @fn_emit(ptr %t244) + call void @fn_emit(ptr @.str2149) + %t245 = load ptr, ptr %t226 + call void @fn_emit(ptr %t245) + call void @fn_emit(ptr @.str2150) + %t246 = load ptr, ptr %t226 + call void @fn_emit(ptr %t246) + call void @fn_emit(ptr @.str2151) + br label %ifend32 +else31: + %t247 = load ptr, ptr %t220 + %t248 = call i32 @fn_str_eq(ptr %t247, ptr @.str2152) + %t249 = icmp ne i32 %t248, 0 + br i1 %t249, label %then33, label %else34 +then33: + call void @fn_emit(ptr @.str2153) + %t250 = load ptr, ptr %t226 + call void @fn_emit(ptr %t250) + call void @fn_emit(ptr @.str2154) + %t251 = load ptr, ptr %t226 + call void @fn_emit(ptr %t251) + call void @fn_emit(ptr @.str2155) + call void @fn_emit(ptr @.str2156) + %t252 = load ptr, ptr %t226 + call void @fn_emit(ptr %t252) + call void @fn_emit(ptr @.str2157) + %t253 = load ptr, ptr %t226 + call void @fn_emit(ptr %t253) + call void @fn_emit(ptr @.str2158) + %t254 = load ptr, ptr %t226 + call void @fn_emit(ptr %t254) + call void @fn_emit(ptr @.str2159) + br label %ifend35 +else34: + call void @fn_emit(ptr @.str2160) + %t255 = load ptr, ptr %t226 + call void @fn_emit(ptr %t255) + call void @fn_emit(ptr @.str2161) + %t256 = load ptr, ptr %t226 + call void @fn_emit(ptr %t256) + call void @fn_emit(ptr @.str2162) + call void @fn_emit(ptr @.str2163) + %t257 = load ptr, ptr %t226 + call void @fn_emit(ptr %t257) + call void @fn_emit(ptr @.str2164) + %t258 = load ptr, ptr %t226 + call void @fn_emit(ptr %t258) + call void @fn_emit(ptr @.str2165) + %t259 = load ptr, ptr %t226 + call void @fn_emit(ptr %t259) + call void @fn_emit(ptr @.str2166) + br label %ifend35 +ifend35: + br label %ifend32 +ifend32: + call void @fn_emit(ptr @.str2167) + %t260 = load ptr, ptr %t226 + call void @fn_emit(ptr %t260) + call void @fn_emit(ptr @.str2168) + %t261 = load i32, ptr %t199 + %t262 = add i32 %t261, 1 + store i32 %t262, ptr %t199 + br label %wcond27 +wend29: + call void @fn_emit(ptr @.str2169) + call void @fn_emit(ptr @.str2170) + %t263 = load ptr, ptr %t188 + call void @fn_emit(ptr %t263) + call void @fn_emit(ptr @.str2171) + %t264 = load i32, ptr %t29 + %t265 = add i32 %t264, 1 + store i32 %t265, ptr %t29 + br label %ifend26 +ifend26: + %t266 = load i32, ptr %t30 + %t267 = add i32 %t266, 1 + store i32 %t267, ptr %t30 + br label %wcond21 +wend23: + call void @fn_emit(ptr @.str2172) + %t268 = load ptr, ptr %t28 + call void @fn_emit(ptr %t268) + call void @fn_emit(ptr @.str2173) + call void @fn_emit(ptr @.str2174) + call void @fn_emit(ptr @.str2175) + call void @fn_emit(ptr @.str2176) + call void @fn_emit(ptr @.str2177) + call void @fn_emit(ptr @.str2178) + call void @fn_emit(ptr @.str2179) + store i32 0, ptr %t29 + store i32 0, ptr %t30 + br label %wcond36 +wcond36: + %t269 = load i32, ptr %t30 + %t270 = load ptr, ptr @g_prog + %t271 = getelementptr inbounds %LSlice, ptr %t270, i32 0, i32 1 + %t272 = load i32, ptr %t271 + %t273 = icmp slt i32 %t269, %t272 + %t274 = zext i1 %t273 to i32 + %t275 = icmp ne i32 %t274, 0 + br i1 %t275, label %wbody37, label %wend38 +wbody37: + %t276 = load ptr, ptr @g_prog + %t277 = getelementptr inbounds %LSlice, ptr %t276, i32 0, i32 0 + %t278 = load ptr, ptr %t277 + %t279 = load i32, ptr %t30 + %t280 = getelementptr inbounds ptr, ptr %t278, i32 %t279 + %t281 = load ptr, ptr %t280 + %t282 = getelementptr inbounds %Cmp_Node, ptr %t281, i32 0, i32 0 + %t283 = load i32, ptr %t282 + %t284 = icmp eq i32 %t283, 8 + %t285 = zext i1 %t284 to i32 + %t286 = icmp ne i32 %t285, 0 + br i1 %t286, label %then39, label %ifend41 +then39: + %t287 = load ptr, ptr @g_prog + %t288 = getelementptr inbounds %LSlice, ptr %t287, i32 0, i32 0 + %t289 = load ptr, ptr %t288 + %t290 = load i32, ptr %t30 + %t291 = getelementptr inbounds ptr, ptr %t289, i32 %t290 + %t292 = load ptr, ptr %t291 + store ptr %t292, ptr %t293 + %t294 = load ptr, ptr %t293 + %t295 = getelementptr inbounds %Cmp_Node, ptr %t294, i32 0, i32 1 + %t296 = load ptr, ptr %t295 + store ptr %t296, ptr %t297 + %t298 = load i32, ptr %t29 + %t299 = call ptr @fn_itoa(i32 %t298) + store ptr %t299, ptr %t300 + call void @fn_emit(ptr @.str2180) + %t301 = load ptr, ptr %t300 + call void @fn_emit(ptr %t301) + call void @fn_emit(ptr @.str2181) + %t302 = load ptr, ptr %t300 + call void @fn_emit(ptr %t302) + call void @fn_emit(ptr @.str2182) + call void @fn_emit(ptr @.str2183) + %t303 = load ptr, ptr %t300 + call void @fn_emit(ptr %t303) + call void @fn_emit(ptr @.str2184) + %t304 = load ptr, ptr %t300 + call void @fn_emit(ptr %t304) + call void @fn_emit(ptr @.str2185) + %t305 = load ptr, ptr %t300 + call void @fn_emit(ptr %t305) + call void @fn_emit(ptr @.str2186) + call void @fn_emit(ptr @.str2187) + %t306 = load ptr, ptr %t300 + call void @fn_emit(ptr %t306) + call void @fn_emit(ptr @.str2188) + call void @fn_emit(ptr @.str2189) + %t307 = load ptr, ptr %t300 + call void @fn_emit(ptr %t307) + call void @fn_emit(ptr @.str2190) + %t308 = load ptr, ptr %t1 + call void @fn_emit(ptr %t308) + call void @fn_emit(ptr @.str2191) + %t309 = load ptr, ptr %t297 + call void @fn_emit(ptr %t309) + call void @fn_emit(ptr @.str2192) + %t310 = load ptr, ptr %t297 + call void @fn_emit(ptr %t310) + call void @fn_emit(ptr @.str2193) + store i32 0, ptr %t311 + br label %wcond42 +wcond42: + %t312 = load i32, ptr %t311 + %t313 = load ptr, ptr %t293 + %t314 = getelementptr inbounds %Cmp_Node, ptr %t313, i32 0, i32 7 + %t315 = load ptr, ptr %t314 + %t316 = getelementptr inbounds %LSlice, ptr %t315, i32 0, i32 1 + %t317 = load i32, ptr %t316 + %t318 = icmp slt i32 %t312, %t317 + %t319 = zext i1 %t318 to i32 + %t320 = icmp ne i32 %t319, 0 + br i1 %t320, label %wbody43, label %wend44 +wbody43: + %t321 = load ptr, ptr %t293 + %t322 = getelementptr inbounds %Cmp_Node, ptr %t321, i32 0, i32 7 + %t323 = load ptr, ptr %t322 + %t324 = getelementptr inbounds %LSlice, ptr %t323, i32 0, i32 0 + %t325 = load ptr, ptr %t324 + %t326 = load i32, ptr %t311 + %t327 = getelementptr inbounds ptr, ptr %t325, i32 %t326 + %t328 = load ptr, ptr %t327 + %t329 = getelementptr inbounds %Cmp_Node, ptr %t328, i32 0, i32 3 + %t330 = load ptr, ptr %t329 + %t331 = call ptr @fn_llty(ptr %t330) + store ptr %t331, ptr %t332 + %t333 = load ptr, ptr %t300 + %t334 = call ptr @fn_str_concat(ptr %t333, ptr @.str2194) + %t335 = load i32, ptr %t311 + %t336 = call ptr @fn_itoa(i32 %t335) + %t337 = call ptr @fn_str_concat(ptr %t334, ptr %t336) + store ptr %t337, ptr %t338 + call void @fn_emit(ptr @.str2195) + %t339 = load ptr, ptr %t338 + call void @fn_emit(ptr %t339) + call void @fn_emit(ptr @.str2196) + %t340 = load i32, ptr %t311 + %t341 = call ptr @fn_itoa(i32 %t340) + call void @fn_emit(ptr %t341) + call void @fn_emit(ptr @.str2197) + call void @fn_emit(ptr @.str2198) + %t342 = load ptr, ptr %t338 + call void @fn_emit(ptr %t342) + call void @fn_emit(ptr @.str2199) + %t343 = load ptr, ptr %t338 + call void @fn_emit(ptr %t343) + call void @fn_emit(ptr @.str2200) + %t344 = load ptr, ptr %t338 + call void @fn_emit(ptr %t344) + call void @fn_emit(ptr @.str2201) + call void @fn_emit(ptr @.str2202) + %t345 = load ptr, ptr %t338 + call void @fn_emit(ptr %t345) + call void @fn_emit(ptr @.str2203) + call void @fn_emit(ptr @.str2204) + %t346 = load ptr, ptr %t338 + call void @fn_emit(ptr %t346) + call void @fn_emit(ptr @.str2205) + %t347 = load ptr, ptr %t297 + call void @fn_emit(ptr %t347) + call void @fn_emit(ptr @.str2206) + %t348 = load ptr, ptr %t300 + call void @fn_emit(ptr %t348) + call void @fn_emit(ptr @.str2207) + %t349 = load i32, ptr %t311 + %t350 = call ptr @fn_itoa(i32 %t349) + call void @fn_emit(ptr %t350) + call void @fn_emit(ptr @.str2208) + %t351 = load ptr, ptr %t332 + %t352 = call i32 @fn_str_eq(ptr %t351, ptr @.str2209) + %t353 = icmp ne i32 %t352, 0 + br i1 %t353, label %then45, label %else46 +then45: + call void @fn_emit(ptr @.str2210) + %t354 = load ptr, ptr %t338 + call void @fn_emit(ptr %t354) + call void @fn_emit(ptr @.str2211) + call void @fn_emit(ptr @.str2212) + %t355 = load ptr, ptr %t338 + call void @fn_emit(ptr %t355) + call void @fn_emit(ptr @.str2213) + %t356 = load ptr, ptr %t338 + call void @fn_emit(ptr %t356) + call void @fn_emit(ptr @.str2214) + br label %ifend47 +else46: + %t357 = load ptr, ptr %t332 + %t358 = call i32 @fn_str_eq(ptr %t357, ptr @.str2215) + %t359 = icmp ne i32 %t358, 0 + br i1 %t359, label %then48, label %else49 +then48: + call void @fn_emit(ptr @.str2216) + %t360 = load ptr, ptr %t338 + call void @fn_emit(ptr %t360) + call void @fn_emit(ptr @.str2217) + call void @fn_emit(ptr @.str2218) + %t361 = load ptr, ptr %t338 + call void @fn_emit(ptr %t361) + call void @fn_emit(ptr @.str2219) + %t362 = load ptr, ptr %t338 + call void @fn_emit(ptr %t362) + call void @fn_emit(ptr @.str2220) + br label %ifend50 +else49: + call void @fn_emit(ptr @.str2221) + %t363 = load ptr, ptr %t338 + call void @fn_emit(ptr %t363) + call void @fn_emit(ptr @.str2222) + call void @fn_emit(ptr @.str2223) + %t364 = load ptr, ptr %t338 + call void @fn_emit(ptr %t364) + call void @fn_emit(ptr @.str2224) + %t365 = load ptr, ptr %t338 + call void @fn_emit(ptr %t365) + call void @fn_emit(ptr @.str2225) + br label %ifend50 +ifend50: + br label %ifend47 +ifend47: + call void @fn_emit(ptr @.str2226) + %t366 = load ptr, ptr %t338 + call void @fn_emit(ptr %t366) + call void @fn_emit(ptr @.str2227) + %t367 = load i32, ptr %t311 + %t368 = add i32 %t367, 1 + store i32 %t368, ptr %t311 + br label %wcond42 +wend44: + call void @fn_emit(ptr @.str2228) + call void @fn_emit(ptr @.str2229) + %t369 = load ptr, ptr %t300 + call void @fn_emit(ptr %t369) + call void @fn_emit(ptr @.str2230) + %t370 = load i32, ptr %t29 + %t371 = add i32 %t370, 1 + store i32 %t371, ptr %t29 + br label %ifend41 +ifend41: + %t372 = load i32, ptr %t30 + %t373 = add i32 %t372, 1 + store i32 %t373, ptr %t30 + br label %wcond36 +wend38: + call void @fn_emit(ptr @.str2231) + %t374 = load ptr, ptr %t28 + call void @fn_emit(ptr %t374) + call void @fn_emit(ptr @.str2232) + call void @fn_emit(ptr @.str2233) + call void @fn_emit(ptr @.str2234) + call void @fn_emit(ptr @.str2235) + call void @fn_emit(ptr @.str2236) + call void @fn_emit(ptr @.str2237) + call void @fn_emit(ptr @.str2238) + store i32 0, ptr %t29 + store i32 0, ptr %t30 + br label %wcond51 +wcond51: + %t375 = load i32, ptr %t30 + %t376 = load ptr, ptr @g_prog + %t377 = getelementptr inbounds %LSlice, ptr %t376, i32 0, i32 1 + %t378 = load i32, ptr %t377 + %t379 = icmp slt i32 %t375, %t378 + %t380 = zext i1 %t379 to i32 + %t381 = icmp ne i32 %t380, 0 + br i1 %t381, label %wbody52, label %wend53 +wbody52: + %t382 = load ptr, ptr @g_prog + %t383 = getelementptr inbounds %LSlice, ptr %t382, i32 0, i32 0 + %t384 = load ptr, ptr %t383 + %t385 = load i32, ptr %t30 + %t386 = getelementptr inbounds ptr, ptr %t384, i32 %t385 + %t387 = load ptr, ptr %t386 + %t388 = getelementptr inbounds %Cmp_Node, ptr %t387, i32 0, i32 0 + %t389 = load i32, ptr %t388 + %t390 = icmp eq i32 %t389, 8 + %t391 = zext i1 %t390 to i32 + %t392 = icmp ne i32 %t391, 0 + br i1 %t392, label %then54, label %ifend56 +then54: + %t393 = load ptr, ptr @g_prog + %t394 = getelementptr inbounds %LSlice, ptr %t393, i32 0, i32 0 + %t395 = load ptr, ptr %t394 + %t396 = load i32, ptr %t30 + %t397 = getelementptr inbounds ptr, ptr %t395, i32 %t396 + %t398 = load ptr, ptr %t397 + %t399 = getelementptr inbounds %Cmp_Node, ptr %t398, i32 0, i32 1 + %t400 = load ptr, ptr %t399 + store ptr %t400, ptr %t401 + %t402 = load i32, ptr %t29 + %t403 = call ptr @fn_itoa(i32 %t402) + store ptr %t403, ptr %t404 + call void @fn_emit(ptr @.str2239) + %t405 = load ptr, ptr %t404 + call void @fn_emit(ptr %t405) + call void @fn_emit(ptr @.str2240) + %t406 = load ptr, ptr %t404 + call void @fn_emit(ptr %t406) + call void @fn_emit(ptr @.str2241) + call void @fn_emit(ptr @.str2242) + %t407 = load ptr, ptr %t404 + call void @fn_emit(ptr %t407) + call void @fn_emit(ptr @.str2243) + %t408 = load ptr, ptr %t404 + call void @fn_emit(ptr %t408) + call void @fn_emit(ptr @.str2244) + %t409 = load ptr, ptr %t404 + call void @fn_emit(ptr %t409) + call void @fn_emit(ptr @.str2245) + call void @fn_emit(ptr @.str2246) + %t410 = load ptr, ptr %t404 + call void @fn_emit(ptr %t410) + call void @fn_emit(ptr @.str2247) + call void @fn_emit(ptr @.str2248) + %t411 = load ptr, ptr %t404 + call void @fn_emit(ptr %t411) + call void @fn_emit(ptr @.str2249) + %t412 = load ptr, ptr %t1 + call void @fn_emit(ptr %t412) + call void @fn_emit(ptr @.str2250) + %t413 = load ptr, ptr %t401 + call void @fn_emit(ptr %t413) + call void @fn_emit(ptr @.str2251) + call void @fn_emit(ptr @.str2252) + %t414 = load ptr, ptr %t404 + call void @fn_emit(ptr %t414) + call void @fn_emit(ptr @.str2253) + %t415 = load ptr, ptr %t404 + call void @fn_emit(ptr %t415) + call void @fn_emit(ptr @.str2254) + call void @fn_emit(ptr @.str2255) + %t416 = load ptr, ptr %t404 + call void @fn_emit(ptr %t416) + call void @fn_emit(ptr @.str2256) + %t417 = load ptr, ptr %t404 + call void @fn_emit(ptr %t417) + call void @fn_emit(ptr @.str2257) + %t418 = load ptr, ptr %t404 + call void @fn_emit(ptr %t418) + call void @fn_emit(ptr @.str2258) + call void @fn_emit(ptr @.str2259) + %t419 = load ptr, ptr %t404 + call void @fn_emit(ptr %t419) + call void @fn_emit(ptr @.str2260) + %t420 = load i32, ptr %t29 + %t421 = add i32 %t420, 1 + store i32 %t421, ptr %t29 + br label %ifend56 +ifend56: + %t422 = load i32, ptr %t30 + %t423 = add i32 %t422, 1 + store i32 %t423, ptr %t30 + br label %wcond51 +wend53: + call void @fn_emit(ptr @.str2261) + %t424 = load ptr, ptr %t28 + call void @fn_emit(ptr %t424) + call void @fn_emit(ptr @.str2262) + call void @fn_emit(ptr @.str2263) + call void @fn_emit(ptr @.str2264) + call void @fn_emit(ptr @.str2265) + call void @fn_emit(ptr @.str2266) + call void @fn_emit(ptr @.str2267) + call void @fn_emit(ptr @.str2268) + %t425 = load ptr, ptr %t1 + call void @fn_emit(ptr %t425) + call void @fn_emit(ptr @.str2269) + call void @fn_emit(ptr @.str2270) + call void @fn_emit(ptr @.str2271) + call void @fn_emit(ptr @.str2272) + %t426 = load ptr, ptr %t1 + call void @fn_emit(ptr %t426) + call void @fn_emit(ptr @.str2273) + %t427 = load ptr, ptr %t1 + call void @fn_emit(ptr %t427) + call void @fn_emit(ptr @.str2274) + call void @fn_emit(ptr @.str2275) + call void @fn_emit(ptr @.str2276) + call void @fn_emit(ptr @.str2277) + call void @fn_emit(ptr @.str2278) + %t428 = load ptr, ptr %t28 + call void @fn_emit(ptr %t428) + call void @fn_emit(ptr @.str2279) + call void @fn_emit(ptr @.str2280) + call void @fn_emit(ptr @.str2281) + call void @fn_emit(ptr @.str2282) + %t429 = load ptr, ptr %t28 + call void @fn_emit(ptr %t429) + call void @fn_emit(ptr @.str2283) + call void @fn_emit(ptr @.str2284) + call void @fn_emit(ptr @.str2285) + %t430 = load ptr, ptr %t28 + call void @fn_emit(ptr %t430) + call void @fn_emit(ptr @.str2286) + call void @fn_emit(ptr @.str2287) + call void @fn_emit(ptr @.str2288) + call void @fn_emit(ptr @.str2289) + %t431 = load ptr, ptr %t1 + call void @fn_emit(ptr %t431) + call void @fn_emit(ptr @.str2290) + call void @fn_emit(ptr @.str2291) + call void @fn_emit(ptr @.str2292) + store i32 0, ptr %t29 + store i32 0, ptr %t30 + br label %wcond57 +wcond57: + %t432 = load i32, ptr %t30 + %t433 = load ptr, ptr @g_prog + %t434 = getelementptr inbounds %LSlice, ptr %t433, i32 0, i32 1 + %t435 = load i32, ptr %t434 + %t436 = icmp slt i32 %t432, %t435 + %t437 = zext i1 %t436 to i32 + %t438 = icmp ne i32 %t437, 0 + br i1 %t438, label %wbody58, label %wend59 +wbody58: + %t439 = load ptr, ptr @g_prog + %t440 = getelementptr inbounds %LSlice, ptr %t439, i32 0, i32 0 + %t441 = load ptr, ptr %t440 + %t442 = load i32, ptr %t30 + %t443 = getelementptr inbounds ptr, ptr %t441, i32 %t442 + %t444 = load ptr, ptr %t443 + %t445 = getelementptr inbounds %Cmp_Node, ptr %t444, i32 0, i32 0 + %t446 = load i32, ptr %t445 + %t447 = icmp eq i32 %t446, 10 + %t448 = zext i1 %t447 to i32 + %t449 = icmp ne i32 %t448, 0 + br i1 %t449, label %then60, label %ifend62 +then60: + %t450 = load ptr, ptr @g_prog + %t451 = getelementptr inbounds %LSlice, ptr %t450, i32 0, i32 0 + %t452 = load ptr, ptr %t451 + %t453 = load i32, ptr %t30 + %t454 = getelementptr inbounds ptr, ptr %t452, i32 %t453 + %t455 = load ptr, ptr %t454 + %t456 = getelementptr inbounds %Cmp_Node, ptr %t455, i32 0, i32 1 + %t457 = load ptr, ptr %t456 + %t458 = call ptr @fn_emit_str_const(ptr %t457) + store ptr %t458, ptr %t459 + %t460 = load i32, ptr %t29 + %t461 = call ptr @fn_itoa(i32 %t460) + store ptr %t461, ptr %t462 + call void @fn_emit(ptr @.str2293) + %t463 = load ptr, ptr %t462 + call void @fn_emit(ptr %t463) + call void @fn_emit(ptr @.str2294) + %t464 = load ptr, ptr %t459 + call void @fn_emit(ptr %t464) + call void @fn_emit(ptr @.str2295) + call void @fn_emit(ptr @.str2296) + %t465 = load ptr, ptr %t462 + call void @fn_emit(ptr %t465) + call void @fn_emit(ptr @.str2297) + %t466 = load ptr, ptr %t462 + call void @fn_emit(ptr %t466) + call void @fn_emit(ptr @.str2298) + call void @fn_emit(ptr @.str2299) + %t467 = load ptr, ptr %t462 + call void @fn_emit(ptr %t467) + call void @fn_emit(ptr @.str2300) + %t468 = load ptr, ptr %t462 + call void @fn_emit(ptr %t468) + call void @fn_emit(ptr @.str2301) + %t469 = load ptr, ptr %t462 + call void @fn_emit(ptr %t469) + call void @fn_emit(ptr @.str2302) + call void @fn_emit(ptr @.str2303) + %t470 = load ptr, ptr %t462 + call void @fn_emit(ptr %t470) + call void @fn_emit(ptr @.str2304) + %t471 = load ptr, ptr @g_prog + %t472 = getelementptr inbounds %LSlice, ptr %t471, i32 0, i32 0 + %t473 = load ptr, ptr %t472 + %t474 = load i32, ptr %t30 + %t475 = getelementptr inbounds ptr, ptr %t473, i32 %t474 + %t476 = load ptr, ptr %t475 + %t477 = getelementptr inbounds %Cmp_Node, ptr %t476, i32 0, i32 1 + %t478 = load ptr, ptr %t477 + %t479 = call i32 @fn_find_arch_id(ptr %t478) + %t480 = call ptr @fn_itoa(i32 %t479) + call void @fn_emit(ptr %t480) + call void @fn_emit(ptr @.str2305) + call void @fn_emit(ptr @.str2306) + %t481 = load ptr, ptr %t462 + call void @fn_emit(ptr %t481) + call void @fn_emit(ptr @.str2307) + %t482 = load i32, ptr %t29 + %t483 = add i32 %t482, 1 + store i32 %t483, ptr %t29 + br label %ifend62 +ifend62: + %t484 = load i32, ptr %t30 + %t485 = add i32 %t484, 1 + store i32 %t485, ptr %t30 + br label %wcond57 +wend59: + call void @fn_emit(ptr @.str2308) + store i32 0, ptr %t30 + br label %wcond63 +wcond63: + %t486 = load i32, ptr %t30 + %t487 = load ptr, ptr @g_prog + %t488 = getelementptr inbounds %LSlice, ptr %t487, i32 0, i32 1 + %t489 = load i32, ptr %t488 + %t490 = icmp slt i32 %t486, %t489 + %t491 = zext i1 %t490 to i32 + %t492 = icmp ne i32 %t491, 0 + br i1 %t492, label %wbody64, label %wend65 +wbody64: + %t493 = load ptr, ptr @g_prog + %t494 = getelementptr inbounds %LSlice, ptr %t493, i32 0, i32 0 + %t495 = load ptr, ptr %t494 + %t496 = load i32, ptr %t30 + %t497 = getelementptr inbounds ptr, ptr %t495, i32 %t496 + %t498 = load ptr, ptr %t497 + %t499 = getelementptr inbounds %Cmp_Node, ptr %t498, i32 0, i32 0 + %t500 = load i32, ptr %t499 + %t501 = icmp eq i32 %t500, 10 + %t502 = zext i1 %t501 to i32 + %t503 = icmp ne i32 %t502, 0 + br i1 %t503, label %then66, label %ifend68 +then66: + %t504 = load ptr, ptr @g_prog + %t505 = getelementptr inbounds %LSlice, ptr %t504, i32 0, i32 0 + %t506 = load ptr, ptr %t505 + %t507 = load i32, ptr %t30 + %t508 = getelementptr inbounds ptr, ptr %t506, i32 %t507 + %t509 = load ptr, ptr %t508 + %t510 = getelementptr inbounds %Cmp_Node, ptr %t509, i32 0, i32 1 + %t511 = load ptr, ptr %t510 + store ptr %t511, ptr %t512 + store i32 0, ptr @g_ll_t + store i32 0, ptr @g_ll_lbl + store i32 0, ptr @g_g_term + call void @fn_loc_reset() + store i32 0, ptr @g_nloop + store i32 0, ptr @g_nself + store ptr @.str2309, ptr @g_ret_ty + %t513 = call ptr @fn_buf_new() + store ptr %t513, ptr %t514 + %t515 = call ptr @fn_buf_new() + store ptr %t515, ptr @g_falloc + %t516 = load ptr, ptr @g_code + store ptr %t516, ptr %t517 + %t518 = load ptr, ptr %t514 + store ptr %t518, ptr @g_code + %t519 = call ptr @fn_node(i32 22) + store ptr %t519, ptr %t520 + %t521 = load ptr, ptr %t520 + %t522 = getelementptr inbounds %Cmp_Node, ptr %t521, i32 0, i32 1 + %t523 = load ptr, ptr %t512 + store ptr %t523, ptr %t522 + %t524 = load ptr, ptr %t520 + %t525 = call ptr @fn_emit_spawn(ptr %t524) + store ptr %t525, ptr %t526 + call void @fn_emit(ptr @.str2310) + %t527 = load ptr, ptr %t526 + call void @fn_emit(ptr %t527) + call void @fn_emit(ptr @.str2311) + %t528 = load ptr, ptr %t517 + store ptr %t528, ptr @g_code + call void @fn_emit(ptr @.str2312) + %t529 = load ptr, ptr %t512 + call void @fn_emit(ptr %t529) + call void @fn_emit(ptr @.str2313) + %t530 = load ptr, ptr @g_falloc + %t531 = call ptr @fn_buf_str(ptr %t530) + call void @fn_emit(ptr %t531) + %t532 = load ptr, ptr %t514 + %t533 = call ptr @fn_buf_str(ptr %t532) + call void @fn_emit(ptr %t533) + call void @fn_emit(ptr @.str2314) + br label %ifend68 +ifend68: + %t534 = load i32, ptr %t30 + %t535 = add i32 %t534, 1 + store i32 %t535, ptr %t30 + br label %wcond63 +wend65: + call void @fn_emit(ptr @.str2315) + store i32 0, ptr %t29 + store i32 0, ptr %t30 + br label %wcond69 +wcond69: + %t536 = load i32, ptr %t30 + %t537 = load ptr, ptr @g_prog + %t538 = getelementptr inbounds %LSlice, ptr %t537, i32 0, i32 1 + %t539 = load i32, ptr %t538 + %t540 = icmp slt i32 %t536, %t539 + %t541 = zext i1 %t540 to i32 + %t542 = icmp ne i32 %t541, 0 + br i1 %t542, label %wbody70, label %wend71 +wbody70: + %t543 = load ptr, ptr @g_prog + %t544 = getelementptr inbounds %LSlice, ptr %t543, i32 0, i32 0 + %t545 = load ptr, ptr %t544 + %t546 = load i32, ptr %t30 + %t547 = getelementptr inbounds ptr, ptr %t545, i32 %t546 + %t548 = load ptr, ptr %t547 + %t549 = getelementptr inbounds %Cmp_Node, ptr %t548, i32 0, i32 0 + %t550 = load i32, ptr %t549 + %t551 = icmp eq i32 %t550, 10 + %t552 = zext i1 %t551 to i32 + %t553 = icmp ne i32 %t552, 0 + br i1 %t553, label %then72, label %ifend74 +then72: + %t554 = load ptr, ptr @g_prog + %t555 = getelementptr inbounds %LSlice, ptr %t554, i32 0, i32 0 + %t556 = load ptr, ptr %t555 + %t557 = load i32, ptr %t30 + %t558 = getelementptr inbounds ptr, ptr %t556, i32 %t557 + %t559 = load ptr, ptr %t558 + %t560 = getelementptr inbounds %Cmp_Node, ptr %t559, i32 0, i32 1 + %t561 = load ptr, ptr %t560 + store ptr %t561, ptr %t562 + %t563 = load i32, ptr %t29 + %t564 = call ptr @fn_itoa(i32 %t563) + store ptr %t564, ptr %t565 + call void @fn_emit(ptr @.str2316) + %t566 = load ptr, ptr %t565 + call void @fn_emit(ptr %t566) + call void @fn_emit(ptr @.str2317) + %t567 = load ptr, ptr %t562 + %t568 = call i32 @fn_find_arch_id(ptr %t567) + %t569 = call ptr @fn_itoa(i32 %t568) + call void @fn_emit(ptr %t569) + call void @fn_emit(ptr @.str2318) + call void @fn_emit(ptr @.str2319) + %t570 = load ptr, ptr %t565 + call void @fn_emit(ptr %t570) + call void @fn_emit(ptr @.str2320) + %t571 = load ptr, ptr %t565 + call void @fn_emit(ptr %t571) + call void @fn_emit(ptr @.str2321) + %t572 = load ptr, ptr %t565 + call void @fn_emit(ptr %t572) + call void @fn_emit(ptr @.str2322) + call void @fn_emit(ptr @.str2323) + %t573 = load ptr, ptr %t565 + call void @fn_emit(ptr %t573) + call void @fn_emit(ptr @.str2324) + %t574 = load ptr, ptr %t565 + call void @fn_emit(ptr %t574) + call void @fn_emit(ptr @.str2325) + %t575 = load ptr, ptr %t562 + call void @fn_emit(ptr %t575) + call void @fn_emit(ptr @.str2326) + %t576 = load ptr, ptr %t565 + call void @fn_emit(ptr %t576) + call void @fn_emit(ptr @.str2327) + call void @fn_emit(ptr @.str2328) + %t577 = load ptr, ptr %t565 + call void @fn_emit(ptr %t577) + call void @fn_emit(ptr @.str2329) + %t578 = load i32, ptr %t29 + %t579 = add i32 %t578, 1 + store i32 %t579, ptr %t29 + br label %ifend74 +ifend74: + %t580 = load i32, ptr %t30 + %t581 = add i32 %t580, 1 + store i32 %t581, ptr %t30 + br label %wcond69 +wend71: + call void @fn_emit(ptr @.str2330) + call void @fn_emit(ptr @.str2331) + call void @fn_emit(ptr @.str2332) + call void @fn_emit(ptr @.str2333) + call void @fn_emit(ptr @.str2334) + call void @fn_emit(ptr @.str2335) + %t582 = load ptr, ptr %t1 + call void @fn_emit(ptr %t582) + call void @fn_emit(ptr @.str2336) + call void @fn_emit(ptr @.str2337) + call void @fn_emit(ptr @.str2338) + call void @fn_emit(ptr @.str2339) + call void @fn_emit(ptr @.str2340) + call void @fn_emit(ptr @.str2341) + br label %ret +ret: + ret void +} + +define void @fn_emit_tick_helpers() { +entry: + call void @fn_emit(ptr @.str2342) + store i32 0, ptr @g_ll_t + store i32 0, ptr @g_ll_lbl + call void @fn_emit_calls_for_phase(ptr @.str2343) + call void @fn_emit_calls_for_phase(ptr @.str2344) + call void @fn_emit_calls_for_phase(ptr @.str2345) + call void @fn_emit_calls_for_phase(ptr @.str2346) + call void @fn_emit(ptr @.str2347) + call void @fn_emit(ptr @.str2348) + store i32 0, ptr @g_ll_t + store i32 0, ptr @g_ll_lbl + call void @fn_emit_calls_for_phase(ptr @.str2349) + call void @fn_emit(ptr @.str2350) + br label %ret +ret: + ret void +} + +define void @fn_emit_game_defs() { entry: %t0 = alloca i32 - %t32 = alloca ptr - %t37 = alloca ptr - %t43 = alloca ptr - %t48 = alloca ptr - %t55 = alloca ptr - %t63 = alloca ptr store i32 0, ptr %t0 br label %wcond0 wcond0: @@ -19286,93 +27452,198 @@ ifend5: br label %wcond0 wend2: call void @fn_emit_despawn_hooks() - call void @fn_emit(ptr @.str1360) - call void @fn_emit(ptr @.str1361) - call void @fn_emit(ptr @.str1362) - %t27 = call ptr @fn_find_fn(ptr @.str1363) - %t28 = icmp ne ptr %t27, null - %t29 = zext i1 %t28 to i32 - %t30 = icmp ne i32 %t29, 0 - br i1 %t30, label %then6, label %ifend8 -then6: - call void @fn_emit(ptr @.str1364) - br label %ifend8 -ifend8: - call void @fn_emit_calls_for_phase(ptr @.str1365) - call void @fn_emit(ptr @.str1366) - call void @fn_emit(ptr @.str1367) - %t31 = call ptr @fn_emit_bind(ptr @.str1368) - store ptr %t31, ptr %t32 - %t33 = load ptr, ptr %t32 - %t34 = call ptr @fn_str_concat(ptr @.str1369, ptr %t33) - %t35 = call ptr @fn_str_concat(ptr %t34, ptr @.str1370) - %t36 = call ptr @fn_emit_bind(ptr %t35) - store ptr %t36, ptr %t37 - %t38 = call ptr @fn_find_fn(ptr @.str1371) - %t39 = icmp ne ptr %t38, null - %t40 = zext i1 %t39 to i32 - %t41 = icmp ne i32 %t40, 0 - br i1 %t41, label %then9, label %else10 + call void @fn_emit_scene_hooks() + call void @fn_emit_tick_helpers() + br label %ret +ret: + ret void +} + +define void @fn_emit_game_main() { +entry: + %t12 = alloca i32 + %t47 = alloca ptr + %t52 = alloca ptr + %t58 = alloca ptr + %t63 = alloca ptr + %t70 = alloca ptr + %t78 = alloca ptr + call void @fn_emit_game_defs() + call void @fn_emit(ptr @.str2351) + call void @fn_emit(ptr @.str2352) + call void @fn_emit(ptr @.str2353) + %t0 = call ptr @fn_find_fn(ptr @.str2354) + %t1 = icmp ne ptr %t0, null + %t2 = zext i1 %t1 to i32 + %t3 = icmp ne i32 %t2, 0 + br i1 %t3, label %then0, label %ifend2 +then0: + call void @fn_emit(ptr @.str2355) + br label %ifend2 +ifend2: + call void @fn_emit_calls_for_phase(ptr @.str2356) + %t4 = load ptr, ptr @g_g_scenes + %t5 = getelementptr inbounds %LSlice, ptr %t4, i32 0, i32 1 + %t6 = load i32, ptr %t5 + %t7 = icmp sgt i32 %t6, 0 + %t8 = zext i1 %t7 to i32 + %t9 = icmp ne i32 %t8, 0 + br i1 %t9, label %then3, label %ifend5 +then3: + call void @fn_emit(ptr @.str2357) + %t10 = load i32, ptr @g_g_start_scene + %t11 = call ptr @fn_itoa(i32 %t10) + call void @fn_emit(ptr %t11) + call void @fn_emit(ptr @.str2358) + store i32 0, ptr %t12 + br label %wcond6 +wcond6: + %t13 = load i32, ptr %t12 + %t14 = load ptr, ptr @g_g_scenes + %t15 = getelementptr inbounds %LSlice, ptr %t14, i32 0, i32 1 + %t16 = load i32, ptr %t15 + %t17 = icmp slt i32 %t13, %t16 + %t18 = zext i1 %t17 to i32 + %t19 = icmp ne i32 %t18, 0 + br i1 %t19, label %wbody7, label %wend8 +wbody7: + %t20 = load ptr, ptr @g_g_scenes + %t21 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 0 + %t22 = load ptr, ptr %t21 + %t23 = load i32, ptr %t12 + %t24 = getelementptr inbounds ptr, ptr %t22, i32 %t23 + %t25 = load ptr, ptr %t24 + %t26 = getelementptr inbounds %Cmp_Node, ptr %t25, i32 0, i32 2 + %t27 = load i32, ptr %t26 + %t28 = load i32, ptr @g_g_start_scene + %t29 = icmp eq i32 %t27, %t28 + %t30 = zext i1 %t29 to i32 + %t31 = icmp ne i32 %t30, 0 + br i1 %t31, label %then9, label %ifend11 then9: - %t42 = call ptr @fn_emit_bind(ptr @.str1372) - store ptr %t42, ptr %t43 - %t44 = load ptr, ptr %t43 - %t45 = call ptr @fn_str_concat(ptr @.str1373, ptr %t44) - %t46 = call ptr @fn_str_concat(ptr %t45, ptr @.str1374) - %t47 = call ptr @fn_emit_bind(ptr %t46) - store ptr %t47, ptr %t48 - %t49 = load ptr, ptr %t37 - %t50 = call ptr @fn_str_concat(ptr @.str1375, ptr %t49) - %t51 = call ptr @fn_str_concat(ptr %t50, ptr @.str1376) - %t52 = load ptr, ptr %t48 - %t53 = call ptr @fn_str_concat(ptr %t51, ptr %t52) - %t54 = call ptr @fn_emit_bind(ptr %t53) - store ptr %t54, ptr %t55 - call void @fn_emit(ptr @.str1377) - %t56 = load ptr, ptr %t55 - call void @fn_emit(ptr %t56) - call void @fn_emit(ptr @.str1378) - br label %ifend11 -else10: - call void @fn_emit(ptr @.str1379) - %t57 = load ptr, ptr %t37 - call void @fn_emit(ptr %t57) - call void @fn_emit(ptr @.str1380) + call void @fn_emit(ptr @.str2359) + %t32 = load ptr, ptr @g_g_scenes + %t33 = getelementptr inbounds %LSlice, ptr %t32, i32 0, i32 0 + %t34 = load ptr, ptr %t33 + %t35 = load i32, ptr %t12 + %t36 = getelementptr inbounds ptr, ptr %t34, i32 %t35 + %t37 = load ptr, ptr %t36 + %t38 = getelementptr inbounds %Cmp_Node, ptr %t37, i32 0, i32 1 + %t39 = load ptr, ptr %t38 + call void @fn_emit(ptr %t39) + call void @fn_emit(ptr @.str2360) br label %ifend11 ifend11: - call void @fn_emit(ptr @.str1381) - %t58 = call ptr @fn_find_fn(ptr @.str1382) - %t59 = icmp ne ptr %t58, null - %t60 = zext i1 %t59 to i32 - %t61 = icmp ne i32 %t60, 0 - br i1 %t61, label %then12, label %ifend14 + %t40 = load i32, ptr %t12 + %t41 = add i32 %t40, 1 + store i32 %t41, ptr %t12 + br label %wcond6 +wend8: + br label %ifend5 +ifend5: + %t42 = call ptr @fn_find_event(ptr @.str2361) + %t43 = icmp ne ptr %t42, null + %t44 = zext i1 %t43 to i32 + %t45 = icmp ne i32 %t44, 0 + br i1 %t45, label %then12, label %ifend14 then12: - %t62 = call ptr @fn_emit_bind(ptr @.str1383) - store ptr %t62, ptr %t63 - call void @fn_emit(ptr @.str1384) - %t64 = load ptr, ptr %t63 - call void @fn_emit(ptr %t64) - call void @fn_emit(ptr @.str1385) + call void @fn_emit(ptr @.str2362) br label %ifend14 ifend14: - call void @fn_emit_calls_for_phase(ptr @.str1386) - call void @fn_emit_calls_for_phase(ptr @.str1387) - call void @fn_emit_calls_for_phase(ptr @.str1388) - call void @fn_emit_calls_for_phase(ptr @.str1389) - call void @fn_emit_calls_for_phase(ptr @.str1390) - call void @fn_emit(ptr @.str1391) - call void @fn_emit(ptr @.str1392) - call void @fn_emit_calls_for_phase(ptr @.str1393) - %t65 = call ptr @fn_find_fn(ptr @.str1394) - %t66 = icmp ne ptr %t65, null - %t67 = zext i1 %t66 to i32 - %t68 = icmp ne i32 %t67, 0 - br i1 %t68, label %then15, label %ifend17 + call void @fn_emit(ptr @.str2363) + call void @fn_emit(ptr @.str2364) + %t46 = call ptr @fn_emit_bind(ptr @.str2365) + store ptr %t46, ptr %t47 + %t48 = load ptr, ptr %t47 + %t49 = call ptr @fn_str_concat(ptr @.str2366, ptr %t48) + %t50 = call ptr @fn_str_concat(ptr %t49, ptr @.str2367) + %t51 = call ptr @fn_emit_bind(ptr %t50) + store ptr %t51, ptr %t52 + %t53 = call ptr @fn_find_fn(ptr @.str2368) + %t54 = icmp ne ptr %t53, null + %t55 = zext i1 %t54 to i32 + %t56 = icmp ne i32 %t55, 0 + br i1 %t56, label %then15, label %else16 then15: - call void @fn_emit(ptr @.str1395) + %t57 = call ptr @fn_emit_bind(ptr @.str2369) + store ptr %t57, ptr %t58 + %t59 = load ptr, ptr %t58 + %t60 = call ptr @fn_str_concat(ptr @.str2370, ptr %t59) + %t61 = call ptr @fn_str_concat(ptr %t60, ptr @.str2371) + %t62 = call ptr @fn_emit_bind(ptr %t61) + store ptr %t62, ptr %t63 + %t64 = load ptr, ptr %t52 + %t65 = call ptr @fn_str_concat(ptr @.str2372, ptr %t64) + %t66 = call ptr @fn_str_concat(ptr %t65, ptr @.str2373) + %t67 = load ptr, ptr %t63 + %t68 = call ptr @fn_str_concat(ptr %t66, ptr %t67) + %t69 = call ptr @fn_emit_bind(ptr %t68) + store ptr %t69, ptr %t70 + call void @fn_emit(ptr @.str2374) + %t71 = load ptr, ptr %t70 + call void @fn_emit(ptr %t71) + call void @fn_emit(ptr @.str2375) + br label %ifend17 +else16: + call void @fn_emit(ptr @.str2376) + %t72 = load ptr, ptr %t52 + call void @fn_emit(ptr %t72) + call void @fn_emit(ptr @.str2377) br label %ifend17 ifend17: - call void @fn_emit(ptr @.str1396) + call void @fn_emit(ptr @.str2378) + %t73 = call ptr @fn_find_fn(ptr @.str2379) + %t74 = icmp ne ptr %t73, null + %t75 = zext i1 %t74 to i32 + %t76 = icmp ne i32 %t75, 0 + br i1 %t76, label %then18, label %ifend20 +then18: + %t77 = call ptr @fn_emit_bind(ptr @.str2380) + store ptr %t77, ptr %t78 + call void @fn_emit(ptr @.str2381) + %t79 = load ptr, ptr %t78 + call void @fn_emit(ptr %t79) + call void @fn_emit(ptr @.str2382) + br label %ifend20 +ifend20: + call void @fn_emit_calls_for_phase(ptr @.str2383) + call void @fn_emit_calls_for_phase(ptr @.str2384) + call void @fn_emit_calls_for_phase(ptr @.str2385) + call void @fn_emit_calls_for_phase(ptr @.str2386) + call void @fn_emit_calls_for_phase(ptr @.str2387) + call void @fn_emit(ptr @.str2388) + call void @fn_emit(ptr @.str2389) + %t80 = load ptr, ptr @g_g_ondespawn + %t81 = getelementptr inbounds %LSlice, ptr %t80, i32 0, i32 1 + %t82 = load i32, ptr %t81 + %t83 = icmp sgt i32 %t82, 0 + %t84 = zext i1 %t83 to i32 + %t85 = icmp ne i32 %t84, 0 + br i1 %t85, label %then21, label %ifend23 +then21: + call void @fn_emit(ptr @.str2390) + br label %ifend23 +ifend23: + call void @fn_emit_calls_for_phase(ptr @.str2391) + %t86 = call ptr @fn_find_event(ptr @.str2392) + %t87 = icmp ne ptr %t86, null + %t88 = zext i1 %t87 to i32 + %t89 = icmp ne i32 %t88, 0 + br i1 %t89, label %then24, label %ifend26 +then24: + call void @fn_emit(ptr @.str2393) + br label %ifend26 +ifend26: + %t90 = call ptr @fn_find_fn(ptr @.str2394) + %t91 = icmp ne ptr %t90, null + %t92 = zext i1 %t91 to i32 + %t93 = icmp ne i32 %t92, 0 + br i1 %t93, label %then27, label %ifend29 +then27: + call void @fn_emit(ptr @.str2395) + br label %ifend29 +ifend29: + call void @fn_emit(ptr @.str2396) br label %ret ret: ret void @@ -19399,8 +27670,8 @@ entry: %t6 = load ptr, ptr %t5 %t7 = getelementptr inbounds %Cmp_Val, ptr %t6, i32 0, i32 0 %t8 = load ptr, ptr %t7 - %t9 = call ptr @fn_str_concat(ptr @.str1397, ptr %t8) - %t10 = call ptr @fn_str_concat(ptr %t9, ptr @.str1398) + %t9 = call ptr @fn_str_concat(ptr @.str2397, ptr %t8) + %t10 = call ptr @fn_str_concat(ptr %t9, ptr @.str2398) %t11 = call ptr @fn_emit_bind(ptr %t10) store ptr %t11, ptr %t12 %t13 = load i32, ptr @g_nmach @@ -19454,7 +27725,7 @@ ifend2: %t46 = load i32, ptr @g_nmach %t47 = add i32 %t46, 1 store i32 %t47, ptr @g_nmach - %t48 = call ptr @fn_lbl(ptr @.str1399) + %t48 = call ptr @fn_lbl(ptr @.str2399) store ptr %t48, ptr %t49 store i32 0, ptr %t50 br label %wcond5 @@ -19485,31 +27756,31 @@ wbody6: %t72 = call ptr @fn_emit_expr(ptr %t71) store ptr %t72, ptr %t73 %t74 = load ptr, ptr %t12 - %t75 = call ptr @fn_str_concat(ptr @.str1400, ptr %t74) - %t76 = call ptr @fn_str_concat(ptr %t75, ptr @.str1401) + %t75 = call ptr @fn_str_concat(ptr @.str2400, ptr %t74) + %t76 = call ptr @fn_str_concat(ptr %t75, ptr @.str2401) %t77 = load ptr, ptr %t73 %t78 = getelementptr inbounds %Cmp_Val, ptr %t77, i32 0, i32 0 %t79 = load ptr, ptr %t78 %t80 = call ptr @fn_str_concat(ptr %t76, ptr %t79) %t81 = call ptr @fn_emit_bind(ptr %t80) store ptr %t81, ptr %t82 - %t83 = call ptr @fn_lbl(ptr @.str1402) + %t83 = call ptr @fn_lbl(ptr @.str2402) store ptr %t83, ptr %t84 - %t85 = call ptr @fn_lbl(ptr @.str1403) + %t85 = call ptr @fn_lbl(ptr @.str2403) store ptr %t85, ptr %t86 - call void @fn_emit(ptr @.str1404) + call void @fn_emit(ptr @.str2404) %t87 = load ptr, ptr %t82 call void @fn_emit(ptr %t87) - call void @fn_emit(ptr @.str1405) + call void @fn_emit(ptr @.str2405) %t88 = load ptr, ptr %t84 call void @fn_emit(ptr %t88) - call void @fn_emit(ptr @.str1406) + call void @fn_emit(ptr @.str2406) %t89 = load ptr, ptr %t86 call void @fn_emit(ptr %t89) - call void @fn_emit(ptr @.str1407) + call void @fn_emit(ptr @.str2407) %t90 = load ptr, ptr %t84 call void @fn_emit(ptr %t90) - call void @fn_emit(ptr @.str1408) + call void @fn_emit(ptr @.str2408) store i32 0, ptr @g_g_term %t91 = load ptr, ptr %t68 %t92 = getelementptr inbounds %Cmp_Node, ptr %t91, i32 0, i32 4 @@ -19521,15 +27792,15 @@ wbody6: %t97 = icmp ne i32 %t96, 0 br i1 %t97, label %then8, label %ifend10 then8: - call void @fn_emit(ptr @.str1409) + call void @fn_emit(ptr @.str2409) %t98 = load ptr, ptr %t49 call void @fn_emit(ptr %t98) - call void @fn_emit(ptr @.str1410) + call void @fn_emit(ptr @.str2410) br label %ifend10 ifend10: %t99 = load ptr, ptr %t86 call void @fn_emit(ptr %t99) - call void @fn_emit(ptr @.str1411) + call void @fn_emit(ptr @.str2411) store i32 0, ptr @g_g_term %t100 = load i32, ptr %t50 %t101 = add i32 %t100, 1 @@ -19542,15 +27813,15 @@ wend7: %t105 = icmp ne i32 %t104, 0 br i1 %t105, label %then11, label %ifend13 then11: - call void @fn_emit(ptr @.str1412) + call void @fn_emit(ptr @.str2412) %t106 = load ptr, ptr %t49 call void @fn_emit(ptr %t106) - call void @fn_emit(ptr @.str1413) + call void @fn_emit(ptr @.str2413) br label %ifend13 ifend13: %t107 = load ptr, ptr %t49 call void @fn_emit(ptr %t107) - call void @fn_emit(ptr @.str1414) + call void @fn_emit(ptr @.str2414) store i32 0, ptr @g_g_term %t108 = load i32, ptr @g_nmach %t109 = sub i32 %t108, 1 @@ -19566,18 +27837,16 @@ entry: %t12 = alloca ptr %t13 = alloca ptr %t14 = alloca i32 - %t61 = alloca ptr - %t66 = alloca ptr + %t57 = alloca ptr + %t62 = alloca ptr + %t73 = alloca ptr store ptr %arg_st, ptr %t0 %t1 = load i32, ptr @g_nmach - %t2 = icmp eq i32 %t1, 0 + %t2 = icmp sgt i32 %t1, 0 %t3 = zext i1 %t2 to i32 %t4 = icmp ne i32 %t3, 0 br i1 %t4, label %then0, label %ifend2 then0: - call void @fn_perr(ptr @.str1415) - br label %ifend2 -ifend2: %t5 = load ptr, ptr @g_mach_stk %t6 = getelementptr inbounds %LSlice, ptr %t5, i32 0, i32 0 %t7 = load ptr, ptr %t6 @@ -19635,39 +27904,81 @@ ifend8: br label %wcond3 wend5: %t49 = load ptr, ptr %t13 - %t50 = icmp eq ptr %t49, null + %t50 = icmp ne ptr %t49, null %t51 = zext i1 %t50 to i32 %t52 = icmp ne i32 %t51, 0 br i1 %t52, label %then9, label %ifend11 then9: - %t53 = load ptr, ptr %t0 - %t54 = getelementptr inbounds %Cmp_Node, ptr %t53, i32 0, i32 1 + %t53 = load ptr, ptr %t12 + %t54 = getelementptr inbounds %Cmp_Node, ptr %t53, i32 0, i32 4 %t55 = load ptr, ptr %t54 - %t56 = call ptr @fn_str_concat(ptr @.str1416, ptr %t55) - call void @fn_perr(ptr %t56) - br label %ifend11 + %t56 = call ptr @fn_emit_expr(ptr %t55) + store ptr %t56, ptr %t57 + %t58 = load ptr, ptr %t13 + %t59 = getelementptr inbounds %Cmp_Node, ptr %t58, i32 0, i32 5 + %t60 = load ptr, ptr %t59 + %t61 = call ptr @fn_emit_expr(ptr %t60) + store ptr %t61, ptr %t62 + call void @fn_emit(ptr @.str2415) + %t63 = load ptr, ptr %t57 + %t64 = getelementptr inbounds %Cmp_Val, ptr %t63, i32 0, i32 0 + %t65 = load ptr, ptr %t64 + call void @fn_emit(ptr %t65) + call void @fn_emit(ptr @.str2416) + %t66 = load ptr, ptr %t62 + %t67 = getelementptr inbounds %Cmp_Val, ptr %t66, i32 0, i32 0 + %t68 = load ptr, ptr %t67 + call void @fn_emit(ptr %t68) + call void @fn_emit(ptr @.str2417) + br label %ret ifend11: - %t57 = load ptr, ptr %t12 - %t58 = getelementptr inbounds %Cmp_Node, ptr %t57, i32 0, i32 4 - %t59 = load ptr, ptr %t58 - %t60 = call ptr @fn_emit_expr(ptr %t59) - store ptr %t60, ptr %t61 - %t62 = load ptr, ptr %t13 - %t63 = getelementptr inbounds %Cmp_Node, ptr %t62, i32 0, i32 5 - %t64 = load ptr, ptr %t63 - %t65 = call ptr @fn_emit_expr(ptr %t64) - store ptr %t65, ptr %t66 - call void @fn_emit(ptr @.str1417) - %t67 = load ptr, ptr %t61 - %t68 = getelementptr inbounds %Cmp_Val, ptr %t67, i32 0, i32 0 - %t69 = load ptr, ptr %t68 - call void @fn_emit(ptr %t69) - call void @fn_emit(ptr @.str1418) - %t70 = load ptr, ptr %t66 - %t71 = getelementptr inbounds %Cmp_Val, ptr %t70, i32 0, i32 0 - %t72 = load ptr, ptr %t71 - call void @fn_emit(ptr %t72) - call void @fn_emit(ptr @.str1419) + br label %ifend2 +ifend2: + %t69 = load ptr, ptr %t0 + %t70 = getelementptr inbounds %Cmp_Node, ptr %t69, i32 0, i32 1 + %t71 = load ptr, ptr %t70 + %t72 = call ptr @fn_find_scene(ptr %t71) + store ptr %t72, ptr %t73 + %t74 = load ptr, ptr %t73 + %t75 = icmp eq ptr %t74, null + %t76 = zext i1 %t75 to i32 + %t77 = icmp ne i32 %t76, 0 + br i1 %t77, label %then12, label %ifend14 +then12: + %t78 = load ptr, ptr %t0 + %t79 = getelementptr inbounds %Cmp_Node, ptr %t78, i32 0, i32 1 + %t80 = load ptr, ptr %t79 + %t81 = call ptr @fn_str_concat(ptr @.str2418, ptr %t80) + call void @fn_perr(ptr %t81) + br label %ifend14 +ifend14: + %t82 = load ptr, ptr @g_g_cur_scene + %t83 = icmp ne ptr %t82, null + %t84 = zext i1 %t83 to i32 + %t85 = icmp ne i32 %t84, 0 + br i1 %t85, label %then15, label %ifend17 +then15: + call void @fn_emit(ptr @.str2419) + %t86 = load ptr, ptr @g_g_cur_scene + %t87 = getelementptr inbounds %Cmp_Node, ptr %t86, i32 0, i32 1 + %t88 = load ptr, ptr %t87 + call void @fn_emit(ptr %t88) + call void @fn_emit(ptr @.str2420) + br label %ifend17 +ifend17: + call void @fn_emit(ptr @.str2421) + %t89 = load ptr, ptr %t73 + %t90 = getelementptr inbounds %Cmp_Node, ptr %t89, i32 0, i32 2 + %t91 = load i32, ptr %t90 + %t92 = call ptr @fn_itoa(i32 %t91) + call void @fn_emit(ptr %t92) + call void @fn_emit(ptr @.str2422) + call void @fn_emit(ptr @.str2423) + %t93 = load ptr, ptr %t73 + %t94 = getelementptr inbounds %Cmp_Node, ptr %t93, i32 0, i32 1 + %t95 = load ptr, ptr %t94 + call void @fn_emit(ptr %t95) + call void @fn_emit(ptr @.str2424) br label %ret ret: ret void @@ -19678,30 +27989,125 @@ entry: %t0 = alloca ptr %t1 = alloca ptr %t2 = alloca ptr - %t6 = alloca ptr + %t9 = alloca ptr + %t22 = alloca ptr + %t32 = alloca ptr + %t47 = alloca ptr store ptr %arg_fn2, ptr %t0 store ptr %arg_p, ptr %t1 store ptr %arg_bytes, ptr %t2 - %t3 = load i32, ptr @g_g_iok - %t4 = call ptr @fn_itoa(i32 %t3) - %t5 = call ptr @fn_str_concat(ptr @.str1420, ptr %t4) - store ptr %t5, ptr %t6 - %t7 = load i32, ptr @g_g_iok - %t8 = add i32 %t7, 1 - store i32 %t8, ptr @g_g_iok - call void @fn_emit(ptr @.str1421) - %t9 = load ptr, ptr %t6 - call void @fn_emit(ptr %t9) - call void @fn_emit(ptr @.str1422) - %t10 = load ptr, ptr %t0 - call void @fn_emit(ptr %t10) - call void @fn_emit(ptr @.str1423) - %t11 = load ptr, ptr %t1 - call void @fn_emit(ptr %t11) - call void @fn_emit(ptr @.str1424) - %t12 = load ptr, ptr %t2 + %t3 = load ptr, ptr @g_g_snap_mode + %t4 = call i32 @fn_str_eq(ptr %t3, ptr @.str2425) + %t5 = icmp ne i32 %t4, 0 + br i1 %t5, label %then0, label %ifend2 +then0: + %t6 = load i32, ptr @g_g_iok + %t7 = call ptr @fn_itoa(i32 %t6) + %t8 = call ptr @fn_str_concat(ptr @.str2426, ptr %t7) + store ptr %t8, ptr %t9 + %t10 = load i32, ptr @g_g_iok + %t11 = add i32 %t10, 1 + store i32 %t11, ptr @g_g_iok + call void @fn_emit(ptr @.str2427) + %t12 = load ptr, ptr %t9 call void @fn_emit(ptr %t12) - call void @fn_emit(ptr @.str1425) + call void @fn_emit(ptr @.str2428) + %t13 = load ptr, ptr %t0 + call void @fn_emit(ptr %t13) + call void @fn_emit(ptr @.str2429) + %t14 = load ptr, ptr %t1 + call void @fn_emit(ptr %t14) + call void @fn_emit(ptr @.str2430) + %t15 = load ptr, ptr %t2 + call void @fn_emit(ptr %t15) + call void @fn_emit(ptr @.str2431) + br label %ret +ifend2: + %t16 = load ptr, ptr @g_g_snap_mode + %t17 = call i32 @fn_str_eq(ptr %t16, ptr @.str2432) + %t18 = icmp ne i32 %t17, 0 + br i1 %t18, label %then3, label %ifend5 +then3: + %t19 = load i32, ptr @g_g_iok + %t20 = call ptr @fn_itoa(i32 %t19) + %t21 = call ptr @fn_str_concat(ptr @.str2433, ptr %t20) + store ptr %t21, ptr %t22 + call void @fn_emit(ptr @.str2434) + %t23 = load ptr, ptr %t22 + call void @fn_emit(ptr %t23) + call void @fn_emit(ptr @.str2435) + %t24 = load ptr, ptr @g_g_off + call void @fn_emit(ptr %t24) + call void @fn_emit(ptr @.str2436) + %t25 = load ptr, ptr %t2 + call void @fn_emit(ptr %t25) + call void @fn_emit(ptr @.str2437) + %t26 = load ptr, ptr %t22 + store ptr %t26, ptr @g_g_off + %t27 = load i32, ptr @g_g_iok + %t28 = add i32 %t27, 1 + store i32 %t28, ptr @g_g_iok + br label %ret +ifend5: + %t29 = load i32, ptr @g_g_iok + %t30 = call ptr @fn_itoa(i32 %t29) + %t31 = call ptr @fn_str_concat(ptr @.str2438, ptr %t30) + store ptr %t31, ptr %t32 + call void @fn_emit(ptr @.str2439) + %t33 = load ptr, ptr %t32 + call void @fn_emit(ptr %t33) + call void @fn_emit(ptr @.str2440) + %t34 = load ptr, ptr @g_g_off + call void @fn_emit(ptr %t34) + call void @fn_emit(ptr @.str2441) + %t35 = load ptr, ptr @g_g_snap_mode + %t36 = call i32 @fn_str_eq(ptr %t35, ptr @.str2442) + %t37 = icmp ne i32 %t36, 0 + br i1 %t37, label %then6, label %else7 +then6: + call void @fn_emit(ptr @.str2443) + %t38 = load ptr, ptr %t32 + call void @fn_emit(ptr %t38) + call void @fn_emit(ptr @.str2444) + %t39 = load ptr, ptr %t1 + call void @fn_emit(ptr %t39) + call void @fn_emit(ptr @.str2445) + %t40 = load ptr, ptr %t2 + call void @fn_emit(ptr %t40) + call void @fn_emit(ptr @.str2446) + br label %ifend8 +else7: + call void @fn_emit(ptr @.str2447) + %t41 = load ptr, ptr %t1 + call void @fn_emit(ptr %t41) + call void @fn_emit(ptr @.str2448) + %t42 = load ptr, ptr %t32 + call void @fn_emit(ptr %t42) + call void @fn_emit(ptr @.str2449) + %t43 = load ptr, ptr %t2 + call void @fn_emit(ptr %t43) + call void @fn_emit(ptr @.str2450) + br label %ifend8 +ifend8: + %t44 = load i32, ptr @g_g_iok + %t45 = call ptr @fn_itoa(i32 %t44) + %t46 = call ptr @fn_str_concat(ptr @.str2451, ptr %t45) + store ptr %t46, ptr %t47 + call void @fn_emit(ptr @.str2452) + %t48 = load ptr, ptr %t47 + call void @fn_emit(ptr %t48) + call void @fn_emit(ptr @.str2453) + %t49 = load ptr, ptr @g_g_off + call void @fn_emit(ptr %t49) + call void @fn_emit(ptr @.str2454) + %t50 = load ptr, ptr %t2 + call void @fn_emit(ptr %t50) + call void @fn_emit(ptr @.str2455) + %t51 = load ptr, ptr %t47 + store ptr %t51, ptr @g_g_off + %t52 = load i32, ptr @g_g_iok + %t53 = add i32 %t52, 1 + store i32 %t53, ptr @g_g_iok br label %ret ret: ret void @@ -19711,140 +28117,149 @@ define void @fn_emit_snapshot_blocks(ptr %arg_fn2) { entry: %t0 = alloca ptr %t2 = alloca ptr - %t9 = alloca i32 - %t40 = alloca i32 - %t67 = alloca ptr - %t71 = alloca ptr + %t12 = alloca i32 + %t43 = alloca i32 + %t70 = alloca ptr + %t74 = alloca ptr store ptr %arg_fn2, ptr %t0 store i32 0, ptr @g_g_iok + store ptr @.str2456, ptr @g_g_off %t1 = call ptr @fn_itoa(i32 1024) store ptr %t1, ptr %t2 %t3 = load ptr, ptr %t0 - call void @fn_emit_io(ptr %t3, ptr @.str1426, ptr @.str1427) + call void @fn_emit_io(ptr %t3, ptr @.str2457, ptr @.str2458) %t4 = load ptr, ptr %t0 - call void @fn_emit_io(ptr %t4, ptr @.str1428, ptr @.str1429) - call void @fn_emit(ptr @.str1430) + call void @fn_emit_io(ptr %t4, ptr @.str2459, ptr @.str2460) + call void @fn_emit(ptr @.str2461) %t5 = load ptr, ptr %t2 call void @fn_emit(ptr %t5) - call void @fn_emit(ptr @.str1431) + call void @fn_emit(ptr @.str2462) %t6 = load ptr, ptr %t0 - call void @fn_emit_io(ptr %t6, ptr @.str1432, ptr @.str1433) + call void @fn_emit_io(ptr %t6, ptr @.str2463, ptr @.str2464) %t7 = load ptr, ptr %t0 - call void @fn_emit_io(ptr %t7, ptr @.str1434, ptr @.str1435) + call void @fn_emit_io(ptr %t7, ptr @.str2465, ptr @.str2466) %t8 = load ptr, ptr %t0 - call void @fn_emit_io(ptr %t8, ptr @.str1436, ptr @.str1437) - store i32 0, ptr %t9 - br label %wcond0 -wcond0: - %t10 = load i32, ptr %t9 - %t11 = load ptr, ptr @g_prog - %t12 = getelementptr inbounds %LSlice, ptr %t11, i32 0, i32 1 + call void @fn_emit_io(ptr %t8, ptr @.str2467, ptr @.str2468) + %t9 = call i32 @fn_net_has_owned() + %t10 = icmp ne i32 %t9, 0 + br i1 %t10, label %then0, label %ifend2 +then0: + %t11 = load ptr, ptr %t0 + call void @fn_emit_io(ptr %t11, ptr @.str2469, ptr @.str2470) + br label %ifend2 +ifend2: + store i32 0, ptr %t12 + br label %wcond3 +wcond3: %t13 = load i32, ptr %t12 - %t14 = icmp slt i32 %t10, %t13 - %t15 = zext i1 %t14 to i32 - %t16 = icmp ne i32 %t15, 0 - br i1 %t16, label %wbody1, label %wend2 -wbody1: - %t17 = load ptr, ptr @g_prog - %t18 = getelementptr inbounds %LSlice, ptr %t17, i32 0, i32 0 - %t19 = load ptr, ptr %t18 - %t20 = load i32, ptr %t9 - %t21 = getelementptr inbounds ptr, ptr %t19, i32 %t20 + %t14 = load ptr, ptr @g_prog + %t15 = getelementptr inbounds %LSlice, ptr %t14, i32 0, i32 1 + %t16 = load i32, ptr %t15 + %t17 = icmp slt i32 %t13, %t16 + %t18 = zext i1 %t17 to i32 + %t19 = icmp ne i32 %t18, 0 + br i1 %t19, label %wbody4, label %wend5 +wbody4: + %t20 = load ptr, ptr @g_prog + %t21 = getelementptr inbounds %LSlice, ptr %t20, i32 0, i32 0 %t22 = load ptr, ptr %t21 - %t23 = getelementptr inbounds %Cmp_Node, ptr %t22, i32 0, i32 0 - %t24 = load i32, ptr %t23 - %t25 = icmp eq i32 %t24, 2 - %t26 = zext i1 %t25 to i32 - %t27 = icmp ne i32 %t26, 0 - br i1 %t27, label %then3, label %ifend5 -then3: - %t28 = load ptr, ptr %t0 - %t29 = load ptr, ptr @g_prog - %t30 = getelementptr inbounds %LSlice, ptr %t29, i32 0, i32 0 - %t31 = load ptr, ptr %t30 - %t32 = load i32, ptr %t9 - %t33 = getelementptr inbounds ptr, ptr %t31, i32 %t32 + %t23 = load i32, ptr %t12 + %t24 = getelementptr inbounds ptr, ptr %t22, i32 %t23 + %t25 = load ptr, ptr %t24 + %t26 = getelementptr inbounds %Cmp_Node, ptr %t25, i32 0, i32 0 + %t27 = load i32, ptr %t26 + %t28 = icmp eq i32 %t27, 2 + %t29 = zext i1 %t28 to i32 + %t30 = icmp ne i32 %t29, 0 + br i1 %t30, label %then6, label %ifend8 +then6: + %t31 = load ptr, ptr %t0 + %t32 = load ptr, ptr @g_prog + %t33 = getelementptr inbounds %LSlice, ptr %t32, i32 0, i32 0 %t34 = load ptr, ptr %t33 - %t35 = getelementptr inbounds %Cmp_Node, ptr %t34, i32 0, i32 1 - %t36 = load ptr, ptr %t35 - %t37 = call ptr @fn_str_concat(ptr @.str1438, ptr %t36) - call void @fn_emit_io(ptr %t28, ptr %t37, ptr @.str1439) - br label %ifend5 -ifend5: - %t38 = load i32, ptr %t9 - %t39 = add i32 %t38, 1 - store i32 %t39, ptr %t9 - br label %wcond0 -wend2: - store i32 0, ptr %t40 - store i32 0, ptr %t9 - br label %wcond6 -wcond6: - %t41 = load i32, ptr %t9 - %t42 = load ptr, ptr @g_prog - %t43 = getelementptr inbounds %LSlice, ptr %t42, i32 0, i32 1 - %t44 = load i32, ptr %t43 - %t45 = icmp slt i32 %t41, %t44 - %t46 = zext i1 %t45 to i32 - %t47 = icmp ne i32 %t46, 0 - br i1 %t47, label %wbody7, label %wend8 -wbody7: - %t48 = load ptr, ptr @g_prog - %t49 = getelementptr inbounds %LSlice, ptr %t48, i32 0, i32 0 - %t50 = load ptr, ptr %t49 - %t51 = load i32, ptr %t9 - %t52 = getelementptr inbounds ptr, ptr %t50, i32 %t51 + %t35 = load i32, ptr %t12 + %t36 = getelementptr inbounds ptr, ptr %t34, i32 %t35 + %t37 = load ptr, ptr %t36 + %t38 = getelementptr inbounds %Cmp_Node, ptr %t37, i32 0, i32 1 + %t39 = load ptr, ptr %t38 + %t40 = call ptr @fn_str_concat(ptr @.str2471, ptr %t39) + call void @fn_emit_io(ptr %t31, ptr %t40, ptr @.str2472) + br label %ifend8 +ifend8: + %t41 = load i32, ptr %t12 + %t42 = add i32 %t41, 1 + store i32 %t42, ptr %t12 + br label %wcond3 +wend5: + store i32 0, ptr %t43 + store i32 0, ptr %t12 + br label %wcond9 +wcond9: + %t44 = load i32, ptr %t12 + %t45 = load ptr, ptr @g_prog + %t46 = getelementptr inbounds %LSlice, ptr %t45, i32 0, i32 1 + %t47 = load i32, ptr %t46 + %t48 = icmp slt i32 %t44, %t47 + %t49 = zext i1 %t48 to i32 + %t50 = icmp ne i32 %t49, 0 + br i1 %t50, label %wbody10, label %wend11 +wbody10: + %t51 = load ptr, ptr @g_prog + %t52 = getelementptr inbounds %LSlice, ptr %t51, i32 0, i32 0 %t53 = load ptr, ptr %t52 - %t54 = getelementptr inbounds %Cmp_Node, ptr %t53, i32 0, i32 0 - %t55 = load i32, ptr %t54 - %t56 = icmp eq i32 %t55, 8 - %t57 = zext i1 %t56 to i32 - %t58 = icmp ne i32 %t57, 0 - br i1 %t58, label %then9, label %ifend11 -then9: - %t59 = load ptr, ptr @g_prog - %t60 = getelementptr inbounds %LSlice, ptr %t59, i32 0, i32 0 - %t61 = load ptr, ptr %t60 - %t62 = load i32, ptr %t9 - %t63 = getelementptr inbounds ptr, ptr %t61, i32 %t62 + %t54 = load i32, ptr %t12 + %t55 = getelementptr inbounds ptr, ptr %t53, i32 %t54 + %t56 = load ptr, ptr %t55 + %t57 = getelementptr inbounds %Cmp_Node, ptr %t56, i32 0, i32 0 + %t58 = load i32, ptr %t57 + %t59 = icmp eq i32 %t58, 8 + %t60 = zext i1 %t59 to i32 + %t61 = icmp ne i32 %t60, 0 + br i1 %t61, label %then12, label %ifend14 +then12: + %t62 = load ptr, ptr @g_prog + %t63 = getelementptr inbounds %LSlice, ptr %t62, i32 0, i32 0 %t64 = load ptr, ptr %t63 - %t65 = getelementptr inbounds %Cmp_Node, ptr %t64, i32 0, i32 1 - %t66 = load ptr, ptr %t65 - store ptr %t66, ptr %t67 - %t68 = load i32, ptr %t40 - %t69 = call ptr @fn_itoa(i32 %t68) - %t70 = call ptr @fn_str_concat(ptr @.str1440, ptr %t69) - store ptr %t70, ptr %t71 - call void @fn_emit(ptr @.str1441) - %t72 = load ptr, ptr %t71 - call void @fn_emit(ptr %t72) - call void @fn_emit(ptr @.str1442) - %t73 = load ptr, ptr %t67 - call void @fn_emit(ptr %t73) - call void @fn_emit(ptr @.str1443) - %t74 = load ptr, ptr %t2 - call void @fn_emit(ptr %t74) - call void @fn_emit(ptr @.str1444) - %t75 = load ptr, ptr %t0 - %t76 = load ptr, ptr %t67 - %t77 = call ptr @fn_str_concat(ptr @.str1445, ptr %t76) - %t78 = load ptr, ptr %t71 - call void @fn_emit_io(ptr %t75, ptr %t77, ptr %t78) - %t79 = load ptr, ptr %t0 - %t80 = load ptr, ptr %t67 - %t81 = call ptr @fn_str_concat(ptr @.str1446, ptr %t80) - %t82 = load ptr, ptr %t2 - call void @fn_emit_io(ptr %t79, ptr %t81, ptr %t82) - %t83 = load i32, ptr %t40 - %t84 = add i32 %t83, 1 - store i32 %t84, ptr %t40 - br label %ifend11 -ifend11: - %t85 = load i32, ptr %t9 - %t86 = add i32 %t85, 1 - store i32 %t86, ptr %t9 - br label %wcond6 -wend8: + %t65 = load i32, ptr %t12 + %t66 = getelementptr inbounds ptr, ptr %t64, i32 %t65 + %t67 = load ptr, ptr %t66 + %t68 = getelementptr inbounds %Cmp_Node, ptr %t67, i32 0, i32 1 + %t69 = load ptr, ptr %t68 + store ptr %t69, ptr %t70 + %t71 = load i32, ptr %t43 + %t72 = call ptr @fn_itoa(i32 %t71) + %t73 = call ptr @fn_str_concat(ptr @.str2473, ptr %t72) + store ptr %t73, ptr %t74 + call void @fn_emit(ptr @.str2474) + %t75 = load ptr, ptr %t74 + call void @fn_emit(ptr %t75) + call void @fn_emit(ptr @.str2475) + %t76 = load ptr, ptr %t70 + call void @fn_emit(ptr %t76) + call void @fn_emit(ptr @.str2476) + %t77 = load ptr, ptr %t2 + call void @fn_emit(ptr %t77) + call void @fn_emit(ptr @.str2477) + %t78 = load ptr, ptr %t0 + %t79 = load ptr, ptr %t70 + %t80 = call ptr @fn_str_concat(ptr @.str2478, ptr %t79) + %t81 = load ptr, ptr %t74 + call void @fn_emit_io(ptr %t78, ptr %t80, ptr %t81) + %t82 = load ptr, ptr %t0 + %t83 = load ptr, ptr %t70 + %t84 = call ptr @fn_str_concat(ptr @.str2479, ptr %t83) + %t85 = load ptr, ptr %t2 + call void @fn_emit_io(ptr %t82, ptr %t84, ptr %t85) + %t86 = load i32, ptr %t43 + %t87 = add i32 %t86, 1 + store i32 %t87, ptr %t43 + br label %ifend14 +ifend14: + %t88 = load i32, ptr %t12 + %t89 = add i32 %t88, 1 + store i32 %t89, ptr %t12 + br label %wcond9 +wend11: br label %ret ret: ret void @@ -19854,43 +28269,1972 @@ define void @fn_emit_snapshot() { entry: %t3 = alloca i32 %t7 = alloca i32 - call void @fn_emith(ptr @.str1447) - call void @fn_emith(ptr @.str1448) - call void @fn_emith(ptr @.str1449) - %t0 = call ptr @fn_find_fn(ptr @.str1450) + %t15 = alloca ptr + %t22 = alloca ptr + store ptr @.str2480, ptr @g_g_snap_mode + call void @fn_emith(ptr @.str2481) + call void @fn_emith(ptr @.str2482) + call void @fn_emith(ptr @.str2483) + %t0 = call ptr @fn_find_fn(ptr @.str2484) %t1 = icmp ne ptr %t0, null %t2 = zext i1 %t1 to i32 store i32 %t2, ptr %t3 - %t4 = call ptr @fn_find_fn(ptr @.str1451) + %t4 = call ptr @fn_find_fn(ptr @.str2485) %t5 = icmp ne ptr %t4, null %t6 = zext i1 %t5 to i32 store i32 %t6, ptr %t7 - call void @fn_emit(ptr @.str1452) - call void @fn_emit(ptr @.str1453) - call void @fn_emit(ptr @.str1454) - call void @fn_emit(ptr @.str1455) - call void @fn_emit_snapshot_blocks(ptr @.str1456) + call void @fn_emit(ptr @.str2486) + call void @fn_emit(ptr @.str2487) + call void @fn_emit(ptr @.str2488) + call void @fn_emit(ptr @.str2489) + call void @fn_emit_snapshot_blocks(ptr @.str2490) %t8 = load i32, ptr %t3 %t9 = icmp ne i32 %t8, 0 br i1 %t9, label %then0, label %ifend2 then0: - call void @fn_emit(ptr @.str1457) + call void @fn_emit(ptr @.str2491) br label %ifend2 ifend2: - call void @fn_emit(ptr @.str1458) - call void @fn_emit(ptr @.str1459) - call void @fn_emit(ptr @.str1460) - call void @fn_emit(ptr @.str1461) - call void @fn_emit(ptr @.str1462) - call void @fn_emit_snapshot_blocks(ptr @.str1463) + call void @fn_emit(ptr @.str2492) + call void @fn_emit(ptr @.str2493) + call void @fn_emit(ptr @.str2494) + call void @fn_emit(ptr @.str2495) + call void @fn_emit(ptr @.str2496) + call void @fn_emit_snapshot_blocks(ptr @.str2497) %t10 = load i32, ptr %t7 %t11 = icmp ne i32 %t10, 0 br i1 %t11, label %then3, label %ifend5 then3: - call void @fn_emit(ptr @.str1464) + call void @fn_emit(ptr @.str2498) br label %ifend5 ifend5: - call void @fn_emit(ptr @.str1465) + call void @fn_emit(ptr @.str2499) + call void @fn_emit(ptr @.str2500) + store ptr @.str2501, ptr @g_g_snap_mode + call void @fn_emit_snapshot_blocks(ptr @.str2502) + %t12 = load i32, ptr @g_g_iok + %t13 = call ptr @fn_itoa(i32 %t12) + %t14 = call ptr @fn_str_concat(ptr @.str2503, ptr %t13) + store ptr %t14, ptr %t15 + call void @fn_emit(ptr @.str2504) + %t16 = load ptr, ptr %t15 + call void @fn_emit(ptr %t16) + call void @fn_emit(ptr @.str2505) + %t17 = load ptr, ptr @g_g_off + call void @fn_emit(ptr %t17) + call void @fn_emit(ptr @.str2506) + call void @fn_emit(ptr @.str2507) + %t18 = load ptr, ptr %t15 + call void @fn_emit(ptr %t18) + call void @fn_emit(ptr @.str2508) + call void @fn_emit(ptr @.str2509) + store ptr @.str2510, ptr @g_g_snap_mode + call void @fn_emit_snapshot_blocks(ptr @.str2511) + call void @fn_emit(ptr @.str2512) + call void @fn_emit(ptr @.str2513) + store ptr @.str2514, ptr @g_g_snap_mode + call void @fn_emit_snapshot_blocks(ptr @.str2515) + %t19 = load i32, ptr @g_g_iok + %t20 = call ptr @fn_itoa(i32 %t19) + %t21 = call ptr @fn_str_concat(ptr @.str2516, ptr %t20) + store ptr %t21, ptr %t22 + call void @fn_emit(ptr @.str2517) + %t23 = load ptr, ptr %t22 + call void @fn_emit(ptr %t23) + call void @fn_emit(ptr @.str2518) + %t24 = load ptr, ptr @g_g_off + call void @fn_emit(ptr %t24) + call void @fn_emit(ptr @.str2519) + call void @fn_emit(ptr @.str2520) + %t25 = load ptr, ptr %t22 + call void @fn_emit(ptr %t25) + call void @fn_emit(ptr @.str2521) + store ptr @.str2522, ptr @g_g_snap_mode + br label %ret +ret: + ret void +} + +define i32 @fn_net_field_ibytes(ptr %arg_ty) { +entry: + %retval = alloca i32 + %t0 = alloca ptr + store ptr %arg_ty, ptr %t0 + %t1 = load ptr, ptr %t0 + %t2 = call ptr @fn_llty(ptr %t1) + %t3 = call i32 @fn_str_eq(ptr %t2, ptr @.str2523) + %t4 = icmp ne i32 %t3, 0 + br i1 %t4, label %then0, label %ifend2 +then0: + store i32 1, ptr %retval + br label %ret +ifend2: + store i32 4, ptr %retval + br label %ret +ret: + %t5 = load i32, ptr %retval + ret i32 %t5 +} + +define ptr @fn_net_field_bytes(ptr %arg_ty) { +entry: + %retval = alloca ptr + %t0 = alloca ptr + store ptr %arg_ty, ptr %t0 + %t1 = load ptr, ptr %t0 + %t2 = call ptr @fn_llty(ptr %t1) + %t3 = call i32 @fn_str_eq(ptr %t2, ptr @.str2524) + %t4 = icmp ne i32 %t3, 0 + br i1 %t4, label %then0, label %ifend2 +then0: + store ptr @.str2525, ptr %retval + br label %ret +ifend2: + store ptr @.str2526, ptr %retval + br label %ret +ret: + %t5 = load ptr, ptr %retval + ret ptr %t5 +} + +define i32 @fn_net_model_bytes(ptr %arg_m) { +entry: + %retval = alloca i32 + %t0 = alloca ptr + %t1 = alloca i32 + %t2 = alloca i32 + %t36 = alloca ptr + %t41 = alloca i32 + store ptr %arg_m, ptr %t0 + store i32 0, ptr %t1 + store i32 0, ptr %t2 + br label %wcond0 +wcond0: + %t3 = load i32, ptr %t2 + %t4 = load ptr, ptr %t0 + %t5 = getelementptr inbounds %Cmp_Node, ptr %t4, i32 0, i32 7 + %t6 = load ptr, ptr %t5 + %t7 = getelementptr inbounds %LSlice, ptr %t6, i32 0, i32 1 + %t8 = load i32, ptr %t7 + %t9 = icmp slt i32 %t3, %t8 + %t10 = zext i1 %t9 to i32 + %t11 = icmp ne i32 %t10, 0 + br i1 %t11, label %wbody1, label %wend2 +wbody1: + %t12 = load ptr, ptr %t0 + %t13 = getelementptr inbounds %Cmp_Node, ptr %t12, i32 0, i32 7 + %t14 = load ptr, ptr %t13 + %t15 = getelementptr inbounds %LSlice, ptr %t14, i32 0, i32 0 + %t16 = load ptr, ptr %t15 + %t17 = load i32, ptr %t2 + %t18 = getelementptr inbounds ptr, ptr %t16, i32 %t17 + %t19 = load ptr, ptr %t18 + %t20 = getelementptr inbounds %Cmp_Node, ptr %t19, i32 0, i32 2 + %t21 = load i32, ptr %t20 + %t22 = icmp eq i32 %t21, 1 + %t23 = zext i1 %t22 to i32 + %t24 = icmp ne i32 %t23, 0 + br i1 %t24, label %then3, label %ifend5 +then3: + %t25 = load ptr, ptr %t0 + %t26 = getelementptr inbounds %Cmp_Node, ptr %t25, i32 0, i32 7 + %t27 = load ptr, ptr %t26 + %t28 = getelementptr inbounds %LSlice, ptr %t27, i32 0, i32 0 + %t29 = load ptr, ptr %t28 + %t30 = load i32, ptr %t2 + %t31 = getelementptr inbounds ptr, ptr %t29, i32 %t30 + %t32 = load ptr, ptr %t31 + %t33 = getelementptr inbounds %Cmp_Node, ptr %t32, i32 0, i32 1 + %t34 = load ptr, ptr %t33 + %t35 = call ptr @fn_find_comp(ptr %t34) + store ptr %t35, ptr %t36 + %t37 = load ptr, ptr %t36 + %t38 = icmp ne ptr %t37, null + %t39 = zext i1 %t38 to i32 + %t40 = icmp ne i32 %t39, 0 + br i1 %t40, label %then6, label %ifend8 +then6: + store i32 0, ptr %t41 + br label %wcond9 +wcond9: + %t42 = load i32, ptr %t41 + %t43 = load ptr, ptr %t36 + %t44 = getelementptr inbounds %Cmp_Node, ptr %t43, i32 0, i32 7 + %t45 = load ptr, ptr %t44 + %t46 = getelementptr inbounds %LSlice, ptr %t45, i32 0, i32 1 + %t47 = load i32, ptr %t46 + %t48 = icmp slt i32 %t42, %t47 + %t49 = zext i1 %t48 to i32 + %t50 = icmp ne i32 %t49, 0 + br i1 %t50, label %wbody10, label %wend11 +wbody10: + %t51 = load ptr, ptr %t36 + %t52 = getelementptr inbounds %Cmp_Node, ptr %t51, i32 0, i32 7 + %t53 = load ptr, ptr %t52 + %t54 = getelementptr inbounds %LSlice, ptr %t53, i32 0, i32 0 + %t55 = load ptr, ptr %t54 + %t56 = load i32, ptr %t41 + %t57 = getelementptr inbounds ptr, ptr %t55, i32 %t56 + %t58 = load ptr, ptr %t57 + %t59 = getelementptr inbounds %Cmp_Node, ptr %t58, i32 0, i32 2 + %t60 = load i32, ptr %t59 + %t61 = icmp eq i32 %t60, 1 + %t62 = zext i1 %t61 to i32 + %t63 = icmp ne i32 %t62, 0 + br i1 %t63, label %then12, label %ifend14 +then12: + %t64 = load i32, ptr %t1 + %t65 = load ptr, ptr %t36 + %t66 = getelementptr inbounds %Cmp_Node, ptr %t65, i32 0, i32 7 + %t67 = load ptr, ptr %t66 + %t68 = getelementptr inbounds %LSlice, ptr %t67, i32 0, i32 0 + %t69 = load ptr, ptr %t68 + %t70 = load i32, ptr %t41 + %t71 = getelementptr inbounds ptr, ptr %t69, i32 %t70 + %t72 = load ptr, ptr %t71 + %t73 = getelementptr inbounds %Cmp_Node, ptr %t72, i32 0, i32 3 + %t74 = load ptr, ptr %t73 + %t75 = call i32 @fn_net_field_ibytes(ptr %t74) + %t76 = add i32 %t64, %t75 + store i32 %t76, ptr %t1 + br label %ifend14 +ifend14: + %t77 = load i32, ptr %t41 + %t78 = add i32 %t77, 1 + store i32 %t78, ptr %t41 + br label %wcond9 +wend11: + br label %ifend8 +ifend8: + br label %ifend5 +ifend5: + %t79 = load i32, ptr %t2 + %t80 = add i32 %t79, 1 + store i32 %t80, ptr %t2 + br label %wcond0 +wend2: + %t81 = load i32, ptr %t1 + store i32 %t81, ptr %retval + br label %ret +ret: + %t82 = load i32, ptr %retval + ret i32 %t82 +} + +define i32 @fn_net_model_syncs(ptr %arg_m) { +entry: + %retval = alloca i32 + %t0 = alloca ptr + store ptr %arg_m, ptr %t0 + %t1 = load ptr, ptr %t0 + %t2 = call i32 @fn_net_model_bytes(ptr %t1) + %t3 = icmp sgt i32 %t2, 0 + %t4 = zext i1 %t3 to i32 + store i32 %t4, ptr %retval + br label %ret +ret: + %t5 = load i32, ptr %retval + ret i32 %t5 +} + +define i32 @fn_net_has_sync() { +entry: + %retval = alloca i32 + %t0 = alloca i32 + store i32 0, ptr %t0 + br label %wcond0 +wcond0: + %t1 = load i32, ptr %t0 + %t2 = load ptr, ptr @g_prog + %t3 = getelementptr inbounds %LSlice, ptr %t2, i32 0, i32 1 + %t4 = load i32, ptr %t3 + %t5 = icmp slt i32 %t1, %t4 + %t6 = zext i1 %t5 to i32 + %t7 = icmp ne i32 %t6, 0 + br i1 %t7, label %wbody1, label %wend2 +wbody1: + %t8 = load ptr, ptr @g_prog + %t9 = getelementptr inbounds %LSlice, ptr %t8, i32 0, i32 0 + %t10 = load ptr, ptr %t9 + %t11 = load i32, ptr %t0 + %t12 = getelementptr inbounds ptr, ptr %t10, i32 %t11 + %t13 = load ptr, ptr %t12 + %t14 = getelementptr inbounds %Cmp_Node, ptr %t13, i32 0, i32 0 + %t15 = load i32, ptr %t14 + %t16 = icmp eq i32 %t15, 10 + %t17 = zext i1 %t16 to i32 + %t18 = icmp ne i32 %t17, 0 + br i1 %t18, label %then3, label %ifend5 +then3: + %t19 = load ptr, ptr @g_prog + %t20 = getelementptr inbounds %LSlice, ptr %t19, i32 0, i32 0 + %t21 = load ptr, ptr %t20 + %t22 = load i32, ptr %t0 + %t23 = getelementptr inbounds ptr, ptr %t21, i32 %t22 + %t24 = load ptr, ptr %t23 + %t25 = call i32 @fn_net_model_syncs(ptr %t24) + %t26 = icmp ne i32 %t25, 0 + br i1 %t26, label %then6, label %ifend8 +then6: + store i32 1, ptr %retval + br label %ret +ifend8: + br label %ifend5 +ifend5: + %t27 = load i32, ptr %t0 + %t28 = add i32 %t27, 1 + store i32 %t28, ptr %t0 + br label %wcond0 +wend2: + store i32 0, ptr %retval + br label %ret +ret: + %t29 = load i32, ptr %retval + ret i32 %t29 +} + +define i32 @fn_net_has_owned() { +entry: + %retval = alloca i32 + %t0 = alloca i32 + %t8 = alloca i32 + store i32 0, ptr %t0 + br label %wcond0 +wcond0: + %t1 = load i32, ptr %t0 + %t2 = load ptr, ptr @g_prog + %t3 = getelementptr inbounds %LSlice, ptr %t2, i32 0, i32 1 + %t4 = load i32, ptr %t3 + %t5 = icmp slt i32 %t1, %t4 + %t6 = zext i1 %t5 to i32 + %t7 = icmp ne i32 %t6, 0 + br i1 %t7, label %wbody1, label %wend2 +wbody1: + %t9 = load ptr, ptr @g_prog + %t10 = getelementptr inbounds %LSlice, ptr %t9, i32 0, i32 0 + %t11 = load ptr, ptr %t10 + %t12 = load i32, ptr %t0 + %t13 = getelementptr inbounds ptr, ptr %t11, i32 %t12 + %t14 = load ptr, ptr %t13 + %t15 = getelementptr inbounds %Cmp_Node, ptr %t14, i32 0, i32 0 + %t16 = load i32, ptr %t15 + %t17 = icmp eq i32 %t16, 10 + %t18 = zext i1 %t17 to i32 + %t19 = icmp ne i32 %t18, 0 + %t20 = zext i1 %t19 to i32 + store i32 %t20, ptr %t8 + br i1 %t19, label %sc3, label %scend4 +sc3: + %t21 = load ptr, ptr @g_prog + %t22 = getelementptr inbounds %LSlice, ptr %t21, i32 0, i32 0 + %t23 = load ptr, ptr %t22 + %t24 = load i32, ptr %t0 + %t25 = getelementptr inbounds ptr, ptr %t23, i32 %t24 + %t26 = load ptr, ptr %t25 + %t27 = getelementptr inbounds %Cmp_Node, ptr %t26, i32 0, i32 2 + %t28 = load i32, ptr %t27 + %t29 = icmp eq i32 %t28, 1 + %t30 = zext i1 %t29 to i32 + %t31 = icmp ne i32 %t30, 0 + %t32 = zext i1 %t31 to i32 + store i32 %t32, ptr %t8 + br label %scend4 +scend4: + %t33 = load i32, ptr %t8 + %t34 = icmp ne i32 %t33, 0 + br i1 %t34, label %then5, label %ifend7 +then5: + store i32 1, ptr %retval + br label %ret +ifend7: + %t35 = load i32, ptr %t0 + %t36 = add i32 %t35, 1 + store i32 %t36, ptr %t0 + br label %wcond0 +wend2: + store i32 0, ptr %retval + br label %ret +ret: + %t37 = load i32, ptr %retval + ret i32 %t37 +} + +define i32 @fn_net_has_role() { +entry: + %retval = alloca i32 + %t0 = alloca i32 + %t8 = alloca i32 + store i32 0, ptr %t0 + br label %wcond0 +wcond0: + %t1 = load i32, ptr %t0 + %t2 = load ptr, ptr @g_prog + %t3 = getelementptr inbounds %LSlice, ptr %t2, i32 0, i32 1 + %t4 = load i32, ptr %t3 + %t5 = icmp slt i32 %t1, %t4 + %t6 = zext i1 %t5 to i32 + %t7 = icmp ne i32 %t6, 0 + br i1 %t7, label %wbody1, label %wend2 +wbody1: + %t9 = load ptr, ptr @g_prog + %t10 = getelementptr inbounds %LSlice, ptr %t9, i32 0, i32 0 + %t11 = load ptr, ptr %t10 + %t12 = load i32, ptr %t0 + %t13 = getelementptr inbounds ptr, ptr %t11, i32 %t12 + %t14 = load ptr, ptr %t13 + %t15 = getelementptr inbounds %Cmp_Node, ptr %t14, i32 0, i32 0 + %t16 = load i32, ptr %t15 + %t17 = icmp eq i32 %t16, 9 + %t18 = zext i1 %t17 to i32 + %t19 = icmp ne i32 %t18, 0 + %t20 = zext i1 %t19 to i32 + store i32 %t20, ptr %t8 + br i1 %t19, label %sc3, label %scend4 +sc3: + %t21 = load ptr, ptr @g_prog + %t22 = getelementptr inbounds %LSlice, ptr %t21, i32 0, i32 0 + %t23 = load ptr, ptr %t22 + %t24 = load i32, ptr %t0 + %t25 = getelementptr inbounds ptr, ptr %t23, i32 %t24 + %t26 = load ptr, ptr %t25 + %t27 = getelementptr inbounds %Cmp_Node, ptr %t26, i32 0, i32 2 + %t28 = load i32, ptr %t27 + %t29 = icmp ne i32 %t28, 0 + %t30 = zext i1 %t29 to i32 + %t31 = icmp ne i32 %t30, 0 + %t32 = zext i1 %t31 to i32 + store i32 %t32, ptr %t8 + br label %scend4 +scend4: + %t33 = load i32, ptr %t8 + %t34 = icmp ne i32 %t33, 0 + br i1 %t34, label %then5, label %ifend7 +then5: + store i32 1, ptr %retval + br label %ret +ifend7: + %t35 = load i32, ptr %t0 + %t36 = add i32 %t35, 1 + store i32 %t36, ptr %t0 + br label %wcond0 +wend2: + store i32 0, ptr %retval + br label %ret +ret: + %t37 = load i32, ptr %retval + ret i32 %t37 +} + +define i32 @fn_net_any() { +entry: + %retval = alloca i32 + %t0 = alloca i32 + %t1 = alloca i32 + %t2 = call i32 @fn_net_has_sync() + %t3 = icmp ne i32 %t2, 0 + %t4 = zext i1 %t3 to i32 + store i32 %t4, ptr %t1 + br i1 %t3, label %scend1, label %sc0 +sc0: + %t5 = call i32 @fn_net_has_owned() + %t6 = icmp ne i32 %t5, 0 + %t7 = zext i1 %t6 to i32 + store i32 %t7, ptr %t1 + br label %scend1 +scend1: + %t8 = load i32, ptr %t1 + %t9 = icmp ne i32 %t8, 0 + %t10 = zext i1 %t9 to i32 + store i32 %t10, ptr %t0 + br i1 %t9, label %scend3, label %sc2 +sc2: + %t11 = call i32 @fn_net_has_role() + %t12 = icmp ne i32 %t11, 0 + %t13 = zext i1 %t12 to i32 + store i32 %t13, ptr %t0 + br label %scend3 +scend3: + %t14 = load i32, ptr %t0 + store i32 %t14, ptr %retval + br label %ret +ret: + %t15 = load i32, ptr %retval + ret i32 %t15 +} + +define void @fn_net_warn(ptr %arg_msg) { +entry: + %t0 = alloca ptr + %t2 = alloca ptr + store ptr %arg_msg, ptr %t0 + %t1 = load ptr, ptr @__stderrp + store ptr %t1, ptr %t2 + %t3 = load ptr, ptr %t2 + %t4 = zext i32 23 to i64 + %t5 = call i64 @fwrite(ptr @.str2527, i64 1, i64 %t4, ptr %t3) + %t6 = trunc i64 %t5 to i32 + %t7 = load ptr, ptr %t2 + %t8 = load ptr, ptr %t0 + %t9 = load ptr, ptr %t0 + %t10 = call i64 @strlen(ptr %t9) + %t11 = trunc i64 %t10 to i32 + %t12 = zext i32 %t11 to i64 + %t13 = call i64 @fwrite(ptr %t8, i64 1, i64 %t12, ptr %t7) + %t14 = trunc i64 %t13 to i32 + %t15 = load ptr, ptr %t2 + %t16 = zext i32 1 to i64 + %t17 = call i64 @fwrite(ptr @.str2528, i64 1, i64 %t16, ptr %t15) + %t18 = trunc i64 %t17 to i32 + br label %ret +ret: + ret void +} + +define void @fn_net_check() { +entry: + %t0 = alloca i32 + %t25 = alloca ptr + %t26 = alloca i32 + %t59 = alloca ptr + %t62 = alloca ptr + %t67 = alloca i32 + %t68 = alloca i32 + store i32 0, ptr %t0 + br label %wcond0 +wcond0: + %t1 = load i32, ptr %t0 + %t2 = load ptr, ptr @g_prog + %t3 = getelementptr inbounds %LSlice, ptr %t2, i32 0, i32 1 + %t4 = load i32, ptr %t3 + %t5 = icmp slt i32 %t1, %t4 + %t6 = zext i1 %t5 to i32 + %t7 = icmp ne i32 %t6, 0 + br i1 %t7, label %wbody1, label %wend2 +wbody1: + %t8 = load ptr, ptr @g_prog + %t9 = getelementptr inbounds %LSlice, ptr %t8, i32 0, i32 0 + %t10 = load ptr, ptr %t9 + %t11 = load i32, ptr %t0 + %t12 = getelementptr inbounds ptr, ptr %t10, i32 %t11 + %t13 = load ptr, ptr %t12 + %t14 = getelementptr inbounds %Cmp_Node, ptr %t13, i32 0, i32 0 + %t15 = load i32, ptr %t14 + %t16 = icmp eq i32 %t15, 10 + %t17 = zext i1 %t16 to i32 + %t18 = icmp ne i32 %t17, 0 + br i1 %t18, label %then3, label %ifend5 +then3: + %t19 = load ptr, ptr @g_prog + %t20 = getelementptr inbounds %LSlice, ptr %t19, i32 0, i32 0 + %t21 = load ptr, ptr %t20 + %t22 = load i32, ptr %t0 + %t23 = getelementptr inbounds ptr, ptr %t21, i32 %t22 + %t24 = load ptr, ptr %t23 + store ptr %t24, ptr %t25 + store i32 0, ptr %t26 + br label %wcond6 +wcond6: + %t27 = load i32, ptr %t26 + %t28 = load ptr, ptr %t25 + %t29 = getelementptr inbounds %Cmp_Node, ptr %t28, i32 0, i32 7 + %t30 = load ptr, ptr %t29 + %t31 = getelementptr inbounds %LSlice, ptr %t30, i32 0, i32 1 + %t32 = load i32, ptr %t31 + %t33 = icmp slt i32 %t27, %t32 + %t34 = zext i1 %t33 to i32 + %t35 = icmp ne i32 %t34, 0 + br i1 %t35, label %wbody7, label %wend8 +wbody7: + %t36 = load ptr, ptr %t25 + %t37 = getelementptr inbounds %Cmp_Node, ptr %t36, i32 0, i32 7 + %t38 = load ptr, ptr %t37 + %t39 = getelementptr inbounds %LSlice, ptr %t38, i32 0, i32 0 + %t40 = load ptr, ptr %t39 + %t41 = load i32, ptr %t26 + %t42 = getelementptr inbounds ptr, ptr %t40, i32 %t41 + %t43 = load ptr, ptr %t42 + %t44 = getelementptr inbounds %Cmp_Node, ptr %t43, i32 0, i32 2 + %t45 = load i32, ptr %t44 + %t46 = icmp eq i32 %t45, 1 + %t47 = zext i1 %t46 to i32 + %t48 = icmp ne i32 %t47, 0 + br i1 %t48, label %then9, label %ifend11 +then9: + %t49 = load ptr, ptr %t25 + %t50 = getelementptr inbounds %Cmp_Node, ptr %t49, i32 0, i32 7 + %t51 = load ptr, ptr %t50 + %t52 = getelementptr inbounds %LSlice, ptr %t51, i32 0, i32 0 + %t53 = load ptr, ptr %t52 + %t54 = load i32, ptr %t26 + %t55 = getelementptr inbounds ptr, ptr %t53, i32 %t54 + %t56 = load ptr, ptr %t55 + %t57 = getelementptr inbounds %Cmp_Node, ptr %t56, i32 0, i32 1 + %t58 = load ptr, ptr %t57 + store ptr %t58, ptr %t59 + %t60 = load ptr, ptr %t59 + %t61 = call ptr @fn_find_comp(ptr %t60) + store ptr %t61, ptr %t62 + %t63 = load ptr, ptr %t62 + %t64 = icmp ne ptr %t63, null + %t65 = zext i1 %t64 to i32 + %t66 = icmp ne i32 %t65, 0 + br i1 %t66, label %then12, label %ifend14 +then12: + store i32 0, ptr %t67 + store i32 0, ptr %t68 + br label %wcond15 +wcond15: + %t69 = load i32, ptr %t68 + %t70 = load ptr, ptr %t62 + %t71 = getelementptr inbounds %Cmp_Node, ptr %t70, i32 0, i32 7 + %t72 = load ptr, ptr %t71 + %t73 = getelementptr inbounds %LSlice, ptr %t72, i32 0, i32 1 + %t74 = load i32, ptr %t73 + %t75 = icmp slt i32 %t69, %t74 + %t76 = zext i1 %t75 to i32 + %t77 = icmp ne i32 %t76, 0 + br i1 %t77, label %wbody16, label %wend17 +wbody16: + %t78 = load ptr, ptr %t62 + %t79 = getelementptr inbounds %Cmp_Node, ptr %t78, i32 0, i32 7 + %t80 = load ptr, ptr %t79 + %t81 = getelementptr inbounds %LSlice, ptr %t80, i32 0, i32 0 + %t82 = load ptr, ptr %t81 + %t83 = load i32, ptr %t68 + %t84 = getelementptr inbounds ptr, ptr %t82, i32 %t83 + %t85 = load ptr, ptr %t84 + %t86 = getelementptr inbounds %Cmp_Node, ptr %t85, i32 0, i32 2 + %t87 = load i32, ptr %t86 + %t88 = icmp eq i32 %t87, 1 + %t89 = zext i1 %t88 to i32 + %t90 = icmp ne i32 %t89, 0 + br i1 %t90, label %then18, label %ifend20 +then18: + store i32 1, ptr %t67 + %t91 = load ptr, ptr %t62 + %t92 = getelementptr inbounds %Cmp_Node, ptr %t91, i32 0, i32 7 + %t93 = load ptr, ptr %t92 + %t94 = getelementptr inbounds %LSlice, ptr %t93, i32 0, i32 0 + %t95 = load ptr, ptr %t94 + %t96 = load i32, ptr %t68 + %t97 = getelementptr inbounds ptr, ptr %t95, i32 %t96 + %t98 = load ptr, ptr %t97 + %t99 = getelementptr inbounds %Cmp_Node, ptr %t98, i32 0, i32 3 + %t100 = load ptr, ptr %t99 + %t101 = call ptr @fn_llty(ptr %t100) + %t102 = call i32 @fn_str_eq(ptr %t101, ptr @.str2529) + %t103 = icmp ne i32 %t102, 0 + br i1 %t103, label %then21, label %ifend23 +then21: + %t104 = load ptr, ptr %t59 + %t105 = call ptr @fn_str_concat(ptr @.str2530, ptr %t104) + %t106 = call ptr @fn_str_concat(ptr %t105, ptr @.str2531) + %t107 = load ptr, ptr %t62 + %t108 = getelementptr inbounds %Cmp_Node, ptr %t107, i32 0, i32 7 + %t109 = load ptr, ptr %t108 + %t110 = getelementptr inbounds %LSlice, ptr %t109, i32 0, i32 0 + %t111 = load ptr, ptr %t110 + %t112 = load i32, ptr %t68 + %t113 = getelementptr inbounds ptr, ptr %t111, i32 %t112 + %t114 = load ptr, ptr %t113 + %t115 = getelementptr inbounds %Cmp_Node, ptr %t114, i32 0, i32 1 + %t116 = load ptr, ptr %t115 + %t117 = call ptr @fn_str_concat(ptr %t106, ptr %t116) + %t118 = call ptr @fn_str_concat(ptr %t117, ptr @.str2532) + call void @fn_perr(ptr %t118) + br label %ifend23 +ifend23: + br label %ifend20 +ifend20: + %t119 = load i32, ptr %t68 + %t120 = add i32 %t119, 1 + store i32 %t120, ptr %t68 + br label %wcond15 +wend17: + %t121 = load i32, ptr %t67 + %t122 = icmp eq i32 %t121, 0 + %t123 = zext i1 %t122 to i32 + %t124 = icmp ne i32 %t123, 0 + br i1 %t124, label %then24, label %ifend26 +then24: + %t125 = load ptr, ptr %t25 + %t126 = getelementptr inbounds %Cmp_Node, ptr %t125, i32 0, i32 1 + %t127 = load ptr, ptr %t126 + %t128 = call ptr @fn_str_concat(ptr @.str2533, ptr %t127) + %t129 = call ptr @fn_str_concat(ptr %t128, ptr @.str2534) + %t130 = load ptr, ptr %t59 + %t131 = call ptr @fn_str_concat(ptr %t129, ptr %t130) + %t132 = call ptr @fn_str_concat(ptr %t131, ptr @.str2535) + call void @fn_net_warn(ptr %t132) + br label %ifend26 +ifend26: + br label %ifend14 +ifend14: + br label %ifend11 +ifend11: + %t133 = load i32, ptr %t26 + %t134 = add i32 %t133, 1 + store i32 %t134, ptr %t26 + br label %wcond6 +wend8: + br label %ifend5 +ifend5: + %t135 = load i32, ptr %t0 + %t136 = add i32 %t135, 1 + store i32 %t136, ptr %t0 + br label %wcond0 +wend2: + br label %ret +ret: + ret void +} + +define void @fn_emit_net_serialize(ptr %arg_m) { +entry: + %t0 = alloca ptr + %t2 = alloca ptr + %t6 = alloca i32 + %t7 = alloca i32 + %t40 = alloca ptr + %t43 = alloca ptr + %t49 = alloca ptr + %t54 = alloca i32 + %t88 = alloca ptr + %t90 = alloca ptr + %t97 = alloca ptr + store ptr %arg_m, ptr %t0 + store i32 0, ptr @g_ll_t + %t1 = call ptr @fn_itoa(i32 1024) + store ptr %t1, ptr %t2 + call void @fn_emit(ptr @.str2536) + %t3 = load ptr, ptr %t0 + %t4 = getelementptr inbounds %Cmp_Node, ptr %t3, i32 0, i32 1 + %t5 = load ptr, ptr %t4 + call void @fn_emit(ptr %t5) + call void @fn_emit(ptr @.str2537) + store i32 0, ptr %t6 + store i32 0, ptr %t7 + br label %wcond0 +wcond0: + %t8 = load i32, ptr %t7 + %t9 = load ptr, ptr %t0 + %t10 = getelementptr inbounds %Cmp_Node, ptr %t9, i32 0, i32 7 + %t11 = load ptr, ptr %t10 + %t12 = getelementptr inbounds %LSlice, ptr %t11, i32 0, i32 1 + %t13 = load i32, ptr %t12 + %t14 = icmp slt i32 %t8, %t13 + %t15 = zext i1 %t14 to i32 + %t16 = icmp ne i32 %t15, 0 + br i1 %t16, label %wbody1, label %wend2 +wbody1: + %t17 = load ptr, ptr %t0 + %t18 = getelementptr inbounds %Cmp_Node, ptr %t17, i32 0, i32 7 + %t19 = load ptr, ptr %t18 + %t20 = getelementptr inbounds %LSlice, ptr %t19, i32 0, i32 0 + %t21 = load ptr, ptr %t20 + %t22 = load i32, ptr %t7 + %t23 = getelementptr inbounds ptr, ptr %t21, i32 %t22 + %t24 = load ptr, ptr %t23 + %t25 = getelementptr inbounds %Cmp_Node, ptr %t24, i32 0, i32 2 + %t26 = load i32, ptr %t25 + %t27 = icmp eq i32 %t26, 1 + %t28 = zext i1 %t27 to i32 + %t29 = icmp ne i32 %t28, 0 + br i1 %t29, label %then3, label %ifend5 +then3: + %t30 = load ptr, ptr %t0 + %t31 = getelementptr inbounds %Cmp_Node, ptr %t30, i32 0, i32 7 + %t32 = load ptr, ptr %t31 + %t33 = getelementptr inbounds %LSlice, ptr %t32, i32 0, i32 0 + %t34 = load ptr, ptr %t33 + %t35 = load i32, ptr %t7 + %t36 = getelementptr inbounds ptr, ptr %t34, i32 %t35 + %t37 = load ptr, ptr %t36 + %t38 = getelementptr inbounds %Cmp_Node, ptr %t37, i32 0, i32 1 + %t39 = load ptr, ptr %t38 + store ptr %t39, ptr %t40 + %t41 = load ptr, ptr %t40 + %t42 = call ptr @fn_find_comp(ptr %t41) + store ptr %t42, ptr %t43 + %t44 = load ptr, ptr %t43 + %t45 = icmp ne ptr %t44, null + %t46 = zext i1 %t45 to i32 + %t47 = icmp ne i32 %t46, 0 + br i1 %t47, label %then6, label %ifend8 +then6: + %t48 = call ptr @fn_nreg() + store ptr %t48, ptr %t49 + call void @fn_emit(ptr @.str2538) + %t50 = load ptr, ptr %t49 + call void @fn_emit(ptr %t50) + call void @fn_emit(ptr @.str2539) + %t51 = load ptr, ptr %t2 + call void @fn_emit(ptr %t51) + call void @fn_emit(ptr @.str2540) + %t52 = load ptr, ptr %t40 + call void @fn_emit(ptr %t52) + call void @fn_emit(ptr @.str2541) + %t53 = load ptr, ptr %t40 + call void @fn_emit(ptr %t53) + call void @fn_emit(ptr @.str2542) + store i32 0, ptr %t54 + br label %wcond9 +wcond9: + %t55 = load i32, ptr %t54 + %t56 = load ptr, ptr %t43 + %t57 = getelementptr inbounds %Cmp_Node, ptr %t56, i32 0, i32 7 + %t58 = load ptr, ptr %t57 + %t59 = getelementptr inbounds %LSlice, ptr %t58, i32 0, i32 1 + %t60 = load i32, ptr %t59 + %t61 = icmp slt i32 %t55, %t60 + %t62 = zext i1 %t61 to i32 + %t63 = icmp ne i32 %t62, 0 + br i1 %t63, label %wbody10, label %wend11 +wbody10: + %t64 = load ptr, ptr %t43 + %t65 = getelementptr inbounds %Cmp_Node, ptr %t64, i32 0, i32 7 + %t66 = load ptr, ptr %t65 + %t67 = getelementptr inbounds %LSlice, ptr %t66, i32 0, i32 0 + %t68 = load ptr, ptr %t67 + %t69 = load i32, ptr %t54 + %t70 = getelementptr inbounds ptr, ptr %t68, i32 %t69 + %t71 = load ptr, ptr %t70 + %t72 = getelementptr inbounds %Cmp_Node, ptr %t71, i32 0, i32 2 + %t73 = load i32, ptr %t72 + %t74 = icmp eq i32 %t73, 1 + %t75 = zext i1 %t74 to i32 + %t76 = icmp ne i32 %t75, 0 + br i1 %t76, label %then12, label %ifend14 +then12: + %t77 = load ptr, ptr %t43 + %t78 = getelementptr inbounds %Cmp_Node, ptr %t77, i32 0, i32 7 + %t79 = load ptr, ptr %t78 + %t80 = getelementptr inbounds %LSlice, ptr %t79, i32 0, i32 0 + %t81 = load ptr, ptr %t80 + %t82 = load i32, ptr %t54 + %t83 = getelementptr inbounds ptr, ptr %t81, i32 %t82 + %t84 = load ptr, ptr %t83 + %t85 = getelementptr inbounds %Cmp_Node, ptr %t84, i32 0, i32 3 + %t86 = load ptr, ptr %t85 + %t87 = call ptr @fn_net_field_bytes(ptr %t86) + store ptr %t87, ptr %t88 + %t89 = call ptr @fn_nreg() + store ptr %t89, ptr %t90 + call void @fn_emit(ptr @.str2543) + %t91 = load ptr, ptr %t90 + call void @fn_emit(ptr %t91) + call void @fn_emit(ptr @.str2544) + %t92 = load ptr, ptr %t40 + call void @fn_emit(ptr %t92) + call void @fn_emit(ptr @.str2545) + %t93 = load ptr, ptr %t49 + call void @fn_emit(ptr %t93) + call void @fn_emit(ptr @.str2546) + %t94 = load i32, ptr %t54 + %t95 = call ptr @fn_itoa(i32 %t94) + call void @fn_emit(ptr %t95) + call void @fn_emit(ptr @.str2547) + %t96 = call ptr @fn_nreg() + store ptr %t96, ptr %t97 + call void @fn_emit(ptr @.str2548) + %t98 = load ptr, ptr %t97 + call void @fn_emit(ptr %t98) + call void @fn_emit(ptr @.str2549) + %t99 = load i32, ptr %t6 + %t100 = call ptr @fn_itoa(i32 %t99) + call void @fn_emit(ptr %t100) + call void @fn_emit(ptr @.str2550) + call void @fn_emit(ptr @.str2551) + %t101 = load ptr, ptr %t97 + call void @fn_emit(ptr %t101) + call void @fn_emit(ptr @.str2552) + %t102 = load ptr, ptr %t90 + call void @fn_emit(ptr %t102) + call void @fn_emit(ptr @.str2553) + %t103 = load ptr, ptr %t88 + call void @fn_emit(ptr %t103) + call void @fn_emit(ptr @.str2554) + %t104 = load i32, ptr %t6 + %t105 = load ptr, ptr %t43 + %t106 = getelementptr inbounds %Cmp_Node, ptr %t105, i32 0, i32 7 + %t107 = load ptr, ptr %t106 + %t108 = getelementptr inbounds %LSlice, ptr %t107, i32 0, i32 0 + %t109 = load ptr, ptr %t108 + %t110 = load i32, ptr %t54 + %t111 = getelementptr inbounds ptr, ptr %t109, i32 %t110 + %t112 = load ptr, ptr %t111 + %t113 = getelementptr inbounds %Cmp_Node, ptr %t112, i32 0, i32 3 + %t114 = load ptr, ptr %t113 + %t115 = call i32 @fn_net_field_ibytes(ptr %t114) + %t116 = add i32 %t104, %t115 + store i32 %t116, ptr %t6 + br label %ifend14 +ifend14: + %t117 = load i32, ptr %t54 + %t118 = add i32 %t117, 1 + store i32 %t118, ptr %t54 + br label %wcond9 +wend11: + br label %ifend8 +ifend8: + br label %ifend5 +ifend5: + %t119 = load i32, ptr %t7 + %t120 = add i32 %t119, 1 + store i32 %t120, ptr %t7 + br label %wcond0 +wend2: + call void @fn_emit(ptr @.str2555) + %t121 = load i32, ptr %t6 + %t122 = call ptr @fn_itoa(i32 %t121) + call void @fn_emit(ptr %t122) + call void @fn_emit(ptr @.str2556) + br label %ret +ret: + ret void +} + +define void @fn_emit_net_apply(ptr %arg_m) { +entry: + %t0 = alloca ptr + %t2 = alloca ptr + %t6 = alloca i32 + %t7 = alloca i32 + %t40 = alloca ptr + %t43 = alloca ptr + %t49 = alloca ptr + %t54 = alloca i32 + %t88 = alloca ptr + %t90 = alloca ptr + %t97 = alloca ptr + store ptr %arg_m, ptr %t0 + store i32 0, ptr @g_ll_t + %t1 = call ptr @fn_itoa(i32 1024) + store ptr %t1, ptr %t2 + call void @fn_emit(ptr @.str2557) + %t3 = load ptr, ptr %t0 + %t4 = getelementptr inbounds %Cmp_Node, ptr %t3, i32 0, i32 1 + %t5 = load ptr, ptr %t4 + call void @fn_emit(ptr %t5) + call void @fn_emit(ptr @.str2558) + store i32 0, ptr %t6 + store i32 0, ptr %t7 + br label %wcond0 +wcond0: + %t8 = load i32, ptr %t7 + %t9 = load ptr, ptr %t0 + %t10 = getelementptr inbounds %Cmp_Node, ptr %t9, i32 0, i32 7 + %t11 = load ptr, ptr %t10 + %t12 = getelementptr inbounds %LSlice, ptr %t11, i32 0, i32 1 + %t13 = load i32, ptr %t12 + %t14 = icmp slt i32 %t8, %t13 + %t15 = zext i1 %t14 to i32 + %t16 = icmp ne i32 %t15, 0 + br i1 %t16, label %wbody1, label %wend2 +wbody1: + %t17 = load ptr, ptr %t0 + %t18 = getelementptr inbounds %Cmp_Node, ptr %t17, i32 0, i32 7 + %t19 = load ptr, ptr %t18 + %t20 = getelementptr inbounds %LSlice, ptr %t19, i32 0, i32 0 + %t21 = load ptr, ptr %t20 + %t22 = load i32, ptr %t7 + %t23 = getelementptr inbounds ptr, ptr %t21, i32 %t22 + %t24 = load ptr, ptr %t23 + %t25 = getelementptr inbounds %Cmp_Node, ptr %t24, i32 0, i32 2 + %t26 = load i32, ptr %t25 + %t27 = icmp eq i32 %t26, 1 + %t28 = zext i1 %t27 to i32 + %t29 = icmp ne i32 %t28, 0 + br i1 %t29, label %then3, label %ifend5 +then3: + %t30 = load ptr, ptr %t0 + %t31 = getelementptr inbounds %Cmp_Node, ptr %t30, i32 0, i32 7 + %t32 = load ptr, ptr %t31 + %t33 = getelementptr inbounds %LSlice, ptr %t32, i32 0, i32 0 + %t34 = load ptr, ptr %t33 + %t35 = load i32, ptr %t7 + %t36 = getelementptr inbounds ptr, ptr %t34, i32 %t35 + %t37 = load ptr, ptr %t36 + %t38 = getelementptr inbounds %Cmp_Node, ptr %t37, i32 0, i32 1 + %t39 = load ptr, ptr %t38 + store ptr %t39, ptr %t40 + %t41 = load ptr, ptr %t40 + %t42 = call ptr @fn_find_comp(ptr %t41) + store ptr %t42, ptr %t43 + %t44 = load ptr, ptr %t43 + %t45 = icmp ne ptr %t44, null + %t46 = zext i1 %t45 to i32 + %t47 = icmp ne i32 %t46, 0 + br i1 %t47, label %then6, label %ifend8 +then6: + %t48 = call ptr @fn_nreg() + store ptr %t48, ptr %t49 + call void @fn_emit(ptr @.str2559) + %t50 = load ptr, ptr %t49 + call void @fn_emit(ptr %t50) + call void @fn_emit(ptr @.str2560) + %t51 = load ptr, ptr %t2 + call void @fn_emit(ptr %t51) + call void @fn_emit(ptr @.str2561) + %t52 = load ptr, ptr %t40 + call void @fn_emit(ptr %t52) + call void @fn_emit(ptr @.str2562) + %t53 = load ptr, ptr %t40 + call void @fn_emit(ptr %t53) + call void @fn_emit(ptr @.str2563) + store i32 0, ptr %t54 + br label %wcond9 +wcond9: + %t55 = load i32, ptr %t54 + %t56 = load ptr, ptr %t43 + %t57 = getelementptr inbounds %Cmp_Node, ptr %t56, i32 0, i32 7 + %t58 = load ptr, ptr %t57 + %t59 = getelementptr inbounds %LSlice, ptr %t58, i32 0, i32 1 + %t60 = load i32, ptr %t59 + %t61 = icmp slt i32 %t55, %t60 + %t62 = zext i1 %t61 to i32 + %t63 = icmp ne i32 %t62, 0 + br i1 %t63, label %wbody10, label %wend11 +wbody10: + %t64 = load ptr, ptr %t43 + %t65 = getelementptr inbounds %Cmp_Node, ptr %t64, i32 0, i32 7 + %t66 = load ptr, ptr %t65 + %t67 = getelementptr inbounds %LSlice, ptr %t66, i32 0, i32 0 + %t68 = load ptr, ptr %t67 + %t69 = load i32, ptr %t54 + %t70 = getelementptr inbounds ptr, ptr %t68, i32 %t69 + %t71 = load ptr, ptr %t70 + %t72 = getelementptr inbounds %Cmp_Node, ptr %t71, i32 0, i32 2 + %t73 = load i32, ptr %t72 + %t74 = icmp eq i32 %t73, 1 + %t75 = zext i1 %t74 to i32 + %t76 = icmp ne i32 %t75, 0 + br i1 %t76, label %then12, label %ifend14 +then12: + %t77 = load ptr, ptr %t43 + %t78 = getelementptr inbounds %Cmp_Node, ptr %t77, i32 0, i32 7 + %t79 = load ptr, ptr %t78 + %t80 = getelementptr inbounds %LSlice, ptr %t79, i32 0, i32 0 + %t81 = load ptr, ptr %t80 + %t82 = load i32, ptr %t54 + %t83 = getelementptr inbounds ptr, ptr %t81, i32 %t82 + %t84 = load ptr, ptr %t83 + %t85 = getelementptr inbounds %Cmp_Node, ptr %t84, i32 0, i32 3 + %t86 = load ptr, ptr %t85 + %t87 = call ptr @fn_net_field_bytes(ptr %t86) + store ptr %t87, ptr %t88 + %t89 = call ptr @fn_nreg() + store ptr %t89, ptr %t90 + call void @fn_emit(ptr @.str2564) + %t91 = load ptr, ptr %t90 + call void @fn_emit(ptr %t91) + call void @fn_emit(ptr @.str2565) + %t92 = load ptr, ptr %t40 + call void @fn_emit(ptr %t92) + call void @fn_emit(ptr @.str2566) + %t93 = load ptr, ptr %t49 + call void @fn_emit(ptr %t93) + call void @fn_emit(ptr @.str2567) + %t94 = load i32, ptr %t54 + %t95 = call ptr @fn_itoa(i32 %t94) + call void @fn_emit(ptr %t95) + call void @fn_emit(ptr @.str2568) + %t96 = call ptr @fn_nreg() + store ptr %t96, ptr %t97 + call void @fn_emit(ptr @.str2569) + %t98 = load ptr, ptr %t97 + call void @fn_emit(ptr %t98) + call void @fn_emit(ptr @.str2570) + %t99 = load i32, ptr %t6 + %t100 = call ptr @fn_itoa(i32 %t99) + call void @fn_emit(ptr %t100) + call void @fn_emit(ptr @.str2571) + call void @fn_emit(ptr @.str2572) + %t101 = load ptr, ptr %t90 + call void @fn_emit(ptr %t101) + call void @fn_emit(ptr @.str2573) + %t102 = load ptr, ptr %t97 + call void @fn_emit(ptr %t102) + call void @fn_emit(ptr @.str2574) + %t103 = load ptr, ptr %t88 + call void @fn_emit(ptr %t103) + call void @fn_emit(ptr @.str2575) + %t104 = load i32, ptr %t6 + %t105 = load ptr, ptr %t43 + %t106 = getelementptr inbounds %Cmp_Node, ptr %t105, i32 0, i32 7 + %t107 = load ptr, ptr %t106 + %t108 = getelementptr inbounds %LSlice, ptr %t107, i32 0, i32 0 + %t109 = load ptr, ptr %t108 + %t110 = load i32, ptr %t54 + %t111 = getelementptr inbounds ptr, ptr %t109, i32 %t110 + %t112 = load ptr, ptr %t111 + %t113 = getelementptr inbounds %Cmp_Node, ptr %t112, i32 0, i32 3 + %t114 = load ptr, ptr %t113 + %t115 = call i32 @fn_net_field_ibytes(ptr %t114) + %t116 = add i32 %t104, %t115 + store i32 %t116, ptr %t6 + br label %ifend14 +ifend14: + %t117 = load i32, ptr %t54 + %t118 = add i32 %t117, 1 + store i32 %t118, ptr %t54 + br label %wcond9 +wend11: + br label %ifend8 +ifend8: + br label %ifend5 +ifend5: + %t119 = load i32, ptr %t7 + %t120 = add i32 %t119, 1 + store i32 %t120, ptr %t7 + br label %wcond0 +wend2: + call void @fn_emit(ptr @.str2576) + br label %ret +ret: + ret void +} + +define void @fn_emit_net_dispatch() { +entry: + %t1 = alloca ptr + %t3 = alloca i32 + %t4 = alloca i32 + %t12 = alloca i32 + %t44 = alloca ptr + %t47 = alloca ptr + %t72 = alloca i32 + %t104 = alloca ptr + %t107 = alloca ptr + %t130 = alloca i32 + %t162 = alloca ptr + %t165 = alloca ptr + %t0 = call ptr @fn_itoa(i32 1024) + store ptr %t0, ptr %t1 + call void @fn_emit(ptr @.str2577) + call void @fn_emit(ptr @.str2578) + %t2 = load ptr, ptr %t1 + call void @fn_emit(ptr %t2) + call void @fn_emit(ptr @.str2579) + store i32 0, ptr %t3 + store i32 0, ptr %t4 + br label %wcond0 +wcond0: + %t5 = load i32, ptr %t4 + %t6 = load ptr, ptr @g_prog + %t7 = getelementptr inbounds %LSlice, ptr %t6, i32 0, i32 1 + %t8 = load i32, ptr %t7 + %t9 = icmp slt i32 %t5, %t8 + %t10 = zext i1 %t9 to i32 + %t11 = icmp ne i32 %t10, 0 + br i1 %t11, label %wbody1, label %wend2 +wbody1: + %t13 = load ptr, ptr @g_prog + %t14 = getelementptr inbounds %LSlice, ptr %t13, i32 0, i32 0 + %t15 = load ptr, ptr %t14 + %t16 = load i32, ptr %t4 + %t17 = getelementptr inbounds ptr, ptr %t15, i32 %t16 + %t18 = load ptr, ptr %t17 + %t19 = getelementptr inbounds %Cmp_Node, ptr %t18, i32 0, i32 0 + %t20 = load i32, ptr %t19 + %t21 = icmp eq i32 %t20, 10 + %t22 = zext i1 %t21 to i32 + %t23 = icmp ne i32 %t22, 0 + %t24 = zext i1 %t23 to i32 + store i32 %t24, ptr %t12 + br i1 %t23, label %sc3, label %scend4 +sc3: + %t25 = load ptr, ptr @g_prog + %t26 = getelementptr inbounds %LSlice, ptr %t25, i32 0, i32 0 + %t27 = load ptr, ptr %t26 + %t28 = load i32, ptr %t4 + %t29 = getelementptr inbounds ptr, ptr %t27, i32 %t28 + %t30 = load ptr, ptr %t29 + %t31 = call i32 @fn_net_model_syncs(ptr %t30) + %t32 = icmp ne i32 %t31, 0 + %t33 = zext i1 %t32 to i32 + store i32 %t33, ptr %t12 + br label %scend4 +scend4: + %t34 = load i32, ptr %t12 + %t35 = icmp ne i32 %t34, 0 + br i1 %t35, label %then5, label %ifend7 +then5: + %t36 = load ptr, ptr @g_prog + %t37 = getelementptr inbounds %LSlice, ptr %t36, i32 0, i32 0 + %t38 = load ptr, ptr %t37 + %t39 = load i32, ptr %t4 + %t40 = getelementptr inbounds ptr, ptr %t38, i32 %t39 + %t41 = load ptr, ptr %t40 + %t42 = getelementptr inbounds %Cmp_Node, ptr %t41, i32 0, i32 1 + %t43 = load ptr, ptr %t42 + store ptr %t43, ptr %t44 + %t45 = load i32, ptr %t3 + %t46 = call ptr @fn_itoa(i32 %t45) + store ptr %t46, ptr %t47 + call void @fn_emit(ptr @.str2580) + %t48 = load ptr, ptr %t47 + call void @fn_emit(ptr %t48) + call void @fn_emit(ptr @.str2581) + %t49 = load ptr, ptr %t44 + %t50 = call i32 @fn_find_arch_id(ptr %t49) + %t51 = call ptr @fn_itoa(i32 %t50) + call void @fn_emit(ptr %t51) + call void @fn_emit(ptr @.str2582) + call void @fn_emit(ptr @.str2583) + %t52 = load ptr, ptr %t47 + call void @fn_emit(ptr %t52) + call void @fn_emit(ptr @.str2584) + %t53 = load ptr, ptr %t47 + call void @fn_emit(ptr %t53) + call void @fn_emit(ptr @.str2585) + %t54 = load ptr, ptr %t47 + call void @fn_emit(ptr %t54) + call void @fn_emit(ptr @.str2586) + call void @fn_emit(ptr @.str2587) + %t55 = load ptr, ptr %t47 + call void @fn_emit(ptr %t55) + call void @fn_emit(ptr @.str2588) + %t56 = load ptr, ptr %t47 + call void @fn_emit(ptr %t56) + call void @fn_emit(ptr @.str2589) + %t57 = load ptr, ptr %t44 + call void @fn_emit(ptr %t57) + call void @fn_emit(ptr @.str2590) + %t58 = load ptr, ptr %t47 + call void @fn_emit(ptr %t58) + call void @fn_emit(ptr @.str2591) + call void @fn_emit(ptr @.str2592) + %t59 = load ptr, ptr %t47 + call void @fn_emit(ptr %t59) + call void @fn_emit(ptr @.str2593) + %t60 = load i32, ptr %t3 + %t61 = add i32 %t60, 1 + store i32 %t61, ptr %t3 + br label %ifend7 +ifend7: + %t62 = load i32, ptr %t4 + %t63 = add i32 %t62, 1 + store i32 %t63, ptr %t4 + br label %wcond0 +wend2: + call void @fn_emit(ptr @.str2594) + call void @fn_emit(ptr @.str2595) + call void @fn_emit(ptr @.str2596) + %t64 = load ptr, ptr %t1 + call void @fn_emit(ptr %t64) + call void @fn_emit(ptr @.str2597) + store i32 0, ptr %t3 + store i32 0, ptr %t4 + br label %wcond8 +wcond8: + %t65 = load i32, ptr %t4 + %t66 = load ptr, ptr @g_prog + %t67 = getelementptr inbounds %LSlice, ptr %t66, i32 0, i32 1 + %t68 = load i32, ptr %t67 + %t69 = icmp slt i32 %t65, %t68 + %t70 = zext i1 %t69 to i32 + %t71 = icmp ne i32 %t70, 0 + br i1 %t71, label %wbody9, label %wend10 +wbody9: + %t73 = load ptr, ptr @g_prog + %t74 = getelementptr inbounds %LSlice, ptr %t73, i32 0, i32 0 + %t75 = load ptr, ptr %t74 + %t76 = load i32, ptr %t4 + %t77 = getelementptr inbounds ptr, ptr %t75, i32 %t76 + %t78 = load ptr, ptr %t77 + %t79 = getelementptr inbounds %Cmp_Node, ptr %t78, i32 0, i32 0 + %t80 = load i32, ptr %t79 + %t81 = icmp eq i32 %t80, 10 + %t82 = zext i1 %t81 to i32 + %t83 = icmp ne i32 %t82, 0 + %t84 = zext i1 %t83 to i32 + store i32 %t84, ptr %t72 + br i1 %t83, label %sc11, label %scend12 +sc11: + %t85 = load ptr, ptr @g_prog + %t86 = getelementptr inbounds %LSlice, ptr %t85, i32 0, i32 0 + %t87 = load ptr, ptr %t86 + %t88 = load i32, ptr %t4 + %t89 = getelementptr inbounds ptr, ptr %t87, i32 %t88 + %t90 = load ptr, ptr %t89 + %t91 = call i32 @fn_net_model_syncs(ptr %t90) + %t92 = icmp ne i32 %t91, 0 + %t93 = zext i1 %t92 to i32 + store i32 %t93, ptr %t72 + br label %scend12 +scend12: + %t94 = load i32, ptr %t72 + %t95 = icmp ne i32 %t94, 0 + br i1 %t95, label %then13, label %ifend15 +then13: + %t96 = load ptr, ptr @g_prog + %t97 = getelementptr inbounds %LSlice, ptr %t96, i32 0, i32 0 + %t98 = load ptr, ptr %t97 + %t99 = load i32, ptr %t4 + %t100 = getelementptr inbounds ptr, ptr %t98, i32 %t99 + %t101 = load ptr, ptr %t100 + %t102 = getelementptr inbounds %Cmp_Node, ptr %t101, i32 0, i32 1 + %t103 = load ptr, ptr %t102 + store ptr %t103, ptr %t104 + %t105 = load i32, ptr %t3 + %t106 = call ptr @fn_itoa(i32 %t105) + store ptr %t106, ptr %t107 + call void @fn_emit(ptr @.str2598) + %t108 = load ptr, ptr %t107 + call void @fn_emit(ptr %t108) + call void @fn_emit(ptr @.str2599) + %t109 = load ptr, ptr %t104 + %t110 = call i32 @fn_find_arch_id(ptr %t109) + %t111 = call ptr @fn_itoa(i32 %t110) + call void @fn_emit(ptr %t111) + call void @fn_emit(ptr @.str2600) + call void @fn_emit(ptr @.str2601) + %t112 = load ptr, ptr %t107 + call void @fn_emit(ptr %t112) + call void @fn_emit(ptr @.str2602) + %t113 = load ptr, ptr %t107 + call void @fn_emit(ptr %t113) + call void @fn_emit(ptr @.str2603) + %t114 = load ptr, ptr %t107 + call void @fn_emit(ptr %t114) + call void @fn_emit(ptr @.str2604) + call void @fn_emit(ptr @.str2605) + %t115 = load ptr, ptr %t107 + call void @fn_emit(ptr %t115) + call void @fn_emit(ptr @.str2606) + %t116 = load ptr, ptr %t104 + call void @fn_emit(ptr %t116) + call void @fn_emit(ptr @.str2607) + call void @fn_emit(ptr @.str2608) + %t117 = load ptr, ptr %t107 + call void @fn_emit(ptr %t117) + call void @fn_emit(ptr @.str2609) + %t118 = load i32, ptr %t3 + %t119 = add i32 %t118, 1 + store i32 %t119, ptr %t3 + br label %ifend15 +ifend15: + %t120 = load i32, ptr %t4 + %t121 = add i32 %t120, 1 + store i32 %t121, ptr %t4 + br label %wcond8 +wend10: + call void @fn_emit(ptr @.str2610) + call void @fn_emit(ptr @.str2611) + call void @fn_emit(ptr @.str2612) + %t122 = load ptr, ptr %t1 + call void @fn_emit(ptr %t122) + call void @fn_emit(ptr @.str2613) + store i32 0, ptr %t3 + store i32 0, ptr %t4 + br label %wcond16 +wcond16: + %t123 = load i32, ptr %t4 + %t124 = load ptr, ptr @g_prog + %t125 = getelementptr inbounds %LSlice, ptr %t124, i32 0, i32 1 + %t126 = load i32, ptr %t125 + %t127 = icmp slt i32 %t123, %t126 + %t128 = zext i1 %t127 to i32 + %t129 = icmp ne i32 %t128, 0 + br i1 %t129, label %wbody17, label %wend18 +wbody17: + %t131 = load ptr, ptr @g_prog + %t132 = getelementptr inbounds %LSlice, ptr %t131, i32 0, i32 0 + %t133 = load ptr, ptr %t132 + %t134 = load i32, ptr %t4 + %t135 = getelementptr inbounds ptr, ptr %t133, i32 %t134 + %t136 = load ptr, ptr %t135 + %t137 = getelementptr inbounds %Cmp_Node, ptr %t136, i32 0, i32 0 + %t138 = load i32, ptr %t137 + %t139 = icmp eq i32 %t138, 10 + %t140 = zext i1 %t139 to i32 + %t141 = icmp ne i32 %t140, 0 + %t142 = zext i1 %t141 to i32 + store i32 %t142, ptr %t130 + br i1 %t141, label %sc19, label %scend20 +sc19: + %t143 = load ptr, ptr @g_prog + %t144 = getelementptr inbounds %LSlice, ptr %t143, i32 0, i32 0 + %t145 = load ptr, ptr %t144 + %t146 = load i32, ptr %t4 + %t147 = getelementptr inbounds ptr, ptr %t145, i32 %t146 + %t148 = load ptr, ptr %t147 + %t149 = call i32 @fn_net_model_syncs(ptr %t148) + %t150 = icmp ne i32 %t149, 0 + %t151 = zext i1 %t150 to i32 + store i32 %t151, ptr %t130 + br label %scend20 +scend20: + %t152 = load i32, ptr %t130 + %t153 = icmp ne i32 %t152, 0 + br i1 %t153, label %then21, label %ifend23 +then21: + %t154 = load ptr, ptr @g_prog + %t155 = getelementptr inbounds %LSlice, ptr %t154, i32 0, i32 0 + %t156 = load ptr, ptr %t155 + %t157 = load i32, ptr %t4 + %t158 = getelementptr inbounds ptr, ptr %t156, i32 %t157 + %t159 = load ptr, ptr %t158 + %t160 = getelementptr inbounds %Cmp_Node, ptr %t159, i32 0, i32 1 + %t161 = load ptr, ptr %t160 + store ptr %t161, ptr %t162 + %t163 = load i32, ptr %t3 + %t164 = call ptr @fn_itoa(i32 %t163) + store ptr %t164, ptr %t165 + call void @fn_emit(ptr @.str2614) + %t166 = load ptr, ptr %t165 + call void @fn_emit(ptr %t166) + call void @fn_emit(ptr @.str2615) + %t167 = load ptr, ptr %t162 + %t168 = call i32 @fn_find_arch_id(ptr %t167) + %t169 = call ptr @fn_itoa(i32 %t168) + call void @fn_emit(ptr %t169) + call void @fn_emit(ptr @.str2616) + call void @fn_emit(ptr @.str2617) + %t170 = load ptr, ptr %t165 + call void @fn_emit(ptr %t170) + call void @fn_emit(ptr @.str2618) + %t171 = load ptr, ptr %t165 + call void @fn_emit(ptr %t171) + call void @fn_emit(ptr @.str2619) + %t172 = load ptr, ptr %t165 + call void @fn_emit(ptr %t172) + call void @fn_emit(ptr @.str2620) + call void @fn_emit(ptr @.str2621) + %t173 = load ptr, ptr %t165 + call void @fn_emit(ptr %t173) + call void @fn_emit(ptr @.str2622) + %t174 = load ptr, ptr @g_prog + %t175 = getelementptr inbounds %LSlice, ptr %t174, i32 0, i32 0 + %t176 = load ptr, ptr %t175 + %t177 = load i32, ptr %t4 + %t178 = getelementptr inbounds ptr, ptr %t176, i32 %t177 + %t179 = load ptr, ptr %t178 + %t180 = call i32 @fn_net_model_bytes(ptr %t179) + %t181 = call ptr @fn_itoa(i32 %t180) + call void @fn_emit(ptr %t181) + call void @fn_emit(ptr @.str2623) + call void @fn_emit(ptr @.str2624) + %t182 = load ptr, ptr %t165 + call void @fn_emit(ptr %t182) + call void @fn_emit(ptr @.str2625) + %t183 = load i32, ptr %t3 + %t184 = add i32 %t183, 1 + store i32 %t184, ptr %t3 + br label %ifend23 +ifend23: + %t185 = load i32, ptr %t4 + %t186 = add i32 %t185, 1 + store i32 %t186, ptr %t4 + br label %wcond16 +wend18: + call void @fn_emit(ptr @.str2626) + br label %ret +ret: + ret void +} + +define void @fn_emit_net_owner() { +entry: + %t1 = alloca ptr + %t0 = call ptr @fn_itoa(i32 1024) + store ptr %t0, ptr %t1 + call void @fn_emit(ptr @.str2627) + call void @fn_emit(ptr @.str2628) + %t2 = load ptr, ptr %t1 + call void @fn_emit(ptr %t2) + call void @fn_emit(ptr @.str2629) + call void @fn_emit(ptr @.str2630) + call void @fn_emit(ptr @.str2631) + %t3 = load ptr, ptr %t1 + call void @fn_emit(ptr %t3) + call void @fn_emit(ptr @.str2632) + call void @fn_emit(ptr @.str2633) + call void @fn_emit(ptr @.str2634) + %t4 = load ptr, ptr %t1 + call void @fn_emit(ptr %t4) + call void @fn_emit(ptr @.str2635) + call void @fn_emit(ptr @.str2636) + br label %ret +ret: + ret void +} + +define void @fn_emit_loopback() { +entry: + call void @fn_emith(ptr @.str2637) + call void @fn_emith(ptr @.str2638) + call void @fn_emith(ptr @.str2639) + call void @fn_emith(ptr @.str2640) + call void @fn_emit(ptr @.str2641) + call void @fn_emit(ptr @.str2642) + call void @fn_emit(ptr @.str2643) + call void @fn_emit(ptr @.str2644) + call void @fn_emit(ptr @.str2645) + call void @fn_emit(ptr @.str2646) + call void @fn_emit(ptr @.str2647) + call void @fn_emit(ptr @.str2648) + call void @fn_emit(ptr @.str2649) + call void @fn_emit(ptr @.str2650) + call void @fn_emit(ptr @.str2651) + call void @fn_emit(ptr @.str2652) + call void @fn_emit(ptr @.str2653) + call void @fn_emit(ptr @.str2654) + call void @fn_emit(ptr @.str2655) + call void @fn_emit(ptr @.str2656) + call void @fn_emit(ptr @.str2657) + call void @fn_emit(ptr @.str2658) + call void @fn_emit(ptr @.str2659) + call void @fn_emit(ptr @.str2660) + call void @fn_emit(ptr @.str2661) + call void @fn_emit(ptr @.str2662) + br label %ret +ret: + ret void +} + +define i32 @fn_net_has_remote() { +entry: + %retval = alloca i32 + %t0 = alloca i32 + store i32 0, ptr %t0 + br label %wcond0 +wcond0: + %t1 = load i32, ptr %t0 + %t2 = load ptr, ptr @g_g_events + %t3 = getelementptr inbounds %LSlice, ptr %t2, i32 0, i32 1 + %t4 = load i32, ptr %t3 + %t5 = icmp slt i32 %t1, %t4 + %t6 = zext i1 %t5 to i32 + %t7 = icmp ne i32 %t6, 0 + br i1 %t7, label %wbody1, label %wend2 +wbody1: + %t8 = load ptr, ptr @g_g_events + %t9 = getelementptr inbounds %LSlice, ptr %t8, i32 0, i32 0 + %t10 = load ptr, ptr %t9 + %t11 = load i32, ptr %t0 + %t12 = getelementptr inbounds ptr, ptr %t10, i32 %t11 + %t13 = load ptr, ptr %t12 + %t14 = getelementptr inbounds %Cmp_Node, ptr %t13, i32 0, i32 3 + %t15 = load ptr, ptr %t14 + %t16 = icmp ne ptr %t15, null + %t17 = zext i1 %t16 to i32 + %t18 = icmp ne i32 %t17, 0 + br i1 %t18, label %then3, label %ifend5 +then3: + store i32 1, ptr %retval + br label %ret +ifend5: + %t19 = load i32, ptr %t0 + %t20 = add i32 %t19, 1 + store i32 %t20, ptr %t0 + br label %wcond0 +wend2: + store i32 0, ptr %retval + br label %ret +ret: + %t21 = load i32, ptr %retval + ret i32 %t21 +} + +define i32 @fn_net_event_id(ptr %arg_name) { +entry: + %retval = alloca i32 + %t0 = alloca ptr + %t1 = alloca i32 + store ptr %arg_name, ptr %t0 + store i32 0, ptr %t1 + br label %wcond0 +wcond0: + %t2 = load i32, ptr %t1 + %t3 = load ptr, ptr @g_g_events + %t4 = getelementptr inbounds %LSlice, ptr %t3, i32 0, i32 1 + %t5 = load i32, ptr %t4 + %t6 = icmp slt i32 %t2, %t5 + %t7 = zext i1 %t6 to i32 + %t8 = icmp ne i32 %t7, 0 + br i1 %t8, label %wbody1, label %wend2 +wbody1: + %t9 = load ptr, ptr @g_g_events + %t10 = getelementptr inbounds %LSlice, ptr %t9, i32 0, i32 0 + %t11 = load ptr, ptr %t10 + %t12 = load i32, ptr %t1 + %t13 = getelementptr inbounds ptr, ptr %t11, i32 %t12 + %t14 = load ptr, ptr %t13 + %t15 = getelementptr inbounds %Cmp_Node, ptr %t14, i32 0, i32 1 + %t16 = load ptr, ptr %t15 + %t17 = load ptr, ptr %t0 + %t18 = call i32 @fn_str_eq(ptr %t16, ptr %t17) + %t19 = icmp ne i32 %t18, 0 + br i1 %t19, label %then3, label %ifend5 +then3: + %t20 = load i32, ptr %t1 + store i32 %t20, ptr %retval + br label %ret +ifend5: + %t21 = load i32, ptr %t1 + %t22 = add i32 %t21, 1 + store i32 %t22, ptr %t1 + br label %wcond0 +wend2: + %t23 = sub i32 0, 1 + store i32 %t23, ptr %retval + br label %ret +ret: + %t24 = load i32, ptr %retval + ret i32 %t24 +} + +define ptr @fn_net_send_sym() { +entry: + %retval = alloca ptr + %t1 = alloca ptr + %t0 = call ptr @fn_find_extern(ptr @.str2663) + store ptr %t0, ptr %t1 + %t2 = load ptr, ptr %t1 + %t3 = icmp ne ptr %t2, null + %t4 = zext i1 %t3 to i32 + %t5 = icmp ne i32 %t4, 0 + br i1 %t5, label %then0, label %ifend2 +then0: + %t6 = load ptr, ptr %t1 + %t7 = getelementptr inbounds %Cmp_Node, ptr %t6, i32 0, i32 4 + %t8 = load ptr, ptr %t7 + %t9 = getelementptr inbounds %Cmp_Node, ptr %t8, i32 0, i32 1 + %t10 = load ptr, ptr %t9 + store ptr %t10, ptr %retval + br label %ret +ifend2: + store ptr @.str2664, ptr %retval + br label %ret +ret: + %t11 = load ptr, ptr %retval + ret ptr %t11 +} + +define ptr @fn_net_poll_sym() { +entry: + %retval = alloca ptr + %t1 = alloca ptr + %t0 = call ptr @fn_find_extern(ptr @.str2665) + store ptr %t0, ptr %t1 + %t2 = load ptr, ptr %t1 + %t3 = icmp ne ptr %t2, null + %t4 = zext i1 %t3 to i32 + %t5 = icmp ne i32 %t4, 0 + br i1 %t5, label %then0, label %ifend2 +then0: + %t6 = load ptr, ptr %t1 + %t7 = getelementptr inbounds %Cmp_Node, ptr %t6, i32 0, i32 4 + %t8 = load ptr, ptr %t7 + %t9 = getelementptr inbounds %Cmp_Node, ptr %t8, i32 0, i32 1 + %t10 = load ptr, ptr %t9 + store ptr %t10, ptr %retval + br label %ret +ifend2: + store ptr @.str2666, ptr %retval + br label %ret +ret: + %t11 = load ptr, ptr %retval + ret ptr %t11 +} + +define void @fn_emit_net_pump() { +entry: + %t5 = alloca ptr + %t7 = alloca i32 + %t21 = alloca ptr + %t30 = alloca ptr + %t41 = alloca i32 + %t42 = alloca i32 + %t44 = alloca ptr + %t65 = alloca ptr + %t71 = alloca ptr + call void @fn_emith(ptr @.str2667) + %t0 = call ptr @fn_find_extern(ptr @.str2668) + %t1 = icmp eq ptr %t0, null + %t2 = zext i1 %t1 to i32 + %t3 = icmp ne i32 %t2, 0 + br i1 %t3, label %then0, label %ifend2 +then0: + store i32 1, ptr @g_g_uses_loopback + br label %ifend2 +ifend2: + %t4 = call ptr @fn_net_poll_sym() + store ptr %t4, ptr %t5 + call void @fn_emit(ptr @.str2669) + call void @fn_emit(ptr @.str2670) + %t6 = load ptr, ptr %t5 + call void @fn_emit(ptr %t6) + call void @fn_emit(ptr @.str2671) + call void @fn_emit(ptr @.str2672) + call void @fn_emit(ptr @.str2673) + store i32 0, ptr %t7 + br label %wcond3 +wcond3: + %t8 = load i32, ptr %t7 + %t9 = load ptr, ptr @g_g_events + %t10 = getelementptr inbounds %LSlice, ptr %t9, i32 0, i32 1 + %t11 = load i32, ptr %t10 + %t12 = icmp slt i32 %t8, %t11 + %t13 = zext i1 %t12 to i32 + %t14 = icmp ne i32 %t13, 0 + br i1 %t14, label %wbody4, label %wend5 +wbody4: + %t15 = load ptr, ptr @g_g_events + %t16 = getelementptr inbounds %LSlice, ptr %t15, i32 0, i32 0 + %t17 = load ptr, ptr %t16 + %t18 = load i32, ptr %t7 + %t19 = getelementptr inbounds ptr, ptr %t17, i32 %t18 + %t20 = load ptr, ptr %t19 + store ptr %t20, ptr %t21 + %t22 = load ptr, ptr %t21 + %t23 = getelementptr inbounds %Cmp_Node, ptr %t22, i32 0, i32 3 + %t24 = load ptr, ptr %t23 + %t25 = icmp ne ptr %t24, null + %t26 = zext i1 %t25 to i32 + %t27 = icmp ne i32 %t26, 0 + br i1 %t27, label %then6, label %ifend8 +then6: + %t28 = load i32, ptr %t7 + %t29 = call ptr @fn_itoa(i32 %t28) + store ptr %t29, ptr %t30 + call void @fn_emit(ptr @.str2674) + %t31 = load ptr, ptr %t30 + call void @fn_emit(ptr %t31) + call void @fn_emit(ptr @.str2675) + %t32 = load ptr, ptr %t21 + %t33 = getelementptr inbounds %Cmp_Node, ptr %t32, i32 0, i32 1 + %t34 = load ptr, ptr %t33 + %t35 = call i32 @fn_net_event_id(ptr %t34) + %t36 = call ptr @fn_itoa(i32 %t35) + call void @fn_emit(ptr %t36) + call void @fn_emit(ptr @.str2676) + call void @fn_emit(ptr @.str2677) + %t37 = load ptr, ptr %t30 + call void @fn_emit(ptr %t37) + call void @fn_emit(ptr @.str2678) + %t38 = load ptr, ptr %t30 + call void @fn_emit(ptr %t38) + call void @fn_emit(ptr @.str2679) + %t39 = load ptr, ptr %t30 + call void @fn_emit(ptr %t39) + call void @fn_emit(ptr @.str2680) + call void @fn_emit(ptr @.str2681) + %t40 = load ptr, ptr %t30 + call void @fn_emit(ptr %t40) + call void @fn_emit(ptr @.str2682) + store i32 4, ptr %t41 + store i32 0, ptr %t42 + %t43 = call ptr @fn_buf_new() + store ptr %t43, ptr %t44 + br label %wcond9 +wcond9: + %t45 = load i32, ptr %t42 + %t46 = load ptr, ptr %t21 + %t47 = getelementptr inbounds %Cmp_Node, ptr %t46, i32 0, i32 7 + %t48 = load ptr, ptr %t47 + %t49 = getelementptr inbounds %LSlice, ptr %t48, i32 0, i32 1 + %t50 = load i32, ptr %t49 + %t51 = icmp slt i32 %t45, %t50 + %t52 = zext i1 %t51 to i32 + %t53 = icmp ne i32 %t52, 0 + br i1 %t53, label %wbody10, label %wend11 +wbody10: + %t54 = load ptr, ptr %t21 + %t55 = getelementptr inbounds %Cmp_Node, ptr %t54, i32 0, i32 7 + %t56 = load ptr, ptr %t55 + %t57 = getelementptr inbounds %LSlice, ptr %t56, i32 0, i32 0 + %t58 = load ptr, ptr %t57 + %t59 = load i32, ptr %t42 + %t60 = getelementptr inbounds ptr, ptr %t58, i32 %t59 + %t61 = load ptr, ptr %t60 + %t62 = getelementptr inbounds %Cmp_Node, ptr %t61, i32 0, i32 3 + %t63 = load ptr, ptr %t62 + %t64 = call ptr @fn_llty(ptr %t63) + store ptr %t64, ptr %t65 + %t66 = load ptr, ptr %t30 + %t67 = call ptr @fn_str_concat(ptr %t66, ptr @.str2683) + %t68 = load i32, ptr %t42 + %t69 = call ptr @fn_itoa(i32 %t68) + %t70 = call ptr @fn_str_concat(ptr %t67, ptr %t69) + store ptr %t70, ptr %t71 + call void @fn_emit(ptr @.str2684) + %t72 = load ptr, ptr %t71 + call void @fn_emit(ptr %t72) + call void @fn_emit(ptr @.str2685) + %t73 = load i32, ptr %t41 + %t74 = call ptr @fn_itoa(i32 %t73) + call void @fn_emit(ptr %t74) + call void @fn_emit(ptr @.str2686) + call void @fn_emit(ptr @.str2687) + %t75 = load ptr, ptr %t71 + call void @fn_emit(ptr %t75) + call void @fn_emit(ptr @.str2688) + %t76 = load ptr, ptr %t65 + call void @fn_emit(ptr %t76) + call void @fn_emit(ptr @.str2689) + %t77 = load ptr, ptr %t71 + call void @fn_emit(ptr %t77) + call void @fn_emit(ptr @.str2690) + %t78 = load i32, ptr %t42 + %t79 = icmp sgt i32 %t78, 0 + %t80 = zext i1 %t79 to i32 + %t81 = icmp ne i32 %t80, 0 + br i1 %t81, label %then12, label %ifend14 +then12: + %t82 = load ptr, ptr %t44 + call void @fn_buf_puts(ptr %t82, ptr @.str2691) + br label %ifend14 +ifend14: + %t83 = load ptr, ptr %t44 + %t84 = load ptr, ptr %t65 + call void @fn_buf_puts(ptr %t83, ptr %t84) + %t85 = load ptr, ptr %t44 + call void @fn_buf_puts(ptr %t85, ptr @.str2692) + %t86 = load ptr, ptr %t44 + %t87 = load ptr, ptr %t71 + call void @fn_buf_puts(ptr %t86, ptr %t87) + %t88 = load i32, ptr %t41 + %t89 = load ptr, ptr %t21 + %t90 = getelementptr inbounds %Cmp_Node, ptr %t89, i32 0, i32 7 + %t91 = load ptr, ptr %t90 + %t92 = getelementptr inbounds %LSlice, ptr %t91, i32 0, i32 0 + %t93 = load ptr, ptr %t92 + %t94 = load i32, ptr %t42 + %t95 = getelementptr inbounds ptr, ptr %t93, i32 %t94 + %t96 = load ptr, ptr %t95 + %t97 = getelementptr inbounds %Cmp_Node, ptr %t96, i32 0, i32 3 + %t98 = load ptr, ptr %t97 + %t99 = call i32 @fn_net_field_ibytes(ptr %t98) + %t100 = add i32 %t88, %t99 + store i32 %t100, ptr %t41 + %t101 = load i32, ptr %t42 + %t102 = add i32 %t101, 1 + store i32 %t102, ptr %t42 + br label %wcond9 +wend11: + call void @fn_emit(ptr @.str2693) + %t103 = load ptr, ptr %t21 + %t104 = getelementptr inbounds %Cmp_Node, ptr %t103, i32 0, i32 1 + %t105 = load ptr, ptr %t104 + call void @fn_emit(ptr %t105) + call void @fn_emit(ptr @.str2694) + %t106 = load ptr, ptr %t44 + %t107 = call ptr @fn_buf_str(ptr %t106) + call void @fn_emit(ptr %t107) + call void @fn_emit(ptr @.str2695) + call void @fn_emit(ptr @.str2696) + call void @fn_emit(ptr @.str2697) + %t108 = load ptr, ptr %t30 + call void @fn_emit(ptr %t108) + call void @fn_emit(ptr @.str2698) + br label %ifend8 +ifend8: + %t109 = load i32, ptr %t7 + %t110 = add i32 %t109, 1 + store i32 %t110, ptr %t7 + br label %wcond3 +wend5: + call void @fn_emit(ptr @.str2699) + call void @fn_emit(ptr @.str2700) + br label %ret +ret: + ret void +} + +define void @fn_emit_net() { +entry: + %t2 = alloca i32 + %t10 = alloca i32 + %t0 = call i32 @fn_net_has_sync() + %t1 = icmp ne i32 %t0, 0 + br i1 %t1, label %then0, label %ifend2 +then0: + call void @fn_net_check() + store i32 0, ptr %t2 + br label %wcond3 +wcond3: + %t3 = load i32, ptr %t2 + %t4 = load ptr, ptr @g_prog + %t5 = getelementptr inbounds %LSlice, ptr %t4, i32 0, i32 1 + %t6 = load i32, ptr %t5 + %t7 = icmp slt i32 %t3, %t6 + %t8 = zext i1 %t7 to i32 + %t9 = icmp ne i32 %t8, 0 + br i1 %t9, label %wbody4, label %wend5 +wbody4: + %t11 = load ptr, ptr @g_prog + %t12 = getelementptr inbounds %LSlice, ptr %t11, i32 0, i32 0 + %t13 = load ptr, ptr %t12 + %t14 = load i32, ptr %t2 + %t15 = getelementptr inbounds ptr, ptr %t13, i32 %t14 + %t16 = load ptr, ptr %t15 + %t17 = getelementptr inbounds %Cmp_Node, ptr %t16, i32 0, i32 0 + %t18 = load i32, ptr %t17 + %t19 = icmp eq i32 %t18, 10 + %t20 = zext i1 %t19 to i32 + %t21 = icmp ne i32 %t20, 0 + %t22 = zext i1 %t21 to i32 + store i32 %t22, ptr %t10 + br i1 %t21, label %sc6, label %scend7 +sc6: + %t23 = load ptr, ptr @g_prog + %t24 = getelementptr inbounds %LSlice, ptr %t23, i32 0, i32 0 + %t25 = load ptr, ptr %t24 + %t26 = load i32, ptr %t2 + %t27 = getelementptr inbounds ptr, ptr %t25, i32 %t26 + %t28 = load ptr, ptr %t27 + %t29 = call i32 @fn_net_model_syncs(ptr %t28) + %t30 = icmp ne i32 %t29, 0 + %t31 = zext i1 %t30 to i32 + store i32 %t31, ptr %t10 + br label %scend7 +scend7: + %t32 = load i32, ptr %t10 + %t33 = icmp ne i32 %t32, 0 + br i1 %t33, label %then8, label %ifend10 +then8: + %t34 = load ptr, ptr @g_prog + %t35 = getelementptr inbounds %LSlice, ptr %t34, i32 0, i32 0 + %t36 = load ptr, ptr %t35 + %t37 = load i32, ptr %t2 + %t38 = getelementptr inbounds ptr, ptr %t36, i32 %t37 + %t39 = load ptr, ptr %t38 + call void @fn_emit_net_serialize(ptr %t39) + %t40 = load ptr, ptr @g_prog + %t41 = getelementptr inbounds %LSlice, ptr %t40, i32 0, i32 0 + %t42 = load ptr, ptr %t41 + %t43 = load i32, ptr %t2 + %t44 = getelementptr inbounds ptr, ptr %t42, i32 %t43 + %t45 = load ptr, ptr %t44 + call void @fn_emit_net_apply(ptr %t45) + br label %ifend10 +ifend10: + %t46 = load i32, ptr %t2 + %t47 = add i32 %t46, 1 + store i32 %t47, ptr %t2 + br label %wcond3 +wend5: + call void @fn_emit_net_dispatch() + br label %ifend2 +ifend2: + %t48 = call i32 @fn_net_has_owned() + %t49 = icmp ne i32 %t48, 0 + br i1 %t49, label %then11, label %ifend13 +then11: + call void @fn_emit_net_owner() + br label %ifend13 +ifend13: + %t50 = call i32 @fn_net_has_remote() + %t51 = icmp ne i32 %t50, 0 + br i1 %t51, label %then14, label %ifend16 +then14: + call void @fn_emith(ptr @.str2701) + call void @fn_emit_net_pump() + br label %ifend16 +ifend16: br label %ret ret: ret void @@ -19907,7 +30251,7 @@ entry: %t3 = load ptr, ptr %t2 store ptr %t3, ptr %t4 %t5 = load ptr, ptr %t4 - %t6 = call i32 @fn_str_eq(ptr %t5, ptr @.str1466) + %t6 = call i32 @fn_str_eq(ptr %t5, ptr @.str2702) %t7 = icmp ne i32 %t6, 0 br i1 %t7, label %then0, label %ifend2 then0: @@ -19915,7 +30259,7 @@ then0: br label %ret ifend2: %t8 = load ptr, ptr %t4 - %t9 = call i32 @fn_str_eq(ptr %t8, ptr @.str1467) + %t9 = call i32 @fn_str_eq(ptr %t8, ptr @.str2703) %t10 = icmp ne i32 %t9, 0 br i1 %t10, label %then3, label %ifend5 then3: @@ -19923,7 +30267,7 @@ then3: br label %ret ifend5: %t11 = load ptr, ptr %t4 - %t12 = call i32 @fn_str_eq(ptr %t11, ptr @.str1468) + %t12 = call i32 @fn_str_eq(ptr %t11, ptr @.str2704) %t13 = icmp ne i32 %t12, 0 br i1 %t13, label %then6, label %ifend8 then6: @@ -19931,7 +30275,7 @@ then6: br label %ret ifend8: %t14 = load ptr, ptr %t4 - %t15 = call i32 @fn_str_eq(ptr %t14, ptr @.str1469) + %t15 = call i32 @fn_str_eq(ptr %t14, ptr @.str2705) %t16 = icmp ne i32 %t15, 0 br i1 %t16, label %then9, label %ifend11 then9: @@ -19939,7 +30283,7 @@ then9: br label %ret ifend11: %t17 = load ptr, ptr %t4 - %t18 = call i32 @fn_str_eq(ptr %t17, ptr @.str1470) + %t18 = call i32 @fn_str_eq(ptr %t17, ptr @.str2706) %t19 = icmp ne i32 %t18, 0 br i1 %t19, label %then12, label %ifend14 then12: @@ -19947,7 +30291,7 @@ then12: br label %ret ifend14: %t20 = load ptr, ptr %t4 - %t21 = call i32 @fn_str_eq(ptr %t20, ptr @.str1471) + %t21 = call i32 @fn_str_eq(ptr %t20, ptr @.str2707) %t22 = icmp ne i32 %t21, 0 br i1 %t22, label %then15, label %ifend17 then15: @@ -19955,7 +30299,7 @@ then15: br label %ret ifend17: %t23 = load ptr, ptr %t4 - %t24 = call i32 @fn_str_eq(ptr %t23, ptr @.str1472) + %t24 = call i32 @fn_str_eq(ptr %t23, ptr @.str2708) %t25 = icmp ne i32 %t24, 0 br i1 %t25, label %then18, label %ifend20 then18: @@ -20453,7 +30797,7 @@ wbody12: %t75 = load i32, ptr %t9 %t76 = getelementptr inbounds ptr, ptr %t74, i32 %t75 %t77 = load ptr, ptr %t76 - %t78 = call ptr @fn_ui_prop(ptr %t77, ptr @.str1473) + %t78 = call ptr @fn_ui_prop(ptr %t77, ptr @.str2709) store ptr %t78, ptr %t79 %t80 = load ptr, ptr %t79 %t81 = icmp ne ptr %t80, null @@ -20582,18 +30926,18 @@ entry: store i32 %arg_idx, ptr %t0 store i32 %arg_key, ptr %t1 store ptr %arg_val, ptr %t2 - call void @fn_emit(ptr @.str1474) + call void @fn_emit(ptr @.str2710) %t3 = load i32, ptr %t0 %t4 = call ptr @fn_itoa(i32 %t3) call void @fn_emit(ptr %t4) - call void @fn_emit(ptr @.str1475) + call void @fn_emit(ptr @.str2711) %t5 = load i32, ptr %t1 %t6 = call ptr @fn_itoa(i32 %t5) call void @fn_emit(ptr %t6) - call void @fn_emit(ptr @.str1476) + call void @fn_emit(ptr @.str2712) %t7 = load ptr, ptr %t2 call void @fn_emit(ptr %t7) - call void @fn_emit(ptr @.str1477) + call void @fn_emit(ptr @.str2713) br label %ret ret: ret void @@ -20605,7 +30949,7 @@ entry: %t0 = alloca ptr store ptr %arg_k, ptr %t0 %t1 = load ptr, ptr %t0 - %t2 = call i32 @fn_str_eq(ptr %t1, ptr @.str1478) + %t2 = call i32 @fn_str_eq(ptr %t1, ptr @.str2714) %t3 = icmp ne i32 %t2, 0 br i1 %t3, label %then0, label %ifend2 then0: @@ -20613,7 +30957,7 @@ then0: br label %ret ifend2: %t4 = load ptr, ptr %t0 - %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str1479) + %t5 = call i32 @fn_str_eq(ptr %t4, ptr @.str2715) %t6 = icmp ne i32 %t5, 0 br i1 %t6, label %then3, label %ifend5 then3: @@ -20621,7 +30965,7 @@ then3: br label %ret ifend5: %t7 = load ptr, ptr %t0 - %t8 = call i32 @fn_str_eq(ptr %t7, ptr @.str1480) + %t8 = call i32 @fn_str_eq(ptr %t7, ptr @.str2716) %t9 = icmp ne i32 %t8, 0 br i1 %t9, label %then6, label %ifend8 then6: @@ -20629,7 +30973,7 @@ then6: br label %ret ifend8: %t10 = load ptr, ptr %t0 - %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str1481) + %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str2717) %t12 = icmp ne i32 %t11, 0 br i1 %t12, label %then9, label %ifend11 then9: @@ -20637,7 +30981,7 @@ then9: br label %ret ifend11: %t13 = load ptr, ptr %t0 - %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str1482) + %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str2718) %t15 = icmp ne i32 %t14, 0 br i1 %t15, label %then12, label %ifend14 then12: @@ -20645,7 +30989,7 @@ then12: br label %ret ifend14: %t16 = load ptr, ptr %t0 - %t17 = call i32 @fn_str_eq(ptr %t16, ptr @.str1483) + %t17 = call i32 @fn_str_eq(ptr %t16, ptr @.str2719) %t18 = icmp ne i32 %t17, 0 br i1 %t18, label %then15, label %ifend17 then15: @@ -20653,7 +30997,7 @@ then15: br label %ret ifend17: %t19 = load ptr, ptr %t0 - %t20 = call i32 @fn_str_eq(ptr %t19, ptr @.str1484) + %t20 = call i32 @fn_str_eq(ptr %t19, ptr @.str2720) %t21 = icmp ne i32 %t20, 0 br i1 %t21, label %then18, label %ifend20 then18: @@ -20661,7 +31005,7 @@ then18: br label %ret ifend20: %t22 = load ptr, ptr %t0 - %t23 = call i32 @fn_str_eq(ptr %t22, ptr @.str1485) + %t23 = call i32 @fn_str_eq(ptr %t22, ptr @.str2721) %t24 = icmp ne i32 %t23, 0 br i1 %t24, label %then21, label %ifend23 then21: @@ -20669,7 +31013,7 @@ then21: br label %ret ifend23: %t25 = load ptr, ptr %t0 - %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str1486) + %t26 = call i32 @fn_str_eq(ptr %t25, ptr @.str2722) %t27 = icmp ne i32 %t26, 0 br i1 %t27, label %then24, label %ifend26 then24: @@ -20677,7 +31021,7 @@ then24: br label %ret ifend26: %t28 = load ptr, ptr %t0 - %t29 = call i32 @fn_str_eq(ptr %t28, ptr @.str1487) + %t29 = call i32 @fn_str_eq(ptr %t28, ptr @.str2723) %t30 = icmp ne i32 %t29, 0 br i1 %t30, label %then27, label %ifend29 then27: @@ -20685,7 +31029,7 @@ then27: br label %ret ifend29: %t31 = load ptr, ptr %t0 - %t32 = call i32 @fn_str_eq(ptr %t31, ptr @.str1488) + %t32 = call i32 @fn_str_eq(ptr %t31, ptr @.str2724) %t33 = icmp ne i32 %t32, 0 br i1 %t33, label %then30, label %ifend32 then30: @@ -20693,7 +31037,7 @@ then30: br label %ret ifend32: %t34 = load ptr, ptr %t0 - %t35 = call i32 @fn_str_eq(ptr %t34, ptr @.str1489) + %t35 = call i32 @fn_str_eq(ptr %t34, ptr @.str2725) %t36 = icmp ne i32 %t35, 0 br i1 %t36, label %then33, label %ifend35 then33: @@ -20701,7 +31045,7 @@ then33: br label %ret ifend35: %t37 = load ptr, ptr %t0 - %t38 = call i32 @fn_str_eq(ptr %t37, ptr @.str1490) + %t38 = call i32 @fn_str_eq(ptr %t37, ptr @.str2726) %t39 = icmp ne i32 %t38, 0 br i1 %t39, label %then36, label %ifend38 then36: @@ -20709,7 +31053,7 @@ then36: br label %ret ifend38: %t40 = load ptr, ptr %t0 - %t41 = call i32 @fn_str_eq(ptr %t40, ptr @.str1491) + %t41 = call i32 @fn_str_eq(ptr %t40, ptr @.str2727) %t42 = icmp ne i32 %t41, 0 br i1 %t42, label %then39, label %ifend41 then39: @@ -20758,13 +31102,13 @@ entry: store ptr %t3, ptr %t4 %t5 = load ptr, ptr %t1 store ptr %t5, ptr @g_code - call void @fn_emit(ptr @.str1492) + call void @fn_emit(ptr @.str2728) %t6 = load ptr, ptr @g_uiw %t7 = getelementptr inbounds %LSlice, ptr %t6, i32 0, i32 1 %t8 = load i32, ptr %t7 %t9 = call ptr @fn_itoa(i32 %t8) call void @fn_emit(ptr %t9) - call void @fn_emit(ptr @.str1493) + call void @fn_emit(ptr @.str2729) store i32 0, ptr %t10 br label %wcond0 wcond0: @@ -20807,7 +31151,7 @@ wbody1: br i1 %t42, label %then3, label %ifend5 then3: %t43 = load i32, ptr %t10 - call void @fn_ll_ui_set(i32 %t43, i32 17, ptr @.str1494) + call void @fn_ll_ui_set(i32 %t43, i32 17, ptr @.str2730) br label %ifend5 ifend5: store i32 0, ptr %t44 @@ -20846,7 +31190,7 @@ wbody7: %t73 = load ptr, ptr %t72 store ptr %t73, ptr %t74 %t75 = load ptr, ptr %t70 - %t76 = call i32 @fn_str_eq(ptr %t75, ptr @.str1495) + %t76 = call i32 @fn_str_eq(ptr %t75, ptr @.str2731) %t77 = icmp ne i32 %t76, 0 br i1 %t77, label %then9, label %ifend11 then9: @@ -20856,34 +31200,34 @@ then9: br label %wcond6 ifend11: %t80 = load ptr, ptr %t70 - %t81 = call i32 @fn_str_eq(ptr %t80, ptr @.str1496) + %t81 = call i32 @fn_str_eq(ptr %t80, ptr @.str2732) %t82 = icmp ne i32 %t81, 0 br i1 %t82, label %then12, label %else13 then12: %t83 = load ptr, ptr %t74 %t84 = call ptr @fn_emit_expr(ptr %t83) store ptr %t84, ptr %t85 - call void @fn_emit(ptr @.str1497) + call void @fn_emit(ptr @.str2733) %t86 = load i32, ptr %t10 %t87 = call ptr @fn_itoa(i32 %t86) call void @fn_emit(ptr %t87) - call void @fn_emit(ptr @.str1498) + call void @fn_emit(ptr @.str2734) %t88 = load ptr, ptr %t85 %t89 = getelementptr inbounds %Cmp_Val, ptr %t88, i32 0, i32 0 %t90 = load ptr, ptr %t89 call void @fn_emit(ptr %t90) - call void @fn_emit(ptr @.str1499) + call void @fn_emit(ptr @.str2735) br label %ifend14 else13: %t92 = load ptr, ptr %t70 - %t93 = call i32 @fn_str_eq(ptr %t92, ptr @.str1500) + %t93 = call i32 @fn_str_eq(ptr %t92, ptr @.str2736) %t94 = icmp ne i32 %t93, 0 %t95 = zext i1 %t94 to i32 store i32 %t95, ptr %t91 br i1 %t94, label %scend16, label %sc15 sc15: %t96 = load ptr, ptr %t70 - %t97 = call i32 @fn_str_eq(ptr %t96, ptr @.str1501) + %t97 = call i32 @fn_str_eq(ptr %t96, ptr @.str2737) %t98 = icmp ne i32 %t97, 0 %t99 = zext i1 %t98 to i32 store i32 %t99, ptr %t91 @@ -20899,12 +31243,12 @@ then17: %t105 = load ptr, ptr %t104 %t106 = getelementptr inbounds %Cmp_Val, ptr %t105, i32 0, i32 0 %t107 = load ptr, ptr %t106 - %t108 = call ptr @fn_str_concat(ptr @.str1502, ptr %t107) - %t109 = call ptr @fn_str_concat(ptr %t108, ptr @.str1503) + %t108 = call ptr @fn_str_concat(ptr @.str2738, ptr %t107) + %t109 = call ptr @fn_str_concat(ptr %t108, ptr @.str2739) %t110 = call ptr @fn_emit_bind(ptr %t109) store ptr %t110, ptr %t111 %t112 = load ptr, ptr %t70 - %t113 = call i32 @fn_str_eq(ptr %t112, ptr @.str1504) + %t113 = call i32 @fn_str_eq(ptr %t112, ptr @.str2740) %t114 = icmp ne i32 %t113, 0 br i1 %t114, label %then20, label %else21 then20: @@ -20921,7 +31265,7 @@ ifend22: br label %ifend19 else18: %t119 = load ptr, ptr %t70 - %t120 = call i32 @fn_str_eq(ptr %t119, ptr @.str1505) + %t120 = call i32 @fn_str_eq(ptr %t119, ptr @.str2741) %t121 = icmp ne i32 %t120, 0 br i1 %t121, label %then23, label %else24 then23: @@ -20937,7 +31281,7 @@ then26: %t129 = load ptr, ptr %t74 %t130 = getelementptr inbounds %Cmp_Node, ptr %t129, i32 0, i32 1 %t131 = load ptr, ptr %t130 - %t132 = call i32 @fn_str_eq(ptr %t131, ptr @.str1506) + %t132 = call i32 @fn_str_eq(ptr %t131, ptr @.str2742) %t133 = icmp ne i32 %t132, 0 br i1 %t133, label %then29, label %ifend31 then29: @@ -20947,7 +31291,7 @@ ifend31: %t134 = load ptr, ptr %t74 %t135 = getelementptr inbounds %Cmp_Node, ptr %t134, i32 0, i32 1 %t136 = load ptr, ptr %t135 - %t137 = call i32 @fn_str_eq(ptr %t136, ptr @.str1507) + %t137 = call i32 @fn_str_eq(ptr %t136, ptr @.str2743) %t138 = icmp ne i32 %t137, 0 br i1 %t138, label %then32, label %ifend34 then32: @@ -21011,7 +31355,7 @@ scend39: br i1 %t176, label %then40, label %ifend42 then40: %t177 = load i32, ptr %t10 - call void @fn_ll_ui_set(i32 %t177, i32 6, ptr @.str1508) + call void @fn_ll_ui_set(i32 %t177, i32 6, ptr @.str2744) br label %ifend42 ifend42: br label %ifend37 @@ -21034,14 +31378,14 @@ wend8: wend2: %t182 = load ptr, ptr %t4 store ptr %t182, ptr @g_code - call void @fn_emit(ptr @.str1509) + call void @fn_emit(ptr @.str2745) %t183 = load ptr, ptr @g_falloc %t184 = call ptr @fn_buf_str(ptr %t183) call void @fn_emit(ptr %t184) %t185 = load ptr, ptr %t1 %t186 = call ptr @fn_buf_str(ptr %t185) call void @fn_emit(ptr %t186) - call void @fn_emit(ptr @.str1510) + call void @fn_emit(ptr @.str2746) br label %ret ret: ret void @@ -21072,7 +31416,7 @@ wbody1: %t14 = icmp ne i32 %t13, 0 br i1 %t14, label %then3, label %ifend5 then3: - call void @fn_emit(ptr @.str1511) + call void @fn_emit(ptr @.str2747) br label %ifend5 ifend5: %t15 = load ptr, ptr %t0 @@ -21087,7 +31431,7 @@ ifend5: %t24 = load ptr, ptr %t23 %t25 = call ptr @fn_llty(ptr %t24) call void @fn_emit(ptr %t25) - call void @fn_emit(ptr @.str1512) + call void @fn_emit(ptr @.str2748) %t26 = load ptr, ptr %t0 %t27 = getelementptr inbounds %Cmp_Node, ptr %t26, i32 0, i32 7 %t28 = load ptr, ptr %t27 @@ -21141,19 +31485,19 @@ entry: %t11 = call ptr @fn_llty(ptr %t10) store ptr %t11, ptr %t12 %t13 = load ptr, ptr %t12 - %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str1513) + %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str2749) %t15 = icmp eq i32 %t14, 0 %t16 = zext i1 %t15 to i32 %t17 = icmp ne i32 %t16, 0 br i1 %t17, label %then0, label %ifend2 then0: %t18 = load ptr, ptr @g_falloc - call void @fn_buf_puts(ptr %t18, ptr @.str1514) + call void @fn_buf_puts(ptr %t18, ptr @.str2750) %t19 = load ptr, ptr @g_falloc %t20 = load ptr, ptr %t12 call void @fn_buf_puts(ptr %t19, ptr %t20) %t21 = load ptr, ptr @g_falloc - call void @fn_buf_puts(ptr %t21, ptr @.str1515) + call void @fn_buf_puts(ptr %t21, ptr @.str2751) br label %ifend2 ifend2: store i32 0, ptr %t22 @@ -21185,21 +31529,21 @@ wbody4: %t44 = call ptr @fn_llty(ptr %t43) %t45 = call ptr @fn_emit_alloca(ptr %t44) store ptr %t45, ptr %t46 - call void @fn_emit(ptr @.str1516) + call void @fn_emit(ptr @.str2752) %t47 = load ptr, ptr %t40 %t48 = getelementptr inbounds %Cmp_Node, ptr %t47, i32 0, i32 3 %t49 = load ptr, ptr %t48 %t50 = call ptr @fn_llty(ptr %t49) call void @fn_emit(ptr %t50) - call void @fn_emit(ptr @.str1517) + call void @fn_emit(ptr @.str2753) %t51 = load ptr, ptr %t40 %t52 = getelementptr inbounds %Cmp_Node, ptr %t51, i32 0, i32 1 %t53 = load ptr, ptr %t52 call void @fn_emit(ptr %t53) - call void @fn_emit(ptr @.str1518) + call void @fn_emit(ptr @.str2754) %t54 = load ptr, ptr %t46 call void @fn_emit(ptr %t54) - call void @fn_emit(ptr @.str1519) + call void @fn_emit(ptr @.str2755) %t55 = load ptr, ptr %t40 %t56 = getelementptr inbounds %Cmp_Node, ptr %t55, i32 0, i32 1 %t57 = load ptr, ptr %t56 @@ -21223,53 +31567,53 @@ wend5: %t70 = icmp ne i32 %t69, 0 br i1 %t70, label %then6, label %ifend8 then6: - call void @fn_emit(ptr @.str1520) + call void @fn_emit(ptr @.str2756) br label %ifend8 ifend8: - call void @fn_emit(ptr @.str1521) + call void @fn_emit(ptr @.str2757) %t71 = load ptr, ptr %t12 - %t72 = call i32 @fn_str_eq(ptr %t71, ptr @.str1522) + %t72 = call i32 @fn_str_eq(ptr %t71, ptr @.str2758) %t73 = icmp ne i32 %t72, 0 br i1 %t73, label %then9, label %else10 then9: - call void @fn_emit(ptr @.str1523) + call void @fn_emit(ptr @.str2759) br label %ifend11 else10: %t74 = load ptr, ptr %t12 - %t75 = call ptr @fn_str_concat(ptr @.str1524, ptr %t74) - %t76 = call ptr @fn_str_concat(ptr %t75, ptr @.str1525) + %t75 = call ptr @fn_str_concat(ptr @.str2760, ptr %t74) + %t76 = call ptr @fn_str_concat(ptr %t75, ptr @.str2761) %t77 = call ptr @fn_emit_bind(ptr %t76) store ptr %t77, ptr %t78 - call void @fn_emit(ptr @.str1526) + call void @fn_emit(ptr @.str2762) %t79 = load ptr, ptr %t12 call void @fn_emit(ptr %t79) - call void @fn_emit(ptr @.str1527) + call void @fn_emit(ptr @.str2763) %t80 = load ptr, ptr %t78 call void @fn_emit(ptr %t80) - call void @fn_emit(ptr @.str1528) + call void @fn_emit(ptr @.str2764) br label %ifend11 ifend11: %t81 = load ptr, ptr %t8 store ptr %t81, ptr @g_code - call void @fn_emit(ptr @.str1529) + call void @fn_emit(ptr @.str2765) %t82 = load ptr, ptr %t12 call void @fn_emit(ptr %t82) - call void @fn_emit(ptr @.str1530) + call void @fn_emit(ptr @.str2766) %t83 = load ptr, ptr %t0 %t84 = getelementptr inbounds %Cmp_Node, ptr %t83, i32 0, i32 1 %t85 = load ptr, ptr %t84 call void @fn_emit(ptr %t85) - call void @fn_emit(ptr @.str1531) + call void @fn_emit(ptr @.str2767) %t86 = load ptr, ptr %t0 call void @fn_emit_params_sig(ptr %t86) - call void @fn_emit(ptr @.str1532) + call void @fn_emit(ptr @.str2768) %t87 = load ptr, ptr @g_falloc %t88 = call ptr @fn_buf_str(ptr %t87) call void @fn_emit(ptr %t88) %t89 = load ptr, ptr %t5 %t90 = call ptr @fn_buf_str(ptr %t89) call void @fn_emit(ptr %t90) - call void @fn_emit(ptr @.str1533) + call void @fn_emit(ptr @.str2769) br label %ret ret: ret void @@ -21287,7 +31631,7 @@ entry: store i32 0, ptr @g_g_term call void @fn_loc_reset() store i32 0, ptr @g_nloop - store ptr @.str1534, ptr @g_ret_ty + store ptr @.str2770, ptr @g_ret_ty %t1 = call ptr @fn_buf_new() store ptr %t1, ptr %t2 %t3 = call ptr @fn_buf_new() @@ -21297,10 +31641,10 @@ entry: %t6 = load ptr, ptr %t2 store ptr %t6, ptr @g_code %t7 = load ptr, ptr @g_falloc - call void @fn_buf_puts(ptr %t7, ptr @.str1535) - call void @fn_emit(ptr @.str1536) - call void @fn_emit(ptr @.str1537) - call void @fn_emit(ptr @.str1538) + call void @fn_buf_puts(ptr %t7, ptr @.str2771) + call void @fn_emit(ptr @.str2772) + call void @fn_emit(ptr @.str2773) + call void @fn_emit(ptr @.str2774) %t8 = load ptr, ptr %t0 %t9 = getelementptr inbounds %Cmp_Node, ptr %t8, i32 0, i32 4 %t10 = load ptr, ptr %t9 @@ -21311,26 +31655,26 @@ entry: %t14 = icmp ne i32 %t13, 0 br i1 %t14, label %then0, label %ifend2 then0: - call void @fn_emit(ptr @.str1539) + call void @fn_emit(ptr @.str2775) br label %ifend2 ifend2: - call void @fn_emit(ptr @.str1540) - %t15 = call ptr @fn_emit_bind(ptr @.str1541) + call void @fn_emit(ptr @.str2776) + %t15 = call ptr @fn_emit_bind(ptr @.str2777) store ptr %t15, ptr %t16 - call void @fn_emit(ptr @.str1542) + call void @fn_emit(ptr @.str2778) %t17 = load ptr, ptr %t16 call void @fn_emit(ptr %t17) - call void @fn_emit(ptr @.str1543) + call void @fn_emit(ptr @.str2779) %t18 = load ptr, ptr %t5 store ptr %t18, ptr @g_code - call void @fn_emit(ptr @.str1544) + call void @fn_emit(ptr @.str2780) %t19 = load ptr, ptr @g_falloc %t20 = call ptr @fn_buf_str(ptr %t19) call void @fn_emit(ptr %t20) %t21 = load ptr, ptr %t2 %t22 = call ptr @fn_buf_str(ptr %t21) call void @fn_emit(ptr %t22) - call void @fn_emit(ptr @.str1545) + call void @fn_emit(ptr @.str2781) br label %ret ret: ret void @@ -21339,6 +31683,8 @@ ret: define void @fn_emit_program() { entry: %t52 = alloca i32 + %t85 = alloca i32 + %t104 = alloca i32 %t0 = call ptr @fn_buf_new() store ptr %t0, ptr @g_head %t1 = call ptr @fn_buf_new() @@ -21346,6 +31692,7 @@ entry: store i32 0, ptr @g_g_uses_str store i32 0, ptr @g_g_uses_intstr store i32 0, ptr @g_g_uses_strslice + store i32 0, ptr @g_g_uses_loopback %t2 = getelementptr %LSlice, ptr null, i32 1 %t3 = ptrtoint ptr %t2 to i64 %t4 = call ptr @malloc(i64 %t3) @@ -21427,6 +31774,7 @@ entry: store i32 0, ptr %t49 store ptr %t46, ptr @g_mach_stk call void @fn_emit_header() + call void @fn_emit_extern_decls() %t50 = call i32 @fn_has_ecs() %t51 = icmp ne i32 %t50, 0 br i1 %t51, label %then0, label %ifend2 @@ -21473,90 +31821,198 @@ ifend8: store i32 %t78, ptr %t52 br label %wcond3 wend5: - %t79 = call i32 @fn_has_ecs() - %t80 = icmp ne i32 %t79, 0 - br i1 %t80, label %then9, label %ifend11 + %t79 = load ptr, ptr @g_g_events + %t80 = getelementptr inbounds %LSlice, ptr %t79, i32 0, i32 1 + %t81 = load i32, ptr %t80 + %t82 = icmp sgt i32 %t81, 0 + %t83 = zext i1 %t82 to i32 + %t84 = icmp ne i32 %t83, 0 + br i1 %t84, label %then9, label %ifend11 then9: - call void @fn_emit_ecs_allocator() - call void @fn_emit_snapshot() + call void @fn_emit_event_fns() br label %ifend11 ifend11: - %t81 = call i32 @fn_has_ui() - %t82 = icmp ne i32 %t81, 0 - br i1 %t82, label %then12, label %ifend14 -then12: + %t86 = call i32 @fn_has_ecs() + %t87 = icmp ne i32 %t86, 0 + %t88 = zext i1 %t87 to i32 + store i32 %t88, ptr %t85 + br i1 %t87, label %sc12, label %scend13 +sc12: + %t89 = load ptr, ptr @g_g_events + %t90 = getelementptr inbounds %LSlice, ptr %t89, i32 0, i32 1 + %t91 = load i32, ptr %t90 + %t92 = icmp sgt i32 %t91, 0 + %t93 = zext i1 %t92 to i32 + %t94 = icmp ne i32 %t93, 0 + %t95 = zext i1 %t94 to i32 + store i32 %t95, ptr %t85 + br label %scend13 +scend13: + %t96 = load i32, ptr %t85 + %t97 = icmp ne i32 %t96, 0 + br i1 %t97, label %then14, label %ifend16 +then14: + call void @fn_emit_world_table() + br label %ifend16 +ifend16: + %t98 = call i32 @fn_has_ecs() + %t99 = icmp ne i32 %t98, 0 + br i1 %t99, label %then17, label %ifend19 +then17: + call void @fn_emit_ecs_allocator() + call void @fn_emit_snapshot() + br label %ifend19 +ifend19: + %t100 = call i32 @fn_has_ecs() + %t101 = icmp ne i32 %t100, 0 + br i1 %t101, label %then20, label %ifend22 +then20: + call void @fn_emit_net() + br label %ifend22 +ifend22: + %t102 = call i32 @fn_has_ui() + %t103 = icmp ne i32 %t102, 0 + br i1 %t103, label %then23, label %ifend25 +then23: call void @fn_emit_ui_build() - br label %ifend14 -ifend14: - %t83 = call i32 @fn_has_systems() - %t84 = icmp ne i32 %t83, 0 - br i1 %t84, label %then15, label %else16 -then15: - call void @fn_emit_game_main() - br label %ifend17 -else16: - store i32 0, ptr %t52 - br label %wcond18 -wcond18: - %t85 = load i32, ptr %t52 - %t86 = load ptr, ptr @g_prog - %t87 = getelementptr inbounds %LSlice, ptr %t86, i32 0, i32 1 - %t88 = load i32, ptr %t87 - %t89 = icmp slt i32 %t85, %t88 - %t90 = zext i1 %t89 to i32 - %t91 = icmp ne i32 %t90, 0 - br i1 %t91, label %wbody19, label %wend20 -wbody19: - %t92 = load ptr, ptr @g_prog - %t93 = getelementptr inbounds %LSlice, ptr %t92, i32 0, i32 0 - %t94 = load ptr, ptr %t93 - %t95 = load i32, ptr %t52 - %t96 = getelementptr inbounds ptr, ptr %t94, i32 %t95 - %t97 = load ptr, ptr %t96 - %t98 = getelementptr inbounds %Cmp_Node, ptr %t97, i32 0, i32 0 - %t99 = load i32, ptr %t98 - %t100 = icmp eq i32 %t99, 6 - %t101 = zext i1 %t100 to i32 - %t102 = icmp ne i32 %t101, 0 - br i1 %t102, label %then21, label %ifend23 -then21: - %t103 = load ptr, ptr @g_prog - %t104 = getelementptr inbounds %LSlice, ptr %t103, i32 0, i32 0 - %t105 = load ptr, ptr %t104 - %t106 = load i32, ptr %t52 - %t107 = getelementptr inbounds ptr, ptr %t105, i32 %t106 - %t108 = load ptr, ptr %t107 - call void @fn_emit_main(ptr %t108) - br label %ifend23 -ifend23: - %t109 = load i32, ptr %t52 - %t110 = add i32 %t109, 1 - store i32 %t110, ptr %t52 - br label %wcond18 -wend20: - br label %ifend17 -ifend17: - %t111 = load i32, ptr @g_g_uses_str + br label %ifend25 +ifend25: + %t105 = call i32 @fn_has_systems() + %t106 = icmp ne i32 %t105, 0 + %t107 = zext i1 %t106 to i32 + store i32 %t107, ptr %t104 + br i1 %t106, label %sc26, label %scend27 +sc26: + %t108 = call i32 @fn_has_entry() + %t109 = icmp ne i32 %t108, 0 + %t110 = zext i1 %t109 to i32 + store i32 %t110, ptr %t104 + br label %scend27 +scend27: + %t111 = load i32, ptr %t104 %t112 = icmp ne i32 %t111, 0 - br i1 %t112, label %then24, label %ifend26 -then24: + br i1 %t112, label %then28, label %else29 +then28: + call void @fn_emit_game_defs() + store i32 0, ptr %t52 + br label %wcond31 +wcond31: + %t113 = load i32, ptr %t52 + %t114 = load ptr, ptr @g_prog + %t115 = getelementptr inbounds %LSlice, ptr %t114, i32 0, i32 1 + %t116 = load i32, ptr %t115 + %t117 = icmp slt i32 %t113, %t116 + %t118 = zext i1 %t117 to i32 + %t119 = icmp ne i32 %t118, 0 + br i1 %t119, label %wbody32, label %wend33 +wbody32: + %t120 = load ptr, ptr @g_prog + %t121 = getelementptr inbounds %LSlice, ptr %t120, i32 0, i32 0 + %t122 = load ptr, ptr %t121 + %t123 = load i32, ptr %t52 + %t124 = getelementptr inbounds ptr, ptr %t122, i32 %t123 + %t125 = load ptr, ptr %t124 + %t126 = getelementptr inbounds %Cmp_Node, ptr %t125, i32 0, i32 0 + %t127 = load i32, ptr %t126 + %t128 = icmp eq i32 %t127, 6 + %t129 = zext i1 %t128 to i32 + %t130 = icmp ne i32 %t129, 0 + br i1 %t130, label %then34, label %ifend36 +then34: + %t131 = load ptr, ptr @g_prog + %t132 = getelementptr inbounds %LSlice, ptr %t131, i32 0, i32 0 + %t133 = load ptr, ptr %t132 + %t134 = load i32, ptr %t52 + %t135 = getelementptr inbounds ptr, ptr %t133, i32 %t134 + %t136 = load ptr, ptr %t135 + call void @fn_emit_main(ptr %t136) + br label %ifend36 +ifend36: + %t137 = load i32, ptr %t52 + %t138 = add i32 %t137, 1 + store i32 %t138, ptr %t52 + br label %wcond31 +wend33: + br label %ifend30 +else29: + %t139 = call i32 @fn_has_systems() + %t140 = icmp ne i32 %t139, 0 + br i1 %t140, label %then37, label %else38 +then37: + call void @fn_emit_game_main() + br label %ifend39 +else38: + store i32 0, ptr %t52 + br label %wcond40 +wcond40: + %t141 = load i32, ptr %t52 + %t142 = load ptr, ptr @g_prog + %t143 = getelementptr inbounds %LSlice, ptr %t142, i32 0, i32 1 + %t144 = load i32, ptr %t143 + %t145 = icmp slt i32 %t141, %t144 + %t146 = zext i1 %t145 to i32 + %t147 = icmp ne i32 %t146, 0 + br i1 %t147, label %wbody41, label %wend42 +wbody41: + %t148 = load ptr, ptr @g_prog + %t149 = getelementptr inbounds %LSlice, ptr %t148, i32 0, i32 0 + %t150 = load ptr, ptr %t149 + %t151 = load i32, ptr %t52 + %t152 = getelementptr inbounds ptr, ptr %t150, i32 %t151 + %t153 = load ptr, ptr %t152 + %t154 = getelementptr inbounds %Cmp_Node, ptr %t153, i32 0, i32 0 + %t155 = load i32, ptr %t154 + %t156 = icmp eq i32 %t155, 6 + %t157 = zext i1 %t156 to i32 + %t158 = icmp ne i32 %t157, 0 + br i1 %t158, label %then43, label %ifend45 +then43: + %t159 = load ptr, ptr @g_prog + %t160 = getelementptr inbounds %LSlice, ptr %t159, i32 0, i32 0 + %t161 = load ptr, ptr %t160 + %t162 = load i32, ptr %t52 + %t163 = getelementptr inbounds ptr, ptr %t161, i32 %t162 + %t164 = load ptr, ptr %t163 + call void @fn_emit_main(ptr %t164) + br label %ifend45 +ifend45: + %t165 = load i32, ptr %t52 + %t166 = add i32 %t165, 1 + store i32 %t166, ptr %t52 + br label %wcond40 +wend42: + br label %ifend39 +ifend39: + br label %ifend30 +ifend30: + %t167 = load i32, ptr @g_g_uses_loopback + %t168 = icmp ne i32 %t167, 0 + br i1 %t168, label %then46, label %ifend48 +then46: + call void @fn_emit_loopback() + br label %ifend48 +ifend48: + %t169 = load i32, ptr @g_g_uses_str + %t170 = icmp ne i32 %t169, 0 + br i1 %t170, label %then49, label %ifend51 +then49: call void @fn_emit_str_prelude() - br label %ifend26 -ifend26: - %t113 = load i32, ptr @g_g_uses_intstr - %t114 = icmp ne i32 %t113, 0 - br i1 %t114, label %then27, label %ifend29 -then27: + br label %ifend51 +ifend51: + %t171 = load i32, ptr @g_g_uses_intstr + %t172 = icmp ne i32 %t171, 0 + br i1 %t172, label %then52, label %ifend54 +then52: call void @fn_emit_int_str() - br label %ifend29 -ifend29: - %t115 = load i32, ptr @g_g_uses_strslice - %t116 = icmp ne i32 %t115, 0 - br i1 %t116, label %then30, label %ifend32 -then30: + br label %ifend54 +ifend54: + %t173 = load i32, ptr @g_g_uses_strslice + %t174 = icmp ne i32 %t173, 0 + br i1 %t174, label %then55, label %ifend57 +then55: call void @fn_emit_str_slice() - br label %ifend32 -ifend32: + br label %ifend57 +ifend57: br label %ret ret: ret void @@ -21605,7 +32061,7 @@ then0: br label %ret ifend2: %t29 = load ptr, ptr %t0 - %t30 = call ptr @fopen(ptr %t29, ptr @.str1546) + %t30 = call ptr @fopen(ptr %t29, ptr @.str2782) store ptr %t30, ptr %t31 %t32 = load ptr, ptr %t31 %t33 = icmp eq ptr %t32, null @@ -21715,7 +32171,7 @@ then0: %t11 = sub i32 %t10, 6 %t12 = load i32, ptr %t4 %t13 = call ptr @fn_str_slice(ptr %t9, i32 %t11, i32 %t12) - %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str1547) + %t14 = call i32 @fn_str_eq(ptr %t13, ptr @.str2783) %t15 = icmp ne i32 %t14, 0 br i1 %t15, label %then3, label %ifend5 then3: @@ -21801,7 +32257,7 @@ then3: br label %ret ifend5: %t20 = load ptr, ptr %t0 - %t21 = call ptr @fn_str_concat(ptr %t20, ptr @.str1548) + %t21 = call ptr @fn_str_concat(ptr %t20, ptr @.str2784) store ptr %t21, ptr %retval br label %ret ret: @@ -21867,7 +32323,7 @@ entry: %t8 = getelementptr ptr, ptr %t7, i32 0 %t9 = load ptr, ptr %t8 %t10 = call ptr @fn_base_name(ptr %t9) - %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str1549) + %t11 = call i32 @fn_str_eq(ptr %t10, ptr @.str2785) %t12 = icmp ne i32 %t11, 0 br i1 %t12, label %then0, label %ifend2 then0: @@ -21890,7 +32346,7 @@ wbody4: %t22 = load ptr, ptr %t21 store ptr %t22, ptr %t23 %t24 = load ptr, ptr %t23 - %t25 = call i32 @fn_str_eq(ptr %t24, ptr @.str1550) + %t25 = call i32 @fn_str_eq(ptr %t24, ptr @.str2786) %t26 = icmp ne i32 %t25, 0 br i1 %t26, label %then6, label %else7 then6: @@ -21898,7 +32354,7 @@ then6: br label %ifend8 else7: %t27 = load ptr, ptr %t23 - %t28 = call i32 @fn_str_eq(ptr %t27, ptr @.str1551) + %t28 = call i32 @fn_str_eq(ptr %t27, ptr @.str2787) %t29 = icmp ne i32 %t28, 0 br i1 %t29, label %then9, label %else10 then9: @@ -21906,7 +32362,7 @@ then9: br label %ifend11 else10: %t30 = load ptr, ptr %t23 - %t31 = call i32 @fn_str_eq(ptr %t30, ptr @.str1552) + %t31 = call i32 @fn_str_eq(ptr %t30, ptr @.str2788) %t32 = icmp ne i32 %t31, 0 br i1 %t32, label %then12, label %else13 then12: @@ -21914,7 +32370,7 @@ then12: br label %ifend14 else13: %t33 = load ptr, ptr %t23 - %t34 = call i32 @fn_str_eq(ptr %t33, ptr @.str1553) + %t34 = call i32 @fn_str_eq(ptr %t33, ptr @.str2789) %t35 = icmp ne i32 %t34, 0 br i1 %t35, label %then15, label %else16 then15: @@ -21922,7 +32378,7 @@ then15: br label %ifend17 else16: %t36 = load ptr, ptr %t23 - %t37 = call i32 @fn_str_eq(ptr %t36, ptr @.str1554) + %t37 = call i32 @fn_str_eq(ptr %t36, ptr @.str2790) %t38 = icmp ne i32 %t37, 0 br i1 %t38, label %then18, label %else19 then18: @@ -21930,7 +32386,7 @@ then18: br label %ifend20 else19: %t39 = load ptr, ptr %t23 - %t40 = call i32 @fn_str_eq(ptr %t39, ptr @.str1555) + %t40 = call i32 @fn_str_eq(ptr %t39, ptr @.str2791) %t41 = icmp ne i32 %t40, 0 br i1 %t41, label %then21, label %else22 then21: @@ -21938,7 +32394,7 @@ then21: br label %ifend23 else22: %t42 = load ptr, ptr %t23 - %t43 = call i32 @fn_str_eq(ptr %t42, ptr @.str1556) + %t43 = call i32 @fn_str_eq(ptr %t42, ptr @.str2792) %t44 = icmp ne i32 %t43, 0 br i1 %t44, label %then24, label %else25 then24: @@ -21971,8 +32427,8 @@ else25: br i1 %t62, label %then30, label %else31 then30: %t63 = load ptr, ptr %t23 - %t64 = call ptr @fn_str_concat(ptr @.str1557, ptr %t63) - %t65 = call ptr @fn_str_concat(ptr %t64, ptr @.str1558) + %t64 = call ptr @fn_str_concat(ptr @.str2793, ptr %t63) + %t65 = call ptr @fn_str_concat(ptr %t64, ptr @.str2794) store ptr %t65, ptr %t66 %t67 = load ptr, ptr @__stderrp %t68 = load ptr, ptr %t66 @@ -22013,7 +32469,7 @@ wend5: %t81 = icmp ne i32 %t80, 0 br i1 %t81, label %then33, label %ifend35 then33: - call void @fn_die(ptr @.str1559) + call void @fn_die(ptr @.str2795) br label %ifend35 ifend35: %t82 = load ptr, ptr %t0 @@ -22025,7 +32481,7 @@ ifend35: %t88 = icmp ne i32 %t87, 0 br i1 %t88, label %then36, label %ifend38 then36: - call void @fn_die(ptr @.str1560) + call void @fn_die(ptr @.str2796) br label %ifend38 ifend38: %t89 = load ptr, ptr %t0 @@ -22133,7 +32589,7 @@ then60: %t141 = load ptr, ptr %t0 %t142 = call ptr @fn_base_name(ptr %t141) %t143 = call ptr @fn_strip_ludic(ptr %t142) - %t144 = call ptr @fn_str_concat(ptr @.str1561, ptr %t143) + %t144 = call ptr @fn_str_concat(ptr @.str2797, ptr %t143) store ptr %t144, ptr %t1 br label %ifend62 ifend62: @@ -22149,12 +32605,12 @@ ifend62: br i1 %t153, label %then63, label %ifend65 then63: %t154 = load ptr, ptr %t147 - %t155 = call ptr @fn_str_concat(ptr @.str1562, ptr %t154) + %t155 = call ptr @fn_str_concat(ptr @.str2798, ptr %t154) %t156 = call i32 @system(ptr %t155) br label %ifend65 ifend65: %t157 = load ptr, ptr %t1 - %t158 = call ptr @fn_str_concat(ptr %t157, ptr @.str1563) + %t158 = call ptr @fn_str_concat(ptr %t157, ptr @.str2799) store ptr %t158, ptr %t159 %t160 = load ptr, ptr %t159 %t161 = call i32 @fn_ir_flush(ptr %t160) @@ -22163,20 +32619,20 @@ ifend65: %t164 = icmp ne i32 %t163, 0 br i1 %t164, label %then66, label %ifend68 then66: - call void @fn_die(ptr @.str1564) + call void @fn_die(ptr @.str2800) br label %ifend68 ifend68: - %t165 = call ptr @fn_getenv_or(ptr @.str1565, ptr @.str1566) + %t165 = call ptr @fn_getenv_or(ptr @.str2801, ptr @.str2802) store ptr %t165, ptr %t166 %t167 = load ptr, ptr @L_argv %t168 = getelementptr ptr, ptr %t167, i32 0 %t169 = load ptr, ptr %t168 %t170 = call ptr @fn_dir_of(ptr %t169) - %t171 = call ptr @fn_getenv_or(ptr @.str1567, ptr %t170) + %t171 = call ptr @fn_getenv_or(ptr @.str2803, ptr %t170) %t172 = call ptr @fn_ensure_slash(ptr %t171) store ptr %t172, ptr %t173 %t174 = load ptr, ptr %t166 - %t175 = call ptr @fn_str_concat(ptr %t174, ptr @.str1568) + %t175 = call ptr @fn_str_concat(ptr %t174, ptr @.str2804) %t176 = load ptr, ptr %t159 %t177 = call ptr @fn_str_concat(ptr %t175, ptr %t176) store ptr %t177, ptr %t178 @@ -22185,18 +32641,18 @@ ifend68: br i1 %t180, label %then69, label %ifend71 then69: %t181 = load ptr, ptr %t173 - %t182 = call ptr @fn_path_join(ptr %t181, ptr @.str1569) + %t182 = call ptr @fn_path_join(ptr %t181, ptr @.str2805) store ptr %t182, ptr %t183 %t184 = load ptr, ptr %t178 - %t185 = call ptr @fn_str_concat(ptr %t184, ptr @.str1570) + %t185 = call ptr @fn_str_concat(ptr %t184, ptr @.str2806) %t186 = load ptr, ptr %t183 %t187 = call ptr @fn_str_concat(ptr %t185, ptr %t186) - %t188 = call ptr @fn_str_concat(ptr %t187, ptr @.str1571) + %t188 = call ptr @fn_str_concat(ptr %t187, ptr @.str2807) store ptr %t188, ptr %t178 br label %ifend71 ifend71: %t189 = load ptr, ptr %t178 - %t190 = call ptr @fn_str_concat(ptr %t189, ptr @.str1572) + %t190 = call ptr @fn_str_concat(ptr %t189, ptr @.str2808) %t191 = load ptr, ptr %t1 %t192 = call ptr @fn_str_concat(ptr %t190, ptr %t191) store ptr %t192, ptr %t178 @@ -22210,7 +32666,7 @@ ifend71: br i1 %t199, label %then72, label %ifend74 then72: %t200 = load ptr, ptr %t159 - %t201 = call ptr @fn_str_concat(ptr @.str1573, ptr %t200) + %t201 = call ptr @fn_str_concat(ptr @.str2809, ptr %t200) %t202 = call i32 @system(ptr %t201) br label %ifend74 ifend74: @@ -22220,7 +32676,7 @@ ifend74: %t206 = icmp ne i32 %t205, 0 br i1 %t206, label %then75, label %ifend77 then75: - call void @fn_die(ptr @.str1574) + call void @fn_die(ptr @.str2810) br label %ifend77 ifend77: %t207 = load i32, ptr %t6 diff --git a/selfhost/parse.ludic b/selfhost/parse.ludic index 05c35598..560e462f 100644 --- a/selfhost/parse.ludic +++ b/selfhost/parse.ludic @@ -109,9 +109,26 @@ fn parse_interp(raw: ptr) -> Node { return acc } +# emit E(field: v, ...) — shared by the statement form and the expression form. +# As an expression it yields a cancellable event's cancelled flag (0/1); a +# non-cancellable event yields 0. +fn parse_emit() -> Node { + pi = pi + 1; let n = node(S_EMIT); n.s = eat_id() + let r = node(E_REC) + eat_op("("); skipnl() + while not is_op(")") { + let fi = node(E_FINIT); fi.s = eat_id(); eat_op(":"); fi.a = expr(); push(r.kids, fi) + skipnl(); if is_op(",") { pi = pi + 1; skipnl() } + } + eat_op(")") + n.a = r + return n +} + fn p_primary() -> Node { let t = toks[pi] if t.kind == TK_INTERP { pi = pi + 1; return parse_interp(t.text) } + if t.kind == TK_ID and (t.text == "emit") and (toks[pi + 1].kind == TK_ID) { return parse_emit() } if t.kind == TK_INT { let n = node(E_INT); n.ival = t.ival; pi = pi + 1; return n } if t.kind == TK_FLOAT { let n = node(E_FLOAT); n.ival = t.ival; pi = pi + 1; return n } if t.kind == TK_STR { let n = node(E_STR); n.s = t.text; pi = pi + 1; return n } @@ -253,16 +270,35 @@ fn stmt() -> Node { push(n.kids, s); sidx = sidx + 1 } eat_op("}"); return n } + # `emit E(...)` fires an event, but a bare `emit(...)` is an ordinary call + # (the compiler dogfoods a function named `emit`), so require an event name. + if (t.text == "emit") and (toks[pi + 1].kind == TK_ID) { return parse_emit() } if (t.text == "become") { pi = pi + 1; let n = node(S_BECOME); n.s = eat_id(); return n } if (t.text == "despawn") { pi = pi + 1; let n = node(S_DESPAWN); n.a = expr(); return n } if (t.text == "enable") or (t.text == "disable") { var en = 0; if (t.text == "enable") { en = 1 } - pi = pi + 1; let n = node(S_TOGGLE); n.ival = en; n.s = eat_id() # `enable P on e` / `disable Model` / `disable Handler` + pi = pi + 1; let n = node(S_TOGGLE); n.ival = en + if is_id("layer") { pi = pi + 1; n.ty = "layer"; n.s = eat_id(); note_toggled_layer(n.s); return n } # enable/disable layer L + n.s = eat_id() # `enable P on e` / `disable Model` / `disable Handler` if is_id("on") { pi = pi + 1; n.a = expr() } # property on an entity return n } + if (t.text == "attach") { # attach P on e [{ field: val, ... }] + pi = pi + 1; let n = node(S_ATTACH); n.s = eat_id() + if not is_id("on") { perr("attach needs 'on '") } + pi = pi + 1; n.a = expr() + if is_op("{") { n.b = record() } # optional field overrides (same-line) + return n + } + if (t.text == "detach") { # detach P on e + pi = pi + 1; let n = node(S_DETACH); n.s = eat_id() + if not is_id("on") { perr("detach needs 'on '") } + pi = pi + 1; n.a = expr() + return n + } if (t.text == "break") { pi = pi + 1; return node(S_BREAK) } if (t.text == "continue") { pi = pi + 1; return node(S_CONTINUE) } + if (t.text == "cancel") { pi = pi + 1; return node(S_CANCEL) } # veto a cancellable event if (t.text == "match") { pi = pi + 1; let n = node(S_MATCH); n.a = expr(); skipnl(); eat_op("{") while true { @@ -337,23 +373,42 @@ fn parse_one_decl() -> void { var qspec: Node = null var onspawn_model: ptr = null var ondespawn_model: ptr = null + var ondespawn_reason: ptr = null # @OnDespawn(M, reason: r) — LC1 teardown reason binding var onattach_prop: ptr = null + var ondetach_prop: ptr = null var onenable_prop: ptr = null var ondisable_prop: ptr = null + var on_event: ptr = null # @On(Event) — a compile-time event listener + var is_public = false # @Public — promote a lifecycle hook to an event var hook_phase: ptr = null # @OnStart / @OnQuit override the phase + var is_sync_prop = false # @Sync property P — every field replicates (NETWORKING N2) + var is_owned = false # @Owned model M — entities carry a network owner (N3) + var role: ptr = null # @Server / @Predicted — a handler's network role (N5) + var remote_dir: ptr = null # @ToServer / @ToClients — a remote event's direction (N4) while is_op("@") { pi = pi + 1; let a = eat_id() # collect a leading @annotation if (a == "export") { is_export = true } + else { if (a == "Public") { is_public = true } # @Public hook promotion + else { if (a == "On") { eat_op("("); on_event = eat_id(); eat_op(")") } # @On(Event) listener else { if (a == "Queries") { qspec = parse_queries_anno() } # @Queries(these: [...], on: ...) else { if (a == "OnSpawn") { eat_op("("); onspawn_model = eat_id(); eat_op(")") } - else { if (a == "OnDespawn") { eat_op("("); ondespawn_model = eat_id(); eat_op(")") } + else { if (a == "OnDespawn") { eat_op("("); ondespawn_model = eat_id() + if is_op(",") { pi = pi + 1; eat_id(); eat_op(":"); ondespawn_reason = eat_id() } # , reason: r + eat_op(")") } else { if (a == "OnAttach") { eat_op("("); onattach_prop = eat_id(); eat_op(")") } + else { if (a == "OnDetach") { eat_op("("); ondetach_prop = eat_id(); eat_op(")") } else { if (a == "OnEnable") { eat_op("("); onenable_prop = eat_id(); eat_op(")") } else { if (a == "OnDisable") { eat_op("("); ondisable_prop = eat_id(); eat_op(")") } else { if (a == "OnStart") { hook_phase = "Start" } # boot else { if (a == "OnQuit") { hook_phase = "OnQuit" } # shutdown + else { if (a == "Sync") { is_sync_prop = true } # @Sync property (N2) + else { if (a == "Owned") { is_owned = true } # @Owned model (N3) + else { if (a == "Server") { role = "server" } # @Server handler (N5) + else { if (a == "Predicted") { role = "predicted" } # @Predicted handler (N5) + else { if (a == "ToServer") { remote_dir = "toserver" } # @ToServer event (N4) + else { if (a == "ToClients") { remote_dir = "toclients" } # @ToClients event (N4) else { if is_op("(") { var d = 0 # any other @anno(args) — parsed and skipped - while true { if is_op("(") { d = d + 1 }; if is_op(")") { d = d - 1 }; pi = pi + 1; if d == 0 { break } } } } } } } } } } } } + while true { if is_op("(") { d = d + 1 }; if is_op(")") { d = d - 1 }; pi = pi + 1; if d == 0 { break } } } } } } } } } } } } } } } } } } } } } skipnl() } if is_id("import") { pi = pi + 1 @@ -364,16 +419,47 @@ fn parse_one_decl() -> void { return } if is_id("enum") { push(prog, parse_enum()); return } - if is_id("property") { push(prog, parse_component()); return } - if is_id("model") { push(prog, parse_archetype()); return } + if is_id("event") { + let ev = parse_event() + if (remote_dir != null) { ev.ty = remote_dir } # N4: a directional remote event (RPC) + register_event(ev); return + } + if is_id("property") { + let c = parse_component() + if is_sync_prop { var fi = 0; while fi < len(c.kids) { c.kids[fi].ival = 1; fi = fi + 1 } } # N2: mark every field replicable + push(prog, c); return + } + if is_id("model") { + let m = parse_archetype() + if is_owned { m.ival = 1 } # N3: this model's entities carry a network owner + push(prog, m); return + } + if is_id("scene") { parse_scene(); return } # layers push handlers into prog; scene -> g_scenes if is_id("handler") { let h = parse_system() - if (onspawn_model != null) { register_onspawn(onspawn_model, h.a); return } # spawn hook - if (ondespawn_model != null) { register_ondespawn(ondespawn_model, h.a); return } # despawn hook - if (onattach_prop != null) { register_onattach(onattach_prop, h.a); return } # attach hook - if (onenable_prop != null) { register_onenable(onenable_prop, h.a); return } # enable hook - if (ondisable_prop != null) { register_ondisable(ondisable_prop, h.a); return } # disable hook - if (hook_phase != null) { h.ty = hook_phase } # @OnStart/@OnQuit + if (role != null) { if (role == "server") { h.ival = 1 } else { h.ival = 2 } } # N5: @Server=1 / @Predicted=2 + if (on_event != null) { register_onlisten(on_event, h.a); return } # @On(Event) listener + if (onspawn_model != null) { + register_onspawn(onspawn_model, h.a) # spawn hook + if is_public { ensure_event(`model_{onspawn_model}_spawn`, false) } # @Public -> model__spawn + return + } + if (ondespawn_model != null) { + register_ondespawn(ondespawn_model, h.a, ondespawn_reason) # despawn hook + if is_public { ensure_event(`model_{ondespawn_model}_despawn`, true) } # @Public -> model__despawn (with reason) + return + } + if (onattach_prop != null) { register_onattach(onattach_prop, h.a); if is_public { ensure_event(`prop_{onattach_prop}_attach`, false) }; return } # -> prop_

_attach + if (ondetach_prop != null) { register_ondetach(ondetach_prop, h.a); if is_public { ensure_event(`prop_{ondetach_prop}_detach`, false) }; return } # -> prop_

_detach + if (onenable_prop != null) { register_onenable(onenable_prop, h.a); if is_public { ensure_event(`prop_{onenable_prop}_enable`, false) }; return } # -> prop_

_enable + if (ondisable_prop != null) { register_ondisable(ondisable_prop, h.a); if is_public { ensure_event(`prop_{ondisable_prop}_disable`, false) }; return } # -> prop_

_disable + if (hook_phase != null) { # @OnStart/@OnQuit + h.ty = hook_phase + if is_public { # -> program_start / program_quit + if (hook_phase == "Start") { ensure_event_empty("program_start") } + else { ensure_event_empty("program_quit") } + } + } if (qspec != null) { # @Queries wraps the body in its S_QUERY qspec.a = h.a let wrap = node(N_BLOCK); push(wrap.kids, qspec); h.a = wrap @@ -421,8 +507,15 @@ fn parse_program() -> void { g_onspawn = new []Node g_ondespawn = new []Node g_onattach = new []Node + g_ondetach = new []Node g_onenable = new []Node g_ondisable = new []Node + g_scenes = new []Node + g_scene_count = 0 + g_start_scene = 0 + g_events = new []Node + g_onlisten = new []Node + g_toggled_layers = new []ptr loaded_paths = new []ptr skipnl() g_game_name = "Ludic" diff --git a/selfhost/parse_game.ludic b/selfhost/parse_game.ludic index 90974ae9..f654f40f 100644 --- a/selfhost/parse_game.ludic +++ b/selfhost/parse_game.ludic @@ -6,15 +6,32 @@ fn parse_component() -> Node { pi = pi + 1; let n = node(N_COMP); n.s = eat_id(); skipnl(); eat_op("{") while true { skipnl(); if is_op("}") { break } var is_computed = false - if is_op("@") { pi = pi + 1; let ann = eat_id(); if (ann == "Computed") { is_computed = true }; skipnl() } + var is_sync = false # @Sync — this field replicates (NETWORKING N2) + if is_op("@") { pi = pi + 1; let ann = eat_id(); if (ann == "Computed") { is_computed = true } else { if (ann == "Sync") { is_sync = true } }; skipnl() } let f = node(N_FIELD); f.s = eat_id(); eat_op(":"); f.ty = ptype() if is_op("=") { pi = pi + 1; f.a = expr() } + if is_sync { f.ival = 1 } # mark the field replicable (read by emit_net) if is_computed { register_computed(n.s, f.s, f.ty, f.a) } # derived: no storage else { push(n.kids, f) } if is_op(",") { pi = pi + 1 } } eat_op("}"); return n } +# event Name { field: T = default, ... } — a public event's POD payload. Same +# field grammar as a `property`, but stored in g_events, not prog: an event is a +# signal shape, not per-entity storage. Zero fields is allowed (`event Ping {}`). +fn parse_event() -> Node { + pi = pi + 1; let n = node(N_EVENT) + if is_id("cancellable") { pi = pi + 1; n.ival = 1 } # a decision event: listeners may `cancel` it + n.s = eat_id(); skipnl(); eat_op("{") + while true { skipnl(); if is_op("}") { break } + let f = node(N_FIELD); f.s = eat_id(); eat_op(":"); f.ty = ptype() + if is_op("=") { pi = pi + 1; f.a = expr() } + push(n.kids, f) + if is_op(",") { pi = pi + 1 } } + eat_op("}"); return n +} + fn parse_system() -> Node { pi = pi + 1; let n = node(N_SYS); n.s = eat_id(); n.ty = "Update" # postfix clauses on `handler Name …`: @anno(...) (parsed and reserved, e.g. @@ -139,6 +156,57 @@ fn parse_spawn() -> Node { eat_op("}"); return n } +# scene Name [start] { on enter {..} on exit {..} layer L { handler .. } .. } +# A scene groups handlers behind an implicit active-scene register; only the +# active scene's handlers run each phase. `on enter`/`on exit` are lifecycle +# blocks (scene .a/.b); each layer's handlers are pushed straight into `prog` as +# ordinary N_SYS nodes, tagged with the owning scene in `.c`, so the whole +# system backend (functions, phases, enable/disable) is reused unchanged. +fn parse_scene() -> void { + pi = pi + 1 # 'scene' + let n = node(N_SCENE); n.s = eat_id() + n.ival = g_scene_count + # optional modifiers after the name, any order: `start` (the boot scene) and + # `public` (promote its on-enter/on-exit to scene__enter / scene__exit). + var is_pub = false + while is_id("start") or is_id("public") { + if is_id("start") { pi = pi + 1; g_start_scene = g_scene_count } + else { pi = pi + 1; is_pub = true } + } + g_scene_count = g_scene_count + 1 + if is_pub { ensure_event_empty(`scene_{n.s}_enter`); ensure_event_empty(`scene_{n.s}_exit`) } + skipnl(); eat_op("{") + while true { + skipnl(); if is_op("}") { break } + if is_id("on") { # on enter { .. } / on exit { .. } + pi = pi + 1; let which = eat_id(); skipnl() + if (which == "enter") { n.a = block() } + else { if (which == "exit") { n.b = block() } else { perr("expected 'enter' or 'exit' after 'on'") } } + continue + } + if is_id("layer") { # layer Name [public] { handler .. } + pi = pi + 1; let lname = eat_id() + if is_id("public") { pi = pi + 1; ensure_event_empty(`layer_{lname}_show`); ensure_event_empty(`layer_{lname}_hide`) } + skipnl(); eat_op("{") + let ltag = node(E_ID); ltag.s = lname # the layer name, tagged onto each handler + while true { + skipnl(); if is_op("}") { break } + if not is_id("handler") { perr("expected 'handler' in layer") } + let h = parse_system() # N_SYS: .s name, .ty phase, .a body + h.c = n # tag the owning scene (null = global) + h.b = ltag # tag the owning layer (for enable/disable layer) + push(prog, h) + skipnl() + } + eat_op("}") + continue + } + perr("expected 'on', 'layer' or '}' in scene") + } + eat_op("}") + push(g_scenes, n) +} + # enum Name { A, B, C } — named int constants; a variant's value is its index. # Accessed as `Name.A` (a compile-time int), so it names magic-int value spaces # (state ids, menu selections, mode registers) without a runtime cost. @@ -150,11 +218,17 @@ fn parse_enum() -> Node { eat_op("}"); return n } -# archetype Name { CompA, CompB } — a named entity kind (bundle of components) +# archetype Name { CompA, @Sync CompB } — a named entity kind (bundle of +# components). A member marked `@Sync` *participates* in replication (NETWORKING +# N2): its @Sync-marked fields cross the wire for this model. Participation is +# per model use-site — the same property syncs in one model, not another. The +# per-member @Sync sets the member E_ID's ival=1 (read by emit_net). fn parse_archetype() -> Node { pi = pi + 1; let n = node(N_ARCH); n.s = eat_id(); skipnl(); eat_op("{") while true { skipnl(); if is_op("}") { break } - let c = node(E_ID); c.s = eat_id(); push(n.kids, c) + let c = node(E_ID) + if is_op("@") { pi = pi + 1; let a = eat_id(); if (a == "Sync") { c.ival = 1 }; skipnl() } + c.s = eat_id(); push(n.kids, c) if is_op(",") { pi = pi + 1 }; skipnl() } eat_op("}"); return n } diff --git a/selfhost/reseed.sh b/selfhost/reseed.sh index 25514317..935e08cf 100755 --- a/selfhost/reseed.sh +++ b/selfhost/reseed.sh @@ -10,7 +10,8 @@ B=build/cfree; mkdir -p "$B" FRAGS="selfhost/str.ludic selfhost/buf.ludic selfhost/io.ludic selfhost/ast.ludic selfhost/lex.ludic selfhost/parse.ludic selfhost/parse_game.ludic selfhost/emit_core.ludic selfhost/emit_head.ludic selfhost/emit_addr.ludic selfhost/emit_intrin.ludic selfhost/emit_intrin2.ludic selfhost/emit_math.ludic selfhost/emit_new.ludic -selfhost/emit_expr.ludic selfhost/emit_stmt.ludic selfhost/emit_ecs.ludic selfhost/emit_query.ludic selfhost/emit_spawn.ludic selfhost/emit_game.ludic selfhost/emit_machine.ludic selfhost/emit_save.ludic selfhost/emit_ui.ludic selfhost/emit_decl.ludic selfhost/main.ludic" +selfhost/emit_expr.ludic selfhost/emit_stmt.ludic selfhost/emit_ecs.ludic selfhost/emit_query.ludic selfhost/emit_spawn.ludic selfhost/emit_game.ludic selfhost/emit_machine.ludic selfhost/emit_save.ludic +selfhost/emit_net.ludic selfhost/emit_ui.ludic selfhost/emit_decl.ludic selfhost/main.ludic" { echo "program SelfHost {"; for f in $FRAGS; do cat "$f"; echo; done; echo "}"; } > "$B/selfhost.ludic" if $CC selfhost/ludicc.seed.ll -o "$B/sh_old" 2>/dev/null; then # compile once with the old seed, then AGAIN with the freshly built one so the diff --git a/test.sh b/test.sh index 077465ec..16a6f71b 100755 --- a/test.sh +++ b/test.sh @@ -71,6 +71,141 @@ if ./selfhost/game-build.sh build/ludicc examples/strings.ludic "/tmp/ludic_str" && [ "$(/tmp/ludic_str become (exit 2, enter 3), Draw 900, Step 201, Draw 900, Step 202 +# -> quit, Draw 900. +if ./selfhost/game-build.sh build/ludicc examples/scenes.ludic "/tmp/ludic_scn" >/tmp/scn.out 2>&1 \ + && [ "$(printf 'aaaaaaaaaa' | /tmp/ludic_scn | tr '\n' ' ')" = "1000 1 101 102 2 3 900 201 900 202 900 " ]; then + ok "scenes.ludic (scene/layer/on enter/on exit/become)" +else bad "scenes: $(tail -1 /tmp/scn.out)"; fi +# Structural attach/detach + @OnAttach/@OnDetach: attach seeds a property on a +# live entity and fires @OnAttach (5+10=15), one Shield matches (1), detach fires +# @OnDetach reading the outgoing value (5+20=25) then clears it (0). +if ./selfhost/game-build.sh build/ludicc examples/detach.ludic "/tmp/ludic_det" >/tmp/det.out 2>&1 \ + && [ "$(/tmp/ludic_det Despawned (drop loot 3+500), +# a survivor at quit -> Quit (skip loot 9+1000; no silent deaths). +if ./selfhost/game-build.sh build/ludicc examples/reason.ludic "/tmp/ludic_rsn" >/tmp/rsn.out 2>&1 \ + && [ "$(/tmp/ludic_rsn Flash 5, Guard 8; Hurt(10,20) -> 20, 30; Cleared -> 999; +# Hurt(amount:42) with entity defaulting to 0 -> 42, 42. Listeners run in +# declaration order; the whole thing desugars to a direct @ev_ call. +if ./selfhost/game-build.sh build/ludicc examples/events.ludic "/tmp/ludic_evt" >/tmp/evt.out 2>&1 \ + && [ "$(/tmp/ludic_evt "/tmp/$n.out" 2>&1 \ + && ${LUDIC_CC:-clang} -O2 "/tmp/$n.ll" -o "/tmp/ludic_$n" >>"/tmp/$n.out" 2>&1 || { bad "$n: build ($(tail -1 /tmp/$n.out))"; return; } + local got; got=$("/tmp/ludic_$n" 10, 32, 42. (Pure Ludic; was a C mod.) +netcase mod_events "10 32 42" +# NETWORKING N0–N6 (NETWORKING-DESIGN.md) — every phase is a self-contained Ludic +# program, driven and asserted from its own `entry`. No C host and no C compiled. +# The transport is the compiler's built-in loopback (an `extern fn` overrides it +# with a real socket in production), so a networked game runs with zero foreign code. +# N0 transport seam: net_send/net_poll — the built-in loopback (no extern host) +netcase net_echo "4 10 20 30 42" +# N1 world snapshot to a buffer: world_size/world_save/world_load (rollback substrate) +netcase net_snapshot "50 7 50" +# N2 @Sync: per-model serialize/apply, selective — Player syncs 12 bytes, max kept mutated +netcase net_sync "12 3 4 50 999" +# N3 @Owned: owner/set_owner/is_owner — fresh entity unowned, then assigned/tested +netcase net_owner "-1 7 0 1" +# N4 remote events (RPCs): @ToServer emit → wire → net_pump re-emits (5+3=8) +netcase net_rpc "0 8" +# N5 roles + drivable sim: @Server gated by set_role; tick_fixed() drives the phases +netcase net_roles "1 102" +# N6 blessed runtime end to end: RPC input → authority applies → replicate → reconcile +netcase net_demo "5 999 5" +# EV1 @Public hook promotion: a @Public @OnSpawn/@OnDespawn also emits the public +# event model__spawn / model__despawn, which native @On listeners (and +# foreign mods over the ABI) subscribe to. Two spawns -> Spawned 100,101; two +# despawns -> Died 200,201 (entity + reason(0) + 200). +if ./selfhost/game-build.sh build/ludicc examples/promote.ludic "/tmp/ludic_prm" >/tmp/prm.out 2>&1 \ + && [ "$(/tmp/ludic_prm model__spawn/despawn events)" +else bad "promote: $(tail -1 /tmp/prm.out)"; fi +# EV3 cancellable events: a `cancellable` event fires before an action; a listener +# `cancel`s it and the caller reads the verdict from `emit E(...)` as an +# expression. Armor vetoes hits over 10: emit(5)->0, emit(15)->1; applying only +# un-vetoed damage leaves hp at 92. +if ./selfhost/game-build.sh build/ludicc examples/cancel.ludic "/tmp/ludic_cnl" >/tmp/cnl.out 2>&1 \ + && [ "$(/tmp/ludic_cnl 7) +netcase world_scan "2 110" # EV2b count/kind/model_id — scan + identify by model +netcase world_spawn "1 42 1" # EV2b world_spawn — create an entity by model id +netcase world_mixed "99" # EV2b real struct offsets (qty after a ptr, byte 8) +netcase world_query "2 110" # EV2b world_query_next — iterate bearers of a property +# EV6 re-entrancy bound: Ping's listener emits Pong and Pong's emits Ping — an +# event cycle. The @ev_depth cap makes the nesting trap as an early return, so the +# program terminates deterministically (n=16 at the cap) instead of hanging. +if ./selfhost/game-build.sh build/ludicc examples/recurse.ludic "/tmp/ludic_rec" >/tmp/rec.out 2>&1 \ + && [ "$(/tmp/ludic_rec 1, fields 30/100, name resolves (1), other entity's write +# doesn't corrupt the first (still 30). +netcase world_dyn "0 1 30 100 1 30" +# EV1 for properties: @Public on @OnAttach/@OnDetach promotes to prop_

_attach / +# prop_

_detach, extending public events past models to properties. Attaching +# then detaching Shield on entity 0 -> Gained 300, Lost 400. +if ./selfhost/game-build.sh build/ludicc examples/prop_events.ludic "/tmp/ludic_pe" >/tmp/pe.out 2>&1 \ + && [ "$(/tmp/ludic_pe prop_

_attach/detach events)" +else bad "prop events: $(tail -1 /tmp/pe.out)"; fi +# EV1 for scenes: a `public` scene promotes on-enter/on-exit to scene__enter / +# scene__exit. Boot enters Menu (10, listener 1); `become Game` leaves Menu (20, +# listener 2) and enters Game (30, listener 3). +if ./selfhost/game-build.sh build/ludicc examples/scene_events.ludic "/tmp/ludic_se" >/tmp/se.out 2>&1 \ + && [ "$(/tmp/ludic_se scene__enter/exit events)" +else bad "scene events: $(tail -1 /tmp/se.out)"; fi +# EV1 for the program scope: @Public @OnStart/@OnQuit -> program_start/program_quit. +# Boot fires @OnStart(1) then program_start(100); shutdown fires @OnQuit(2) then +# program_quit(200) -> the top-level mod entry/exit points. +if ./selfhost/game-build.sh build/ludicc examples/program_events.ludic "/tmp/ludic_pge" >/tmp/pge.out 2>&1 \ + && [ "$(/tmp/ludic_pge program_start/quit)" +else bad "program events: $(tail -1 /tmp/pge.out)"; fi +# EV1 for layers (+ SCENES E2 layer toggle): a `public` layer + `enable/disable +# layer L` flips the layer (its handlers stop) and fires layer__show/hide. +# Frame 1 Draw(50) then disable->Hidden(2); frame 2 Draw gated off, enable->Shown(1); +# frame 3 Draw(50) then quit. Needs input frames, so feed keys. +if ./selfhost/game-build.sh build/ludicc examples/layer_events.ludic "/tmp/ludic_le" >/tmp/le.out 2>&1 \ + && [ "$(printf 'aaaa' | /tmp/ludic_le | tr '\n' ' ')" = "50 2 1 50 " ]; then + ok "layer_events.ludic (layer toggle + public layer -> layer__show/hide)" +else bad "layer events: $(tail -1 /tmp/le.out)"; fi # --- Toolchain-agent CLI smoke tests append below this line --- echo "== self-hosted front-end binaries (ludicc / ludic) ==" # The two commands are one multi-call native binary built from the seed with diff --git a/tools/build-tools.sh b/tools/build-tools.sh index 174e55bc..5fbcea7b 100755 --- a/tools/build-tools.sh +++ b/tools/build-tools.sh @@ -5,41 +5,39 @@ # ./tools/build-tools.sh --test build, then run tools/test-tools.sh # ./tools/build-tools.sh --install also symlink both into ~/.local/bin # -# Both binaries are plain C with no dependencies, same as the compiler. They -# share the lexer and vocabulary in tools/ludic-tools/ludic_syntax.h, so a -# keyword added there reaches every editor at once. +# Both binaries are written in Ludic (tools/ludic-tools/fmt.ludic, lsp.ludic) and +# compiled by the Ludic compiler itself — no C is compiled. clang only assembles +# the emitted LLVM IR, the same floor the compiler stands on. The vocabulary the +# grammar/lexer share still lives in tools/ludic-tools/ludic_syntax.h (data, read +# by check-vocabulary.py); the tools carry their own copy of it in Ludic. set -e cd "$(dirname "$0")/.." CC="${LUDIC_CC:-clang}" -CFLAGS="-O2 -Wall -Wno-unused-function" SRC=tools/ludic-tools OUT=build mkdir -p "$OUT" -build_one() { - local name="$1" main="$2" - local newest - # rebuild when any header or the entry point is newer than the binary - if [ -x "$OUT/$name" ]; then - newest=$(find "$SRC" -name '*.h' -o -name "$(basename "$main")" | while read -r f; do - [ "$f" -nt "$OUT/$name" ] && echo new - done) || true - if [ -z "$newest" ]; then echo "$name: up to date"; return; fi +# the Ludic compiler, assembled from the checked-in IR seed (C-free) +if [ ! -x "$OUT/ludicc" ] || [ selfhost/ludicc.seed.ll -nt "$OUT/ludicc" ]; then + echo "cc: selfhost/ludicc.seed.ll -> $OUT/ludicc (from the IR seed, no C compiler)" + $CC selfhost/ludicc.seed.ll -o "$OUT/ludicc" +fi + +build_ludic() { + local name="$1" src="$2" + if [ -x "$OUT/$name" ] && [ ! "$src" -nt "$OUT/$name" ] && [ ! "$OUT/ludicc" -nt "$OUT/$name" ]; then + echo "$name: up to date"; return fi - echo "cc: $main -> $OUT/$name" - $CC $CFLAGS "$main" -o "$OUT/$name" + echo "ludicc: $src -> $OUT/$name (Ludic -> LLVM IR -> binary, no C)" + "$OUT/ludicc" "$src" --emit-llvm -o "$OUT/$name.ll" >/dev/null 2>&1 \ + && $CC -O2 "$OUT/$name.ll" -o "$OUT/$name" \ + && rm -f "$OUT/$name.ll" || { echo "build failed: $name"; exit 1; } } -build_one ludic-fmt "$SRC/ludic_fmt_main.c" -build_one ludic-lsp "$SRC/ludic_lsp.c" - -# The language server shells out to the compiler for real diagnostics, so having -# it around is most of the value. -if [ ! -x "$OUT/ludicc" ]; then - echo "note: $OUT/ludicc not built yet — run ./build.sh for compiler diagnostics" -fi +build_ludic ludic-fmt "$SRC/fmt.ludic" +build_ludic ludic-lsp "$SRC/lsp.ludic" # VS Code needs the grammar inside its own extension directory, so it gets a # copy. A copy that can drift is the whole failure mode this toolchain is built diff --git a/tools/editors/jetbrains/src/main/kotlin/io/ludic/ide/LudicTokens.kt b/tools/editors/jetbrains/src/main/kotlin/io/ludic/ide/LudicTokens.kt index 71bc692d..d4d5eae6 100644 --- a/tools/editors/jetbrains/src/main/kotlin/io/ludic/ide/LudicTokens.kt +++ b/tools/editors/jetbrains/src/main/kotlin/io/ludic/ide/LudicTokens.kt @@ -42,15 +42,15 @@ object LudicTokens { object LudicVocabulary { val DECL = setOf( "program", "import", "property", "model", "enum", "ui", - "const", "var", "fn", "extern", "handler", "entry" + "const", "var", "fn", "extern", "handler", "entry", "event", "scene" ) val CLAUSE = setOf( - "phase", "query", "on" + "phase", "query", "on", "cancellable", "public", "layer", "start" ) val STMT = setOf( "let", "return", "if", "else", "while", "for", "in", "spawn", "despawn", "enable", "disable", "match", "machine", "state", "become", "where", - "and", "or", "not", "break", "continue", "new" + "and", "or", "not", "break", "continue", "new", "emit", "cancel" ) val PRIMITIVES = setOf("int", "fixed", "bool", "entity", "str", "ptr", "byte", "words", "fixeds", "ptrs", "void") val PHASES = setOf("Start", "Input", "FixedUpdate", "Update", "LateUpdate", "Render") diff --git a/tools/ludic-tools/fmt.ludic b/tools/ludic-tools/fmt.ludic new file mode 100644 index 00000000..31cee8d5 --- /dev/null +++ b/tools/ludic-tools/fmt.ludic @@ -0,0 +1,563 @@ +# fmt.ludic — the canonical Ludic formatter, written in Ludic (replaces the C +# ludic_fmt_main.c + ludic_fmt.h). Works on the token stream, so comments and +# blank lines survive and nothing is ever dropped or reordered — only the +# whitespace between tokens is normalized. Lines are re-indented and respaced but +# never joined or split. Mirrors tools/ludic-tools/ludic_fmt.h exactly. +# +# ludic-fmt a.ludic print the formatted text +# ludic-fmt -w a.ludic rewrite in place +# ludic-fmt --check a.ludic exit 1 if unformatted +# ludic-fmt a.md format the ```ludic fences in a document +# cat a.ludic | ludic-fmt - filter mode (stdin -> stdout) +program LudicFmt { + # ---- token kinds (mirror ludic_syntax.h) ---- + const LT_EOF: int = 0 + const LT_NL: int = 1 + const LT_COMMENT: int = 2 + const LT_ID: int = 3 + const LT_KW: int = 4 + const LT_TYPE: int = 5 + const LT_PHASE: int = 6 + const LT_BOOL: int = 7 + const LT_INT: int = 8 + const LT_FLOAT: int = 9 + const LT_STR: int = 10 + const LT_CHAR: int = 11 + const LT_ANNO: int = 12 + const LT_OP: int = 13 + const LT_ERR: int = 14 + + # ---- tiny stdio + string helpers (self-contained) ---- + fn read_file(path: str) -> ptr { + let f = file_open(path, "rb") + if (f == null) { return null } + file_seek(f, 0, 2) + let n = file_tell(f) + file_seek(f, 0, 0) + let buf = bytes(n + 1) + file_read(f, buf, n) + buf[n] = 0 + file_close(f) + return buf + } + fn cstr_len(s: ptr) -> int { var n = 0; while s[n] != 0 { n = n + 1 }; return n } + fn char_is_digit(c: int) -> bool { return c >= 48 and c <= 57 } + fn char_is_alpha(c: int) -> bool { + if c >= 65 and c <= 90 { return true } + if c >= 97 and c <= 122 { return true } + return c == 95 + } + fn char_is_alnum(c: int) -> bool { return char_is_alpha(c) or char_is_digit(c) } + fn char_is_hex(c: int) -> bool { return char_is_digit(c) or (c >= 97 and c <= 102) or (c >= 65 and c <= 70) } + fn itoa(v: int) -> ptr { + if v == 0 { let z = bytes(2); z[0] = 48; z[1] = 0; return z } + var neg = false; var x = v + if x < 0 { neg = true; x = 0 - x } + let tmp = bytes(16); var n = 0 + while x > 0 { tmp[n] = 48 + x % 10; x = x / 10; n = n + 1 } + var total = n + if neg { total = total + 1 } + let out = bytes(total + 1); var k = 0 + if neg { out[0] = 45; k = 1 } + var i = 0 + while i < n { out[k + i] = tmp[n - 1 - i]; i = i + 1 } + out[total] = 0 + return out + } + + # ---- a growable byte buffer ---- + property Buf { data: ptr = null, len: int = 0, cap: int = 0 } + fn buf_new() -> Buf { let b = new Buf; b.cap = 256; b.data = bytes(b.cap); b.len = 0; return b } + fn buf_ensure(b: Buf, extra: int) -> void { + if b.len + extra + 1 <= b.cap { return } + while b.len + extra + 1 > b.cap { b.cap = b.cap * 2 } + b.data = resize(b.data, b.cap) + } + fn buf_putc(b: Buf, c: int) -> void { buf_ensure(b, 1); b.data[b.len] = c; b.len = b.len + 1 } + fn buf_puts(b: Buf, s: ptr) -> void { var i = 0; while s[i] != 0 { buf_putc(b, s[i]); i = i + 1 } } + fn buf_indent(b: Buf, n: int) -> void { var i = 0; while i < n { buf_putc(b, 32); i = i + 1 } } + fn buf_str(b: Buf) -> ptr { b.data[b.len] = 0; return b.data } + # append src[a..b) raw + fn buf_addrange(b: Buf, s: ptr, a: int, e: int) -> void { var k = a; while k < e { buf_putc(b, s[k]); k = k + 1 } } + + # ---- the token stream (parallel slices) ---- + var src: ptr = null + var tk_kind: []int + var tk_start: []int + var tk_end: []int + var tk_line: []int + var linestart: []int + + fn ntok() -> int { return len(tk_kind) } + fn tok_len(i: int) -> int { return tk_end[i] - tk_start[i] } + fn tok_text(i: int) -> ptr { return src[tk_start[i]..tk_end[i]] } + fn push_tok(k: int, st: int, en: int, ln: int) -> void { + push(tk_kind, k); push(tk_start, st); push(tk_end, en); push(tk_line, ln) + } + + # ---- vocabulary classifiers ---- + fn is_type_word(w: ptr) -> bool { + return (w == "int") or (w == "fixed") or (w == "bool") or (w == "entity") or (w == "str") or (w == "ptr") or (w == "byte") or (w == "words") or (w == "fixeds") or (w == "ptrs") or (w == "void") + } + fn is_phase_word(w: ptr) -> bool { + return (w == "Start") or (w == "Input") or (w == "FixedUpdate") or (w == "Update") or (w == "LateUpdate") or (w == "Render") + } + fn is_keyword_word(w: ptr) -> bool { + if (w == "program") or (w == "import") or (w == "property") or (w == "model") or (w == "enum") or (w == "ui") { return true } + if (w == "const") or (w == "var") or (w == "fn") or (w == "extern") or (w == "handler") or (w == "entry") or (w == "event") or (w == "scene") { return true } + if (w == "phase") or (w == "query") or (w == "on") or (w == "cancellable") or (w == "public") or (w == "layer") or (w == "start") { return true } + if (w == "let") or (w == "return") or (w == "if") or (w == "else") or (w == "while") or (w == "for") or (w == "in") or (w == "spawn") or (w == "despawn") { return true } + if (w == "enable") or (w == "disable") or (w == "match") or (w == "machine") or (w == "state") or (w == "become") or (w == "where") { return true } + if (w == "and") or (w == "or") or (w == "not") or (w == "break") or (w == "continue") or (w == "new") or (w == "emit") or (w == "cancel") { return true } + return false + } + fn is_clause_word(w: ptr) -> bool { + return (w == "phase") or (w == "query") or (w == "reads") or (w == "writes") or (w == "needs") or (w == "uses") or (w == "requires") or (w == "ensures") or (w == "invariant") or (w == "effects") + } + + # ---- the lexer: keeps comments, newlines, byte spans; never exits on bad input ---- + fn is_op2(c0: int, c1: int) -> bool { + if c0 == 45 and c1 == 62 { return true } # -> + if c1 == 61 and (c0 == 43 or c0 == 45 or c0 == 42 or c0 == 47 or c0 == 61 or c0 == 33 or c0 == 60 or c0 == 62) { return true } # += -= *= /= == != <= >= + if c0 == 38 and c1 == 38 { return true } # && + if c0 == 124 and c1 == 124 { return true } # || + if c0 == 46 and c1 == 46 { return true } # .. + if c0 == 61 and c1 == 62 { return true } # => + return false + } + fn is_op1(c: int) -> bool { + return c == 43 or c == 45 or c == 42 or c == 47 or c == 37 or c == 60 or c == 62 or c == 61 or c == 40 or c == 41 or c == 123 or c == 125 or c == 91 or c == 93 or c == 44 or c == 58 or c == 46 or c == 33 or c == 64 or c == 59 + } + + fn lex(s: ptr) -> void { + src = s + tk_kind = new []int; tk_start = new []int; tk_end = new []int; tk_line = new []int + linestart = new []int + push(linestart, 0) + var i = 0; var line = 0 + while s[i] != 0 { + let c = s[i] + if c == 10 { push_tok(LT_NL, i, i + 1, line); i = i + 1; line = line + 1; push(linestart, i); continue } + if c == 32 or c == 9 or c == 13 { i = i + 1; continue } + if c == 35 { # '#' comment to end of line + let st = i; while s[i] != 0 and s[i] != 10 { i = i + 1 }; push_tok(LT_COMMENT, st, i, line); continue + } + if c == 34 { # "string" + let st = i; i = i + 1 + while s[i] != 0 and s[i] != 34 and s[i] != 10 { if s[i] == 92 and s[i + 1] != 0 { i = i + 2 } else { i = i + 1 } } + if s[i] == 34 { i = i + 1 } + push_tok(LT_STR, st, i, line); continue + } + if c == 96 { # `interpolated` + let st = i; i = i + 1 + while s[i] != 0 and s[i] != 96 { if s[i] == 92 and s[i + 1] != 0 { i = i + 2 } else { i = i + 1 } } + if s[i] == 96 { i = i + 1 } + push_tok(LT_STR, st, i, line); continue + } + if c == 39 { # 'c' + let st = i; i = i + 1 + if s[i] == 92 and s[i + 1] != 0 { i = i + 2 } else { if s[i] != 0 and s[i] != 10 { i = i + 1 } } + if s[i] == 39 { i = i + 1 } + push_tok(LT_CHAR, st, i, line); continue + } + if char_is_digit(c) { + let st = i + if c == 48 and (s[i + 1] == 120 or s[i + 1] == 88) { # 0x hex + i = i + 2; while char_is_hex(s[i]) { i = i + 1 }; push_tok(LT_INT, st, i, line); continue + } + while char_is_digit(s[i]) { i = i + 1 } + if s[i] == 46 and char_is_digit(s[i + 1]) { + i = i + 1; while char_is_digit(s[i]) { i = i + 1 }; push_tok(LT_FLOAT, st, i, line); continue + } + push_tok(LT_INT, st, i, line); continue + } + if c == 64 and (char_is_alpha(s[i + 1]) or s[i + 1] == 95) { # @name annotation + let st = i; i = i + 1; while char_is_alnum(s[i]) { i = i + 1 }; push_tok(LT_ANNO, st, i, line); continue + } + if char_is_alpha(c) { + let st = i; while char_is_alnum(s[i]) { i = i + 1 } + let w = s[st..i] + var k = LT_ID + if (w == "true") or (w == "false") or (w == "null") { k = LT_BOOL } + else { if is_type_word(w) { k = LT_TYPE } + else { if is_phase_word(w) { k = LT_PHASE } + else { if is_keyword_word(w) { k = LT_KW } } } } + push_tok(k, st, i, line); continue + } + if is_op2(c, s[i + 1]) { push_tok(LT_OP, i, i + 2, line); i = i + 2; continue } + if is_op1(c) { push_tok(LT_OP, i, i + 1, line); i = i + 1; continue } + # anything else: one UTF-8 character's worth as an LT_ERR token + var ln = 1 + if c >= 240 { ln = 4 } else { if c >= 224 { ln = 3 } else { if c >= 128 { ln = 2 } } } + var kk = 1 + while kk < ln { if s[i + kk] == 0 or (s[i + kk] & 192) != 128 { ln = kk }; kk = kk + 1 } + push_tok(LT_ERR, i, i + ln, line); i = i + ln + } + push_tok(LT_EOF, i, i, line) + } + + # ---- token-stream helpers ---- + fn next_sig(i: int) -> int { + var j = i + 1 + while j < ntok() { let k = tk_kind[j]; if k != LT_NL and k != LT_COMMENT { return j }; j = j + 1 } + return 0 - 1 + } + fn prev_sig(i: int) -> int { + var j = i - 1 + while j >= 0 { let k = tk_kind[j]; if k != LT_NL and k != LT_COMMENT { return j }; j = j - 1 } + return 0 - 1 + } + fn name_like(k: int) -> bool { return k == LT_ID or k == LT_KW or k == LT_TYPE or k == LT_PHASE or k == LT_BOOL } + # a '.' hugs an operand, a closing bracket, and another dot + fn dot_tight(t: int) -> bool { + if name_like(tk_kind[t]) { return true } + if tk_kind[t] != LT_OP { return false } + let n = tok_len(t); let c0 = src[tk_start[t]] + if n == 1 and (c0 == 41 or c0 == 93 or c0 == 46) { return true } + if n == 2 and c0 == 46 and src[tk_start[t] + 1] == 46 { return true } + return false + } + # is the token at index i a unary '-'/'!' rather than a binary operator? + fn is_unary(i: int) -> bool { + if tk_kind[i] != LT_OP { return false } + let n = tok_len(i) + if not (n == 1 and (src[tk_start[i]] == 45 or src[tk_start[i]] == 33)) { return false } + let p = prev_sig(i) + if p < 0 { return true } + let pk = tk_kind[p] + if pk == LT_ID or pk == LT_INT or pk == LT_FLOAT or pk == LT_STR or pk == LT_CHAR or pk == LT_BOOL or pk == LT_TYPE or pk == LT_PHASE { return false } + if pk == LT_OP { + let c = src[tk_start[p]] + return not (tok_len(p) == 1 and (c == 41 or c == 93 or c == 125)) # a closing bracket ends an operand + } + return true # keyword/annotation/comment: operand starts here + } + + # whitespace between the previous emitted token (prev) and the current one (cur) + fn space_before(prev: int, cur: int) -> int { + if prev < 0 { return 0 } + let pk = tk_kind[prev]; let ck = tk_kind[cur] + let plen = tok_len(prev); let clen = tok_len(cur) + let p0 = src[tk_start[prev]]; let c0 = src[tk_start[cur]] + let p1 = (plen == 1); let c1 = (clen == 1) + if pk == LT_ERR or ck == LT_ERR { return tk_start[cur] - tk_end[prev] } # preserve an error token's spacing + if c1 and (c0 == 41 or c0 == 93 or c0 == 44 or c0 == 58 or c0 == 59) { return 0 } # ) ] , : ; + if c1 and c0 == 46 and ck == LT_OP and dot_tight(prev) { return 0 } + if p1 and p0 == 46 and pk == LT_OP and dot_tight(cur) { return 0 } + if p1 and (p0 == 40 or p0 == 91) and pk == LT_OP { return 0 } # nothing hugs an opener from the right + if pk == LT_OP and is_unary(prev) { return 0 } + if pk == LT_ANNO and c1 and c0 == 40 { return 0 } # @anno( + if c1 and c0 == 40 and ck == LT_OP { + if pk == LT_ID or pk == LT_TYPE or pk == LT_PHASE { return 0 } # fn move( / clear( + if pk == LT_OP { if p1 and (p0 == 41 or p0 == 93) { return 1 }; return 0 } + return 1 + } + return 1 + } + + # ---- the formatting pass ---- + fn format(indent_width: int) -> Buf { + let o = buf_new() + let stack = words(600) + let hang = words(600) + var sp = 0 + var cur = 0 + var open = 0 + var brack = 0 + var ui_depth = 0 - 1 + var pending_blank = 0 + var wrote_any = 0 + var prev_line_had_comment = 0 + let N = ntok() + var i = 0 + while i < N and tk_kind[i] != LT_EOF { + let a = i + while i < N and tk_kind[i] != LT_NL and tk_kind[i] != LT_EOF { i = i + 1 } + let b = i + if i < N and tk_kind[i] == LT_NL { i = i + 1 } + + if a == b { # a blank line + if wrote_any == 1 { pending_blank = 1 } + continue + } + + # where does this line start? + var line_level = cur + var tsp = sp + var t = a + while t < b and tk_kind[t] == LT_OP and tok_len(t) == 1 and src[tk_start[t]] == 125 { # leading '}' + if tsp > 0 { tsp = tsp - 1; line_level = stack[tsp] } + t = t + 1 + } + # original column of this line + var orig_ind = 0 + var kk = linestart[tk_line[a]] + while kk < tk_start[a] { if src[kk] == 9 { orig_ind = orig_ind + 4 } else { orig_ind = orig_ind + 1 }; kk = kk + 1 } + # a comment continuing the previous comment line keeps the author's column + var comment_run = 0 + if tk_kind[a] == LT_COMMENT and b == a + 1 and prev_line_had_comment == 1 { comment_run = 1 } + + var ind = 0 + var hangprev = 0 + if sp > 0 { hangprev = hang[sp - 1] } + if open > 0 or (sp > 0 and hangprev == 1) { # author owns alignment inside open call/brace + let ls = linestart[tk_line[a]] + ind = 0 + var k2 = ls + while k2 < tk_start[a] { if src[k2] == 9 { ind = ind + 4 } else { ind = ind + 1 }; k2 = k2 + 1 } + } else { + var extra = 0 + if is_clause_word(tok_text(a)) and tk_kind[a] == LT_KW { extra = indent_width } + ind = line_level * indent_width + extra + if comment_run == 1 and orig_ind > ind { ind = orig_ind } + } + + if pending_blank == 1 and wrote_any == 1 { buf_putc(o, 10) } + pending_blank = 0 + buf_indent(o, ind) + + # emit the tokens + var prev = 0 - 1 + var line_brack = brack + var line_ui_open = 0 + if ui_depth >= 0 and sp > ui_depth { line_ui_open = 1 } + t = a + while t < b { + var want = 0 + if tk_kind[t] == LT_COMMENT { if prev >= 0 { want = 2 } else { want = 0 } } + else { + want = space_before(prev, t) + if line_brack > 0 { # query {Tag} filter is one word + if tk_kind[t] == LT_OP and tok_len(t) == 1 and src[tk_start[t]] == 125 { want = 0 } + if prev >= 0 and tk_kind[prev] == LT_OP and tok_len(prev) == 1 and src[tk_start[prev]] == 123 { want = 0 } + } + if line_ui_open == 1 { # widget props are k=v + var eq_here = 0 + if tk_kind[t] == LT_OP and tok_len(t) == 1 and src[tk_start[t]] == 61 { eq_here = 1 } + var eq_prev = 0 + if prev >= 0 and tk_kind[prev] == LT_OP and tok_len(prev) == 1 and src[tk_start[prev]] == 61 { eq_prev = 1 } + if eq_here == 1 or eq_prev == 1 { want = 0 } + } + } + var gap = 0 + if prev >= 0 { gap = tk_start[t] - tk_end[prev] } + if gap >= 2 and want >= 1 { if gap > 60 { gap = 60 }; want = gap } # hand alignment wins + if want < 0 { want = 0 } + var w2 = 0 + while w2 < want { buf_putc(o, 32); w2 = w2 + 1 } + buf_addrange(o, src, tk_start[t], tk_end[t]) + prev = t + if tk_kind[t] == LT_OP and tok_len(t) == 1 { + let c = src[tk_start[t]] + if c == 91 { line_brack = line_brack + 1 } + else { if c == 93 { line_brack = line_brack - 1; if line_brack < 0 { line_brack = 0 } } } + } + t = t + 1 + } + buf_putc(o, 10) + wrote_any = 1 + prev_line_had_comment = 0 + if prev >= 0 and tk_kind[prev] == LT_COMMENT { prev_line_had_comment = 1 } + + # carry the nesting into the next line + if tk_kind[a] == LT_KW and (tok_text(a) == "ui") and ui_depth < 0 { ui_depth = sp } + var level = cur + t = a + while t < b { + if tk_kind[t] == LT_OP and tok_len(t) == 1 { + let c = src[tk_start[t]] + if c == 123 { # '{' + if sp < 512 { + let nxt = next_sig(t) + stack[sp] = line_level + var h = 0 + if nxt >= 0 and nxt < b { h = 1 } + hang[sp] = h + sp = sp + 1 + } + level = line_level + 1 + } + else { if c == 125 { if sp > 0 { sp = sp - 1; level = stack[sp] } } + else { if c == 40 or c == 91 { open = open + 1; if c == 91 { brack = brack + 1 } } + else { if c == 41 or c == 93 { open = open - 1; if open < 0 { open = 0 }; if c == 93 { brack = brack - 1; if brack < 0 { brack = 0 } } } } } } + } + t = t + 1 + } + cur = level + if ui_depth >= 0 and sp <= ui_depth { ui_depth = 0 - 1 } + } + return o + } + + # ---- markdown: format the body of every ```ludic fence, leave prose alone ---- + var g_flen: int = 0 + var g_info: int = 0 + var g_marker: int = 0 + # detect a fence at line offset i; sets g_flen/g_info/g_marker; returns bool + fn md_fence_at(s: ptr, i: int) -> bool { + var j = i; while s[j] == 32 { j = j + 1 } + let m = s[j] + if m != 96 and m != 126 { return false } # ` or ~ + var n = 0; while s[j] == m { j = j + 1; n = n + 1 } + if n < 3 { return false } + g_flen = n; g_info = j; g_marker = m + return true + } + fn md_info_is_ludic(s: ptr, at: int) -> bool { + var a = at; while s[a] == 32 or s[a] == 9 { a = a + 1 } + # case-insensitive "ludic" + if not (((s[a] == 108 or s[a] == 76)) and ((s[a + 1] == 117 or s[a + 1] == 85)) and ((s[a + 2] == 100 or s[a + 2] == 68)) and ((s[a + 3] == 105 or s[a + 3] == 73)) and ((s[a + 4] == 99 or s[a + 4] == 67))) { return false } + let af = s[a + 5] + return af == 0 or af == 10 or af == 32 or af == 9 or af == 13 + } + fn line_end(s: ptr, i: int) -> int { var e = i; while s[e] != 0 and s[e] != 10 { e = e + 1 }; return e } + + fn format_markdown(s: ptr, indent_width: int) -> Buf { + let o = buf_new() + var i = 0 + while s[i] != 0 { + let ls = i + let le = line_end(s, ls) + var indent = 0; while s[ls + indent] == 32 { indent = indent + 1 } + if md_fence_at(s, ls) and md_info_is_ludic(s, g_info) { + # copy the opening fence line verbatim (with its newline) + var e0 = le; if s[le] != 0 { e0 = le + 1 } + buf_addrange(o, s, ls, e0) + i = e0 + # gather the body up to the closing fence + let bs = i + var be = bs + while true { + if s[be] == 0 { break } + let ps = be; let pe = line_end(s, ps) + if md_fence_at(s, ps) and g_marker == g_marker and g_flen >= g_flen { + # re-run detection for THIS line (md_fence_at set globals for ps) + let cmark = g_marker; let clen = g_flen; let cinfo = g_info + if md_fence_at(s, ps) { + if g_marker == cmark and g_flen >= clen { + var only = 1 + var k = g_info + while k < pe { if s[k] != 32 and s[k] != 13 { only = 0; break }; k = k + 1 } + if only == 1 { be = ps; break } + } + } + } + if s[pe] != 0 { be = pe + 1 } else { be = pe } + } + # de-indent the body, format it, re-indent it + let body = buf_new() + var p = bs + while p < be { + var q = line_end(s, p) + var skip = 0 + while skip < indent and (p + skip) < q and s[p + skip] == 32 { skip = skip + 1 } + buf_addrange(body, s, p + skip, q) + buf_putc(body, 10) + if s[q] != 0 { p = q + 1 } else { p = q } + } + # feed the body through the ludic formatter + lex(buf_str(body)) + let f = format(indent_width) + let ftext = buf_str(f) + var fp = 0 + while ftext[fp] != 0 { + var fq = fp; while ftext[fq] != 0 and ftext[fq] != 10 { fq = fq + 1 } + if fq > fp { buf_indent(o, indent) } + buf_addrange(o, ftext, fp, fq) + buf_putc(o, 10) + if ftext[fq] != 0 { fp = fq + 1 } else { fp = fq } + } + i = be + continue + } + var e1 = le; if s[le] != 0 { e1 = le + 1 } + buf_addrange(o, s, ls, e1) + i = e1 + } + return o + } + + # ---- ends-with helpers for extension detection ---- + fn ends_with(s: ptr, suf: ptr) -> bool { + let n = cstr_len(s); let m = cstr_len(suf) + if m > n { return false } + return (s[n - m..n] == suf) + } + + # ---- stdin slurp (for `-`) ---- + fn slurp_stdin() -> ptr { + let b = buf_new() + var c = read_char() + while c >= 0 { buf_putc(b, c); c = read_char() } + return buf_str(b) + } + + # format one source string according to its kind (markdown vs ludic) + fn format_source(text: ptr, is_md: bool, indent_width: int) -> ptr { + if is_md { let m = format_markdown(text, indent_width); return buf_str(m) } + lex(text) + let f = format(indent_width) + return buf_str(f) + } + + fn streq(a: ptr, b: ptr) -> bool { return (a == b) } + + entry { + var write = false + var check = false + var indent = 2 + var quiet = false + var changed = false + var failed = false + let files = new []ptr + var ai = 1 + while ai < arg_count() { + let a = arg(ai) + if (a == "-w") or (a == "--write") { write = true } + else { if (a == "--check") or (a == "-l") { check = true } + else { if (a == "-q") or (a == "--quiet") { quiet = true } + else { if (a == "--indent") { ai = ai + 1; if ai < arg_count() { indent = 0; let d = arg(ai); var di = 0; while d[di] != 0 { indent = indent * 10 + (d[di] - 48); di = di + 1 } } } + else { if (a == "-h") or (a == "--help") { print("ludic-fmt — format Ludic source"); return } + else { push(files, a) } } } } } + ai = ai + 1 + } + if indent < 1 or indent > 8 { indent = 2 } + + # stdin filter mode + if len(files) == 0 or (len(files) == 1 and (files[0] == "-")) { + let text = slurp_stdin() + let out = format_source(text, false, indent) + file_write(file_stdout(), out, cstr_len(out)) + return + } + + var fi = 0 + while fi < len(files) { + let path = files[fi] + let text = read_file(path) + if (text == null) { + let m = `ludic-fmt: cannot open {path}\n` + file_write(file_stderr(), m, cstr_len(m)); failed = true + } else { + let is_md = ends_with(path, ".md") or ends_with(path, ".markdown") + let out = format_source(text, is_md, indent) + let same = (out == text) + if check { + if not same { changed = true; if not quiet { print(path) } } + } else { if write { + if not same { + let f = file_open(path, "wb") + if (f == null) { let m = `ludic-fmt: cannot write {path}\n`; file_write(file_stderr(), m, cstr_len(m)); failed = true } + else { file_write(f, out, cstr_len(out)); file_close(f); if not quiet { let m = `formatted {path}\n`; file_write(file_stderr(), m, cstr_len(m)) } } + changed = true + } + } else { + file_write(file_stdout(), out, cstr_len(out)) + } } + } + fi = fi + 1 + } + if failed { exit(2) } + if check and changed { exit(1) } + } +} diff --git a/tools/ludic-tools/lsp.ludic b/tools/ludic-tools/lsp.ludic new file mode 100644 index 00000000..05d58b33 --- /dev/null +++ b/tools/ludic-tools/lsp.ludic @@ -0,0 +1,2409 @@ +# lsp.ludic — the Ludic language server, written in Ludic (replaces the C +# ludic_lsp.c + ludic_index.h + ludic_workspace.h + ludic_json.h). Speaks LSP +# 3.17 over stdio: completion, hover, go-to-definition, references, rename, +# document/workspace symbols, semantic tokens, folding, signature help, inlay +# hints, formatting, and structural diagnostics — an error-tolerant model of the +# workspace that keeps parsing after a syntax error and resolves names across the +# whole compilation unit. Ground-truth compilation stays with ludicc; this layer +# supplies structure, not judgement. +program LudicLsp { + # ---- token kinds ---- + const LT_EOF: int = 0 + const LT_NL: int = 1 + const LT_COMMENT: int = 2 + const LT_ID: int = 3 + const LT_KW: int = 4 + const LT_TYPE: int = 5 + const LT_PHASE: int = 6 + const LT_BOOL: int = 7 + const LT_INT: int = 8 + const LT_FLOAT: int = 9 + const LT_STR: int = 10 + const LT_CHAR: int = 11 + const LT_ANNO: int = 12 + const LT_OP: int = 13 + const LT_ERR: int = 14 + + # ---- symbol kinds ---- + const LS_UNIT: int = 0 + const LS_COMPONENT: int = 1 + const LS_FIELD: int = 2 + const LS_ARCHETYPE: int = 3 + const LS_CONST: int = 4 + const LS_VAR: int = 5 + const LS_FN: int = 6 + const LS_PARAM: int = 7 + const LS_EXTERN: int = 8 + const LS_SYSTEM: int = 9 + const LS_UI: int = 10 + const LS_WIDGET: int = 11 + const LS_SCENE: int = 12 + const LS_LAYER: int = 13 + const LS_LOCAL: int = 14 + const LS_QUERYVAR: int = 15 + const LS_STATE: int = 16 + const LS_IMPORT: int = 17 + + # ---- semantic classes ---- + const SC_NONE: int = 0 + const SC_KEYWORD: int = 1 + const SC_TYPE: int = 2 + const SC_COMPONENT: int = 3 + const SC_ARCHETYPE: int = 4 + const SC_SCENE: int = 5 + const SC_LAYER: int = 6 + const SC_UI: int = 7 + const SC_WIDGET: int = 8 + const SC_PROP: int = 9 + const SC_FIELD: int = 10 + const SC_SYSTEM: int = 11 + const SC_FUNCTION: int = 12 + const SC_BUILTIN: int = 13 + const SC_PARAM: int = 14 + const SC_VARIABLE: int = 15 + const SC_CONST: int = 16 + const SC_MODVAR: int = 17 + const SC_PHASE: int = 18 + const SC_NUMBER: int = 19 + const SC_STRING: int = 20 + const SC_COMMENT: int = 21 + const SC_OPERATOR: int = 22 + const SC_ANNOTATION: int = 23 + const SC_UNKNOWN: int = 24 + + # ---- tiny helpers ---- + fn read_file(path: ptr) -> ptr { + let f = file_open(path, "rb") + if (f == null) { return null } + file_seek(f, 0, 2) + let n = file_tell(f) + file_seek(f, 0, 0) + let buf = bytes(n + 1) + file_read(f, buf, n) + buf[n] = 0 + file_close(f) + return buf + } + fn cstr_len(s: ptr) -> int { var n = 0; while s[n] != 0 { n = n + 1 }; return n } + fn char_is_digit(c: int) -> bool { return c >= 48 and c <= 57 } + fn char_is_alpha(c: int) -> bool { + if c >= 65 and c <= 90 { return true } + if c >= 97 and c <= 122 { return true } + return c == 95 + } + fn char_is_alnum(c: int) -> bool { return char_is_alpha(c) or char_is_digit(c) } + fn char_is_hex(c: int) -> bool { return char_is_digit(c) or (c >= 97 and c <= 102) or (c >= 65 and c <= 70) } + fn itoa(v: int) -> ptr { + if v == 0 { let z = bytes(2); z[0] = 48; z[1] = 0; return z } + var neg = false; var x = v + if x < 0 { neg = true; x = 0 - x } + let tmp = bytes(16); var n = 0 + while x > 0 { tmp[n] = 48 + x % 10; x = x / 10; n = n + 1 } + var total = n + if neg { total = total + 1 } + let out = bytes(total + 1); var k = 0 + if neg { out[0] = 45; k = 1 } + var i = 0 + while i < n { out[k + i] = tmp[n - 1 - i]; i = i + 1 } + out[total] = 0 + return out + } + fn atoi(s: ptr) -> int { + var n = 0; var i = 0; var neg = false + while s[i] == 32 or s[i] == 9 { i = i + 1 } + if s[i] == 45 { neg = true; i = i + 1 } + while char_is_digit(s[i]) { n = n * 10 + (s[i] - 48); i = i + 1 } + if neg { return 0 - n } + return n + } + + # ---- growable byte buffer ---- + property Buf { data: ptr = null, len: int = 0, cap: int = 0 } + fn buf_new() -> Buf { let b = new Buf; b.cap = 256; b.data = bytes(b.cap); b.len = 0; return b } + fn buf_ensure(b: Buf, extra: int) -> void { + if b.len + extra + 1 <= b.cap { return } + while b.len + extra + 1 > b.cap { b.cap = b.cap * 2 } + b.data = resize(b.data, b.cap) + } + fn buf_putc(b: Buf, c: int) -> void { buf_ensure(b, 1); b.data[b.len] = c; b.len = b.len + 1 } + fn buf_puts(b: Buf, s: ptr) -> void { var i = 0; while s[i] != 0 { buf_putc(b, s[i]); i = i + 1 } } + fn buf_puti(b: Buf, n: int) -> void { buf_puts(b, itoa(n)) } + fn buf_addrange(b: Buf, s: ptr, a: int, e: int) -> void { var k = a; while k < e { buf_putc(b, s[k]); k = k + 1 } } + fn buf_str(b: Buf) -> ptr { b.data[b.len] = 0; return b.data } + + # ---- string helpers ---- + fn streq(a: ptr, b: ptr) -> bool { return (a == b) } + fn concat3(a: ptr, b: ptr, c: ptr) -> ptr { return ((a + b) + c) } + fn ends_with(s: ptr, suf: ptr) -> bool { + let n = cstr_len(s); let m = cstr_len(suf) + if m > n { return false } + return (s[n - m..n] == suf) + } + fn starts_with(s: ptr, pre: ptr) -> bool { + let m = cstr_len(pre) + if m > cstr_len(s) { return false } + return (s[0..m] == pre) + } + + # ============================================================================ + # documents + # ============================================================================ + property Sym { + kind: int = 0 + name: ptr = null + ty: ptr = null + detail: ptr = null + doc: ptr = null + tok: int = 0 + start: int = 0 + end: int = 0 + bstart: int = 0 + bend: int = 0 + parent: int = 0 + exported: int = 0 + } + property Doc { + path: ptr = null + uri: ptr = null + raw: ptr = null + text: ptr = null + is_md: int = 0 + is_unit: int = 0 + is_module: int = 0 + unit: ptr = null + src: ptr = null + tk_kind: []int + tk_start: []int + tk_end: []int + tk_line: []int + linestart: []int + tmatch: []int + cls: []int + syms: []Sym + imports: []ptr + had_diags: int = 0 + isopen: int = 0 + version: int = 0 + } + + var g_docs: []Doc + var g_root: ptr = null + var g_shutdown: int = 0 + + # ---- the lexer, over a Doc ---- + fn is_op2(c0: int, c1: int) -> bool { + if c0 == 45 and c1 == 62 { return true } + if c1 == 61 and (c0 == 43 or c0 == 45 or c0 == 42 or c0 == 47 or c0 == 61 or c0 == 33 or c0 == 60 or c0 == 62) { return true } + if c0 == 38 and c1 == 38 { return true } + if c0 == 124 and c1 == 124 { return true } + if c0 == 46 and c1 == 46 { return true } + if c0 == 61 and c1 == 62 { return true } + return false + } + fn is_op1(c: int) -> bool { + return c == 43 or c == 45 or c == 42 or c == 47 or c == 37 or c == 60 or c == 62 or c == 61 or c == 40 or c == 41 or c == 123 or c == 125 or c == 91 or c == 93 or c == 44 or c == 58 or c == 46 or c == 33 or c == 64 or c == 59 + } + fn is_type_word(w: ptr) -> bool { + return (w == "int") or (w == "fixed") or (w == "bool") or (w == "entity") or (w == "str") or (w == "ptr") or (w == "byte") or (w == "words") or (w == "fixeds") or (w == "ptrs") or (w == "void") + } + fn is_phase_word(w: ptr) -> bool { + return (w == "Start") or (w == "Input") or (w == "FixedUpdate") or (w == "Update") or (w == "LateUpdate") or (w == "Render") + } + fn is_keyword_word(w: ptr) -> bool { + if (w == "program") or (w == "import") or (w == "property") or (w == "model") or (w == "enum") or (w == "ui") { return true } + if (w == "const") or (w == "var") or (w == "fn") or (w == "extern") or (w == "handler") or (w == "entry") or (w == "event") or (w == "scene") { return true } + if (w == "phase") or (w == "query") or (w == "on") or (w == "cancellable") or (w == "public") or (w == "layer") or (w == "start") { return true } + if (w == "let") or (w == "return") or (w == "if") or (w == "else") or (w == "while") or (w == "for") or (w == "in") or (w == "spawn") or (w == "despawn") { return true } + if (w == "enable") or (w == "disable") or (w == "match") or (w == "machine") or (w == "state") or (w == "become") or (w == "where") { return true } + if (w == "and") or (w == "or") or (w == "not") or (w == "break") or (w == "continue") or (w == "new") or (w == "emit") or (w == "cancel") { return true } + return false + } + fn is_widget_word(w: ptr) -> bool { + return (w == "panel") or (w == "col") or (w == "row") or (w == "label") or (w == "button") or (w == "image") or (w == "spacer") + } + + fn lex_doc(D: Doc) -> void { + let s = D.src + D.tk_kind = new []int; D.tk_start = new []int; D.tk_end = new []int; D.tk_line = new []int + D.linestart = new []int + push(D.linestart, 0) + var i = 0; var line = 0 + while s[i] != 0 { + let c = s[i] + if c == 10 { push(D.tk_kind, LT_NL); push(D.tk_start, i); push(D.tk_end, i + 1); push(D.tk_line, line); i = i + 1; line = line + 1; push(D.linestart, i); continue } + if c == 32 or c == 9 or c == 13 { i = i + 1; continue } + var st = i + if c == 35 { while s[i] != 0 and s[i] != 10 { i = i + 1 }; push(D.tk_kind, LT_COMMENT); push(D.tk_start, st); push(D.tk_end, i); push(D.tk_line, line); continue } + if c == 34 { i = i + 1; while s[i] != 0 and s[i] != 34 and s[i] != 10 { if s[i] == 92 and s[i + 1] != 0 { i = i + 2 } else { i = i + 1 } }; if s[i] == 34 { i = i + 1 }; push(D.tk_kind, LT_STR); push(D.tk_start, st); push(D.tk_end, i); push(D.tk_line, line); continue } + if c == 96 { i = i + 1; while s[i] != 0 and s[i] != 96 { if s[i] == 92 and s[i + 1] != 0 { i = i + 2 } else { i = i + 1 } }; if s[i] == 96 { i = i + 1 }; push(D.tk_kind, LT_STR); push(D.tk_start, st); push(D.tk_end, i); push(D.tk_line, line); continue } + if c == 39 { i = i + 1; if s[i] == 92 and s[i + 1] != 0 { i = i + 2 } else { if s[i] != 0 and s[i] != 10 { i = i + 1 } }; if s[i] == 39 { i = i + 1 }; push(D.tk_kind, LT_CHAR); push(D.tk_start, st); push(D.tk_end, i); push(D.tk_line, line); continue } + if char_is_digit(c) { + if c == 48 and (s[i + 1] == 120 or s[i + 1] == 88) { i = i + 2; while char_is_hex(s[i]) { i = i + 1 }; push(D.tk_kind, LT_INT); push(D.tk_start, st); push(D.tk_end, i); push(D.tk_line, line); continue } + while char_is_digit(s[i]) { i = i + 1 } + if s[i] == 46 and char_is_digit(s[i + 1]) { i = i + 1; while char_is_digit(s[i]) { i = i + 1 }; push(D.tk_kind, LT_FLOAT); push(D.tk_start, st); push(D.tk_end, i); push(D.tk_line, line); continue } + push(D.tk_kind, LT_INT); push(D.tk_start, st); push(D.tk_end, i); push(D.tk_line, line); continue + } + if c == 64 and (char_is_alpha(s[i + 1]) or s[i + 1] == 95) { i = i + 1; while char_is_alnum(s[i]) { i = i + 1 }; push(D.tk_kind, LT_ANNO); push(D.tk_start, st); push(D.tk_end, i); push(D.tk_line, line); continue } + if char_is_alpha(c) { + while char_is_alnum(s[i]) { i = i + 1 } + let w = s[st..i] + var k = LT_ID + if (w == "true") or (w == "false") or (w == "null") { k = LT_BOOL } + else { if is_type_word(w) { k = LT_TYPE } + else { if is_phase_word(w) { k = LT_PHASE } + else { if is_keyword_word(w) { k = LT_KW } } } } + push(D.tk_kind, k); push(D.tk_start, st); push(D.tk_end, i); push(D.tk_line, line); continue + } + if is_op2(c, s[i + 1]) { push(D.tk_kind, LT_OP); push(D.tk_start, i); push(D.tk_end, i + 2); push(D.tk_line, line); i = i + 2; continue } + if is_op1(c) { push(D.tk_kind, LT_OP); push(D.tk_start, i); push(D.tk_end, i + 1); push(D.tk_line, line); i = i + 1; continue } + var ln = 1 + if c >= 240 { ln = 4 } else { if c >= 224 { ln = 3 } else { if c >= 128 { ln = 2 } } } + var kk = 1 + while kk < ln { if s[i + kk] == 0 or (s[i + kk] & 192) != 128 { ln = kk }; kk = kk + 1 } + push(D.tk_kind, LT_ERR); push(D.tk_start, i); push(D.tk_end, i + ln); push(D.tk_line, line); i = i + ln + } + push(D.tk_kind, LT_EOF); push(D.tk_start, i); push(D.tk_end, i); push(D.tk_line, line) + } + + fn ntok(D: Doc) -> int { return len(D.tk_kind) } + fn tlen(D: Doc, i: int) -> int { return D.tk_end[i] - D.tk_start[i] } + fn ttext(D: Doc, i: int) -> ptr { return D.src[D.tk_start[i]..D.tk_end[i]] } + fn tis(D: Doc, i: int, s: ptr) -> bool { if i < 0 or i >= ntok(D) { return false }; return (ttext(D, i) == s) } + fn next_sig(D: Doc, i: int) -> int { var j = i + 1; while j < ntok(D) { let k = D.tk_kind[j]; if k != LT_NL and k != LT_COMMENT { return j }; j = j + 1 }; return 0 - 1 } + fn prev_sig(D: Doc, i: int) -> int { var j = i - 1; while j >= 0 { let k = D.tk_kind[j]; if k != LT_NL and k != LT_COMMENT { return j }; j = j - 1 }; return 0 - 1 } + + # ---- positions (UTF-16 for LSP) ---- + fn utf16_len(s: ptr, a: int, nbytes: int) -> int { + var u = 0; var i = 0 + while i < nbytes { + let c = s[a + i] + if c < 128 { i = i + 1; u = u + 1 } + else { if c < 224 { i = i + 2; u = u + 1 } + else { if c < 240 { i = i + 3; u = u + 1 } + else { i = i + 4; u = u + 2 } } } + } + return u + } + fn line_of(D: Doc, off: int) -> int { + var lo = 0; var hi = len(D.linestart) - 1 + while lo < hi { let mid = (lo + hi + 1) / 2; if D.linestart[mid] <= off { lo = mid } else { hi = mid - 1 } } + return lo + } + fn col_of(D: Doc, off: int) -> int { let l = line_of(D, off); return utf16_len(D.text, D.linestart[l], off - D.linestart[l]) } + fn offset_of(D: Doc, line: int, ch: int) -> int { + if line < 0 { return 0 } + if line >= len(D.linestart) { return cstr_len(D.text) } + var off = D.linestart[line] + var endo = cstr_len(D.text) + if line + 1 < len(D.linestart) { endo = D.linestart[line + 1] } + var u = 0 + while off < endo and u < ch { + let c = D.text[off] + if c < 128 { off = off + 1; u = u + 1 } + else { if c < 224 { off = off + 2; u = u + 1 } + else { if c < 240 { off = off + 3; u = u + 1 } + else { off = off + 4; u = u + 2 } } } + } + return off + } + fn tok_at(D: Doc, off: int) -> int { + var touching = 0 - 1 + var i = 0 + let N = ntok(D) + while i < N { + let k = D.tk_kind[i] + if k != LT_NL and k != LT_EOF { + if off >= D.tk_start[i] and off < D.tk_end[i] { return i } + if off == D.tk_end[i] and touching < 0 { touching = i } + if D.tk_start[i] > off { return touching } + } + i = i + 1 + } + return touching + } + + # ---- brace matching ---- + fn match_braces(D: Doc) -> void { + let N = ntok(D) + D.tmatch = new []int + var i = 0 + while i < N { push(D.tmatch, 0 - 1); i = i + 1 } + let stack = words(1200) + var top = 0 + i = 0 + while i < N { + if D.tk_kind[i] == LT_OP and tlen(D, i) == 1 { + let c = D.src[D.tk_start[i]] + if c == 123 or c == 40 or c == 91 { if top < 1200 { stack[top] = i; top = top + 1 } } + else { if c == 125 or c == 41 or c == 93 { if top > 0 { top = top - 1; let o = stack[top]; D.tmatch[o] = i; D.tmatch[i] = o } } } + } + i = i + 1 + } + } + + # ---- doc comment: the comment block directly above a declaration ---- + fn collect_doc(D: Doc, decl_tok: int) -> ptr { + var line = D.tk_line[decl_tok] + var first = 0 - 1 + var i = decl_tok - 1 + while i >= 0 { + let k = D.tk_kind[i] + if k == LT_NL { i = i - 1; continue } + if k != LT_COMMENT { break } + if D.tk_line[i] >= line { break } + let p = prev_sig(D, i) + if p >= 0 and D.tk_line[p] == D.tk_line[i] { break } + if D.tk_line[i] < line - 1 and first >= 0 { break } + if first >= 0 and D.tk_line[first] != D.tk_line[i] + 1 { break } + first = i; line = D.tk_line[i] + i = i - 1 + } + if first < 0 { return "" } + let out = buf_new() + i = first + while i < decl_tok { + if D.tk_kind[i] == LT_COMMENT { + var s = D.tk_start[i] + 1 + while s < D.tk_end[i] and (D.text[s] == 32 or D.text[s] == 9 or D.text[s] == 35 or D.text[s] == 42) { s = s + 1 } + buf_addrange(out, D.text, s, D.tk_end[i]) + buf_putc(out, 10) + } + i = i + 1 + } + return buf_str(out) + } + + # ============================================================================ + # the shallow parser — records declarations and bindings with their spans + # ============================================================================ + var pD: Doc = null + var pi: int = 0 + + fn pk() -> int { if pi < ntok(pD) { return pD.tk_kind[pi] }; return LT_EOF } + fn pis(s: ptr) -> bool { return tis(pD, pi, s) } + fn pskipnl() -> void { while pi < ntok(pD) and (pk() == LT_NL or pk() == LT_COMMENT) { pi = pi + 1 } } + fn padv() -> void { if pi < ntok(pD) { pi = pi + 1 }; pskipnl() } + fn pword() -> ptr { if pi < ntok(pD) { return ttext(pD, pi) }; return "" } + fn pname() -> int { + let k = pk() + if k == LT_ID or k == LT_TYPE or k == LT_PHASE or k == LT_KW or k == LT_BOOL { let t = pi; padv(); return t } + return 0 - 1 + } + fn sym_add(kind: int, nametok: int, parent: int) -> int { + let s = new Sym + s.kind = kind; s.tok = nametok; s.parent = parent + s.name = ""; s.ty = ""; s.detail = ""; s.doc = "" + if nametok >= 0 { s.start = pD.tk_start[nametok]; s.end = pD.tk_end[nametok]; s.name = ttext(pD, nametok) } + s.bstart = 0; s.bend = cstr_len(pD.text) + push(pD.syms, s) + return len(pD.syms) - 1 + } + fn cur_match() -> int { if pi < ntok(pD) { return pD.tmatch[pi] }; return 0 - 1 } + fn skip_group() -> void { let m = cur_match(); if m < 0 { padv(); return }; pi = m + 1; pskipnl() } + + # `name: Type` pairs inside ( ) — record params, build the signature into sig + fn lp_params(owner: int, kind: int, sig: Buf) -> void { + if not pis("(") { return } + let close = cur_match() + buf_putc(sig, 40) # '(' + padv() + var first = true + while pi < ntok(pD) and (close < 0 or pi < close) { + if pis(")") { break } + if pis(",") { padv(); continue } + let nt = pname() + if nt < 0 { padv(); continue } + var ty = "" + if pis(":") { padv(); let tt = pname(); if tt >= 0 { ty = ttext(pD, tt) } } + let sidx = sym_add(kind, nt, owner) + pD.syms[sidx].ty = ty + if not first { buf_puts(sig, ", ") } + buf_puts(sig, pD.syms[sidx].name); buf_puts(sig, ": ") + if ty == "" { buf_puts(sig, "?") } else { buf_puts(sig, ty) } + first = false + } + if close >= 0 { pi = close + 1 } + pskipnl() + buf_putc(sig, 41) # ')' + } + + # (a, b) variable list -> token indices into out; returns count + fn lp_varlist(out: []int) -> int { + var n = 0 + if not pis("(") { return 0 } + let close = cur_match() + padv() + while pi < ntok(pD) and (close < 0 or pi < close) { + if pis(")") { break } + if pis(",") { padv(); continue } + let nt = pname() + if nt < 0 { padv(); continue } + push(out, nt); n = n + 1 + } + if close >= 0 { pi = close + 1 } + pskipnl() + return n + } + + # [Pos, Vel, {Enemy}] — bind listed components to vars in order (skip {Tag}) + fn lp_query_terms(owner: int, vars: []int, nvars: int, scope_start: int, scope_end: int) -> void { + if not pis("[") { return } + let close = cur_match() + padv() + var bind = 0 + while pi < ntok(pD) and (close < 0 or pi < close) { + if pis("]") { break } + if pis(",") { padv(); continue } + if pis("{") { let cb = cur_match(); padv(); let nt = pname(); if cb >= 0 { pi = cb + 1 } else { padv() }; pskipnl(); continue } + let nt = pname() + if nt < 0 { padv(); continue } + if bind < nvars and vars[bind] >= 0 { + let sidx = sym_add(LS_QUERYVAR, vars[bind], owner) + pD.syms[sidx].ty = ttext(pD, nt) + pD.syms[sidx].bstart = scope_start; pD.syms[sidx].bend = scope_end + pD.syms[sidx].detail = concat3(pD.syms[sidx].name, ": ", concat3(pD.syms[sidx].ty, " (query binding)", "")) + } + bind = bind + 1 + } + if close >= 0 { pi = close + 1 } + pskipnl() + if pis("where") { padv() } + } + + fn lp_block(owner: int, scope_end: int) -> void { + if not pis("{") { return } + let close = cur_match() + var endo = scope_end + if close >= 0 { endo = pD.tk_start[close] } + padv() + while pi < ntok(pD) and pk() != LT_EOF { + if close >= 0 and pi >= close { break } + if pis("}") { break } + if pis("{") { lp_block(owner, endo); continue } + let before = pi + lp_stmt(owner, endo) + if pi == before { padv() } + } + if close >= 0 { pi = close + 1 } else { padv() } + pskipnl() + } + fn lp_stmt(owner: int, scope_end: int) -> void { + if pis("let") { + padv(); let nt = pname(); if nt < 0 { return } + var ty = "" + if pis(":") { padv(); let tt = pname(); if tt >= 0 { ty = ttext(pD, tt) } } + let sidx = sym_add(LS_LOCAL, nt, owner) + pD.syms[sidx].ty = ty + pD.syms[sidx].bstart = pD.tk_start[nt]; pD.syms[sidx].bend = scope_end + return + } + if pis("for") { + padv() + if pis("(") { + let vars = new []int + let nv = lp_varlist(vars) + if pis("in") { padv() } + if pis("query") { padv() } + var here = pD.tk_start[ntok(pD) - 1] + if pi < ntok(pD) { here = pD.tk_start[pi] } + lp_query_terms(owner, vars, nv, here, scope_end) + return + } + let nt = pname() + if nt >= 0 { + let sidx = sym_add(LS_LOCAL, nt, owner) + pD.syms[sidx].ty = "int" + pD.syms[sidx].bstart = pD.tk_start[nt]; pD.syms[sidx].bend = scope_end + } + return + } + if pis("state") { padv(); let nt = pname(); if nt >= 0 { let x = sym_add(LS_STATE, nt, owner) }; return } + padv() + } + + # panel id=Root w=288 { … } — each id= mints a UI_ handle + fn lp_widget(owner: int, uisym: int) -> void { + let type_tok = pname() + if type_tok < 0 { return } + while pi < ntok(pD) and pk() == LT_ID { + let ns = next_sig(pD, pi) + var checkidx = ns + if checkidx < 0 { checkidx = pi } + if not tis(pD, checkidx, "=") { break } + let kb = ttext(pD, pi) + padv() + if pis("=") { padv() } + if kb == "id" { + let nt = pname() + if nt >= 0 { + let sidx = sym_add(LS_WIDGET, nt, uisym) + pD.syms[sidx].name = concat3("UI_", ttext(pD, nt), "") + pD.syms[sidx].detail = concat3(ttext(pD, type_tok), " widget handle", "") + pD.syms[sidx].ty = "int" + } + } else { + while pi < ntok(pD) and pk() != LT_EOF and not pis("{") and not pis("}") { + if pis("(") or pis("[") { skip_group(); continue } + let nx = next_sig(pD, pi) + if pk() == LT_ID and nx >= 0 and tis(pD, nx, "=") { break } + padv() + } + } + } + if pis("{") { + let close = cur_match() + padv() + while pi < ntok(pD) and pk() != LT_EOF and not pis("}") { + if close >= 0 and pi >= close { break } + let before = pi + lp_widget(owner, uisym) + if pi == before { padv() } + } + if close >= 0 { pi = close + 1 } else { padv() } + pskipnl() + } + } + + # one top-level declaration + fn lp_decl(parent: int) -> void { + let w = pword() + let decl_tok = pi + + if w == "import" { + padv() + if pk() == LT_STR { + let t = pi + var n = tlen(pD, t) - 2 + if n < 0 { n = 0 } + let rel = pD.src[pD.tk_start[t] + 1..pD.tk_start[t] + 1 + n] + push(pD.imports, rel) + let sidx = sym_add(LS_IMPORT, t, parent) + pD.syms[sidx].name = rel + padv() + } + return + } + if (w == "property") or (w == "model") { + let is_comp = (w == "property") + padv(); let nt = pname(); if nt < 0 { return } + var kind = LS_ARCHETYPE + if is_comp { kind = LS_COMPONENT } + let sidx = sym_add(kind, nt, parent) + pD.syms[sidx].doc = collect_doc(pD, decl_tok) + while pk() == LT_ANNO { padv() } + let det = buf_new() + buf_puts(det, w); buf_putc(det, 32); buf_puts(det, pD.syms[sidx].name); buf_puts(det, " {") + if not pis("{") { pD.syms[sidx].detail = buf_str(det); return } + let close = cur_match() + pD.syms[sidx].bstart = pD.tk_start[pi] + if close >= 0 { pD.syms[sidx].bend = pD.tk_end[close] } else { pD.syms[sidx].bend = cstr_len(pD.text) } + padv() + var first = true + while pi < ntok(pD) and pk() != LT_EOF and not pis("}") { + if close >= 0 and pi >= close { break } + if pis(",") { padv(); continue } + while pk() == LT_ANNO { padv() } # @Sync / @Computed on a field + let ft = pname(); if ft < 0 { padv(); continue } + if is_comp { + let f = sym_add(LS_FIELD, ft, sidx) + var fty = "" + if pis(":") { padv(); let tt = pname(); if tt >= 0 { fty = ttext(pD, tt) } } + pD.syms[f].ty = fty + pD.syms[f].detail = concat3(pD.syms[sidx].name, ".", concat3(pD.syms[f].name, ": ", fty)) + if pis("=") { padv(); while pi < ntok(pD) and not pis(",") and not pis("}") and pk() != LT_EOF { if pis("(") or pis("{") or pis("[") { skip_group() } else { padv() } } } + if not first { buf_putc(det, 44) } + buf_putc(det, 32); buf_puts(det, pD.syms[f].name); buf_puts(det, ": "); buf_puts(det, fty) + } else { + if not first { buf_putc(det, 44) } + buf_putc(det, 32); buf_puts(det, ttext(pD, ft)) + } + first = false + } + buf_puts(det, " }") + pD.syms[sidx].detail = buf_str(det) + if close >= 0 { pi = close + 1 } else { padv() } + pskipnl() + return + } + if (w == "const") or (w == "var") { + var kind = LS_VAR + if w == "const" { kind = LS_CONST } + padv(); let nt = pname(); if nt < 0 { return } + let sidx = sym_add(kind, nt, parent) + pD.syms[sidx].doc = collect_doc(pD, decl_tok) + if pis(":") { padv(); let tt = pname(); if tt >= 0 { pD.syms[sidx].ty = ttext(pD, tt) } } + pD.syms[sidx].detail = concat3(w, " ", concat3(pD.syms[sidx].name, ": ", pD.syms[sidx].ty)) + while pi < ntok(pD) and pk() != LT_NL and pk() != LT_EOF { if pis("(") or pis("{") or pis("[") { skip_group() } else { pi = pi + 1 } } + pskipnl() + return + } + if w == "extern" { + padv(); if pis("fn") { padv() } + let nt = pname(); if nt < 0 { return } + let sidx = sym_add(LS_EXTERN, nt, parent) + pD.syms[sidx].doc = collect_doc(pD, decl_tok) + let sig = buf_new(); buf_puts(sig, "extern fn "); buf_puts(sig, pD.syms[sidx].name) + lp_params(sidx, LS_PARAM, sig) + if pis("->") { padv(); let tt = pname(); if tt >= 0 { pD.syms[sidx].ty = ttext(pD, tt); buf_puts(sig, " -> "); buf_puts(sig, pD.syms[sidx].ty) } } + pD.syms[sidx].detail = buf_str(sig) + while pi < ntok(pD) and pk() != LT_NL and pk() != LT_EOF { pi = pi + 1 } + pskipnl() + return + } + if (w == "fn") or (w == "pure") or (w == "export") { + let exported = (w == "export") + if (w == "pure") or exported { padv(); if pis("pure") { padv() } } + if pis("fn") { padv() } + let nt = pname(); if nt < 0 { return } + let sidx = sym_add(LS_FN, nt, parent) + if exported { pD.syms[sidx].exported = 1 } + pD.syms[sidx].doc = collect_doc(pD, decl_tok) + let sig = buf_new(); if exported { buf_puts(sig, "export ") }; buf_puts(sig, "fn "); buf_puts(sig, pD.syms[sidx].name) + lp_params(sidx, LS_PARAM, sig) + if pis("->") { padv(); let tt = pname(); if tt >= 0 { pD.syms[sidx].ty = ttext(pD, tt) } } + buf_puts(sig, " -> "); if pD.syms[sidx].ty == "" { buf_puts(sig, "void") } else { buf_puts(sig, pD.syms[sidx].ty) } + pD.syms[sidx].detail = buf_str(sig) + while pis("requires") or pis("ensures") or pis("invariant") or pis("effects") { + padv() + while pi < ntok(pD) and pk() != LT_NL and pk() != LT_EOF and not pis("{") { if pis("(") or pis("[") { skip_group() } else { pi = pi + 1 } } + pskipnl() + } + if pis("{") { + let close = cur_match() + pD.syms[sidx].bstart = pD.tk_start[pi] + if close >= 0 { pD.syms[sidx].bend = pD.tk_end[close] } else { pD.syms[sidx].bend = cstr_len(pD.text) } + var q = 0 + while q < len(pD.syms) { if pD.syms[q].parent == sidx and pD.syms[q].kind == LS_PARAM { pD.syms[q].bstart = pD.syms[sidx].bstart; pD.syms[q].bend = pD.syms[sidx].bend }; q = q + 1 } + lp_block(sidx, pD.syms[sidx].bend) + } + return + } + if w == "entry" { + padv() + if pis("{") { let close = cur_match(); var endo = cstr_len(pD.text); if close >= 0 { endo = pD.tk_end[close] }; lp_block(parent, endo) } + return + } + if (w == "handler") or (w == "edge") { + if w == "edge" { padv(); if not pis("handler") { return } } + padv() + let nt = pname(); if nt < 0 { return } + let sidx = sym_add(LS_SYSTEM, nt, parent) + pD.syms[sidx].doc = collect_doc(pD, decl_tok) + pD.syms[sidx].ty = "Update" + while pk() == LT_ANNO { padv() } + let vars = new []int + var nv = 0 + var have_query = false + while true { + if pis("phase") { padv(); let tt = pname(); if tt >= 0 { pD.syms[sidx].ty = ttext(pD, tt) } } + else { if pis("query") { padv(); have_query = true; nv = lp_varlist(vars); break } + else { if pis("reads") or pis("writes") or pis("uses") or pis("effects") { padv(); if pis("[") { skip_group() } } + else { if pis("needs") { padv(); let x = pname(); if pis("[") { skip_group() } } + else { break } } } } + pskipnl() + } + pD.syms[sidx].detail = concat3("system ", pD.syms[sidx].name, concat3(" phase ", pD.syms[sidx].ty, "")) + if have_query { + let save = pi + var scan = pi + while scan < ntok(pD) and not tis(pD, scan, "{") and pD.tk_kind[scan] != LT_EOF { scan = scan + 1 } + var cl = 0 - 1 + if scan < ntok(pD) { cl = pD.tmatch[scan] } + var bs = 0 + if scan < ntok(pD) { bs = pD.tk_start[scan] } + var be = cstr_len(pD.text) + if cl >= 0 { be = pD.tk_end[cl] } + pi = save + lp_query_terms(sidx, vars, nv, bs, be) + } + if pis("{") { + let close = cur_match() + pD.syms[sidx].bstart = pD.tk_start[pi] + if close >= 0 { pD.syms[sidx].bend = pD.tk_end[close] } else { pD.syms[sidx].bend = cstr_len(pD.text) } + lp_block(sidx, pD.syms[sidx].bend) + } + return + } + if w == "ui" { + padv(); let nt = pname(); if nt < 0 { return } + let sidx = sym_add(LS_UI, nt, parent) + pD.syms[sidx].doc = collect_doc(pD, decl_tok) + pD.syms[sidx].detail = concat3("ui ", pD.syms[sidx].name, "") + let h = sym_add(LS_WIDGET, nt, sidx) + pD.syms[h].name = concat3("UI_", pD.syms[sidx].name, "") + pD.syms[h].ty = "int" + pD.syms[h].detail = concat3("root handle of ui ", pD.syms[sidx].name, "") + if pis("{") { + let close = cur_match() + pD.syms[sidx].bstart = pD.tk_start[pi] + if close >= 0 { pD.syms[sidx].bend = pD.tk_end[close] } else { pD.syms[sidx].bend = cstr_len(pD.text) } + padv() + while pi < ntok(pD) and pk() != LT_EOF and not pis("}") { + if close >= 0 and pi >= close { break } + let before = pi + lp_widget(sidx, sidx) + if pi == before { padv() } + } + if close >= 0 { pi = close + 1 } else { padv() } + pskipnl() + } + return + } + if w == "scene" { + padv(); let nt = pname(); if nt < 0 { return } + let sidx = sym_add(LS_SCENE, nt, parent) + pD.syms[sidx].doc = collect_doc(pD, decl_tok) + var startmod = "" + if pis("start") { startmod = " start"; padv() } + pD.syms[sidx].detail = concat3("scene ", pD.syms[sidx].name, startmod) + if pis("{") { + let close = cur_match() + pD.syms[sidx].bstart = pD.tk_start[pi] + if close >= 0 { pD.syms[sidx].bend = pD.tk_end[close] } else { pD.syms[sidx].bend = cstr_len(pD.text) } + padv() + while pi < ntok(pD) and pk() != LT_EOF and not pis("}") { + if close >= 0 and pi >= close { break } + let before = pi + if pis("on") { padv(); let x = pname(); lp_block(sidx, pD.syms[sidx].bend) } + else { if pis("layer") { + padv(); let lt = pname() + var lsidx = 0 - 1 + if lt >= 0 { lsidx = sym_add(LS_LAYER, lt, sidx); pD.syms[lsidx].detail = concat3("layer ", pD.syms[lsidx].name, concat3(" of scene ", pD.syms[sidx].name, "")) } + if pis("{") { + let lc = cur_match() + if lsidx >= 0 { pD.syms[lsidx].bstart = pD.tk_start[pi]; if lc >= 0 { pD.syms[lsidx].bend = pD.tk_end[lc] } else { pD.syms[lsidx].bend = pD.syms[sidx].bend } } + padv() + while pi < ntok(pD) and pk() != LT_EOF and not pis("}") { + if lc >= 0 and pi >= lc { break } + let b2 = pi + var lo = sidx + if lsidx >= 0 { lo = lsidx } + lp_decl(lo) + if pi == b2 { padv() } + } + if lc >= 0 { pi = lc + 1 } else { padv() } + pskipnl() + } + } else { padv() } } + if pi == before { padv() } + } + if close >= 0 { pi = close + 1 } else { padv() } + pskipnl() + } + return + } + padv() + } + + fn parse_doc(D: Doc) -> void { + D.syms = new []Sym + D.imports = new []ptr + D.is_unit = 0; D.is_module = 0; D.unit = "" + pD = D; pi = 0 + pskipnl() + while pis("import") { lp_decl(0 - 1); pskipnl() } + if pis("program") { + D.is_module = 1; D.is_unit = 1 + padv() + let nt = pname() + var up = 0 - 1 + if nt >= 0 { + up = sym_add(LS_UNIT, nt, 0 - 1) + D.unit = pD.syms[up].name + pD.syms[up].detail = concat3("program ", D.unit, "") + } + if pis("{") { + let close = cur_match() + if up >= 0 { pD.syms[up].bstart = pD.tk_start[pi]; if close >= 0 { pD.syms[up].bend = pD.tk_end[close] } else { pD.syms[up].bend = cstr_len(pD.text) } } + padv() + while pi < ntok(pD) and pk() != LT_EOF and not pis("}") { + if close >= 0 and pi >= close { break } + let before = pi; lp_decl(up) + if pi == before { padv() } + } + } + return + } + while pi < ntok(pD) and pk() != LT_EOF { + let before = pi; lp_decl(0 - 1) + if pi == before { padv() } + } + } + + # ============================================================================ + # workspace: many documents, one project + # ============================================================================ + fn is_local_kind(k: int) -> bool { return k == LS_LOCAL or k == LS_PARAM or k == LS_QUERYVAR or k == LS_STATE } + fn is_toplevel_kind(k: int) -> bool { + return k == LS_COMPONENT or k == LS_ARCHETYPE or k == LS_CONST or k == LS_VAR or k == LS_FN or k == LS_EXTERN or k == LS_SYSTEM or k == LS_UI or k == LS_WIDGET or k == LS_SCENE or k == LS_LAYER or k == LS_UNIT + } + fn is_outline_kind(k: int) -> bool { + return k == LS_UNIT or k == LS_COMPONENT or k == LS_FIELD or k == LS_ARCHETYPE or k == LS_CONST or k == LS_VAR or k == LS_FN or k == LS_EXTERN or k == LS_SYSTEM or k == LS_UI or k == LS_WIDGET or k == LS_SCENE or k == LS_LAYER + } + + # ---- paths & URIs ---- + fn hexval(c: int) -> int { + if c >= 48 and c <= 57 { return c - 48 } + let l = c | 32 + if l >= 97 and l <= 102 { return l - 97 + 10 } + return 0 - 1 + } + fn uri_to_path(uri: ptr) -> ptr { + var s = uri + if starts_with(uri, "file://") { s = uri[7..cstr_len(uri)] } + let n = cstr_len(s) + let out = bytes(n + 1) + var j = 0; var i = 0 + while i < n { + if s[i] == 37 and hexval(s[i + 1]) >= 0 and hexval(s[i + 2]) >= 0 { out[j] = hexval(s[i + 1]) * 16 + hexval(s[i + 2]); j = j + 1; i = i + 3 } + else { out[j] = s[i]; j = j + 1; i = i + 1 } + } + out[j] = 0 + return out + } + fn uri_safe(c: int) -> bool { + if char_is_alnum(c) { return true } + return c == 45 or c == 46 or c == 126 or c == 47 # - . ~ / + } + fn hexch(n: int) -> int { if n < 10 { return 48 + n }; return 55 + n } + fn path_to_uri(path: ptr) -> ptr { + let out = buf_new() + buf_puts(out, "file://") + var i = 0 + while path[i] != 0 { + let c = path[i] + if uri_safe(c) { buf_putc(out, c) } + else { buf_putc(out, 37); buf_putc(out, hexch((c & 255) / 16)); buf_putc(out, hexch((c & 255) % 16)) } + i = i + 1 + } + return buf_str(out) + } + fn dirname(p: ptr) -> ptr { + var last = 0 - 1 + var i = 0 + while p[i] != 0 { if p[i] == 47 { last = i }; i = i + 1 } + if last < 0 { return "." } + if last == 0 { return "/" } + return p[0..last] + } + fn normpath(p: ptr) -> ptr { + let n = cstr_len(p) + let abs = (n > 0 and p[0] == 47) + let list = new []ptr + var cnt = 0 + var i = 0 + while i < n { + while i < n and p[i] == 47 { i = i + 1 } + let st = i + while i < n and p[i] != 47 { i = i + 1 } + if i > st { + let c = p[st..i] + if (c == ".") { } + else { if (c == "..") { + if cnt > 0 and not (list[cnt - 1] == "..") { cnt = cnt - 1 } + else { if not abs { if cnt < len(list) { list[cnt] = c } else { push(list, c) }; cnt = cnt + 1 } } + } else { + if cnt < len(list) { list[cnt] = c } else { push(list, c) }; cnt = cnt + 1 + } } + } + } + if cnt == 0 { if abs { return "/" }; return "." } + let out = buf_new() + if abs { buf_putc(out, 47) } + var k = 0 + while k < cnt { if k > 0 { buf_putc(out, 47) }; buf_puts(out, list[k]); k = k + 1 } + return buf_str(out) + } + fn join_path(dir: ptr, rel: ptr) -> ptr { + if rel[0] == 47 { return normpath(rel) } + return normpath(concat3(dir, "/", rel)) + } + + # ---- markdown scrub: blank everything outside a ```ludic fence ---- + fn word_ludic_at(s: ptr, at: int) -> bool { + return ((s[at] == 108 or s[at] == 76)) and ((s[at + 1] == 117 or s[at + 1] == 85)) and ((s[at + 2] == 100 or s[at + 2] == 68)) and ((s[at + 3] == 105 or s[at + 3] == 73)) and ((s[at + 4] == 99 or s[at + 4] == 67)) + } + fn scrub_markdown(src: ptr) -> ptr { + let n = cstr_len(src) + let out = bytes(n + 1) + var c0 = 0 + while c0 < n { out[c0] = src[c0]; c0 = c0 + 1 } + out[n] = 0 + var i = 0 + while i < n { + let ls = i + var le = i + while le < n and src[le] != 10 { le = le + 1 } + var ind = 0 + while ls + ind < le and src[ls + ind] == 32 { ind = ind + 1 } + let j = ls + ind + var m = 0 + if j < le { m = src[j] } + var run = 0 + while j + run < le and src[j + run] == m { run = run + 1 } + let fenced = (m == 96 or m == 126) and run >= 3 + let info = j + run + var is_ludic = false + if fenced { + var kk = info + while kk < le and (src[kk] == 32 or src[kk] == 9) { kk = kk + 1 } + if le - kk >= 5 { if word_ludic_at(src, kk) and (le - kk == 5 or src[kk + 5] == 32 or src[kk + 5] == 9 or src[kk + 5] == 13) { is_ludic = true } } + } + var b = ls + while b < le { out[b] = 32; b = b + 1 } + i = le + 1; if le >= n { i = n } + if not fenced { continue } + while i < n { + let bs = i + var be = i + while be < n and src[be] != 10 { be = be + 1 } + var bi = 0 + while bs + bi < be and src[bs + bi] == 32 { bi = bi + 1 } + let cj = bs + bi + var crun = 0 + while cj + crun < be and src[cj + crun] == m { crun = crun + 1 } + var only = true + var k2 = cj + crun + while k2 < be { if src[k2] != 32 and src[k2] != 13 { only = false; break }; k2 = k2 + 1 } + if crun >= run and only { var bb = bs; while bb < be { out[bb] = 32; bb = bb + 1 }; i = be + 1; if be >= n { i = n }; break } + if not is_ludic { var bb = bs; while bb < be { out[bb] = 32; bb = bb + 1 } } + i = be + 1; if be >= n { i = n } + } + } + return out + } + + # ---- documents ---- + fn set_text(D: Doc, raw: ptr) -> void { + D.raw = raw + if D.is_md == 1 { D.text = scrub_markdown(raw) } else { D.text = raw } + D.src = D.text + } + fn reindex(D: Doc) -> void { + lex_doc(D) + match_braces(D) + parse_doc(D) + D.cls = new []int + var i = 0 + let N = ntok(D) + while i < N { push(D.cls, SC_NONE); i = i + 1 } + } + fn new_doc(path: ptr, text: ptr) -> Doc { + let D = new Doc + D.path = normpath(path) + D.uri = path_to_uri(D.path) + D.is_md = 0 + if ends_with(D.path, ".md") or ends_with(D.path, ".markdown") { D.is_md = 1 } + D.syms = new []Sym; D.imports = new []ptr; D.unit = "" + set_text(D, text) + reindex(D) + return D + } + fn by_path(path: ptr) -> Doc { + let p = normpath(path) + var i = 0 + while i < len(g_docs) { if (g_docs[i].path == p) { return g_docs[i] }; i = i + 1 } + return null + } + fn by_uri(uri: ptr) -> Doc { + let p = uri_to_path(uri) + let D = by_path(p) + if (D != null) { return D } + var i = 0 + while i < len(g_docs) { if (g_docs[i].uri == uri) { return g_docs[i] }; i = i + 1 } + return null + } + fn ensure_doc(path: ptr) -> Doc { + let D = by_path(path) + if (D != null) { return D } + let text = read_file(path) + if (text == null) { return null } + let nd = new_doc(path, text) + push(g_docs, nd) + return nd + } + + fn scan_root(root: ptr) -> void { + if (root == null) { return } + let listfile = "/tmp/ludic_lsp_scan.txt" + run(concat3(concat3("find '", root, "' -name '*.ludic' -not -path '*/build/*' -not -path '*/node_modules/*' -not -path '*/.*' > "), listfile, " 2>/dev/null")) + let list = read_file(listfile) + if (list == null) { return } + var i = 0; var start = 0 + while list[i] != 0 { + if list[i] == 10 { if i > start { let d = ensure_doc(list[start..i]) }; start = i + 1 } + i = i + 1 + } + if i > start { let d = ensure_doc(list[start..i]) } + } + + # ---- cross-file resolution ---- + var g_owner: Doc = null + var g_symidx: int = 0 + + fn imports_of(D: Doc, out: []Doc) -> void { + var i = 0 + while i < len(D.imports) { + let full = join_path(dirname(D.path), D.imports[i]) + let I = ensure_doc(full) + if (I != null) { + var seen = false + var k = 0 + while k < len(out) { if (out[k].path == I.path) { seen = true }; k = k + 1 } + if not seen { push(out, I); imports_of(I, out) } + } + i = i + 1 + } + } + fn related(D: Doc) -> []Doc { + let out = new []Doc + if (D == null) { return out } + push(out, D) + imports_of(D, out) + var i = 0 + while i < len(g_docs) { + let R = g_docs[i] + if R.is_unit == 1 and not (R.path == D.path) { + let reach = new []Doc + imports_of(R, reach) + var hits = false + var k = 0 + while k < len(reach) { if (reach[k].path == D.path) { hits = true }; k = k + 1 } + if hits { + var seen = false + k = 0 + while k < len(out) { if (out[k].path == R.path) { seen = true }; k = k + 1 } + if not seen { push(out, R) } + k = 0 + while k < len(reach) { + var s2 = false + var q = 0 + while q < len(out) { if (out[q].path == reach[k].path) { s2 = true }; q = q + 1 } + if not s2 { push(out, reach[k]) } + k = k + 1 + } + } + } + i = i + 1 + } + return out + } + fn unit_root(D: Doc) -> Doc { + if (D == null) or D.is_md == 1 { return null } + if D.is_unit == 1 { return D } + let rel = related(D) + var i = 0 + while i < len(rel) { if rel[i].is_unit == 1 and rel[i].is_md == 0 { return rel[i] }; i = i + 1 } + return null + } + fn find_local(D: Doc, name: ptr, off: int) -> int { + var best = 0 - 1 + var i = 0 + while i < len(D.syms) { + let s = D.syms[i] + if is_local_kind(s.kind) and (s.name == name) { + if off >= s.bstart and off <= s.bend { if best < 0 or s.bstart >= D.syms[best].bstart { best = i } } + } + i = i + 1 + } + return best + } + # returns sym index in g_owner (set), or -1 + fn find_top(D: Doc, name: ptr) -> int { + let rel = related(D) + var i = 0 + while i < len(rel) { + var k = 0 + while k < len(rel[i].syms) { + if is_toplevel_kind(rel[i].syms[k].kind) and (rel[i].syms[k].name == name) { g_owner = rel[i]; return k } + k = k + 1 + } + i = i + 1 + } + i = 0 + while i < len(g_docs) { + var k = 0 + while k < len(g_docs[i].syms) { + if is_toplevel_kind(g_docs[i].syms[k].kind) and (g_docs[i].syms[k].name == name) { g_owner = g_docs[i]; return k } + k = k + 1 + } + i = i + 1 + } + return 0 - 1 + } + # component sym index (in g_owner) for a dotted receiver, or -1 + fn receiver_component(D: Doc, dot_tok: int) -> int { + let recv = prev_sig(D, dot_tok) + if recv < 0 or D.tk_kind[recv] != LT_ID { return 0 - 1 } + let name = ttext(D, recv) + var ty = null + let l = find_local(D, name, D.tk_start[recv]) + if l >= 0 { ty = D.syms[l].ty } + else { let t = find_top(D, name); if t >= 0 { ty = g_owner.syms[t].ty } } + if (ty == null) { return 0 - 1 } + if (ty == "") { return 0 - 1 } + return find_top(D, ty) + } + # resolve the token: sets g_owner/g_symidx; returns the token index (or -1) + fn resolve_tok(D: Doc, tok: int) -> int { + g_owner = null; g_symidx = 0 - 1 + if tok < 0 { return 0 - 1 } + if D.tk_kind[tok] != LT_ID and D.tk_kind[tok] != LT_STR { return 0 - 1 } + let name = ttext(D, tok) + var i = 0 + while i < len(D.syms) { if D.syms[i].tok == tok { g_owner = D; g_symidx = i; return tok }; i = i + 1 } + let prev = prev_sig(D, tok) + if prev >= 0 and tis(D, prev, ".") { + let comp = receiver_component(D, prev) + if comp >= 0 and (g_owner != null) { + let co = g_owner + var k = 0 + while k < len(co.syms) { + if co.syms[k].kind == LS_FIELD and co.syms[k].parent == comp and (co.syms[k].name == name) { g_owner = co; g_symidx = k; return tok } + k = k + 1 + } + } + g_owner = null; g_symidx = 0 - 1 + return tok + } + let l = find_local(D, name, D.tk_start[tok]) + if l >= 0 { g_owner = D; g_symidx = l; return tok } + let t = find_top(D, name) + if t >= 0 { g_symidx = t; return tok } + g_owner = null; g_symidx = 0 - 1 + return tok + } + fn resolve_at(D: Doc, off: int) -> int { return resolve_tok(D, tok_at(D, off)) } + + fn first_on_line(D: Doc, tok: int) -> bool { let p = prev_sig(D, tok); return p < 0 or D.tk_line[p] != D.tk_line[tok] } + fn in_ui_body(D: Doc, off: int) -> bool { + var i = 0 + while i < len(D.syms) { if D.syms[i].kind == LS_UI and off > D.syms[i].bstart and off < D.syms[i].bend { return true }; i = i + 1 } + return false + } + + # ---- builtins / intrinsics (name -> signature) ---- + var g_builtins: []ptr + var g_bsigs: []ptr + fn badd(name: ptr, sig: ptr) -> void { push(g_builtins, name); push(g_bsigs, sig) } + fn is_builtin_name(name: ptr) -> bool { var i = 0; while i < len(g_builtins) { if (g_builtins[i] == name) { return true }; i = i + 1 }; return false } + fn builtin_sig(name: ptr) -> ptr { var i = 0; while i < len(g_builtins) { if (g_builtins[i] == name) { return g_bsigs[i] }; i = i + 1 }; return null } + fn init_builtins() -> void { + g_builtins = new []ptr; g_bsigs = new []ptr + badd("min", "min(a: int, b: int) -> int") + badd("max", "max(a: int, b: int) -> int") + badd("abs", "abs(a: int) -> int") + badd("clamp", "clamp(v: int, lo: int, hi: int) -> int") + badd("seed", "seed(i: int)") + badd("rng_range", "rng_range(lo: int, hi: int) -> int") + badd("rng_chance", "rng_chance(pct: int) -> bool") + badd("fx", "fx(i: int) -> fixed") + badd("flr", "flr(f: fixed) -> int") + badd("map_size", "map_size(w: int, h: int)") + badd("map_row", "map_row(y: int, row: str)") + badd("tile", "tile(x: int, y: int) -> int") + badd("clear", "clear(color: int)") + badd("present", "present()") + badd("fill_rect", "fill_rect(x: int, y: int, w: int, h: int, color: int)") + badd("frame_rect", "frame_rect(x: int, y: int, w: int, h: int, color: int)") + badd("put_px", "put_px(x: int, y: int, color: int)") + badd("text", "text(x: int, y: int, s: str, color: int, scale: int)") + badd("text_int", "text_int(x: int, y: int, n: int, color: int, scale: int)") + badd("font_load", "font_load(path: str) -> int") + badd("text_ttf", "text_ttf(font: int, x: int, y: int, utf8: str, color: int, px: int)") + badd("text_w", "text_w(font: int, utf8: str, px: int) -> int") + badd("text_h", "text_h(font: int, px: int) -> int") + badd("image_load", "image_load(path: str) -> int") + badd("draw_image", "draw_image(id: int, x: int, y: int)") + badd("draw_image_scaled", "draw_image_scaled(id: int, x: int, y: int, w: int, h: int)") + badd("draw_9slice", "draw_9slice(id: int, x: int, y: int, w: int, h: int, inset: int)") + badd("png_load", "png_load(path: str) -> int") + badd("sprites_load", "sprites_load(path: str)") + badd("draw_sprite", "draw_sprite(id: int, x: int, y: int)") + badd("draw_sprite_scaled", "draw_sprite_scaled(id: int, x: int, y: int, scale: int)") + badd("ui_build", "ui_build()") + badd("ui_open", "ui_open(id: int)") + badd("ui_tick", "ui_tick(key: int)") + badd("ui_render", "ui_render()") + badd("ui_clicked", "ui_clicked(id: int) -> bool") + badd("ui_set_text", "ui_set_text(id: int, s: str)") + badd("ui_set_int", "ui_set_int(id: int, n: int)") + badd("ui_focus", "ui_focus(id: int)") + badd("ui_focused", "ui_focused() -> int") + badd("ui_visible", "ui_visible(id: int, on: bool)") + badd("key", "key() -> int") + badd("reg", "reg(i: int) -> int") + badd("set_reg", "set_reg(i: int, v: int)") + badd("self", "self() -> entity") + badd("save", "save()") + badd("load", "load() -> bool") + badd("status", "status(s: str)") + badd("print", "print(x)") + badd("str", "str(x) -> str") + badd("quit", "quit()") + badd("bytes", "bytes(n: int) -> ptr") + badd("words", "words(n: int) -> words") + badd("resize", "resize(p: ptr, n: int) -> ptr") + badd("arg_count", "arg_count() -> int") + badd("arg", "arg(i: int) -> str") + badd("file_stderr", "file_stderr() -> ptr") + badd("file_stdout", "file_stdout() -> ptr") + badd("free", "free(p: ptr)") + badd("fill", "fill(p: ptr, byte: int, n: int)") + badd("offset", "offset(p: ptr, off: int) -> ptr") + badd("as_fixed", "as_fixed(i: int) -> fixed") + badd("as_int", "as_int(f: fixed) -> int") + badd("file_open", "file_open(path: str, mode: str) -> ptr") + badd("file_read", "file_read(f: ptr, buf: ptr, n: int) -> int") + badd("file_write", "file_write(f: ptr, buf: ptr, n: int) -> int") + badd("file_seek", "file_seek(f: ptr, off: int, whence: int) -> int") + badd("file_tell", "file_tell(f: ptr) -> int") + badd("file_close", "file_close(f: ptr)") + badd("read_char", "read_char() -> int") + badd("exit", "exit(code: int)") + badd("is_windowed", "is_windowed() -> bool") + badd("game_title", "game_title() -> str") + badd("win_open", "win_open(title: str, w: int, h: int, scale: int)") + badd("win_poll", "win_poll() -> int") + badd("win_present", "win_present(px: ptr, w: int, h: int)") + badd("win_running", "win_running() -> bool") + badd("win_close", "win_close()") + } + + # ---- classification ---- + fn class_of_symkind(k: int) -> int { + if k == LS_COMPONENT { return SC_COMPONENT } + if k == LS_ARCHETYPE { return SC_ARCHETYPE } + if k == LS_FIELD { return SC_FIELD } + if k == LS_CONST { return SC_CONST } + if k == LS_VAR { return SC_MODVAR } + if k == LS_FN or k == LS_EXTERN { return SC_FUNCTION } + if k == LS_SYSTEM { return SC_SYSTEM } + if k == LS_UI { return SC_UI } + if k == LS_WIDGET { return SC_CONST } + if k == LS_SCENE { return SC_SCENE } + if k == LS_LAYER { return SC_LAYER } + if k == LS_PARAM { return SC_PARAM } + if k == LS_QUERYVAR or k == LS_LOCAL or k == LS_STATE { return SC_VARIABLE } + if k == LS_UNIT { return SC_UI } + return SC_UNKNOWN + } + fn classify(D: Doc) -> void { + let N = ntok(D) + if len(D.cls) < N { D.cls = new []int; var z = 0; while z < N { push(D.cls, SC_NONE); z = z + 1 } } + var i = 0 + while i < N { + let k = D.tk_kind[i] + var c = SC_NONE + if k == LT_COMMENT { c = SC_COMMENT } + else { if k == LT_STR or k == LT_CHAR { c = SC_STRING } + else { if k == LT_INT or k == LT_FLOAT { c = SC_NUMBER } + else { if k == LT_BOOL or k == LT_KW { c = SC_KEYWORD } + else { if k == LT_TYPE { c = SC_TYPE } + else { if k == LT_PHASE { c = SC_PHASE } + else { if k == LT_ANNO { c = SC_ANNOTATION } + else { if k == LT_OP { c = SC_OPERATOR } + else { if k == LT_ID { c = SC_UNKNOWN } } } } } } } } } + if k != LT_ID { D.cls[i] = c; i = i + 1; continue } + let name = ttext(D, i) + var decl = 0 - 1 + var s = 0 + while s < len(D.syms) { if D.syms[s].tok == i { decl = s; break }; s = s + 1 } + if decl >= 0 { D.cls[i] = class_of_symkind(D.syms[decl].kind); i = i + 1; continue } + let prev = prev_sig(D, i) + if prev >= 0 and tis(D, prev, ".") { D.cls[i] = SC_FIELD; i = i + 1; continue } + let nxt = next_sig(D, i) + var followed_eq = false + if nxt >= 0 and tis(D, nxt, "=") { followed_eq = true } + if in_ui_body(D, D.tk_start[i]) { + if followed_eq { D.cls[i] = SC_PROP; i = i + 1; continue } + if first_on_line(D, i) or (prev >= 0 and (tis(D, prev, "{") or tis(D, prev, "}"))) { + if is_widget_word(name) { D.cls[i] = SC_WIDGET } else { D.cls[i] = SC_UI } + i = i + 1; continue + } + } + let l = find_local(D, name, D.tk_start[i]) + if l >= 0 { if D.syms[l].kind == LS_PARAM { D.cls[i] = SC_PARAM } else { D.cls[i] = SC_VARIABLE }; i = i + 1; continue } + let top = find_top(D, name) + if top >= 0 { D.cls[i] = class_of_symkind(g_owner.syms[top].kind); i = i + 1; continue } + if is_builtin_name(name) { D.cls[i] = SC_BUILTIN; i = i + 1; continue } + if followed_eq { D.cls[i] = SC_FIELD; i = i + 1; continue } + D.cls[i] = SC_UNKNOWN + i = i + 1 + } + } + + # semantic token type index + modifiers (via g_semmods) + var g_semmods: int = 0 + fn sem_type_of(cls: int) -> int { + g_semmods = 0 + if cls == SC_KEYWORD { return 0 } + if cls == SC_TYPE { g_semmods = 4; return 1 } + if cls == SC_COMPONENT { return 2 } + if cls == SC_ARCHETYPE { return 3 } + if cls == SC_SCENE { return 4 } + if cls == SC_LAYER { return 4 } + if cls == SC_UI { return 3 } + if cls == SC_WIDGET { g_semmods = 4; return 3 } + if cls == SC_SYSTEM { return 5 } + if cls == SC_FUNCTION { return 5 } + if cls == SC_BUILTIN { g_semmods = 4; return 5 } + if cls == SC_PARAM { return 6 } + if cls == SC_VARIABLE { return 7 } + if cls == SC_MODVAR { return 7 } + if cls == SC_CONST { g_semmods = 2; return 7 } + if cls == SC_PROP { return 8 } + if cls == SC_FIELD { return 8 } + if cls == SC_PHASE { g_semmods = 6; return 9 } + if cls == SC_NUMBER { return 10 } + if cls == SC_STRING { return 11 } + if cls == SC_COMMENT { return 12 } + if cls == SC_OPERATOR { return 13 } + if cls == SC_ANNOTATION { return 14 } + return 0 - 1 + } + + # ============================================================================ + # JSON (just enough for LSP) + # ============================================================================ + const JNULL: int = 0 + const JBOOL: int = 1 + const JNUM: int = 2 + const JSTR: int = 3 + const JARR: int = 4 + const JOBJ: int = 5 + property JVal { t: int = 0, num: int = 0, b: int = 0, s: ptr = null, kids: []JVal, keys: []ptr } + fn jval(t: int) -> JVal { let v = new JVal; v.t = t; v.kids = new []JVal; v.keys = new []ptr; return v } + + var jsrc: ptr = null + var jp: int = 0 + fn jskip() -> void { while jsrc[jp] == 32 or jsrc[jp] == 9 or jsrc[jp] == 10 or jsrc[jp] == 13 { jp = jp + 1 } } + fn jhex4(s: ptr, at: int) -> int { + var v = 0; var i = 0 + while i < 4 { let h = hexval(s[at + i]); if h < 0 { return v }; v = v * 16 + h; i = i + 1 } + return v + } + fn utf8_emit(o: Buf, cp: int) -> void { + if cp < 128 { buf_putc(o, cp) } + else { if cp < 2048 { buf_putc(o, 192 | (cp >> 6)); buf_putc(o, 128 | (cp & 63)) } + else { if cp < 65536 { buf_putc(o, 224 | (cp >> 12)); buf_putc(o, 128 | ((cp >> 6) & 63)); buf_putc(o, 128 | (cp & 63)) } + else { buf_putc(o, 240 | (cp >> 18)); buf_putc(o, 128 | ((cp >> 12) & 63)); buf_putc(o, 128 | ((cp >> 6) & 63)); buf_putc(o, 128 | (cp & 63)) } } } + } + fn jparse_string() -> ptr { + jp = jp + 1 # skip opening quote + let o = buf_new() + while jsrc[jp] != 0 and jsrc[jp] != 34 { + if jsrc[jp] == 92 { + jp = jp + 1 + let c = jsrc[jp]; jp = jp + 1 + if c == 110 { buf_putc(o, 10) } + else { if c == 116 { buf_putc(o, 9) } + else { if c == 114 { buf_putc(o, 13) } + else { if c == 98 { buf_putc(o, 8) } + else { if c == 102 { buf_putc(o, 12) } + else { if c == 117 { + var cp = jhex4(jsrc, jp); jp = jp + 4 + if cp >= 55296 and cp < 56320 and jsrc[jp] == 92 and jsrc[jp + 1] == 117 { + let lo = jhex4(jsrc, jp + 2); jp = jp + 6 + cp = 65536 + ((cp - 55296) << 10) + (lo - 56320) + } + utf8_emit(o, cp) + } else { buf_putc(o, c) } } } } } } + } else { buf_putc(o, jsrc[jp]); jp = jp + 1 } + } + if jsrc[jp] == 34 { jp = jp + 1 } + return buf_str(o) + } + fn jparse() -> JVal { + jskip() + let c = jsrc[jp] + if c == 123 { # '{' + jp = jp + 1 + let v = jval(JOBJ) + while true { + jskip() + if jsrc[jp] == 125 { jp = jp + 1; break } + var key = "" + if jsrc[jp] == 34 { key = jparse_string() } + jskip(); if jsrc[jp] == 58 { jp = jp + 1 } + let kid = jparse() + push(v.keys, key); push(v.kids, kid) + jskip() + if jsrc[jp] == 44 { jp = jp + 1 } + else { if jsrc[jp] == 125 { jp = jp + 1; break } else { if jsrc[jp] == 0 { break } } } + } + return v + } + if c == 91 { # '[' + jp = jp + 1 + let v = jval(JARR) + while true { + jskip() + if jsrc[jp] == 93 { jp = jp + 1; break } + let kid = jparse() + push(v.keys, ""); push(v.kids, kid) + jskip() + if jsrc[jp] == 44 { jp = jp + 1 } + else { if jsrc[jp] == 93 { jp = jp + 1; break } else { if jsrc[jp] == 0 { break } } } + } + return v + } + if c == 34 { let v = jval(JSTR); v.s = jparse_string(); return v } + if jsrc[jp] == 116 and jsrc[jp + 1] == 114 { jp = jp + 4; let v = jval(JBOOL); v.b = 1; return v } # true + if jsrc[jp] == 102 and jsrc[jp + 1] == 97 { jp = jp + 5; let v = jval(JBOOL); v.b = 0; return v } # false + if jsrc[jp] == 110 and jsrc[jp + 1] == 117 { jp = jp + 4; return jval(JNULL) } # null + # number + var neg = false + if jsrc[jp] == 45 { neg = true; jp = jp + 1 } + if char_is_digit(jsrc[jp]) { + var n = 0 + while char_is_digit(jsrc[jp]) { n = n * 10 + (jsrc[jp] - 48); jp = jp + 1 } + if jsrc[jp] == 46 { jp = jp + 1; while char_is_digit(jsrc[jp]) { jp = jp + 1 } } # skip fraction + let v = jval(JNUM); if neg { v.num = 0 - n } else { v.num = n }; return v + } + jp = jp + 1 + return jval(JNULL) + } + fn jget(v: JVal, key: ptr) -> JVal { + if (v == null) { return null } + if v.t != JOBJ { return null } + var i = 0 + while i < len(v.keys) { if (v.keys[i] == key) { return v.kids[i] }; i = i + 1 } + return null + } + fn jat(v: JVal, i: int) -> JVal { if (v == null) { return null }; if i < 0 or i >= len(v.kids) { return null }; return v.kids[i] } + fn jlen(v: JVal) -> int { if (v == null) { return 0 }; return len(v.kids) } + fn jstr(v: JVal, def: ptr) -> ptr { if (v != null) and v.t == JSTR and (v.s != null) { return v.s }; return def } + fn jint(v: JVal, def: int) -> int { if (v != null) and v.t == JNUM { return v.num }; return def } + fn jpath(v: JVal, path: ptr) -> JVal { + var cur = v + let n = cstr_len(path) + var start = 0; var i = 0 + while i <= n { + if i == n or path[i] == 46 { + let key = path[start..i] + cur = jget(cur, key) + if (cur == null) { return null } + start = i + 1 + } + i = i + 1 + } + return cur + } + + # ============================================================================ + # the formatter (Doc-based; reused for LSP formatting) — mirrors fmt.ludic + # ============================================================================ + fn f_name_like(k: int) -> bool { return k == LT_ID or k == LT_KW or k == LT_TYPE or k == LT_PHASE or k == LT_BOOL } + fn f_dot_tight(F: Doc, t: int) -> bool { + if f_name_like(F.tk_kind[t]) { return true } + if F.tk_kind[t] != LT_OP { return false } + let n = tlen(F, t); let c0 = F.src[F.tk_start[t]] + if n == 1 and (c0 == 41 or c0 == 93 or c0 == 46) { return true } + if n == 2 and c0 == 46 and F.src[F.tk_start[t] + 1] == 46 { return true } + return false + } + fn f_is_unary(F: Doc, i: int) -> bool { + if F.tk_kind[i] != LT_OP { return false } + let n = tlen(F, i) + if not (n == 1 and (F.src[F.tk_start[i]] == 45 or F.src[F.tk_start[i]] == 33)) { return false } + let p = prev_sig(F, i) + if p < 0 { return true } + let pk2 = F.tk_kind[p] + if pk2 == LT_ID or pk2 == LT_INT or pk2 == LT_FLOAT or pk2 == LT_STR or pk2 == LT_CHAR or pk2 == LT_BOOL or pk2 == LT_TYPE or pk2 == LT_PHASE { return false } + if pk2 == LT_OP { let c = F.src[F.tk_start[p]]; return not (tlen(F, p) == 1 and (c == 41 or c == 93 or c == 125)) } + return true + } + fn f_space_before(F: Doc, prev: int, cur: int) -> int { + if prev < 0 { return 0 } + let pk2 = F.tk_kind[prev]; let ck = F.tk_kind[cur] + let plen = tlen(F, prev); let clen = tlen(F, cur) + let p0 = F.src[F.tk_start[prev]]; let c0 = F.src[F.tk_start[cur]] + let p1 = (plen == 1); let c1 = (clen == 1) + if pk2 == LT_ERR or ck == LT_ERR { return F.tk_start[cur] - F.tk_end[prev] } + if c1 and (c0 == 41 or c0 == 93 or c0 == 44 or c0 == 58 or c0 == 59) { return 0 } + if c1 and c0 == 46 and ck == LT_OP and f_dot_tight(F, prev) { return 0 } + if p1 and p0 == 46 and pk2 == LT_OP and f_dot_tight(F, cur) { return 0 } + if p1 and (p0 == 40 or p0 == 91) and pk2 == LT_OP { return 0 } + if pk2 == LT_OP and f_is_unary(F, prev) { return 0 } + if pk2 == LT_ANNO and c1 and c0 == 40 { return 0 } + if c1 and c0 == 40 and ck == LT_OP { + if pk2 == LT_ID or pk2 == LT_TYPE or pk2 == LT_PHASE { return 0 } + if pk2 == LT_OP { if p1 and (p0 == 41 or p0 == 93) { return 1 }; return 0 } + return 1 + } + return 1 + } + fn f_is_clause(w: ptr) -> bool { + return (w == "phase") or (w == "query") or (w == "reads") or (w == "writes") or (w == "needs") or (w == "uses") or (w == "requires") or (w == "ensures") or (w == "invariant") or (w == "effects") + } + fn make_text_doc(text: ptr) -> Doc { + let F = new Doc + F.raw = text; F.text = text; F.src = text; F.is_md = 0 + lex_doc(F) + return F + } + fn format_doc(F: Doc, iw: int) -> ptr { + let o = buf_new() + let stack = words(600) + let hang = words(600) + var sp = 0; var cur = 0; var open = 0; var brack = 0; var ui_depth = 0 - 1 + var pending_blank = 0; var wrote_any = 0; var prev_line_had_comment = 0 + let N = ntok(F) + var i = 0 + while i < N and F.tk_kind[i] != LT_EOF { + let a = i + while i < N and F.tk_kind[i] != LT_NL and F.tk_kind[i] != LT_EOF { i = i + 1 } + let b = i + if i < N and F.tk_kind[i] == LT_NL { i = i + 1 } + if a == b { if wrote_any == 1 { pending_blank = 1 }; continue } + var line_level = cur + var tsp = sp; var t = a + while t < b and F.tk_kind[t] == LT_OP and tlen(F, t) == 1 and F.src[F.tk_start[t]] == 125 { if tsp > 0 { tsp = tsp - 1; line_level = stack[tsp] }; t = t + 1 } + var orig_ind = 0 + var kk = F.linestart[F.tk_line[a]] + while kk < F.tk_start[a] { if F.src[kk] == 9 { orig_ind = orig_ind + 4 } else { orig_ind = orig_ind + 1 }; kk = kk + 1 } + var comment_run = 0 + if F.tk_kind[a] == LT_COMMENT and b == a + 1 and prev_line_had_comment == 1 { comment_run = 1 } + var ind = 0 + var hangprev = 0 + if sp > 0 { hangprev = hang[sp - 1] } + if open > 0 or (sp > 0 and hangprev == 1) { + var k2 = F.linestart[F.tk_line[a]] + ind = 0 + while k2 < F.tk_start[a] { if F.src[k2] == 9 { ind = ind + 4 } else { ind = ind + 1 }; k2 = k2 + 1 } + } else { + var extra = 0 + if f_is_clause(ttext(F, a)) and F.tk_kind[a] == LT_KW { extra = iw } + ind = line_level * iw + extra + if comment_run == 1 and orig_ind > ind { ind = orig_ind } + } + if pending_blank == 1 and wrote_any == 1 { buf_putc(o, 10) } + pending_blank = 0 + var wi = 0 + while wi < ind { buf_putc(o, 32); wi = wi + 1 } + var prev = 0 - 1 + var line_brack = brack + var line_ui_open = 0 + if ui_depth >= 0 and sp > ui_depth { line_ui_open = 1 } + t = a + while t < b { + var want = 0 + if F.tk_kind[t] == LT_COMMENT { if prev >= 0 { want = 2 } else { want = 0 } } + else { + want = f_space_before(F, prev, t) + if line_brack > 0 { + if F.tk_kind[t] == LT_OP and tlen(F, t) == 1 and F.src[F.tk_start[t]] == 125 { want = 0 } + if prev >= 0 and F.tk_kind[prev] == LT_OP and tlen(F, prev) == 1 and F.src[F.tk_start[prev]] == 123 { want = 0 } + } + if line_ui_open == 1 { + var eqh = 0 + if F.tk_kind[t] == LT_OP and tlen(F, t) == 1 and F.src[F.tk_start[t]] == 61 { eqh = 1 } + var eqp = 0 + if prev >= 0 and F.tk_kind[prev] == LT_OP and tlen(F, prev) == 1 and F.src[F.tk_start[prev]] == 61 { eqp = 1 } + if eqh == 1 or eqp == 1 { want = 0 } + } + } + var gap = 0 + if prev >= 0 { gap = F.tk_start[t] - F.tk_end[prev] } + if gap >= 2 and want >= 1 { if gap > 60 { gap = 60 }; want = gap } + if want < 0 { want = 0 } + var w2 = 0 + while w2 < want { buf_putc(o, 32); w2 = w2 + 1 } + buf_addrange(o, F.src, F.tk_start[t], F.tk_end[t]) + prev = t + if F.tk_kind[t] == LT_OP and tlen(F, t) == 1 { + let c = F.src[F.tk_start[t]] + if c == 91 { line_brack = line_brack + 1 } + else { if c == 93 { line_brack = line_brack - 1; if line_brack < 0 { line_brack = 0 } } } + } + t = t + 1 + } + buf_putc(o, 10) + wrote_any = 1 + prev_line_had_comment = 0 + if prev >= 0 and F.tk_kind[prev] == LT_COMMENT { prev_line_had_comment = 1 } + if F.tk_kind[a] == LT_KW and (ttext(F, a) == "ui") and ui_depth < 0 { ui_depth = sp } + var level = cur + t = a + while t < b { + if F.tk_kind[t] == LT_OP and tlen(F, t) == 1 { + let c = F.src[F.tk_start[t]] + if c == 123 { + if sp < 512 { let nxt = next_sig(F, t); stack[sp] = line_level; var h = 0; if nxt >= 0 and nxt < b { h = 1 }; hang[sp] = h; sp = sp + 1 } + level = line_level + 1 + } + else { if c == 125 { if sp > 0 { sp = sp - 1; level = stack[sp] } } + else { if c == 40 or c == 91 { open = open + 1; if c == 91 { brack = brack + 1 } } + else { if c == 41 or c == 93 { open = open - 1; if open < 0 { open = 0 }; if c == 93 { brack = brack - 1; if brack < 0 { brack = 0 } } } } } } + } + t = t + 1 + } + cur = level + if ui_depth >= 0 and sp <= ui_depth { ui_depth = 0 - 1 } + } + return buf_str(o) + } + # markdown fence formatting (mirrors fmt.ludic) + var mf_flen: int = 0 + var mf_info: int = 0 + var mf_marker: int = 0 + fn mf_fence_at(s: ptr, i: int) -> bool { + var j = i; while s[j] == 32 { j = j + 1 } + let m = s[j] + if m != 96 and m != 126 { return false } + var n = 0; while s[j] == m { j = j + 1; n = n + 1 } + if n < 3 { return false } + mf_flen = n; mf_info = j; mf_marker = m + return true + } + fn f_line_end(s: ptr, i: int) -> int { var e = i; while s[e] != 0 and s[e] != 10 { e = e + 1 }; return e } + fn format_md(s: ptr, iw: int) -> ptr { + let o = buf_new() + var i = 0 + while s[i] != 0 { + let ls = i + let le = f_line_end(s, ls) + var indent = 0; while s[ls + indent] == 32 { indent = indent + 1 } + var is_ludic_fence = false + if mf_fence_at(s, ls) { + var kk = mf_info; while s[kk] == 32 or s[kk] == 9 { kk = kk + 1 } + if word_ludic_at(s, kk) { is_ludic_fence = true } + } + if is_ludic_fence { + var e0 = le; if s[le] != 0 { e0 = le + 1 } + buf_addrange(o, s, ls, e0) + i = e0 + let bs = i + var be = bs + let openm = mf_marker; let openlen = mf_flen + while true { + if s[be] == 0 { break } + let ps = be; let pe = f_line_end(s, ps) + if mf_fence_at(s, ps) { + if mf_marker == openm and mf_flen >= openlen { + var only = 1; var k = mf_info + while k < pe { if s[k] != 32 and s[k] != 13 { only = 0; break }; k = k + 1 } + if only == 1 { be = ps; break } + } + } + if s[pe] != 0 { be = pe + 1 } else { be = pe } + } + let body = buf_new() + var p = bs + while p < be { + let q = f_line_end(s, p) + var skip = 0 + while skip < indent and (p + skip) < q and s[p + skip] == 32 { skip = skip + 1 } + buf_addrange(body, s, p + skip, q) + buf_putc(body, 10) + if s[q] != 0 { p = q + 1 } else { p = q } + } + let F = make_text_doc(buf_str(body)) + let ftext = format_doc(F, iw) + var fp = 0 + while ftext[fp] != 0 { + var fq = fp; while ftext[fq] != 0 and ftext[fq] != 10 { fq = fq + 1 } + if fq > fp { var wi = 0; while wi < indent { buf_putc(o, 32); wi = wi + 1 } } + buf_addrange(o, ftext, fp, fq) + buf_putc(o, 10) + if ftext[fq] != 0 { fp = fq + 1 } else { fp = fq } + } + i = be + continue + } + var e1 = le; if s[le] != 0 { e1 = le + 1 } + buf_addrange(o, s, ls, e1) + i = e1 + } + return buf_str(o) + } + fn skip_ws2(s: ptr, at: int) -> int { var a = at; while s[a] == 32 or s[a] == 9 { a = a + 1 }; return a } + + # ============================================================================ + # framing + output + # ============================================================================ + extern fn fflush(f: ptr) -> int = "fflush" + + fn jstr_out(o: Buf, z: ptr) -> void { + buf_putc(o, 34) + if (z == null) { buf_putc(o, 34); return } + var i = 0 + while z[i] != 0 { + let c = z[i] + if c == 34 { buf_putc(o, 92); buf_putc(o, 34) } + else { if c == 92 { buf_putc(o, 92); buf_putc(o, 92) } + else { if c == 10 { buf_putc(o, 92); buf_putc(o, 110) } + else { if c == 13 { buf_putc(o, 92); buf_putc(o, 114) } + else { if c == 9 { buf_putc(o, 92); buf_putc(o, 116) } + else { if c >= 0 and c < 32 { buf_putc(o, 92); buf_putc(o, 117); buf_putc(o, 48); buf_putc(o, 48); buf_putc(o, hexch(c / 16)); buf_putc(o, hexch(c % 16)) } + else { buf_putc(o, c) } } } } } } + i = i + 1 + } + buf_putc(o, 34) + } + + fn send_raw(body: ptr) -> void { + let hdr = buf_new() + buf_puts(hdr, "Content-Length: "); buf_puti(hdr, cstr_len(body)); buf_putc(hdr, 13); buf_putc(hdr, 10); buf_putc(hdr, 13); buf_putc(hdr, 10) + let hs = buf_str(hdr) + let out = file_stdout() + file_write(out, hs, cstr_len(hs)) + file_write(out, body, cstr_len(body)) + let z = fflush(out) + } + fn send_result(idv: JVal, result: ptr) -> void { + let o = buf_new() + buf_puts(o, "{\"jsonrpc\":\"2.0\",\"id\":") + if (idv == null) { buf_puts(o, "null") } + else { if idv.t == JSTR { jstr_out(o, idv.s) } else { buf_puti(o, idv.num) } } + buf_puts(o, ",\"result\":") + if (result == null) or (result[0] == 0) { buf_puts(o, "null") } else { buf_puts(o, result) } + buf_putc(o, 125) + send_raw(buf_str(o)) + } + fn send_notify(method: ptr, params: ptr) -> void { + let o = buf_new() + buf_puts(o, "{\"jsonrpc\":\"2.0\",\"method\":"); jstr_out(o, method); buf_puts(o, ",\"params\":"); buf_puts(o, params); buf_putc(o, 125) + send_raw(buf_str(o)) + } + + fn lower(c: int) -> int { if c >= 65 and c <= 90 { return c + 32 }; return c } + fn starts_with_ci(s: ptr, pre: ptr) -> bool { + var i = 0 + while pre[i] != 0 { if s[i] == 0 or lower(s[i]) != lower(pre[i]) { return false }; i = i + 1 } + return true + } + fn read_message() -> ptr { + var length = 0 - 1 + let line = buf_new() + while true { + line.len = 0 + var c = read_char() + if c < 0 { return null } + while c >= 0 and c != 10 { buf_putc(line, c); c = read_char() } + let s = buf_str(line) + var L = cstr_len(s) + if L > 0 and s[L - 1] == 13 { s[L - 1] = 0; L = L - 1 } + if L == 0 { break } + if starts_with_ci(s, "content-length:") { length = atoi(s[15..cstr_len(s)]) } + } + if length <= 0 { return null } + let buf = bytes(length + 1) + var got = 0 + while got < length { let c = read_char(); if c < 0 { break }; buf[got] = c; got = got + 1 } + buf[got] = 0 + return buf + } + + # ---- position output ---- + fn put_pos(o: Buf, D: Doc, off: int) -> void { buf_puts(o, "{\"line\":"); buf_puti(o, line_of(D, off)); buf_puts(o, ",\"character\":"); buf_puti(o, col_of(D, off)); buf_putc(o, 125) } + fn put_range(o: Buf, D: Doc, a: int, b: int) -> void { buf_puts(o, "{\"start\":"); put_pos(o, D, a); buf_puts(o, ",\"end\":"); put_pos(o, D, b); buf_putc(o, 125) } + fn put_location(o: Buf, D: Doc, a: int, b: int) -> void { buf_puts(o, "{\"uri\":"); jstr_out(o, D.uri); buf_puts(o, ",\"range\":"); put_range(o, D, a, b); buf_putc(o, 125) } + + fn doc_of(msg: JVal) -> Doc { + let uri = jstr(jpath(msg, "params.textDocument.uri"), null) + if (uri == null) { return null } + let D = by_uri(uri) + if (D != null) { return D } + return ensure_doc(uri_to_path(uri)) + } + fn off_of(msg: JVal, D: Doc, base: ptr) -> int { + let line = jint(jpath(msg, concat3(base, ".line", "")), 0) + let ch = jint(jpath(msg, concat3(base, ".character", "")), 0) + return offset_of(D, line, ch) + } + fn basename(p: ptr) -> ptr { var last = 0 - 1; var i = 0; while p[i] != 0 { if p[i] == 47 { last = i }; i = i + 1 }; return p[last + 1..i] } + + # ---- LSP symbol kinds & completion kinds ---- + fn lsp_symbol_kind(k: int) -> int { + if k == LS_UNIT { return 2 } + if k == LS_COMPONENT { return 23 } + if k == LS_FIELD { return 8 } + if k == LS_ARCHETYPE { return 5 } + if k == LS_CONST { return 14 } + if k == LS_VAR { return 13 } + if k == LS_FN or k == LS_EXTERN { return 12 } + if k == LS_SYSTEM { return 6 } + if k == LS_UI { return 5 } + if k == LS_WIDGET { return 14 } + if k == LS_SCENE { return 3 } + if k == LS_LAYER { return 3 } + return 13 + } + fn comp_kind_of(k: int) -> int { + if k == LS_COMPONENT { return 22 } + if k == LS_ARCHETYPE { return 7 } + if k == LS_CONST { return 21 } + if k == LS_VAR { return 6 } + if k == LS_FN or k == LS_EXTERN { return 3 } + if k == LS_SYSTEM { return 23 } + if k == LS_UI { return 7 } + if k == LS_WIDGET { return 21 } + if k == LS_SCENE { return 11 } + if k == LS_LAYER { return 11 } + if k == LS_FIELD { return 5 } + return 6 + } + + # ---- diagnostics (structural) ---- + fn diag_structural(D: Doc, o: Buf) -> void { + let ds_s = new []int; let ds_e = new []int; let ds_m = new []ptr + let stack = words(1200); var top = 0 + var i = 0; let N = ntok(D) + while i < N { + if D.tk_kind[i] != LT_OP or tlen(D, i) != 1 { i = i + 1; continue } + let c = D.src[D.tk_start[i]] + if c == 123 or c == 40 or c == 91 { if top < 1200 { stack[top] = i; top = top + 1 } } + else { if c == 125 or c == 41 or c == 93 { + if top == 0 { push(ds_s, D.tk_start[i]); push(ds_e, D.tk_end[i]); push(ds_m, concat3("unmatched '", D.src[D.tk_start[i]..D.tk_end[i]], "'")) } + else { top = top - 1; let oi = stack[top]; let oc = D.src[D.tk_start[oi]] + var wantc = 93 + if oc == 123 { wantc = 125 } else { if oc == 40 { wantc = 41 } } + if wantc != c { push(ds_s, D.tk_start[i]); push(ds_e, D.tk_end[i]); push(ds_m, "mismatched bracket") } + } + } } + i = i + 1 + } + var k = 0 + while k < top { let oi = stack[k]; push(ds_s, D.tk_start[oi]); push(ds_e, D.tk_end[oi]); push(ds_m, concat3("unclosed '", D.src[D.tk_start[oi]..D.tk_end[oi]], "'")); k = k + 1 } + var j = 0 + while j < len(ds_s) { + if j > 0 { buf_putc(o, 44) } + buf_puts(o, "{\"range\":"); put_range(o, D, ds_s[j], ds_e[j]); buf_puts(o, ",\"severity\":1,\"source\":\"ludic\",\"message\":"); jstr_out(o, ds_m[j]); buf_putc(o, 125) + j = j + 1 + } + } + fn publish_diag(D: Doc) -> void { + let o = buf_new() + buf_puts(o, "{\"uri\":"); jstr_out(o, D.uri); buf_puts(o, ",\"diagnostics\":[") + if D.is_md == 0 { diag_structural(D, o) } + buf_puts(o, "]}") + send_notify("textDocument/publishDiagnostics", buf_str(o)) + } + + # ---- document symbols ---- + fn put_doc_symbols(o: Buf, D: Doc, parent: int) -> void { + buf_putc(o, 91) + var first = 1 + var i = 0 + while i < len(D.syms) { + let y = D.syms[i] + if y.parent == parent and is_outline_kind(y.kind) and (y.name != null) and (cstr_len(y.name) > 0) { + if first == 0 { buf_putc(o, 44) } + first = 0 + buf_puts(o, "{\"name\":"); jstr_out(o, y.name) + buf_puts(o, ",\"detail\":"); jstr_out(o, y.detail) + buf_puts(o, ",\"kind\":"); buf_puti(o, lsp_symbol_kind(y.kind)) + buf_puts(o, ",\"range\":") + var a = y.start; var b = y.end + if y.bend > y.end and y.bstart >= y.start { b = y.bend } + put_range(o, D, a, b) + buf_puts(o, ",\"selectionRange\":"); put_range(o, D, y.start, y.end) + buf_puts(o, ",\"children\":"); put_doc_symbols(o, D, i) + buf_putc(o, 125) + } + i = i + 1 + } + buf_putc(o, 93) + } + + # ---- hover ---- + fn hover_md(o: Buf, code: ptr, docstr: ptr) -> void { + let m = buf_new() + buf_puts(m, "```ludic\n"); buf_puts(m, code); buf_puts(m, "\n```") + if (docstr != null) and (docstr[0] != 0) { buf_puts(m, "\n\n"); buf_puts(m, docstr) } + buf_puts(o, "{\"contents\":{\"kind\":\"markdown\",\"value\":"); jstr_out(o, buf_str(m)); buf_puts(o, "}}") + } + fn on_hover(msg: JVal, id: JVal) -> void { + let D = doc_of(msg) + if (D == null) { send_result(id, "null"); return } + let off = off_of(msg, D, "params.position") + let tok = tok_at(D, off) + if tok < 0 { send_result(id, "null"); return } + resolve_at(D, off) + if (g_owner != null) and g_symidx >= 0 { + let ow = g_owner + let y = ow.syms[g_symidx] + var code = y.detail + if code == "" { code = y.name } + var docstr = y.doc + if not (ow.path == D.path) { docstr = concat3(docstr, "\n\n_declared in ", concat3(basename(ow.path), "_", "")) } + let o = buf_new(); hover_md(o, code, docstr); send_result(id, buf_str(o)); return + } + let name = ttext(D, tok) + let sig = builtin_sig(name) + if (sig != null) { let o = buf_new(); hover_md(o, sig, ""); send_result(id, buf_str(o)); return } + if D.tk_kind[tok] == LT_PHASE { let o = buf_new(); hover_md(o, name, "A system phase."); send_result(id, buf_str(o)); return } + if D.tk_kind[tok] == LT_TYPE { let o = buf_new(); hover_md(o, name, "A built-in type."); send_result(id, buf_str(o)); return } + send_result(id, "null") + } + + # ---- definition ---- + fn on_definition(msg: JVal, id: JVal) -> void { + let D = doc_of(msg) + if (D == null) { send_result(id, "null"); return } + let off = off_of(msg, D, "params.position") + let tok = tok_at(D, off) + if tok >= 0 and D.tk_kind[tok] == LT_STR { + let p = prev_sig(D, tok) + if p >= 0 and tis(D, p, "import") { + var n = tlen(D, tok) - 2; if n < 0 { n = 0 } + let rel = D.src[D.tk_start[tok] + 1..D.tk_start[tok] + 1 + n] + let full = join_path(dirname(D.path), rel) + let T = ensure_doc(full) + if (T != null) { let o = buf_new(); put_location(o, T, 0, 0); send_result(id, buf_str(o)); return } + } + } + resolve_at(D, off) + if (g_owner == null) or g_symidx < 0 { send_result(id, "null"); return } + let ow = g_owner + let y = ow.syms[g_symidx] + let o = buf_new(); put_location(o, ow, y.start, y.end); send_result(id, buf_str(o)) + } + + # ---- occurrences (references / rename) ---- + var g_occ_doc: []Doc + var g_occ_tok: []int + fn find_occurrences(from: Doc, tdoc: Doc, tsym: int) -> void { + g_occ_doc = new []Doc; g_occ_tok = new []int + let want = tdoc.syms[tsym].name + var docs = new []Doc + if is_local_kind(tdoc.syms[tsym].kind) { push(docs, from) } else { docs = related(from) } + var i = 0 + while i < len(docs) { + let T = docs[i] + var k = 0 + while k < ntok(T) { + if T.tk_kind[k] == LT_ID and (ttext(T, k) == want) { + resolve_tok(T, k) + if (g_owner != null) and (g_owner.path == tdoc.path) and g_symidx == tsym { push(g_occ_doc, T); push(g_occ_tok, k) } + } + k = k + 1 + } + i = i + 1 + } + } + fn on_references(msg: JVal, id: JVal) -> void { + let D = doc_of(msg) + if (D == null) { send_result(id, "[]"); return } + let off = off_of(msg, D, "params.position") + let tok = resolve_at(D, off) + if tok < 0 or (g_owner == null) or g_symidx < 0 { send_result(id, "[]"); return } + let tdoc = g_owner; let tsym = g_symidx + find_occurrences(D, tdoc, tsym) + let o = buf_new(); buf_putc(o, 91) + var i = 0 + while i < len(g_occ_doc) { + if i > 0 { buf_putc(o, 44) } + let T = g_occ_doc[i]; let k = g_occ_tok[i] + put_location(o, T, T.tk_start[k], T.tk_end[k]) + i = i + 1 + } + buf_putc(o, 93); send_result(id, buf_str(o)) + } + fn on_rename(msg: JVal, id: JVal) -> void { + let D = doc_of(msg) + let newname = jstr(jpath(msg, "params.newName"), null) + if (D == null) or (newname == null) or (newname[0] == 0) { send_result(id, "null"); return } + let off = off_of(msg, D, "params.position") + let tok = resolve_at(D, off) + if tok < 0 or (g_owner == null) or g_symidx < 0 { send_result(id, "null"); return } + let tdoc = g_owner; let tsym = g_symidx + find_occurrences(D, tdoc, tsym) + # group by doc + let seen = new []Doc + let o = buf_new(); buf_puts(o, "{\"changes\":{") + var gi = 0 + while gi < len(g_occ_doc) { + var already = false + var s = 0 + while s < len(seen) { if (seen[s].path == g_occ_doc[gi].path) { already = true }; s = s + 1 } + if not already { + push(seen, g_occ_doc[gi]) + if len(seen) > 1 { buf_putc(o, 44) } + jstr_out(o, g_occ_doc[gi].uri); buf_putc(o, 58); buf_putc(o, 91) + var first = 1 + var k = 0 + while k < len(g_occ_doc) { + if (g_occ_doc[k].path == g_occ_doc[gi].path) { + if first == 0 { buf_putc(o, 44) } + first = 0 + let T = g_occ_doc[k]; let tk = g_occ_tok[k] + buf_puts(o, "{\"range\":"); put_range(o, T, T.tk_start[tk], T.tk_end[tk]); buf_puts(o, ",\"newText\":"); jstr_out(o, newname); buf_putc(o, 125) + } + k = k + 1 + } + buf_putc(o, 93) + } + gi = gi + 1 + } + buf_puts(o, "}}"); send_result(id, buf_str(o)) + } + + # ---- completion ---- + var g_first: int = 1 + fn comp_item(o: Buf, label: ptr, kind: int, detail: ptr) -> void { + if g_first == 0 { buf_putc(o, 44) } + g_first = 0 + buf_puts(o, "{\"label\":"); jstr_out(o, label); buf_puts(o, ",\"kind\":"); buf_puti(o, kind) + if (detail != null) and (detail[0] != 0) { buf_puts(o, ",\"detail\":"); jstr_out(o, detail) } + buf_putc(o, 125) + } + fn comp_scope(o: Buf, D: Doc, off: int, types_only: int) -> void { + if types_only == 0 { + var i = 0 + while i < len(D.syms) { + let y = D.syms[i] + if is_local_kind(y.kind) and off >= y.bstart and off <= y.bend { + var det = y.detail; if det == "" { det = y.ty } + comp_item(o, y.name, 6, det) + } + i = i + 1 + } + } + let rel = related(D) + var r = 0 + while r < len(rel) { + var k = 0 + while k < len(rel[r].syms) { + let y = rel[r].syms[k] + if is_toplevel_kind(y.kind) and y.kind != LS_UNIT { + var okk = true + if types_only == 1 and not (y.kind == LS_COMPONENT or y.kind == LS_ARCHETYPE) { okk = false } + if okk { comp_item(o, y.name, comp_kind_of(y.kind), y.detail) } + } + k = k + 1 + } + r = r + 1 + } + } + fn comp_types(o: Buf) -> void { + comp_item(o, "int", 14, "built-in type"); comp_item(o, "fixed", 14, "built-in type"); comp_item(o, "bool", 14, "built-in type") + comp_item(o, "entity", 14, "built-in type"); comp_item(o, "str", 14, "built-in type"); comp_item(o, "ptr", 14, "built-in type"); comp_item(o, "void", 14, "built-in type") + } + fn comp_builtins(o: Buf) -> void { var i = 0; while i < len(g_builtins) { comp_item(o, g_builtins[i], 3, g_bsigs[i]); i = i + 1 } } + fn on_completion(msg: JVal, id: JVal) -> void { + let D = doc_of(msg) + if (D == null) { send_result(id, "{\"isIncomplete\":false,\"items\":[]}"); return } + let off = off_of(msg, D, "params.position") + let o = buf_new() + buf_puts(o, "{\"isIncomplete\":false,\"items\":[") + g_first = 1 + var tok = 0 - 1 + var i = ntok(D) - 1 + while i >= 0 { + let k = D.tk_kind[i] + if k != LT_NL and k != LT_EOF and k != LT_COMMENT { if D.tk_end[i] <= off { tok = i; break } } + i = i - 1 + } + var anchor = tok + if anchor >= 0 and D.tk_kind[anchor] == LT_ID and D.tk_end[anchor] >= off { anchor = prev_sig(D, anchor) } + var in_qt = 0 + var depth = 0 + var j = anchor + while j >= 0 { + if D.tk_kind[j] == LT_OP and tlen(D, j) == 1 { + let ch = D.src[D.tk_start[j]] + if ch == 93 { depth = depth + 1 } + else { if ch == 91 { if depth == 0 { in_qt = 1; j = 0 - 1 } else { depth = depth - 1 } } + else { if ch == 123 or ch == 125 { j = 0 - 1 } } } + } + j = j - 1 + } + var done = 0 + if in_qt == 1 { comp_scope(o, D, off, 1); done = 1 } + else { if anchor >= 0 { + if tis(D, anchor, ".") { + let comp = receiver_component(D, anchor) + if comp >= 0 and (g_owner != null) { + let co = g_owner + var k = 0 + while k < len(co.syms) { if co.syms[k].kind == LS_FIELD and co.syms[k].parent == comp { comp_item(o, co.syms[k].name, 5, co.syms[k].detail) }; k = k + 1 } + } + done = 1 + } + else { if tis(D, anchor, "phase") { comp_item(o, "Start", 13, ""); comp_item(o, "Input", 13, ""); comp_item(o, "FixedUpdate", 13, ""); comp_item(o, "Update", 13, ""); comp_item(o, "LateUpdate", 13, ""); comp_item(o, "Render", 13, ""); done = 1 } + else { if tis(D, anchor, ":") or tis(D, anchor, "->") { comp_types(o); comp_scope(o, D, off, 1); done = 1 } + else { if tis(D, anchor, "spawn") { comp_scope(o, D, off, 1); done = 1 } + else { if D.tk_kind[anchor] == LT_OP and tlen(D, anchor) == 1 and D.src[D.tk_start[anchor]] == 64 { comp_item(o, "deterministic", 14, "@deterministic"); done = 1 } + } } } } + } } + if done == 0 and in_ui_body(D, off) { + comp_item(o, "panel", 7, "widget"); comp_item(o, "col", 7, "widget"); comp_item(o, "row", 7, "widget"); comp_item(o, "label", 7, "widget"); comp_item(o, "button", 7, "widget"); comp_item(o, "image", 7, "widget"); comp_item(o, "spacer", 7, "widget") + } + if done == 0 { + comp_item(o, "let", 14, "statement"); comp_item(o, "if", 14, "statement"); comp_item(o, "for", 14, "statement"); comp_item(o, "while", 14, "statement"); comp_item(o, "return", 14, "statement"); comp_item(o, "spawn", 14, "statement"); comp_item(o, "handler", 14, "declaration"); comp_item(o, "property", 14, "declaration"); comp_item(o, "model", 14, "declaration") + comp_types(o) + comp_builtins(o) + comp_scope(o, D, off, 0) + } + buf_puts(o, "]}") + send_result(id, buf_str(o)) + } + + # ---- inlay hints, signature help, semantic tokens, folding ---- + fn on_inlay_hint(msg: JVal, id: JVal) -> void { + let D = doc_of(msg) + if (D == null) { send_result(id, "[]"); return } + let o = buf_new(); buf_putc(o, 91) + var first = 1 + var i = 0 + while i < len(D.syms) { + let y = D.syms[i] + if y.kind == LS_QUERYVAR and (y.ty != null) and (y.ty[0] != 0) { + if first == 0 { buf_putc(o, 44) } + first = 0 + buf_puts(o, "{\"position\":"); put_pos(o, D, y.end); buf_puts(o, ",\"label\":"); jstr_out(o, concat3(": ", y.ty, "")); buf_puts(o, ",\"kind\":1,\"paddingLeft\":false}") + } + i = i + 1 + } + buf_putc(o, 93); send_result(id, buf_str(o)) + } + fn on_signature_help(msg: JVal, id: JVal) -> void { + let D = doc_of(msg) + if (D == null) { send_result(id, "null"); return } + let off = off_of(msg, D, "params.position") + var depth = 0; var callee = 0 - 1; var arg = 0 + var i = ntok(D) - 1 + while i >= 0 { + let t = i + if D.tk_start[t] >= off { i = i - 1; continue } + if D.tk_kind[t] == LT_OP and tlen(D, t) == 1 { + let c = D.src[D.tk_start[t]] + if c == 41 { depth = depth + 1 } + else { if c == 40 { + if depth == 0 { + callee = prev_sig(D, t) + var k = t + 1 + while k < ntok(D) and D.tk_start[k] < off { if tis(D, k, ",") { arg = arg + 1 }; k = k + 1 } + i = 0 - 1 + } else { depth = depth - 1 } + } } + } + i = i - 1 + } + if callee < 0 or D.tk_kind[callee] != LT_ID { send_result(id, "null"); return } + let name = ttext(D, callee) + var sig = builtin_sig(name) + var docstr = "" + if (sig == null) { + let t = find_top(D, name) + if t >= 0 and (g_owner.syms[t].kind == LS_FN or g_owner.syms[t].kind == LS_EXTERN) { sig = g_owner.syms[t].detail; docstr = g_owner.syms[t].doc } + } + if (sig == null) { send_result(id, "null"); return } + let o = buf_new() + buf_puts(o, "{\"signatures\":[{\"label\":"); jstr_out(o, sig) + if (docstr != null) and (docstr[0] != 0) { buf_puts(o, ",\"documentation\":"); jstr_out(o, docstr) } + buf_puts(o, "}],\"activeSignature\":0,\"activeParameter\":"); buf_puti(o, arg); buf_putc(o, 125) + send_result(id, buf_str(o)) + } + fn on_semantic_tokens(msg: JVal, id: JVal) -> void { + let D = doc_of(msg) + if (D == null) { send_result(id, "null"); return } + classify(D) + let o = buf_new(); buf_puts(o, "{\"data\":[") + var prev_line = 0; var prev_char = 0; var first = 1 + var i = 0; let N = ntok(D) + while i < N { + let k = D.tk_kind[i] + if k != LT_NL and k != LT_EOF { + let ty = sem_type_of(D.cls[i]) + if ty >= 0 { + let line = D.tk_line[i] + let ch = col_of(D, D.tk_start[i]) + let ln = utf16_len(D.text, D.tk_start[i], tlen(D, i)) + if ln > 0 { + let dl = line - prev_line + var dc = ch + if dl == 0 { dc = ch - prev_char } + if first == 0 { buf_putc(o, 44) } + first = 0 + buf_puti(o, dl); buf_putc(o, 44); buf_puti(o, dc); buf_putc(o, 44); buf_puti(o, ln); buf_putc(o, 44); buf_puti(o, ty); buf_putc(o, 44); buf_puti(o, g_semmods) + prev_line = line; prev_char = ch + } + } + } + i = i + 1 + } + buf_puts(o, "]}"); send_result(id, buf_str(o)) + } + fn on_folding(msg: JVal, id: JVal) -> void { + let D = doc_of(msg) + if (D == null) { send_result(id, "[]"); return } + let o = buf_new(); buf_putc(o, 91); var first = 1 + var i = 0; let N = ntok(D) + while i < N { + if D.tk_kind[i] == LT_OP and tlen(D, i) == 1 and D.src[D.tk_start[i]] == 123 { + let m = D.tmatch[i] + if m >= 0 { + let a = D.tk_line[i]; let b = D.tk_line[m] + if b > a { + if first == 0 { buf_putc(o, 44) } + first = 0 + buf_puts(o, "{\"startLine\":"); buf_puti(o, a); buf_puts(o, ",\"endLine\":"); buf_puti(o, b - 1); buf_puts(o, ",\"kind\":\"region\"}") + } + } + } + i = i + 1 + } + buf_putc(o, 93); send_result(id, buf_str(o)) + } + fn on_workspace_symbol(msg: JVal, id: JVal) -> void { + let q = jstr(jpath(msg, "params.query"), "") + let o = buf_new(); buf_putc(o, 91); var first = 1 + var d = 0 + while d < len(g_docs) { + let D = g_docs[d] + var k = 0 + while k < len(D.syms) { + let y = D.syms[k] + if is_outline_kind(y.kind) and (y.name != null) and (cstr_len(y.name) > 0) { + var keep = true + if q[0] != 0 { keep = contains_ci(y.name, q) } + if keep { + if first == 0 { buf_putc(o, 44) } + first = 0 + buf_puts(o, "{\"name\":"); jstr_out(o, y.name); buf_puts(o, ",\"kind\":"); buf_puti(o, lsp_symbol_kind(y.kind)); buf_puts(o, ",\"location\":"); put_location(o, D, y.start, y.end); buf_putc(o, 125) + } + } + k = k + 1 + } + d = d + 1 + } + buf_putc(o, 93); send_result(id, buf_str(o)) + } + fn contains_ci(hay: ptr, needle: ptr) -> bool { + let hn = cstr_len(hay); let nn = cstr_len(needle) + if nn == 0 { return true } + var i = 0 + while i + nn <= hn { + var m = true + var j = 0 + while j < nn { if lower(hay[i + j]) != lower(needle[j]) { m = false; break }; j = j + 1 } + if m { return true } + i = i + 1 + } + return false + } + fn on_formatting(msg: JVal, id: JVal) -> void { + let D = doc_of(msg) + if (D == null) { send_result(id, "null"); return } + var tab = jint(jpath(msg, "params.options.tabSize"), 2) + if tab < 1 or tab > 8 { tab = 2 } + var out = null + if D.is_md == 1 { out = format_md(D.raw, tab) } + else { let F = make_text_doc(D.raw); out = format_doc(F, tab) } + let endline = len(D.linestart) - 1 + let ls0 = D.linestart[endline] + let e0 = cstr_len(D.text) + let endchar = utf16_len(D.text, ls0, e0 - ls0) + let o = buf_new() + buf_puts(o, "[{\"range\":{\"start\":{\"line\":0,\"character\":0},\"end\":{\"line\":"); buf_puti(o, endline); buf_puts(o, ",\"character\":"); buf_puti(o, endchar); buf_puts(o, "}},\"newText\":"); jstr_out(o, out); buf_puts(o, "}]") + send_result(id, buf_str(o)) + } + + # ---- document lifecycle ---- + fn on_did_open(msg: JVal) -> void { + let uri = jstr(jpath(msg, "params.textDocument.uri"), null) + let text = jstr(jpath(msg, "params.textDocument.text"), "") + if (uri == null) { return } + let path = uri_to_path(uri) + var D = by_path(path) + if (D == null) { D = new_doc(path, text); push(g_docs, D) } + else { set_text(D, text); reindex(D) } + D.isopen = 1 + publish_diag(D) + } + fn on_did_change(msg: JVal) -> void { + let D = doc_of(msg) + if (D == null) { return } + let changes = jpath(msg, "params.contentChanges") + let last = jat(changes, jlen(changes) - 1) + let text = jstr(jget(last, "text"), null) + if (text == null) { return } + set_text(D, text) + reindex(D) + publish_diag(D) + } + fn on_did_close(msg: JVal) -> void { + let D = doc_of(msg) + if (D == null) { return } + D.isopen = 0 + let disk = read_file(D.path) + if (disk != null) { set_text(D, disk); reindex(D) } + } + + fn caps() -> ptr { + let o = buf_new() + buf_puts(o, "{\"capabilities\":{") + buf_puts(o, "\"positionEncoding\":\"utf-16\"") + buf_puts(o, ",\"textDocumentSync\":{\"openClose\":true,\"change\":1,\"save\":{\"includeText\":false}}") + buf_puts(o, ",\"documentSymbolProvider\":true") + buf_puts(o, ",\"workspaceSymbolProvider\":true") + buf_puts(o, ",\"definitionProvider\":true") + buf_puts(o, ",\"declarationProvider\":true") + buf_puts(o, ",\"referencesProvider\":true") + buf_puts(o, ",\"documentHighlightProvider\":true") + buf_puts(o, ",\"hoverProvider\":true") + buf_puts(o, ",\"renameProvider\":{\"prepareProvider\":true}") + buf_puts(o, ",\"documentFormattingProvider\":true") + buf_puts(o, ",\"documentRangeFormattingProvider\":true") + buf_puts(o, ",\"foldingRangeProvider\":true") + buf_puts(o, ",\"documentLinkProvider\":{\"resolveProvider\":false}") + buf_puts(o, ",\"inlayHintProvider\":true") + buf_puts(o, ",\"completionProvider\":{\"triggerCharacters\":[\".\",\"@\",\"[\",\" \"],\"resolveProvider\":false}") + buf_puts(o, ",\"signatureHelpProvider\":{\"triggerCharacters\":[\"(\",\",\"]}") + buf_puts(o, ",\"semanticTokensProvider\":{\"legend\":{\"tokenTypes\":[\"keyword\",\"type\",\"struct\",\"class\",\"namespace\",\"function\",\"parameter\",\"variable\",\"property\",\"enumMember\",\"number\",\"string\",\"comment\",\"operator\",\"decorator\"],\"tokenModifiers\":[\"declaration\",\"readonly\",\"defaultLibrary\"]},\"full\":true,\"range\":true}") + buf_puts(o, "},\"serverInfo\":{\"name\":\"ludic-lsp\",\"version\":\"1.0.0\"}}") + return buf_str(o) + } + fn on_initialize(msg: JVal, id: JVal) -> void { + let root = jpath(msg, "params.rootUri") + if (root != null) and root.t == JSTR { g_root = uri_to_path(root.s) } + if (g_root != null) { scan_root(g_root) } + send_result(id, caps()) + } + + fn handle(msg: JVal) -> void { + let method = jstr(jget(msg, "method"), null) + let id = jget(msg, "id") + if (method == null) { return } + if (method == "initialize") { on_initialize(msg, id); return } + if (method == "initialized") { return } + if (method == "shutdown") { g_shutdown = 1; send_result(id, "null"); return } + if (method == "exit") { if g_shutdown == 1 { exit(0) }; exit(1) } + if (method == "textDocument/didOpen") { on_did_open(msg); return } + if (method == "textDocument/didChange") { on_did_change(msg); return } + if (method == "textDocument/didClose") { on_did_close(msg); return } + if (method == "textDocument/didSave") { on_did_change(msg); return } + if (method == "textDocument/documentSymbol") { let D = doc_of(msg); if (D == null) { send_result(id, "[]"); return }; let o = buf_new(); put_doc_symbols(o, D, 0 - 1); send_result(id, buf_str(o)); return } + if (method == "workspace/symbol") { on_workspace_symbol(msg, id); return } + if (method == "textDocument/definition") or (method == "textDocument/declaration") or (method == "textDocument/typeDefinition") { on_definition(msg, id); return } + if (method == "textDocument/hover") { on_hover(msg, id); return } + if (method == "textDocument/references") { on_references(msg, id); return } + if (method == "textDocument/documentHighlight") { on_references(msg, id); return } + if (method == "textDocument/rename") { on_rename(msg, id); return } + if (method == "textDocument/prepareRename") { let D = doc_of(msg); if (D == null) { send_result(id, "null"); return }; let off = off_of(msg, D, "params.position"); let tok = resolve_at(D, off); if tok < 0 or (g_owner == null) or g_symidx < 0 or D.tk_kind[tok] != LT_ID { send_result(id, "null"); return }; let o = buf_new(); buf_puts(o, "{\"range\":"); put_range(o, D, D.tk_start[tok], D.tk_end[tok]); buf_puts(o, ",\"placeholder\":"); jstr_out(o, ttext(D, tok)); buf_putc(o, 125); send_result(id, buf_str(o)); return } + if (method == "textDocument/formatting") or (method == "textDocument/rangeFormatting") { on_formatting(msg, id); return } + if (method == "textDocument/foldingRange") { on_folding(msg, id); return } + if (method == "textDocument/inlayHint") { on_inlay_hint(msg, id); return } + if (method == "textDocument/signatureHelp") { on_signature_help(msg, id); return } + if (method == "textDocument/completion") { on_completion(msg, id); return } + if (method == "textDocument/documentLink") { send_result(id, "[]"); return } + if (method == "textDocument/semanticTokens/full") or (method == "textDocument/semanticTokens/range") { on_semantic_tokens(msg, id); return } + if (id != null) { send_result(id, "null") } + } + + entry { + init_builtins() + g_docs = new []Doc + while true { + let raw = read_message() + if (raw == null) { break } + jsrc = raw; jp = 0 + let msg = jparse() + handle(msg) + } + } +} diff --git a/tools/ludic-tools/ludic_fmt.h b/tools/ludic-tools/ludic_fmt.h deleted file mode 100644 index 89bc12af..00000000 --- a/tools/ludic-tools/ludic_fmt.h +++ /dev/null @@ -1,339 +0,0 @@ -/* ============================================================================ - * ludic_fmt.h — the canonical Ludic formatter. - * - * This is deliberately NOT `ludicc --fmt`. The compiler's printer walks the AST - * after import splicing, so it drops every comment and inlines every imported - * file into whichever file you pointed it at — fine for inspecting what the - * compiler saw, catastrophic as an editor's "format on save". - * - * This formatter works on the token stream instead: - * - comments and blank lines survive, because they are tokens; - * - nothing is ever dropped or reordered, because every token is re-emitted - * in order — the only freedom taken is the whitespace between them; - * - lines are re-indented and respaced but never joined or split, so the - * author keeps control of line structure and a format-on-save never - * rewrites a file out from under someone mid-edit. - * ==========================================================================*/ -#ifndef LUDIC_FMT_H -#define LUDIC_FMT_H - -#include "ludic_syntax.h" - -typedef struct { char* b; size_t n, cap; } FSB; -static void fsb_ensure(FSB* s, size_t add){ - if (s->n + add + 1 > s->cap){ s->cap = (s->n + add + 1) * 2; s->b = realloc(s->b, s->cap); } -} -static void fsb_add(FSB* s, const char* z, size_t l){ fsb_ensure(s, l); memcpy(s->b + s->n, z, l); s->n += l; s->b[s->n] = 0; } -static void fsb_puts(FSB* s, const char* z){ fsb_add(s, z, strlen(z)); } -static void fsb_putc(FSB* s, char c){ fsb_add(s, &c, 1); } -static void fsb_indent(FSB* s, int n){ for (int i = 0; i < n; i++) fsb_putc(s, ' '); } - -/* Can this token be one side of a member access? */ -static int lud_name_like(int kind){ - return kind == LT_ID || kind == LT_KW || kind == LT_TYPE || kind == LT_PHASE || kind == LT_BOOL; -} -/* A '.' hugs an operand, a closing bracket, and another dot — the last so that - * a run of dots stays a run of dots instead of being spaced into pieces. */ -static int lud_dot_tight(const LLex* L, const LTok* t){ - if (lud_name_like(t->kind)) return 1; - if (t->kind != LT_OP) return 0; - int n = ltok_len(t); - char c0 = L->src[t->start]; - if (n == 1 && (c0 == ')' || c0 == ']' || c0 == '.')) return 1; - if (n == 2 && c0 == '.' && L->src[t->start + 1] == '.') return 1; - return 0; -} - -/* Is the token at index i a unary '-' / '!' rather than a binary operator? - * Unary iff nothing that can end an operand precedes it. */ -static int fmt_is_unary(const LLex* L, int i){ - const LTok* t = &L->v[i]; - if (t->kind != LT_OP) return 0; - int n = ltok_len(t); - if (!(n == 1 && (L->src[t->start] == '-' || L->src[t->start] == '!'))) return 0; - int p = ltok_prev_sig(L, i); - if (p < 0) return 1; - const LTok* pt = &L->v[p]; - switch (pt->kind){ - case LT_ID: case LT_INT: case LT_FLOAT: case LT_STR: case LT_CHAR: - case LT_BOOL: case LT_TYPE: case LT_PHASE: - return 0; - case LT_OP: { - char c = L->src[pt->start]; - /* a closing bracket ends an operand; every other operator does not */ - return !(ltok_len(pt) == 1 && (c == ')' || c == ']' || c == '}')); - } - default: return 1; /* keyword, annotation, comment: operand starts here */ - } -} - -/* Whitespace between the previous emitted token (prev) and the current one. */ -static int fmt_space_before(const LLex* L, int prev, int cur){ - if (prev < 0) return 0; - const LTok* p = &L->v[prev]; - const LTok* c = &L->v[cur]; - const char* src = L->src; - int plen = ltok_len(p), clen = ltok_len(c); - char p0 = src[p->start], c0 = src[c->start]; - int p1 = (plen == 1), c1 = (clen == 1); - - /* An error token is bytes we did not understand. Whatever spacing it had - * is the only spacing we can justify, so it is preserved verbatim. */ - if (p->kind == LT_ERR || c->kind == LT_ERR) return c->start - p->end; - - /* nothing hugs a closer, a separator or a member dot from the left */ - if (c1 && (c0 == ')' || c0 == ']' || c0 == ',' || c0 == ':' || c0 == ';')) return 0; - /* `.` binds tight only when it really is member access — `a.b`. A lone dot - * next to a brace is something else (or a typo) and gets normal spacing. */ - if (c1 && c0 == '.' && c->kind == LT_OP && lud_dot_tight(L, p)) return 0; - if (p1 && p0 == '.' && p->kind == LT_OP && lud_dot_tight(L, c)) return 0; - /* nothing hugs an opener from the right */ - if (p1 && (p0 == '(' || p0 == '[') && p->kind == LT_OP) return 0; - /* a unary sign binds to its operand */ - if (p->kind == LT_OP && fmt_is_unary(L, prev)) return 0; - /* @anno(args) */ - if (p->kind == LT_ANNO && c1 && c0 == '(') return 0; - - if (c1 && c0 == '(' && c->kind == LT_OP){ - /* `fn move(` and `clear(` hug; `if (`, `return (`, `x * (` do not */ - switch (p->kind){ - case LT_ID: case LT_TYPE: case LT_PHASE: return 0; - case LT_OP: return !(p1 && (p0 == ')' || p0 == ']')); - default: return 1; - } - } - return 1; -} - -/* Clause keywords hang under the declaration they qualify: a system's - * `phase`/`query` lines and a function's contract lines are indented one level - * past the `system`/`fn` they belong to, with the body brace back at the - * declaration's own level. Every example in the tree is written that way. */ -static int fmt_is_clause_word(const LLex* L, int i){ - static const char* CLAUSES[] = { "phase","query","reads","writes","needs","uses", - "requires","ensures","invariant","effects", 0 }; - if (i < 0 || i >= L->n || L->v[i].kind != LT_KW) return 0; - char b[32]; ltok_text(L, i, b, sizeof(b)); - return lud_in(CLAUSES, b); -} - -/* One pass over the token stream, re-emitting it with canonical whitespace. - * - * Two carve-outs keep the result idiomatic rather than merely uniform: - * - a run of two or more spaces is preserved verbatim, so hand-aligned - * columns (`const R_DIR: int = 0`) and deliberately set-off trailing - * comments survive a format-on-save; - * - `id=Root` inside a `ui` block and `{Enemy}` inside a query stay tight, - * because those are the spellings the language documents and uses. - */ -static char* ludic_format(const char* src, int indent_width){ - LLex L; lud_lex(&L, src); - FSB o = {0}; - /* One entry per open brace, holding the indent level to return to. Every - * brace opened on the same line shares that line's level, so a line like - * `if a { if b { if c {` steps in by ONE level, not three — and the line - * that closes them all lands back where it started. */ - int stack[512]; int hang[512]; int sp = 0; - int cur = 0; - int open = 0; /* unclosed ( or [ : the author owns the alignment */ - int brack = 0; /* unclosed [ only: query-term context */ - int ui_depth = -1; /* brace depth just outside the innermost `ui` block */ - int pending_blank = 0; - int wrote_any = 0; - int prev_line_had_comment = 0; - - int i = 0; - while (i < L.n && L.v[i].kind != LT_EOF){ - int a = i; - while (i < L.n && L.v[i].kind != LT_NL && L.v[i].kind != LT_EOF) i++; - int b = i; /* [a,b) are this line's tokens */ - if (i < L.n && L.v[i].kind == LT_NL) i++; - - if (a == b){ /* a blank line */ - if (wrote_any) pending_blank = 1; - continue; - } - - /* ---- where does this line start? --------------------------------- */ - int line_level = cur; - { /* leading closers belong to the level of the line that opened them */ - int tsp = sp, t = a; - while (t < b && L.v[t].kind == LT_OP && ltok_len(&L.v[t]) == 1 && src[L.v[t].start] == '}'){ - if (tsp > 0) line_level = stack[--tsp]; - t++; - } - } - /* Original column of this line, for the cases where the author's - * alignment is the only sensible answer. */ - int orig_ind = 0; - for (int k = L.linestart[L.v[a].line]; k < L.v[a].start; k++) orig_ind += (src[k] == '\t') ? 4 : 1; - - /* A comment on its own line, indented past its block and following a - * line that itself ended in a comment, is the continuation of that - * comment — a column the author chose, not stray indentation. */ - int comment_run = (L.v[a].kind == LT_COMMENT && b == a + 1 && prev_line_had_comment); - - int ind; - if (open > 0 || (sp > 0 && hang[sp - 1])){ - /* Inside an unclosed call, query, or a brace that was opened with - * content trailing it, the author is aligning to a column the - * formatter cannot see. Leave those lines exactly as written. */ - int ls = L.linestart[L.v[a].line]; - ind = 0; - for (int k = ls; k < L.v[a].start; k++) ind += (src[k] == '\t') ? 4 : 1; - } else { - ind = line_level * indent_width + (fmt_is_clause_word(&L, a) ? indent_width : 0); - if (comment_run && orig_ind > ind) ind = orig_ind; - } - - if (pending_blank && wrote_any) fsb_putc(&o, '\n'); - pending_blank = 0; - fsb_indent(&o, ind); - - /* ---- the tokens --------------------------------------------------- */ - int prev = -1; - int line_brack = brack, line_ui_open = (ui_depth >= 0 && sp > ui_depth); - for (int t = a; t < b; t++){ - const LTok* tk = &L.v[t]; - int gap = (prev >= 0) ? tk->start - L.v[prev].end : 0; - int want; - - if (tk->kind == LT_COMMENT){ - want = (prev >= 0) ? 2 : 0; /* set a trailing comment off */ - } else { - want = fmt_space_before(&L, prev, t); - /* a query's {Tag} filter is one word, not a record literal */ - if (line_brack > 0){ - if (tk->kind == LT_OP && ltok_len(tk) == 1 && src[tk->start] == '}') want = 0; - if (prev >= 0 && L.v[prev].kind == LT_OP && ltok_len(&L.v[prev]) == 1 && src[L.v[prev].start] == '{') want = 0; - } - /* widget props are written k=v */ - if (line_ui_open){ - int eq_here = tk->kind == LT_OP && ltok_len(tk) == 1 && src[tk->start] == '='; - int eq_prev = prev >= 0 && L.v[prev].kind == LT_OP && - ltok_len(&L.v[prev]) == 1 && src[L.v[prev].start] == '='; - if (eq_here || eq_prev) want = 0; - } - } - /* hand alignment wins over the canonical single space */ - if (gap >= 2 && want >= 1){ if (gap > 60) gap = 60; want = gap; } - if (want < 0) want = 0; - for (int k = 0; k < want; k++) fsb_putc(&o, ' '); - fsb_add(&o, src + tk->start, ltok_len(tk)); - prev = t; - - if (tk->kind == LT_OP && ltok_len(tk) == 1){ - char c = src[tk->start]; - if (c == '[') line_brack++; - else if (c == ']'){ line_brack--; if (line_brack < 0) line_brack = 0; } - } - } - fsb_putc(&o, '\n'); - wrote_any = 1; - prev_line_had_comment = (prev >= 0 && L.v[prev].kind == LT_COMMENT); - - /* ---- carry the nesting into the next line ------------------------- */ - if (ltok_is(&L, a, "ui") && L.v[a].kind == LT_KW && ui_depth < 0) ui_depth = sp; - { - int level = cur; - for (int t = a; t < b; t++){ - const LTok* tk = &L.v[t]; - if (tk->kind != LT_OP || ltok_len(tk) != 1) continue; - char c = src[tk->start]; - if (c == '{'){ - if (sp < 512){ - int nxt = ltok_next_sig(&L, t); - stack[sp] = line_level; - hang[sp] = (nxt >= 0 && nxt < b); /* content follows on this line */ - sp++; - } - level = line_level + 1; - } - else if (c == '}'){ if (sp > 0) level = stack[--sp]; } - else if (c == '(' || c == '['){ open++; if (c == '[') brack++; } - else if (c == ')' || c == ']'){ open--; if (open < 0) open = 0; if (c == ']'){ brack--; if (brack < 0) brack = 0; } } - } - cur = level; - } - if (ui_depth >= 0 && sp <= ui_depth) ui_depth = -1; - } - lud_lex_free(&L); - if (!o.b) { o.b = malloc(1); o.b[0] = 0; } - return o.b; -} - -/* ---------- markdown ------------------------------------------------------ - * Fenced Ludic in prose is still Ludic. This rewrites the body of every - * ```ludic fence in a Markdown document and leaves the prose untouched, so - * LANGUAGE.md and README.md can be kept honest by the same formatter as the - * source tree. Fence indentation (a fence inside a list item) is preserved. */ -static int md_fence_at(const char* s, int i, int* fence_len, int* info_at, char* marker){ - int j = i, n = 0; - while (s[j] == ' ') j++; /* leading indent */ - char m = s[j]; - if (m != '`' && m != '~') return 0; - while (s[j] == m){ j++; n++; } - if (n < 3) return 0; - *fence_len = n; *info_at = j; *marker = m; - return 1; -} -static int md_info_is_ludic(const char* s, int at){ - while (s[at] == ' ' || s[at] == '\t') at++; - if (strncasecmp(s + at, "ludic", 5)) return 0; - char after = s[at + 5]; - return after == 0 || after == '\n' || after == ' ' || after == '\t' || after == '\r'; -} -static char* ludic_format_markdown(const char* src, int indent_width){ - FSB o = {0}; - int i = 0; - while (src[i]){ - int ls = i; /* line start */ - int le = ls; while (src[le] && src[le] != '\n') le++; - int flen, info, indent = 0; char marker; - while (src[ls + indent] == ' ') indent++; - if (md_fence_at(src, ls, &flen, &info, &marker) && md_info_is_ludic(src, info)){ - /* copy the opening fence line verbatim */ - fsb_add(&o, src + ls, le - ls + (src[le] ? 1 : 0)); - i = src[le] ? le + 1 : le; - /* gather the body up to the closing fence */ - int bs = i; - int be = bs; - for (;;){ - if (!src[be]) break; - int ps = be, pe = ps; while (src[pe] && src[pe] != '\n') pe++; - int clen, cinfo; char cmark; - if (md_fence_at(src, ps, &clen, &cinfo, &cmark) && cmark == marker && clen >= flen){ - int only = 1; - for (int k = cinfo; k < pe; k++) if (src[k] != ' ' && src[k] != '\r'){ only = 0; break; } - if (only) break; - } - be = src[pe] ? pe + 1 : pe; - } - /* de-indent the body, format it, re-indent it */ - FSB body = {0}; - for (int p = bs; p < be; ){ - int q = p; while (src[q] && src[q] != '\n') q++; - int skip = 0; while (skip < indent && p + skip < q && src[p + skip] == ' ') skip++; - fsb_add(&body, src + p + skip, q - (p + skip)); - fsb_putc(&body, '\n'); - p = src[q] ? q + 1 : q; - } - char* f = ludic_format(body.b ? body.b : "", indent_width); - for (char* p = f; *p; ){ - char* q = strchr(p, '\n'); if (!q) q = p + strlen(p); - if (q > p) fsb_indent(&o, indent); - fsb_add(&o, p, q - p); - fsb_putc(&o, '\n'); - p = *q ? q + 1 : q; - } - free(f); free(body.b); - i = be; - continue; - } - fsb_add(&o, src + ls, le - ls + (src[le] ? 1 : 0)); - i = src[le] ? le + 1 : le; - } - if (!o.b){ o.b = malloc(1); o.b[0] = 0; } - return o.b; -} -#endif /* LUDIC_FMT_H */ diff --git a/tools/ludic-tools/ludic_fmt_main.c b/tools/ludic-tools/ludic_fmt_main.c deleted file mode 100644 index 95376bb3..00000000 --- a/tools/ludic-tools/ludic_fmt_main.c +++ /dev/null @@ -1,118 +0,0 @@ -/* ============================================================================ - * ludic-fmt — the Ludic formatter, as a plain CLI. - * - * Editors call this through the language server, but CI and pre-commit hooks - * want a binary they can run: - * - * ludic-fmt a.ludic b.ludic print the formatted text - * ludic-fmt -w examples rewrite every .ludic under examples/ - * ludic-fmt --check . exit 1 if anything is unformatted - * ludic-fmt LANGUAGE.md -w reformat the ```ludic fences in a document - * cat x.ludic | ludic-fmt - filter mode, for editors without LSP - * ==========================================================================*/ -#include "ludic_fmt.h" -#include -#include -#include - -static int g_write = 0, g_check = 0, g_indent = 2, g_quiet = 0; -static int g_changed = 0, g_failed = 0; - -static char* slurp(FILE* f){ - FSB s = {0}; - char buf[65536]; size_t n; - while ((n = fread(buf, 1, sizeof(buf), f)) > 0) fsb_add(&s, buf, n); - if (!s.b){ s.b = malloc(1); s.b[0] = 0; } - return s.b; -} -static int is_md(const char* p){ - size_t n = strlen(p); - return (n > 3 && !strcmp(p + n - 3, ".md")) || (n > 9 && !strcmp(p + n - 9, ".markdown")); -} -static int is_ludic(const char* p){ - size_t n = strlen(p); - return n > 6 && !strcmp(p + n - 6, ".ludic"); -} - -static void do_file(const char* path){ - FILE* f = fopen(path, "rb"); - if (!f){ fprintf(stderr, "ludic-fmt: cannot open %s\n", path); g_failed = 1; return; } - char* src = slurp(f); fclose(f); - char* out = is_md(path) ? ludic_format_markdown(src, g_indent) : ludic_format(src, g_indent); - int same = !strcmp(src, out); - if (g_check){ - if (!same){ g_changed = 1; if (!g_quiet) printf("%s\n", path); } - } else if (g_write){ - if (!same){ - FILE* w = fopen(path, "wb"); - if (!w){ fprintf(stderr, "ludic-fmt: cannot write %s\n", path); g_failed = 1; } - else { fwrite(out, 1, strlen(out), w); fclose(w); if (!g_quiet) fprintf(stderr, "formatted %s\n", path); } - g_changed = 1; - } - } else { - fwrite(out, 1, strlen(out), stdout); - } - free(src); free(out); -} -static void do_dir(const char* dir, int depth){ - if (depth > 16) return; - DIR* d = opendir(dir); - if (!d){ fprintf(stderr, "ludic-fmt: cannot open %s\n", dir); g_failed = 1; return; } - struct dirent* e; - while ((e = readdir(d))){ - if (e->d_name[0] == '.') continue; - if (!strcmp(e->d_name, "build") || !strcmp(e->d_name, "node_modules")) continue; - char p[PATH_MAX]; snprintf(p, sizeof(p), "%s/%s", dir, e->d_name); - struct stat st; if (stat(p, &st)) continue; - if (S_ISDIR(st.st_mode)) do_dir(p, depth + 1); - else if (is_ludic(p)) do_file(p); - } - closedir(d); -} - -static const char* USAGE = -"ludic-fmt — format Ludic source\n" -"\n" -"usage: ludic-fmt [options] [file|dir ...]\n" -" ludic-fmt - read stdin, write stdout\n" -"\n" -"options:\n" -" -w, --write rewrite files in place\n" -" --check list unformatted files; exit 1 if any (implies no output)\n" -" --indent N spaces per level (default 2)\n" -" -q, --quiet no per-file chatter\n" -" -h, --help this text\n" -"\n" -"Directories are walked for *.ludic. A .md/.markdown file has the body of every\n" -"```ludic fence formatted and the prose left alone.\n"; - -int main(int argc, char** argv){ - const char* files[4096]; int nf = 0; - for (int i = 1; i < argc; i++){ - const char* a = argv[i]; - if (!strcmp(a, "-w") || !strcmp(a, "--write")) g_write = 1; - else if (!strcmp(a, "--check") || !strcmp(a, "-l")) g_check = 1; - else if (!strcmp(a, "-q") || !strcmp(a, "--quiet")) g_quiet = 1; - else if (!strcmp(a, "--indent") && i + 1 < argc) g_indent = atoi(argv[++i]); - else if (!strcmp(a, "-h") || !strcmp(a, "--help")){ fputs(USAGE, stdout); return 0; } - else if (a[0] == '-' && a[1] && strcmp(a, "-")){ fprintf(stderr, "ludic-fmt: unknown option %s\n", a); return 2; } - else if (nf < 4096) files[nf++] = a; - } - if (g_indent < 1 || g_indent > 8) g_indent = 2; - - if (nf == 0 || (nf == 1 && !strcmp(files[0], "-"))){ - char* src = slurp(stdin); - char* out = ludic_format(src, g_indent); - fwrite(out, 1, strlen(out), stdout); - free(src); free(out); - return 0; - } - for (int i = 0; i < nf; i++){ - struct stat st; - if (stat(files[i], &st)){ fprintf(stderr, "ludic-fmt: no such file %s\n", files[i]); g_failed = 1; continue; } - if (S_ISDIR(st.st_mode)) do_dir(files[i], 0); - else do_file(files[i]); - } - if (g_failed) return 2; - return (g_check && g_changed) ? 1 : 0; -} diff --git a/tools/ludic-tools/ludic_index.h b/tools/ludic-tools/ludic_index.h deleted file mode 100644 index 34d93dd4..00000000 --- a/tools/ludic-tools/ludic_index.h +++ /dev/null @@ -1,672 +0,0 @@ -/* ============================================================================ - * ludic_index.h — an error-tolerant model of a Ludic workspace. - * - * The compiler's parser is the wrong tool for an editor: it stops at the first - * error and it splices imports into one flat program. A language server needs - * the opposite — keep going after a syntax error (a file being typed into is - * broken most of the time), keep every file separate, and remember where each - * name came from so it can be jumped to, renamed and completed. - * - * So this is a second, deliberately shallow reader of the same grammar. It - * recognises declarations and bindings and records their spans; it does not - * type-check. Ground-truth errors still come from `ludicc` itself (see - * ludic_lsp.c) — this layer supplies structure, not judgement. - * ==========================================================================*/ -#ifndef LUDIC_INDEX_H -#define LUDIC_INDEX_H - -#include "ludic_syntax.h" -#include - -/* ---------- symbol kinds --------------------------------------------------*/ -enum { - LS_UNIT, LS_COMPONENT, LS_FIELD, LS_ARCHETYPE, LS_CONST, LS_VAR, - LS_FN, LS_PARAM, LS_EXTERN, LS_SYSTEM, LS_UI, LS_WIDGET, LS_SCENE, - LS_LAYER, LS_LOCAL, LS_QUERYVAR, LS_STATE, LS_IMPORT -}; - -/* semantic classes, one per token — the source for semantic highlighting */ -enum { - SC_NONE, SC_KEYWORD, SC_TYPE, SC_COMPONENT, SC_ARCHETYPE, SC_SCENE, - SC_LAYER, SC_UI, SC_WIDGET, SC_PROP, SC_FIELD, SC_SYSTEM, SC_FUNCTION, - SC_BUILTIN, SC_PARAM, SC_VARIABLE, SC_CONST, SC_MODVAR, SC_PHASE, - SC_NUMBER, SC_STRING, SC_COMMENT, SC_OPERATOR, SC_ANNOTATION, SC_UNKNOWN -}; - -typedef struct { - int kind; - char name[96]; - char type[96]; /* declared type; for a query var, its component */ - char detail[224]; /* one-line signature, shown in hover and outlines */ - char doc[640]; /* the comment block sitting directly above */ - int tok; /* token index of the NAME */ - int start, end; /* byte span of the name */ - int body_start, body_end; /* span the symbol governs (a block, or the - * whole file for a top-level declaration) */ - int parent; /* enclosing symbol index, -1 at the top level */ - int exported; -} LSym; - -typedef struct { - int line, col, endline, endcol, severity; /* 1 = error, 2 = warning */ - char msg[512]; - char path[1024]; /* empty = this document */ -} LDiag; - -typedef struct LDoc { - char* path; /* filesystem path */ - char* uri; /* file:// URI */ - char* raw; /* the buffer exactly as the editor has it */ - char* text; /* what the lexer sees: `raw`, or — for Markdown — a - * copy with every byte outside a ```ludic fence blanked - * out, so offsets still line up with the real file */ - int version; - int open; /* the editor holds it (so `text` beats the disk) */ - int is_markdown; /* a .md file: only its ```ludic fences are Ludic */ - LLex lex; - int* match; /* per token: matching brace/bracket token, else -1 */ - unsigned char* cls; /* per token: semantic class */ - LSym* sym; int nsym, symcap; - char** imports; int nimport; - int had_diags; /* we published a non-empty list for it last time */ - int is_unit; /* declares `game` or `module` */ - int is_module; - char unit[96]; -} LDoc; - -typedef struct { - LDoc** d; int n, cap; - char* root; /* workspace root directory */ -} LIndex; - -/* ---------- small helpers -------------------------------------------------*/ -static void lsym_reserve(LDoc* D){ - if (D->nsym >= D->symcap){ D->symcap = D->symcap ? D->symcap * 2 : 128; D->sym = realloc(D->sym, D->symcap * sizeof(LSym)); } -} -static void lcpy(char* dst, int cap, const char* s, int n){ - if (n >= cap) n = cap - 1; if (n < 0) n = 0; - memcpy(dst, s, n); dst[n] = 0; -} -static void lcatf(char* dst, int cap, const char* fmt, ...){ - int used = (int)strlen(dst); if (used >= cap - 1) return; - va_list ap; va_start(ap, fmt); vsnprintf(dst + used, cap - used, fmt, ap); va_end(ap); -} - -/* ---------- positions ----------------------------------------------------- - * LSP counts characters in UTF-16 code units by default. Ludic source is UTF-8 - * and string literals really do carry non-ASCII (the language ships a Unicode - * TrueType path), so the conversion is not optional. */ -static int lutf16_len(const char* s, int nbytes){ - int u = 0; - for (int i = 0; i < nbytes; ){ - unsigned char c = (unsigned char)s[i]; - if (c < 0x80){ i += 1; u += 1; } - else if (c < 0xE0){ i += 2; u += 1; } - else if (c < 0xF0){ i += 3; u += 1; } - else { i += 4; u += 2; } /* astral planes are a surrogate pair */ - } - return u; -} -static int ldoc_line_of(const LDoc* D, int off){ - int lo = 0, hi = D->lex.nline - 1; - while (lo < hi){ int mid = (lo + hi + 1) / 2; if (D->lex.linestart[mid] <= off) lo = mid; else hi = mid - 1; } - return lo; -} -static int ldoc_col_of(const LDoc* D, int off){ - int line = ldoc_line_of(D, off); - return lutf16_len(D->text + D->lex.linestart[line], off - D->lex.linestart[line]); -} -static int ldoc_offset_of(const LDoc* D, int line, int character){ - if (line < 0) return 0; - if (line >= D->lex.nline) return (int)strlen(D->text); - int off = D->lex.linestart[line]; - int end = (line + 1 < D->lex.nline) ? D->lex.linestart[line + 1] : (int)strlen(D->text); - int u = 0; - while (off < end && u < character){ - unsigned char c = (unsigned char)D->text[off]; - if (c < 0x80){ off += 1; u += 1; } - else if (c < 0xE0){ off += 2; u += 1; } - else if (c < 0xF0){ off += 3; u += 1; } - else { off += 4; u += 2; } - } - return off; -} -/* The token the cursor is on. A caret sitting exactly between two tokens - * belongs to the one it is *inside*; only when it is inside none of them does - * the token ending there win — otherwise `st.|guard` resolves to the dot. */ -static int ldoc_tok_at(const LDoc* D, int off){ - int touching = -1; - for (int i = 0; i < D->lex.n; i++){ - const LTok* t = &D->lex.v[i]; - if (t->kind == LT_NL || t->kind == LT_EOF) continue; - if (off >= t->start && off < t->end) return i; - if (off == t->end && touching < 0) touching = i; - if (t->start > off) break; - } - return touching; -} - -/* ---------- brace matching ------------------------------------------------*/ -static void ldoc_match_braces(LDoc* D){ - free(D->match); - D->match = malloc(sizeof(int) * (D->lex.n + 1)); - for (int i = 0; i < D->lex.n; i++) D->match[i] = -1; - int stack[512], top = 0; - for (int i = 0; i < D->lex.n; i++){ - const LTok* t = &D->lex.v[i]; - if (t->kind != LT_OP || ltok_len(t) != 1) continue; - char c = D->text[t->start]; - if (c == '{' || c == '(' || c == '['){ if (top < 512) stack[top++] = i; } - else if (c == '}' || c == ')' || c == ']'){ - if (top > 0){ int o = stack[--top]; D->match[o] = i; D->match[i] = o; } - } - } -} - -/* ---------- doc comments -------------------------------------------------- - * The comment block immediately above a declaration is its documentation — - * the convention the runtime and examples already follow. */ -static void ldoc_collect_doc(LDoc* D, int decl_tok, char* out, int cap){ - out[0] = 0; - int line = D->lex.v[decl_tok].line; - /* walk backwards over comment-only lines */ - int first = -1; - for (int i = decl_tok - 1; i >= 0; i--){ - const LTok* t = &D->lex.v[i]; - if (t->kind == LT_NL) continue; - if (t->kind != LT_COMMENT) break; - if (t->line >= line) break; /* trailing, not leading */ - /* the comment must own its line */ - int p = ltok_prev_sig(&D->lex, i); - if (p >= 0 && D->lex.v[p].line == t->line) break; - if (t->line < line - 1 && first >= 0) break;/* a blank line ends it */ - if (first >= 0 && D->lex.v[first].line != t->line + 1) break; - first = i; line = t->line; - } - if (first < 0) return; - for (int i = first; i < decl_tok; i++){ - const LTok* t = &D->lex.v[i]; - if (t->kind != LT_COMMENT) continue; - int s = t->start + 1; /* skip '#' */ - while (s < t->end && (D->text[s] == ' ' || D->text[s] == '\t' || D->text[s] == '#' || D->text[s] == '*')) s++; - int used = (int)strlen(out); - int n = t->end - s; - if (used + n + 2 >= cap) break; - memcpy(out + used, D->text + s, n); out[used + n] = '\n'; out[used + n + 1] = 0; - } -} - -/* ---------- the shallow parser -------------------------------------------*/ -typedef struct { LDoc* D; int i; } LP; - -static int lp_kind(LP* p){ return p->i < p->D->lex.n ? p->D->lex.v[p->i].kind : LT_EOF; } -static int lp_is(LP* p, const char* s){ return ltok_is(&p->D->lex, p->i, s); } -static void lp_skipnl(LP* p){ while (p->i < p->D->lex.n && (lp_kind(p) == LT_NL || lp_kind(p) == LT_COMMENT)) p->i++; } -static void lp_adv(LP* p){ if (p->i < p->D->lex.n) p->i++; lp_skipnl(p); } -static char* lp_word(LP* p, char* buf, int cap){ - buf[0] = 0; - if (p->i < p->D->lex.n) lcpy(buf, cap, p->D->text + p->D->lex.v[p->i].start, ltok_len(&p->D->lex.v[p->i])); - return buf; -} -/* Consume an identifier-ish token, returning its index (or -1). */ -static int lp_name(LP* p){ - int k = lp_kind(p); - if (k == LT_ID || k == LT_TYPE || k == LT_PHASE || k == LT_KW || k == LT_BOOL){ int t = p->i; lp_adv(p); return t; } - return -1; -} -static int lsym_add(LDoc* D, int kind, int nametok, int parent){ - lsym_reserve(D); - LSym* s = &D->sym[D->nsym]; - memset(s, 0, sizeof(*s)); - s->kind = kind; s->tok = nametok; s->parent = parent; - if (nametok >= 0){ - const LTok* t = &D->lex.v[nametok]; - s->start = t->start; s->end = t->end; - lcpy(s->name, sizeof(s->name), D->text + t->start, ltok_len(t)); - } - s->body_start = 0; s->body_end = (int)strlen(D->text); - return D->nsym++; -} -/* Skip a balanced group starting at the current opener; leaves p after it. */ -static void lp_skip_group(LP* p){ - int m = (p->i < p->D->lex.n) ? p->D->match[p->i] : -1; - if (m < 0){ lp_adv(p); return; } - p->i = m + 1; lp_skipnl(p); -} -/* Read `name: Type` pairs inside the parentheses at p->i, recording params. */ -static void lp_params(LP* p, int owner, int kind, char* sig, int sigcap){ - if (!lp_is(p, "(")) return; - int close = p->D->match[p->i]; - lcatf(sig, sigcap, "("); - lp_adv(p); - int first = 1; - while (p->i < p->D->lex.n && (close < 0 || p->i < close)){ - if (lp_is(p, ")")) break; - if (lp_is(p, ",")){ lp_adv(p); continue; } - int nt = lp_name(p); if (nt < 0){ lp_adv(p); continue; } - char ty[96]; ty[0] = 0; - if (lp_is(p, ":")){ lp_adv(p); int tt = lp_name(p); if (tt >= 0) lcpy(ty, sizeof(ty), p->D->text + p->D->lex.v[tt].start, ltok_len(&p->D->lex.v[tt])); } - int s = lsym_add(p->D, kind, nt, owner); - lcpy(p->D->sym[s].type, sizeof(p->D->sym[s].type), ty, (int)strlen(ty)); - lcatf(sig, sigcap, "%s%s: %s", first ? "" : ", ", p->D->sym[s].name, ty[0] ? ty : "?"); - first = 0; - } - if (close >= 0) p->i = close + 1; - lp_skipnl(p); - lcatf(sig, sigcap, ")"); -} -/* `[Pos, Vel, {Enemy}]` — bind the listed components to the named variables in - * order, skipping {Tag} terms, which filter without binding. */ -static void lp_query_terms(LP* p, int owner, int* vars, int nvars, int scope_start, int scope_end){ - if (!lp_is(p, "[")) return; - int close = p->D->match[p->i]; - lp_adv(p); - int bind = 0; - while (p->i < p->D->lex.n && (close < 0 || p->i < close)){ - if (lp_is(p, "]")) break; - if (lp_is(p, ",")){ lp_adv(p); continue; } - if (lp_is(p, "{")){ /* a filter term */ - int cb = p->D->match[p->i]; lp_adv(p); - int nt = lp_name(p); (void)nt; - if (cb >= 0) p->i = cb + 1; else lp_adv(p); - lp_skipnl(p); continue; - } - int nt = lp_name(p); if (nt < 0){ lp_adv(p); continue; } - if (bind < nvars && vars[bind] >= 0){ - int s = lsym_add(p->D, LS_QUERYVAR, vars[bind], owner); - lcpy(p->D->sym[s].type, sizeof(p->D->sym[s].type), p->D->text + p->D->lex.v[nt].start, ltok_len(&p->D->lex.v[nt])); - p->D->sym[s].body_start = scope_start; p->D->sym[s].body_end = scope_end; - lcatf(p->D->sym[s].detail, sizeof(p->D->sym[s].detail), "%s: %s (query binding)", p->D->sym[s].name, p->D->sym[s].type); - } - bind++; - } - if (close >= 0) p->i = close + 1; - lp_skipnl(p); - if (lp_is(p, "where")) lp_adv(p); /* the condition is ordinary expression */ -} -/* `(a, b)` variable list before `in query` / after the `query` clause. */ -static int lp_varlist(LP* p, int* out, int max){ - int n = 0; - if (!lp_is(p, "(")) return 0; - int close = p->D->match[p->i]; - lp_adv(p); - while (p->i < p->D->lex.n && (close < 0 || p->i < close)){ - if (lp_is(p, ")")) break; - if (lp_is(p, ",")){ lp_adv(p); continue; } - int nt = lp_name(p); if (nt < 0){ lp_adv(p); continue; } - if (n < max) out[n++] = nt; - } - if (close >= 0) p->i = close + 1; - lp_skipnl(p); - return n; -} - -static void lp_block(LP* p, int owner, int scope_end); - -/* statements — we only care about what BINDS a name or opens a scope */ -static void lp_stmt(LP* p, int owner, int scope_end){ - LDoc* D = p->D; - if (lp_is(p, "let")){ - lp_adv(p); int nt = lp_name(p); if (nt < 0) return; - char ty[96]; ty[0] = 0; - if (lp_is(p, ":")){ lp_adv(p); int tt = lp_name(p); if (tt >= 0) lcpy(ty, sizeof(ty), D->text + D->lex.v[tt].start, ltok_len(&D->lex.v[tt])); } - int s = lsym_add(D, LS_LOCAL, nt, owner); - lcpy(D->sym[s].type, sizeof(D->sym[s].type), ty, (int)strlen(ty)); - D->sym[s].body_start = D->lex.v[nt].start; D->sym[s].body_end = scope_end; - return; - } - if (lp_is(p, "for")){ - lp_adv(p); - if (lp_is(p, "(")){ /* for (a, b) in query [...] */ - int vars[16]; int nv = lp_varlist(p, vars, 16); - if (lp_is(p, "in")) lp_adv(p); - if (lp_is(p, "query")) lp_adv(p); - int body_end = scope_end; - /* the loop body is the next {...}; bindings live there */ - lp_query_terms(p, owner, vars, nv, D->lex.v[p->i < D->lex.n ? p->i : D->lex.n - 1].start, body_end); - return; - } - int nt = lp_name(p); /* for i in a .. b */ - if (nt >= 0){ - int s = lsym_add(D, LS_LOCAL, nt, owner); - lcpy(D->sym[s].type, sizeof(D->sym[s].type), "int", 3); - D->sym[s].body_start = D->lex.v[nt].start; D->sym[s].body_end = scope_end; - } - return; - } - if (lp_is(p, "state")){ /* machine { state Idle = 0 {…} } */ - lp_adv(p); int nt = lp_name(p); - if (nt >= 0) lsym_add(D, LS_STATE, nt, owner); - return; - } - lp_adv(p); -} - -static void lp_block(LP* p, int owner, int scope_end){ - if (!lp_is(p, "{")) return; - int close = p->D->match[p->i]; - int end = close >= 0 ? p->D->lex.v[close].start : scope_end; - lp_adv(p); - while (p->i < p->D->lex.n && lp_kind(p) != LT_EOF){ - if (close >= 0 && p->i >= close) break; - if (lp_is(p, "}")) break; - if (lp_is(p, "{")){ lp_block(p, owner, end); continue; } - int before = p->i; - lp_stmt(p, owner, end); - if (p->i == before) lp_adv(p); - } - if (close >= 0) p->i = close + 1; else lp_adv(p); - lp_skipnl(p); -} - -/* `panel id=Root w=288 { … }` — each id= mints a UI_ handle. */ -static void lp_widget(LP* p, int owner, int uisym){ - LDoc* D = p->D; - int type_tok = lp_name(p); if (type_tok < 0) return; - while (p->i < D->lex.n && lp_kind(p) == LT_ID && ltok_is(&D->lex, ltok_next_sig(&D->lex, p->i) < 0 ? p->i : ltok_next_sig(&D->lex, p->i), "=")){ - int key = p->i; char kb[64]; lcpy(kb, sizeof(kb), D->text + D->lex.v[key].start, ltok_len(&D->lex.v[key])); - lp_adv(p); /* key */ - if (lp_is(p, "=")) lp_adv(p); /* '=' */ - if (!strcmp(kb, "id")){ - int nt = lp_name(p); - if (nt >= 0){ - int s = lsym_add(D, LS_WIDGET, nt, uisym); - snprintf(D->sym[s].name, sizeof(D->sym[s].name), "UI_%.*s", - ltok_len(&D->lex.v[nt]), D->text + D->lex.v[nt].start); - lcatf(D->sym[s].detail, sizeof(D->sym[s].detail), "%s widget handle", - (const char*)(D->text + D->lex.v[type_tok].start)); - lcpy(D->sym[s].type, sizeof(D->sym[s].type), "int", 3); - } - } else { - /* skip one value expression: stop at the next `key=` or at a brace */ - while (p->i < D->lex.n && lp_kind(p) != LT_EOF && !lp_is(p, "{") && !lp_is(p, "}")){ - if (lp_is(p, "(") || lp_is(p, "[")){ lp_skip_group(p); continue; } - int nx = ltok_next_sig(&D->lex, p->i); - if (lp_kind(p) == LT_ID && nx >= 0 && ltok_is(&D->lex, nx, "=")) break; - lp_adv(p); - } - } - } - if (lp_is(p, "{")){ - int close = D->match[p->i]; - lp_adv(p); - while (p->i < D->lex.n && lp_kind(p) != LT_EOF && !lp_is(p, "}")){ - if (close >= 0 && p->i >= close) break; - int before = p->i; - lp_widget(p, owner, uisym); - if (p->i == before) lp_adv(p); - } - if (close >= 0) p->i = close + 1; else lp_adv(p); - lp_skipnl(p); - } -} - -/* one top-level declaration */ -static void lp_decl(LP* p, int parent){ - LDoc* D = p->D; - char w[96]; lp_word(p, w, sizeof(w)); - int decl_tok = p->i; - - if (!strcmp(w, "import")){ - lp_adv(p); - if (lp_kind(p) == LT_STR){ - const LTok* t = &D->lex.v[p->i]; - int n = ltok_len(t) - 2; if (n < 0) n = 0; - char* rel = malloc(n + 1); memcpy(rel, D->text + t->start + 1, n); rel[n] = 0; - D->imports = realloc(D->imports, (D->nimport + 1) * sizeof(char*)); - D->imports[D->nimport++] = rel; - int s = lsym_add(D, LS_IMPORT, p->i, parent); - lcpy(D->sym[s].name, sizeof(D->sym[s].name), rel, (int)strlen(rel)); - lp_adv(p); - } - return; - } - if (!strcmp(w, "property") || !strcmp(w, "model")){ - int is_comp = !strcmp(w, "property"); - lp_adv(p); int nt = lp_name(p); if (nt < 0) return; - int s = lsym_add(D, is_comp ? LS_COMPONENT : LS_ARCHETYPE, nt, parent); - ldoc_collect_doc(D, decl_tok, D->sym[s].doc, sizeof(D->sym[s].doc)); - while (lp_kind(p) == LT_ANNO) lp_adv(p); - snprintf(D->sym[s].detail, sizeof(D->sym[s].detail), "%s %s {", - is_comp ? "property" : "model", D->sym[s].name); - if (!lp_is(p, "{")) return; - int close = D->match[p->i]; - D->sym[s].body_start = D->lex.v[p->i].start; - D->sym[s].body_end = close >= 0 ? D->lex.v[close].end : (int)strlen(D->text); - lp_adv(p); - int first = 1; - while (p->i < D->lex.n && lp_kind(p) != LT_EOF && !lp_is(p, "}")){ - if (close >= 0 && p->i >= close) break; - if (lp_is(p, ",")){ lp_adv(p); continue; } - int ft = lp_name(p); if (ft < 0){ lp_adv(p); continue; } - if (is_comp){ - int f = lsym_add(D, LS_FIELD, ft, s); - if (lp_is(p, ":")){ - lp_adv(p); int tt = lp_name(p); - if (tt >= 0) lcpy(D->sym[f].type, sizeof(D->sym[f].type), D->text + D->lex.v[tt].start, ltok_len(&D->lex.v[tt])); - } - lcatf(D->sym[f].detail, sizeof(D->sym[f].detail), "%s.%s: %s", D->sym[s].name, D->sym[f].name, D->sym[f].type); - if (lp_is(p, "=")){ lp_adv(p); while (p->i < D->lex.n && !lp_is(p, ",") && !lp_is(p, "}") && lp_kind(p) != LT_EOF){ if (lp_is(p, "(") || lp_is(p, "{") || lp_is(p, "[")) lp_skip_group(p); else lp_adv(p); } } - lcatf(D->sym[s].detail, sizeof(D->sym[s].detail), "%s %s: %s", first ? "" : ",", D->sym[f].name, D->sym[f].type); - } else { - lcatf(D->sym[s].detail, sizeof(D->sym[s].detail), "%s %.*s", first ? "" : ",", - ltok_len(&D->lex.v[ft]), D->text + D->lex.v[ft].start); - } - first = 0; - } - lcatf(D->sym[s].detail, sizeof(D->sym[s].detail), " }"); - if (close >= 0) p->i = close + 1; else lp_adv(p); - lp_skipnl(p); - return; - } - if (!strcmp(w, "const") || !strcmp(w, "var")){ - int kind = !strcmp(w, "const") ? LS_CONST : LS_VAR; - lp_adv(p); int nt = lp_name(p); if (nt < 0) return; - int s = lsym_add(D, kind, nt, parent); - ldoc_collect_doc(D, decl_tok, D->sym[s].doc, sizeof(D->sym[s].doc)); - if (lp_is(p, ":")){ lp_adv(p); int tt = lp_name(p); if (tt >= 0) lcpy(D->sym[s].type, sizeof(D->sym[s].type), D->text + D->lex.v[tt].start, ltok_len(&D->lex.v[tt])); } - lcatf(D->sym[s].detail, sizeof(D->sym[s].detail), "%s %s: %s", w, D->sym[s].name, D->sym[s].type); - while (p->i < D->lex.n && lp_kind(p) != LT_NL && lp_kind(p) != LT_EOF){ - if (lp_is(p, "(") || lp_is(p, "{") || lp_is(p, "[")) lp_skip_group(p); else p->i++; - } - lp_skipnl(p); - return; - } - if (!strcmp(w, "extern")){ - lp_adv(p); if (lp_is(p, "fn")) lp_adv(p); - int nt = lp_name(p); if (nt < 0) return; - int s = lsym_add(D, LS_EXTERN, nt, parent); - ldoc_collect_doc(D, decl_tok, D->sym[s].doc, sizeof(D->sym[s].doc)); - char sig[224]; snprintf(sig, sizeof(sig), "extern fn %s", D->sym[s].name); - lp_params(p, s, LS_PARAM, sig, sizeof(sig)); - if (lp_is(p, "->")){ lp_adv(p); int tt = lp_name(p); if (tt >= 0){ lcpy(D->sym[s].type, sizeof(D->sym[s].type), D->text + D->lex.v[tt].start, ltok_len(&D->lex.v[tt])); lcatf(sig, sizeof(sig), " -> %s", D->sym[s].type); } } - lcpy(D->sym[s].detail, sizeof(D->sym[s].detail), sig, (int)strlen(sig)); - while (p->i < D->lex.n && lp_kind(p) != LT_NL && lp_kind(p) != LT_EOF) p->i++; - lp_skipnl(p); - return; - } - if (!strcmp(w, "fn") || !strcmp(w, "pure") || !strcmp(w, "export")){ - int exported = !strcmp(w, "export"); - if (!strcmp(w, "pure") || exported){ lp_adv(p); if (lp_is(p, "pure")) lp_adv(p); } - if (lp_is(p, "fn")) lp_adv(p); - int nt = lp_name(p); if (nt < 0) return; - int s = lsym_add(D, LS_FN, nt, parent); - D->sym[s].exported = exported; - ldoc_collect_doc(D, decl_tok, D->sym[s].doc, sizeof(D->sym[s].doc)); - char sig[224]; snprintf(sig, sizeof(sig), "%sfn %s", exported ? "export " : "", D->sym[s].name); - lp_params(p, s, LS_PARAM, sig, sizeof(sig)); - if (lp_is(p, "->")){ lp_adv(p); int tt = lp_name(p); if (tt >= 0) lcpy(D->sym[s].type, sizeof(D->sym[s].type), D->text + D->lex.v[tt].start, ltok_len(&D->lex.v[tt])); } - lcatf(sig, sizeof(sig), " -> %s", D->sym[s].type[0] ? D->sym[s].type : "void"); - lcpy(D->sym[s].detail, sizeof(D->sym[s].detail), sig, (int)strlen(sig)); - /* contracts sit between the signature and the body */ - while (lp_is(p, "requires") || lp_is(p, "ensures") || lp_is(p, "invariant") || lp_is(p, "effects")){ - lp_adv(p); - while (p->i < D->lex.n && lp_kind(p) != LT_NL && lp_kind(p) != LT_EOF && !lp_is(p, "{")){ - if (lp_is(p, "(") || lp_is(p, "[")) lp_skip_group(p); else p->i++; - } - lp_skipnl(p); - } - if (lp_is(p, "{")){ - int close = D->match[p->i]; - D->sym[s].body_start = D->lex.v[p->i].start; - D->sym[s].body_end = close >= 0 ? D->lex.v[close].end : (int)strlen(D->text); - /* params are visible for the whole body */ - for (int q = 0; q < D->nsym; q++) if (D->sym[q].parent == s && D->sym[q].kind == LS_PARAM){ - D->sym[q].body_start = D->sym[s].body_start; D->sym[q].body_end = D->sym[s].body_end; - } - lp_block(p, s, D->sym[s].body_end); - } - return; - } - if (!strcmp(w, "handler") || !strcmp(w, "edge")){ - if (!strcmp(w, "edge")){ lp_adv(p); if (!lp_is(p, "handler")) return; } - lp_adv(p); - int nt = lp_name(p); if (nt < 0) return; - int s = lsym_add(D, LS_SYSTEM, nt, parent); - ldoc_collect_doc(D, decl_tok, D->sym[s].doc, sizeof(D->sym[s].doc)); - lcpy(D->sym[s].type, sizeof(D->sym[s].type), "Update", 6); - while (lp_kind(p) == LT_ANNO) lp_adv(p); - int vars[16]; int nv = 0; int have_query = 0; - for (;;){ - if (lp_is(p, "phase")){ lp_adv(p); int tt = lp_name(p); if (tt >= 0) lcpy(D->sym[s].type, sizeof(D->sym[s].type), D->text + D->lex.v[tt].start, ltok_len(&D->lex.v[tt])); } - else if (lp_is(p, "query")){ lp_adv(p); have_query = 1; nv = lp_varlist(p, vars, 16); break; } - else if (lp_is(p, "reads") || lp_is(p, "writes") || lp_is(p, "uses") || lp_is(p, "effects")){ lp_adv(p); if (lp_is(p, "[")) lp_skip_group(p); } - else if (lp_is(p, "needs")){ lp_adv(p); lp_name(p); if (lp_is(p, "[")) lp_skip_group(p); } - else break; - lp_skipnl(p); - } - lcatf(D->sym[s].detail, sizeof(D->sym[s].detail), "system %s phase %s", D->sym[s].name, D->sym[s].type); - /* find the body first, so query bindings can be scoped to it */ - int body_open = p->i; - if (have_query){ - int save = p->i; - /* the query terms come before the body */ - int scan = p->i; - while (scan < D->lex.n && !ltok_is(&D->lex, scan, "{") && D->lex.v[scan].kind != LT_EOF) scan++; - int close = (scan < D->lex.n) ? D->match[scan] : -1; - int bs = (scan < D->lex.n) ? D->lex.v[scan].start : 0; - int be = close >= 0 ? D->lex.v[close].end : (int)strlen(D->text); - p->i = save; - lp_query_terms(p, s, vars, nv, bs, be); - body_open = p->i; - } - (void)body_open; - if (lp_is(p, "{")){ - int close = D->match[p->i]; - D->sym[s].body_start = D->lex.v[p->i].start; - D->sym[s].body_end = close >= 0 ? D->lex.v[close].end : (int)strlen(D->text); - lp_block(p, s, D->sym[s].body_end); - } - return; - } - if (!strcmp(w, "ui")){ - lp_adv(p); int nt = lp_name(p); if (nt < 0) return; - int s = lsym_add(D, LS_UI, nt, parent); - ldoc_collect_doc(D, decl_tok, D->sym[s].doc, sizeof(D->sym[s].doc)); - lcatf(D->sym[s].detail, sizeof(D->sym[s].detail), "ui %s", D->sym[s].name); - /* the block name is a handle too */ - { int h = lsym_add(D, LS_WIDGET, nt, s); - snprintf(D->sym[h].name, sizeof(D->sym[h].name), "UI_%s", D->sym[s].name); - lcpy(D->sym[h].type, sizeof(D->sym[h].type), "int", 3); - lcatf(D->sym[h].detail, sizeof(D->sym[h].detail), "root handle of ui %s", D->sym[s].name); } - if (lp_is(p, "{")){ - int close = D->match[p->i]; - D->sym[s].body_start = D->lex.v[p->i].start; - D->sym[s].body_end = close >= 0 ? D->lex.v[close].end : (int)strlen(D->text); - lp_adv(p); - while (p->i < D->lex.n && lp_kind(p) != LT_EOF && !lp_is(p, "}")){ - if (close >= 0 && p->i >= close) break; - int before = p->i; - lp_widget(p, s, s); - if (p->i == before) lp_adv(p); - } - if (close >= 0) p->i = close + 1; else lp_adv(p); - lp_skipnl(p); - } - return; - } - if (!strcmp(w, "scene")){ - lp_adv(p); int nt = lp_name(p); if (nt < 0) return; - int s = lsym_add(D, LS_SCENE, nt, parent); - ldoc_collect_doc(D, decl_tok, D->sym[s].doc, sizeof(D->sym[s].doc)); - int start = 0; - if (lp_is(p, "start")){ start = 1; lp_adv(p); } - lcatf(D->sym[s].detail, sizeof(D->sym[s].detail), "scene %s%s", D->sym[s].name, start ? " start" : ""); - if (lp_is(p, "{")){ - int close = D->match[p->i]; - D->sym[s].body_start = D->lex.v[p->i].start; - D->sym[s].body_end = close >= 0 ? D->lex.v[close].end : (int)strlen(D->text); - lp_adv(p); - while (p->i < D->lex.n && lp_kind(p) != LT_EOF && !lp_is(p, "}")){ - if (close >= 0 && p->i >= close) break; - int before = p->i; - if (lp_is(p, "on")){ lp_adv(p); lp_name(p); lp_block(p, s, D->sym[s].body_end); } - else if (lp_is(p, "layer")){ - lp_adv(p); int lt = lp_name(p); - int ls = lt >= 0 ? lsym_add(D, LS_LAYER, lt, s) : -1; - if (ls >= 0) lcatf(D->sym[ls].detail, sizeof(D->sym[ls].detail), "layer %s of scene %s", D->sym[ls].name, D->sym[s].name); - if (lp_is(p, "{")){ - int lc = D->match[p->i]; - if (ls >= 0){ D->sym[ls].body_start = D->lex.v[p->i].start; D->sym[ls].body_end = lc >= 0 ? D->lex.v[lc].end : D->sym[s].body_end; } - lp_adv(p); - while (p->i < D->lex.n && lp_kind(p) != LT_EOF && !lp_is(p, "}")){ - if (lc >= 0 && p->i >= lc) break; - int b2 = p->i; lp_decl(p, ls >= 0 ? ls : s); - if (p->i == b2) lp_adv(p); - } - if (lc >= 0) p->i = lc + 1; else lp_adv(p); - lp_skipnl(p); - } - } else lp_adv(p); - if (p->i == before) lp_adv(p); - } - if (close >= 0) p->i = close + 1; else lp_adv(p); - lp_skipnl(p); - } - return; - } - lp_adv(p); -} - -static void ldoc_parse(LDoc* D){ - D->nsym = 0; - for (int i = 0; i < D->nimport; i++) free(D->imports[i]); - free(D->imports); D->imports = 0; D->nimport = 0; - D->is_unit = 0; D->is_module = 0; D->unit[0] = 0; - - LP p = { D, 0 }; - lp_skipnl(&p); - while (lp_is(&p, "import")) { lp_decl(&p, -1); lp_skipnl(&p); } - int unit_parent = -1; - if (lp_is(&p, "program") || lp_is(&p, "program")){ - D->is_module = lp_is(&p, "program"); - D->is_unit = 1; - lp_adv(&p); - int nt = lp_name(&p); - if (nt >= 0){ - unit_parent = lsym_add(D, LS_UNIT, nt, -1); - lcpy(D->unit, sizeof(D->unit), D->sym[unit_parent].name, (int)strlen(D->sym[unit_parent].name)); - lcatf(D->sym[unit_parent].detail, sizeof(D->sym[unit_parent].detail), "%s %s", D->is_module ? "program" : "program", D->unit); - } - if (lp_is(&p, "{")){ - int close = D->match[p.i]; - if (unit_parent >= 0){ - D->sym[unit_parent].body_start = D->lex.v[p.i].start; - D->sym[unit_parent].body_end = close >= 0 ? D->lex.v[close].end : (int)strlen(D->text); - } - lp_adv(&p); - while (p.i < D->lex.n && lp_kind(&p) != LT_EOF && !lp_is(&p, "}")){ - if (close >= 0 && p.i >= close) break; - int before = p.i; lp_decl(&p, unit_parent); - if (p.i == before) lp_adv(&p); - } - } - return; - } - /* A fragment: an imported file is a bare list of declarations. */ - while (p.i < D->lex.n && lp_kind(&p) != LT_EOF){ - int before = p.i; lp_decl(&p, -1); - if (p.i == before) lp_adv(&p); - } -} -#endif /* LUDIC_INDEX_H */ diff --git a/tools/ludic-tools/ludic_json.h b/tools/ludic-tools/ludic_json.h deleted file mode 100644 index 0aee150a..00000000 --- a/tools/ludic-tools/ludic_json.h +++ /dev/null @@ -1,191 +0,0 @@ -/* ============================================================================ - * ludic_json.h — just enough JSON for LSP, and no dependencies. - * - * The rest of this toolchain is C with no third-party libraries, and the - * language server should not be the thing that drags a package manager into a - * project whose whole premise is a self-contained native pipeline. This is a - * recursive-descent reader and an escaping writer; nothing more. - * ==========================================================================*/ -#ifndef LUDIC_JSON_H -#define LUDIC_JSON_H - -#include -#include -#include -#include -#include - -enum { JNULL, JBOOL, JNUM, JSTR, JARR, JOBJ }; - -typedef struct JVal JVal; -struct JVal { - int t; - double num; - int b; - char* s; /* JSTR: decoded UTF-8 */ - JVal** kids; char** keys; int n, cap; -}; - -static JVal* jnew(int t){ JVal* v = calloc(1, sizeof(JVal)); v->t = t; return v; } -static void jfree(JVal* v){ - if (!v) return; - for (int i = 0; i < v->n; i++){ jfree(v->kids[i]); free(v->keys ? v->keys[i] : 0); } - free(v->kids); free(v->keys); free(v->s); free(v); -} -static void jpush(JVal* v, const char* key, JVal* kid){ - if (v->n >= v->cap){ - v->cap = v->cap ? v->cap * 2 : 8; - v->kids = realloc(v->kids, v->cap * sizeof(JVal*)); - v->keys = realloc(v->keys, v->cap * sizeof(char*)); - } - v->keys[v->n] = key ? strdup(key) : 0; - v->kids[v->n++] = kid; -} - -static void jskip(const char** p){ while (**p == ' ' || **p == '\t' || **p == '\n' || **p == '\r') (*p)++; } -static JVal* jparse_at(const char** p); - -static void jutf8(char** o, unsigned cp){ - if (cp < 0x80) *(*o)++ = (char)cp; - else if (cp < 0x800){ *(*o)++ = (char)(0xC0 | (cp >> 6)); *(*o)++ = (char)(0x80 | (cp & 63)); } - else if (cp < 0x10000){ *(*o)++ = (char)(0xE0 | (cp >> 12)); *(*o)++ = (char)(0x80 | ((cp >> 6) & 63)); *(*o)++ = (char)(0x80 | (cp & 63)); } - else { *(*o)++ = (char)(0xF0 | (cp >> 18)); *(*o)++ = (char)(0x80 | ((cp >> 12) & 63)); *(*o)++ = (char)(0x80 | ((cp >> 6) & 63)); *(*o)++ = (char)(0x80 | (cp & 63)); } -} -static char* jparse_string(const char** p){ - if (**p != '"') return 0; - (*p)++; - const char* s = *p; - size_t cap = strlen(s) + 1; - char* out = malloc(cap); char* o = out; - while (**p && **p != '"'){ - if (**p == '\\'){ - (*p)++; - char c = **p; (*p)++; - switch (c){ - case 'n': *o++ = '\n'; break; - case 't': *o++ = '\t'; break; - case 'r': *o++ = '\r'; break; - case 'b': *o++ = '\b'; break; - case 'f': *o++ = '\f'; break; - case 'u': { - unsigned cp = (unsigned)strtoul((char[5]){ (*p)[0], (*p)[1], (*p)[2], (*p)[3], 0 }, 0, 16); - *p += 4; - if (cp >= 0xD800 && cp < 0xDC00 && (*p)[0] == '\\' && (*p)[1] == 'u'){ - unsigned lo = (unsigned)strtoul((char[5]){ (*p)[2], (*p)[3], (*p)[4], (*p)[5], 0 }, 0, 16); - *p += 6; - cp = 0x10000 + ((cp - 0xD800) << 10) + (lo - 0xDC00); - } - jutf8(&o, cp); - break; - } - default: *o++ = c; - } - } else *o++ = *(*p)++; - } - if (**p == '"') (*p)++; - *o = 0; - return out; -} -static JVal* jparse_at(const char** p){ - jskip(p); - char c = **p; - if (c == '{'){ - (*p)++; JVal* v = jnew(JOBJ); - for (;;){ - jskip(p); - if (**p == '}'){ (*p)++; break; } - char* k = jparse_string(p); - jskip(p); if (**p == ':') (*p)++; - JVal* kid = jparse_at(p); - jpush(v, k ? k : "", kid); - free(k); - jskip(p); - if (**p == ',') (*p)++; - else if (**p == '}'){ (*p)++; break; } - else if (!**p) break; - } - return v; - } - if (c == '['){ - (*p)++; JVal* v = jnew(JARR); - for (;;){ - jskip(p); - if (**p == ']'){ (*p)++; break; } - jpush(v, 0, jparse_at(p)); - jskip(p); - if (**p == ',') (*p)++; - else if (**p == ']'){ (*p)++; break; } - else if (!**p) break; - } - return v; - } - if (c == '"'){ JVal* v = jnew(JSTR); v->s = jparse_string(p); return v; } - if (!strncmp(*p, "true", 4)){ *p += 4; JVal* v = jnew(JBOOL); v->b = 1; return v; } - if (!strncmp(*p, "false", 5)){ *p += 5; JVal* v = jnew(JBOOL); v->b = 0; return v; } - if (!strncmp(*p, "null", 4)){ *p += 4; return jnew(JNULL); } - { char* end; double d = strtod(*p, &end); if (end != *p){ *p = end; JVal* v = jnew(JNUM); v->num = d; return v; } } - (*p)++; /* unparsable: step past it */ - return jnew(JNULL); -} -static JVal* jparse(const char* text){ const char* p = text; return jparse_at(&p); } - -static JVal* jget(JVal* v, const char* key){ - if (!v || v->t != JOBJ) return 0; - for (int i = 0; i < v->n; i++) if (v->keys[i] && !strcmp(v->keys[i], key)) return v->kids[i]; - return 0; -} -static JVal* jat(JVal* v, int i){ return (v && i >= 0 && i < v->n) ? v->kids[i] : 0; } -static const char* jstr(JVal* v, const char* def){ return (v && v->t == JSTR && v->s) ? v->s : def; } -static int jint(JVal* v, int def){ return (v && v->t == JNUM) ? (int)v->num : def; } -static int jbool(JVal* v, int def){ return v ? (v->t == JBOOL ? v->b : (v->t == JNUM ? v->num != 0 : def)) : def; } -/* dotted lookup: jpath(msg, "params.textDocument.uri") */ -static JVal* jpath(JVal* v, const char* path){ - char buf[256]; snprintf(buf, sizeof(buf), "%s", path); - char* save = 0; - for (char* tok = strtok_r(buf, ".", &save); tok; tok = strtok_r(0, ".", &save)){ - v = jget(v, tok); - if (!v) return 0; - } - return v; -} - -/* ---------- writing -------------------------------------------------------*/ -typedef struct { char* b; size_t n, cap; } JSB; -static void jsb_ensure(JSB* s, size_t add){ - if (s->n + add + 1 > s->cap){ s->cap = (s->n + add + 1) * 2; s->b = realloc(s->b, s->cap); } -} -static void jsb_add(JSB* s, const char* z, size_t l){ jsb_ensure(s, l); memcpy(s->b + s->n, z, l); s->n += l; s->b[s->n] = 0; } -static void jsb_puts(JSB* s, const char* z){ jsb_add(s, z, strlen(z)); } -static void jsb_putc(JSB* s, char c){ jsb_add(s, &c, 1); } -static void jsb_putf(JSB* s, const char* fmt, ...){ - char tmp[1024]; - va_list ap; va_start(ap, fmt); - int n = vsnprintf(tmp, sizeof(tmp), fmt, ap); - va_end(ap); - if (n < (int)sizeof(tmp)){ jsb_add(s, tmp, n); return; } - char* big = malloc(n + 1); - va_start(ap, fmt); vsnprintf(big, n + 1, fmt, ap); va_end(ap); - jsb_add(s, big, n); free(big); -} -/* Escape a UTF-8 string as a JSON string literal, quotes included. */ -static void jsb_str(JSB* s, const char* z){ - jsb_putc(s, '"'); - if (!z) z = ""; - for (const unsigned char* p = (const unsigned char*)z; *p; p++){ - switch (*p){ - case '"': jsb_puts(s, "\\\""); break; - case '\\': jsb_puts(s, "\\\\"); break; - case '\n': jsb_puts(s, "\\n"); break; - case '\r': jsb_puts(s, "\\r"); break; - case '\t': jsb_puts(s, "\\t"); break; - default: - if (*p < 0x20) jsb_putf(s, "\\u%04x", *p); - else jsb_putc(s, (char)*p); - } - } - jsb_putc(s, '"'); -} -static void jsb_kv_str(JSB* s, const char* k, const char* v){ jsb_str(s, k); jsb_putc(s, ':'); jsb_str(s, v); } -static void jsb_kv_int(JSB* s, const char* k, long v){ jsb_str(s, k); jsb_putf(s, ":%ld", v); } -static void jsb_kv_bool(JSB* s, const char* k, int v){ jsb_str(s, k); jsb_puts(s, v ? ":true" : ":false"); } -#endif /* LUDIC_JSON_H */ diff --git a/tools/ludic-tools/ludic_lsp.c b/tools/ludic-tools/ludic_lsp.c deleted file mode 100644 index 7ed7ee8a..00000000 --- a/tools/ludic-tools/ludic_lsp.c +++ /dev/null @@ -1,1265 +0,0 @@ -/* ============================================================================ - * ludic-lsp — the Ludic language server. - * - * Speaks LSP 3.17 over stdio, so it is the IDE-agnostic half of this toolchain: - * VS Code, JetBrains, Neovim, Helix, Emacs, Sublime and Zed all drive the same - * binary, and an editor nobody has written a plugin for yet still gets - * completion, diagnostics, hover and formatting by pointing at it. - * - * It answers structural questions itself (from ludic_index.h, which keeps - * parsing after an error the way a compiler must not), and defers questions of - * correctness to `ludicc` — the compiler stays the single source of truth about - * whether a program is valid. - * - * Markdown is a first-class input: a ```ludic fence in a .md gets the same - * highlighting, hover and diagnostics as a .ludic file. - * ==========================================================================*/ -#define _GNU_SOURCE -#include "ludic_workspace.h" -#include "ludic_fmt.h" -#include "ludic_json.h" -#include - -/* ---------- server state --------------------------------------------------*/ -static LIndex X; -static char* g_ludicc = 0; /* path to the compiler, if we found one */ -static int g_indent = 2; -static int g_compiler_diags = 1; -static int g_shutdown = 0; -static int g_utf8_positions = 0; /* the client accepted utf-8 offsets */ -static FILE* g_log = 0; - -static void lg(const char* fmt, ...){ - if (!g_log) return; - va_list ap; va_start(ap, fmt); vfprintf(g_log, fmt, ap); va_end(ap); - fputc('\n', g_log); fflush(g_log); -} - -/* ---------- framing -------------------------------------------------------*/ -static void send_raw(const char* body){ - printf("Content-Length: %zu\r\n\r\n%s", strlen(body), body); - fflush(stdout); -} -static void send_result(JVal* id, const char* result_json){ - JSB s = {0}; - jsb_puts(&s, "{\"jsonrpc\":\"2.0\",\"id\":"); - if (!id) jsb_puts(&s, "null"); - else if (id->t == JSTR) jsb_str(&s, id->s); - else jsb_putf(&s, "%ld", (long)id->num); - jsb_puts(&s, ",\"result\":"); - jsb_puts(&s, result_json && *result_json ? result_json : "null"); - jsb_puts(&s, "}"); - send_raw(s.b); free(s.b); -} -static void send_notify(const char* method, const char* params_json){ - JSB s = {0}; - jsb_puts(&s, "{\"jsonrpc\":\"2.0\",\"method\":"); - jsb_str(&s, method); - jsb_puts(&s, ",\"params\":"); - jsb_puts(&s, params_json ? params_json : "null"); - jsb_puts(&s, "}"); - send_raw(s.b); free(s.b); -} -/* Read one Content-Length framed message. NULL at EOF. */ -static char* read_message(void){ - char line[8192]; - long len = -1; - for (;;){ - if (!fgets(line, sizeof(line), stdin)) return 0; - if (line[0] == '\r' || line[0] == '\n') break; - if (!strncasecmp(line, "Content-Length:", 15)) len = strtol(line + 15, 0, 10); - } - if (len <= 0) return 0; - char* buf = malloc(len + 1); - long got = 0; - while (got < len){ - size_t r = fread(buf + got, 1, len - got, stdin); - if (!r) break; - got += r; - } - buf[got] = 0; - return buf; -} - -/* ---------- position helpers ---------------------------------------------*/ -static int pos_char(LDoc* D, int off){ - if (g_utf8_positions){ - int line = ldoc_line_of(D, off); - return off - D->lex.linestart[line]; - } - return ldoc_col_of(D, off); -} -static void put_pos(JSB* s, LDoc* D, int off){ - jsb_putf(s, "{\"line\":%d,\"character\":%d}", ldoc_line_of(D, off), pos_char(D, off)); -} -static void put_range(JSB* s, LDoc* D, int a, int b){ - jsb_puts(s, "{\"start\":"); put_pos(s, D, a); - jsb_puts(s, ",\"end\":"); put_pos(s, D, b); - jsb_puts(s, "}"); -} -static void put_location(JSB* s, LDoc* D, int a, int b){ - jsb_puts(s, "{\"uri\":"); jsb_str(s, D->uri); - jsb_puts(s, ",\"range\":"); put_range(s, D, a, b); - jsb_puts(s, "}"); -} - -/* ---------- diagnostics ---------------------------------------------------*/ -typedef struct { LDoc* doc; LDiag* v; int n, cap; } DiagSet; -static void diag_add(DiagSet* ds, LDoc* D, int line, int col, int endline, int endcol, int sev, const char* msg){ - if (ds->n >= ds->cap){ ds->cap = ds->cap ? ds->cap * 2 : 16; ds->v = realloc(ds->v, ds->cap * sizeof(LDiag)); } - LDiag* d = &ds->v[ds->n++]; - memset(d, 0, sizeof(*d)); - d->line = line; d->col = col; d->endline = endline; d->endcol = endcol; d->severity = sev; - snprintf(d->msg, sizeof(d->msg), "%s", msg); - snprintf(d->path, sizeof(d->path), "%s", D->path); -} -/* Structural problems we can see without the compiler, cheaply, on every - * keystroke: unbalanced delimiters and unterminated literals. */ -static void diag_structural(LDoc* D, DiagSet* ds){ - int stack[512], top = 0; - for (int i = 0; i < D->lex.n; i++){ - const LTok* t = &D->lex.v[i]; - if (t->bad){ - const char* m = t->kind == LT_STR ? "unterminated string literal" - : t->kind == LT_CHAR ? "unterminated character literal" - : "unexpected character"; - diag_add(ds, D, ldoc_line_of(D, t->start), pos_char(D, t->start), - ldoc_line_of(D, t->end), pos_char(D, t->end), 1, m); - continue; - } - if (t->kind != LT_OP || ltok_len(t) != 1) continue; - char c = D->text[t->start]; - if (c == '{' || c == '(' || c == '['){ if (top < 512) stack[top++] = i; } - else if (c == '}' || c == ')' || c == ']'){ - if (!top){ - char m[64]; snprintf(m, sizeof(m), "unmatched '%c'", c); - diag_add(ds, D, ldoc_line_of(D, t->start), pos_char(D, t->start), - ldoc_line_of(D, t->end), pos_char(D, t->end), 1, m); - } else { - int o = stack[--top]; - char oc = D->text[D->lex.v[o].start]; - char want = oc == '{' ? '}' : oc == '(' ? ')' : ']'; - if (want != c){ - char m[80]; snprintf(m, sizeof(m), "expected '%c' to close '%c', found '%c'", want, oc, c); - diag_add(ds, D, ldoc_line_of(D, t->start), pos_char(D, t->start), - ldoc_line_of(D, t->end), pos_char(D, t->end), 1, m); - } - } - } - } - for (int k = 0; k < top; k++){ - const LTok* t = &D->lex.v[stack[k]]; - char m[64]; snprintf(m, sizeof(m), "unclosed '%c'", D->text[t->start]); - diag_add(ds, D, ldoc_line_of(D, t->start), pos_char(D, t->start), - ldoc_line_of(D, t->end), pos_char(D, t->end), 1, m); - } -} - -/* Ask the compiler. `ludicc --fmt` runs lex + parse + validate and stops before - * codegen, which is exactly the checking pass we want and costs milliseconds. - * A fragment (an imported file with no `game` block) is not a program on its - * own, so we check the unit root that pulls it in and let the file paths in the - * compiler's own output route each error back to the right buffer. */ -static void diag_compiler(LDoc* D, DiagSet* ds){ - if (!g_ludicc || !g_compiler_diags) return; - /* A .md is Ludic only inside its fences; the file as a whole is prose, and - * handing it to the compiler yields errors about the prose. The fences are - * still checked structurally, which is as far as a fragment can be checked - * anyway — most of them are deliberately incomplete snippets. */ - if (D->is_markdown) return; - LDoc* root = lw_unit_root(&X, D); - if (!root) root = D->is_unit ? D : 0; - if (!root) return; - /* Paths reach us from URIs the editor sends, and they end up in a shell - * command. A quote in a path would let a filename run something; refuse - * rather than escape, since no real Ludic file needs one. */ - if (strchr(root->path, '\'') || strchr(g_ludicc, '\'')) return; - - /* the compiler reads from disk; an unsaved buffer would be checked stale */ - char cmd[PATH_MAX * 2 + 64]; - snprintf(cmd, sizeof(cmd), "'%s' '%s' --fmt -o /dev/null 2>&1", g_ludicc, root->path); - FILE* p = popen(cmd, "r"); - if (!p) return; - char line[4096]; - char msg[512]; msg[0] = 0; - int have = 0, lineno = 0; - while (fgets(line, sizeof(line), p)){ - size_t n = strlen(line); - while (n && (line[n-1] == '\n' || line[n-1] == '\r')) line[--n] = 0; - int ln; - char rest[1024]; - if (sscanf(line, "ludicc: error: line %d: %1023[^\n]", &ln, rest) == 2){ - if (have){ diag_add(ds, root, lineno - 1, 0, lineno - 1, 200, 1, msg); } - lineno = ln; snprintf(msg, sizeof(msg), "%s", rest); have = 1; - continue; - } - /* the follow-up line names the file the error is really in */ - char path[1024]; - if (have && sscanf(line, " %1023[^:]:%d |", path, &ln) == 2){ - LDoc* target = lw_ensure(&X, path); - if (!target) target = root; - int l0 = ln - 1; - int end = 200; - if (l0 >= 0 && l0 < target->lex.nline){ - int s0 = target->lex.linestart[l0]; - int e0 = (l0 + 1 < target->lex.nline) ? target->lex.linestart[l0+1] - 1 : (int)strlen(target->text); - end = pos_char(target, e0 > s0 ? e0 : s0); - } - diag_add(ds, target, l0, 0, l0, end, 1, msg); - have = 0; msg[0] = 0; - continue; - } - if (!have && !strncmp(line, "ludicc: ", 8) && !strstr(line, "error: line")){ - diag_add(ds, root, 0, 0, 0, 0, 1, line + 8); - } - } - if (have) diag_add(ds, root, lineno - 1, 0, lineno - 1, 200, 1, msg); - pclose(p); -} - -/* Publish for every document that got a diagnostic, and clear the rest. - * - * Markdown gets none. A fence in prose is a snippet — `system Move { … }` with - * an elision mark, or a body shown without its enclosing `game` block — so - * almost every "error" found there is the documentation doing its job. The - * useful half of the server still applies to fences: highlighting, hover, - * completion, go-to-definition and formatting are never wrong on a snippet. */ -static void publish_diagnostics(LDoc* D){ - DiagSet ds = {0}; - if (!D->is_markdown) diag_structural(D, &ds); - /* only bother the compiler when the buffer itself parses — otherwise we are - * reporting the same brace twice, in two different dialects */ - int structural = ds.n; - if (!structural) diag_compiler(D, &ds); - - /* Every document that has a diagnostic now, plus every document that had - * one last time — otherwise fixing an error in an imported file leaves its - * marker on screen forever, because nothing would ever publish an empty - * list for that file again. */ - LDoc* touched[128]; int nt = 0; - touched[nt++] = D; - for (int i = 0; i < ds.n; i++){ - LDoc* T = lw_by_path(&X, ds.v[i].path); - if (!T) continue; - int seen = 0; for (int k = 0; k < nt; k++) if (touched[k] == T) seen = 1; - if (!seen && nt < 128) touched[nt++] = T; - } - for (int i = 0; i < X.n && nt < 128; i++){ - if (!X.d[i]->had_diags) continue; - int seen = 0; for (int k = 0; k < nt; k++) if (touched[k] == X.d[i]) seen = 1; - if (!seen) touched[nt++] = X.d[i]; - } - for (int k = 0; k < nt; k++){ - LDoc* T = touched[k]; - T->had_diags = 0; - JSB s = {0}; - jsb_puts(&s, "{\"uri\":"); jsb_str(&s, T->uri); - jsb_puts(&s, ",\"diagnostics\":["); - int first = 1; - for (int i = 0; i < ds.n; i++){ - if (strcmp(ds.v[i].path, T->path)) continue; - if (!first) jsb_putc(&s, ','); - first = 0; - T->had_diags = 1; - jsb_putf(&s, "{\"range\":{\"start\":{\"line\":%d,\"character\":%d},\"end\":{\"line\":%d,\"character\":%d}}", - ds.v[i].line < 0 ? 0 : ds.v[i].line, ds.v[i].col, - ds.v[i].endline < 0 ? 0 : ds.v[i].endline, ds.v[i].endcol); - jsb_putf(&s, ",\"severity\":%d,\"source\":\"ludic\",\"message\":", ds.v[i].severity); - jsb_str(&s, ds.v[i].msg); - jsb_putc(&s, '}'); - } - jsb_puts(&s, "]}"); - send_notify("textDocument/publishDiagnostics", s.b); - free(s.b); - } - free(ds.v); -} - -/* ---------- semantic tokens ----------------------------------------------*/ -/* The legend, in the order the client will index into. */ -static const char* STOK_TYPES[] = { - "keyword","type","struct","class","namespace","function","parameter", - "variable","property","enumMember","number","string","comment","operator", - "decorator", 0 -}; -enum { STM_DECL = 1, STM_READONLY = 2, STM_DEFLIB = 4 }; -static const char* STOK_MODS[] = { "declaration","readonly","defaultLibrary", 0 }; - -static int sem_type_of(int cls, int* mods){ - *mods = 0; - switch (cls){ - case SC_KEYWORD: return 0; - case SC_TYPE: *mods = STM_DEFLIB; return 1; - case SC_COMPONENT: return 2; - case SC_ARCHETYPE: return 3; - case SC_SCENE: return 4; - case SC_LAYER: return 4; - case SC_UI: return 3; - case SC_WIDGET: *mods = STM_DEFLIB; return 3; - case SC_SYSTEM: return 5; - case SC_FUNCTION: return 5; - case SC_BUILTIN: *mods = STM_DEFLIB; return 5; - case SC_PARAM: return 6; - case SC_VARIABLE: return 7; - case SC_MODVAR: return 7; - case SC_CONST: *mods = STM_READONLY; return 7; - case SC_PROP: return 8; - case SC_FIELD: return 8; - case SC_PHASE: *mods = STM_READONLY | STM_DEFLIB; return 9; - case SC_NUMBER: return 10; - case SC_STRING: return 11; - case SC_COMMENT: return 12; - case SC_OPERATOR: return 13; - case SC_ANNOTATION: return 14; - default: return -1; - } -} -static char* semantic_tokens(LDoc* D, int from_line, int to_line){ - lw_classify(&X, D); - JSB s = {0}; - jsb_puts(&s, "{\"data\":["); - int prev_line = 0, prev_char = 0, first = 1; - for (int i = 0; i < D->lex.n; i++){ - const LTok* t = &D->lex.v[i]; - if (t->kind == LT_NL || t->kind == LT_EOF) continue; - if (t->line < from_line || (to_line >= 0 && t->line > to_line)) continue; - int mods; int ty = sem_type_of(D->cls[i], &mods); - if (ty < 0) continue; - int line = t->line; - int ch = pos_char(D, t->start); - int len = g_utf8_positions ? ltok_len(t) : lutf16_len(D->text + t->start, ltok_len(t)); - if (len <= 0) continue; - int dl = line - prev_line; - int dc = dl ? ch : ch - prev_char; - if (!first) jsb_putc(&s, ','); - first = 0; - jsb_putf(&s, "%d,%d,%d,%d,%d", dl, dc, len, ty, mods); - prev_line = line; prev_char = ch; - } - jsb_puts(&s, "]}"); - return s.b; -} - -/* ---------- symbol presentation ------------------------------------------*/ -static int lsp_symbol_kind(int k){ - switch (k){ /* LSP SymbolKind numbers */ - case LS_UNIT: return 2; /* Module */ - case LS_COMPONENT: return 23; /* Struct */ - case LS_FIELD: return 8; /* Field */ - case LS_ARCHETYPE: return 5; /* Class */ - case LS_CONST: return 14; /* Constant */ - case LS_VAR: return 13; /* Variable */ - case LS_FN: return 12; /* Function */ - case LS_EXTERN: return 12; - case LS_SYSTEM: return 6; /* Method */ - case LS_UI: return 5; - case LS_WIDGET: return 14; - case LS_SCENE: return 3; /* Namespace */ - case LS_LAYER: return 3; - case LS_PARAM: return 13; - case LS_LOCAL: return 13; - case LS_QUERYVAR: return 13; - case LS_STATE: return 22; /* EnumMember */ - case LS_IMPORT: return 2; - default: return 13; - } -} -static int sym_is_outline(int k){ - switch (k){ - case LS_UNIT: case LS_COMPONENT: case LS_FIELD: case LS_ARCHETYPE: - case LS_CONST: case LS_VAR: case LS_FN: case LS_EXTERN: case LS_SYSTEM: - case LS_UI: case LS_WIDGET: case LS_SCENE: case LS_LAYER: - return 1; - default: return 0; - } -} -/* DocumentSymbol is a tree; emit children of `parent` recursively. */ -static void put_doc_symbols(JSB* s, LDoc* D, int parent){ - int first = 1; - jsb_putc(s, '['); - for (int i = 0; i < D->nsym; i++){ - LSym* y = &D->sym[i]; - if (y->parent != parent || !sym_is_outline(y->kind) || !y->name[0]) continue; - if (!first) jsb_putc(s, ','); - first = 0; - jsb_puts(s, "{\"name\":"); jsb_str(s, y->name); - jsb_puts(s, ",\"detail\":"); jsb_str(s, y->detail); - jsb_putf(s, ",\"kind\":%d,\"range\":", lsp_symbol_kind(y->kind)); - int a = y->start, b = y->end; - if (y->body_end > y->end && y->body_start >= y->start){ a = y->start; b = y->body_end; } - put_range(s, D, a, b); - jsb_puts(s, ",\"selectionRange\":"); put_range(s, D, y->start, y->end); - jsb_puts(s, ",\"children\":"); - put_doc_symbols(s, D, i); - jsb_putc(s, '}'); - } - jsb_putc(s, ']'); -} - -/* ---------- hover ---------------------------------------------------------*/ -static void hover_markdown(JSB* s, const char* code, const char* doc){ - JSB m = {0}; - jsb_puts(&m, "```ludic\n"); - jsb_puts(&m, code); - jsb_puts(&m, "\n```"); - if (doc && *doc){ jsb_puts(&m, "\n\n"); jsb_puts(&m, doc); } - jsb_puts(s, "{\"contents\":{\"kind\":\"markdown\",\"value\":"); - jsb_str(s, m.b); - jsb_puts(s, "}}"); - free(m.b); -} - -/* ---------- completion ----------------------------------------------------*/ -enum { CI_TEXT = 1, CI_METHOD = 2, CI_FUNCTION = 3, CI_FIELD = 5, CI_VARIABLE = 6, - CI_CLASS = 7, CI_PROPERTY = 10, CI_UNIT = 11, CI_VALUE = 12, CI_ENUM = 13, - CI_KEYWORD = 14, CI_SNIPPET = 15, CI_CONSTANT = 21, CI_STRUCT = 22, CI_EVENT = 23 }; - -typedef struct { JSB* s; int first; } CompOut; -static void comp_item(CompOut* c, const char* label, int kind, const char* detail, const char* doc, const char* insert){ - if (!c->first) jsb_putc(c->s, ','); - c->first = 0; - jsb_puts(c->s, "{\"label\":"); jsb_str(c->s, label); - jsb_putf(c->s, ",\"kind\":%d", kind); - if (detail && *detail){ jsb_puts(c->s, ",\"detail\":"); jsb_str(c->s, detail); } - if (doc && *doc){ - jsb_puts(c->s, ",\"documentation\":{\"kind\":\"markdown\",\"value\":"); - jsb_str(c->s, doc); - jsb_putc(c->s, '}'); - } - if (insert && *insert){ - jsb_puts(c->s, ",\"insertText\":"); jsb_str(c->s, insert); - jsb_puts(c->s, ",\"insertTextFormat\":2"); - } - jsb_putc(c->s, '}'); -} -static void comp_words(CompOut* c, const char** words, int kind, const char* detail){ - for (int i = 0; words[i]; i++) comp_item(c, words[i], kind, detail, 0, 0); -} -static void comp_builtins(CompOut* c){ - for (int i = 0; LUDIC_BUILTINS[i].name; i++) - comp_item(c, LUDIC_BUILTINS[i].name, CI_FUNCTION, LUDIC_BUILTINS[i].sig, LUDIC_BUILTINS[i].doc, 0); - for (int i = 0; LUDIC_INTRINSICS[i].name; i++) - comp_item(c, LUDIC_INTRINSICS[i].name, CI_FUNCTION, LUDIC_INTRINSICS[i].sig, LUDIC_INTRINSICS[i].doc, 0); -} -static int comp_kind_of(int symkind){ - switch (symkind){ - case LS_COMPONENT: return CI_STRUCT; - case LS_ARCHETYPE: return CI_CLASS; - case LS_CONST: return CI_CONSTANT; - case LS_VAR: return CI_VARIABLE; - case LS_FN: case LS_EXTERN: return CI_FUNCTION; - case LS_SYSTEM: return CI_EVENT; - case LS_UI: return CI_CLASS; - case LS_WIDGET: return CI_CONSTANT; - case LS_SCENE: return CI_UNIT; - case LS_LAYER: return CI_UNIT; - case LS_FIELD: return CI_FIELD; - default: return CI_VARIABLE; - } -} -/* Everything the compilation unit declares, plus the locals in scope here. - * `types_only` is for the positions where nothing but a component or archetype - * can appear — a query's term list, a `spawn`, a type annotation — and there a - * local variable is not a candidate at all. */ -static void comp_scope(CompOut* c, LDoc* D, int off, int types_only){ - if (!types_only) - for (int i = 0; i < D->nsym; i++){ - LSym* y = &D->sym[i]; - if (!lsym_is_local(y->kind)) continue; - if (off < y->body_start || off > y->body_end) continue; - comp_item(c, y->name, CI_VARIABLE, y->detail[0] ? y->detail : y->type, 0, 0); - } - LDoc* rel[128]; int n = lw_related(&X, D, rel, 128); - for (int i = 0; i < n; i++) - for (int k = 0; k < rel[i]->nsym; k++){ - LSym* y = &rel[i]->sym[k]; - if (!lsym_is_toplevel(y->kind) || y->kind == LS_UNIT) continue; - if (types_only && !(y->kind == LS_COMPONENT || y->kind == LS_ARCHETYPE)) continue; - comp_item(c, y->name, comp_kind_of(y->kind), y->detail, y->doc, 0); - } -} - -/* ---------- URI/doc plumbing ---------------------------------------------*/ -static LDoc* doc_of(JVal* msg){ - const char* uri = jstr(jpath(msg, "params.textDocument.uri"), 0); - if (!uri) return 0; - LDoc* D = lw_by_uri(&X, uri); - if (D) return D; - char* path = lw_uri_to_path(uri); - D = lw_ensure(&X, path); - free(path); - return D; -} -static int off_of(JVal* msg, LDoc* D, const char* base){ - char kl[128], kc[128]; - snprintf(kl, sizeof(kl), "%s.line", base); - snprintf(kc, sizeof(kc), "%s.character", base); - int line = jint(jpath(msg, kl), 0), ch = jint(jpath(msg, kc), 0); - if (g_utf8_positions){ - if (line < 0 || line >= D->lex.nline) return 0; - int s0 = D->lex.linestart[line]; - int e0 = (line + 1 < D->lex.nline) ? D->lex.linestart[line + 1] : (int)strlen(D->text); - int off = s0 + ch; - return off > e0 ? e0 : off; - } - return ldoc_offset_of(D, line, ch); -} - -/* ---------- request handlers ---------------------------------------------*/ -static void on_initialize(JVal* msg, JVal* id){ - JVal* root = jpath(msg, "params.rootUri"); - if (root && root->t == JSTR) X.root = lw_uri_to_path(root->s); - else { - JVal* folders = jpath(msg, "params.workspaceFolders"); - JVal* f0 = jat(folders, 0); - const char* u = jstr(jget(f0, "uri"), 0); - if (u) X.root = lw_uri_to_path(u); - } - /* the client may prefer plain byte offsets; take it if offered, it is both - * cheaper and exactly what our lexer already produces */ - JVal* enc = jpath(msg, "params.capabilities.general.positionEncodings"); - if (enc) for (int i = 0; i < enc->n; i++){ - const char* e = jstr(jat(enc, i), ""); - if (!strcmp(e, "utf-8")){ g_utf8_positions = 1; break; } - } - JVal* init = jpath(msg, "params.initializationOptions"); - const char* cc = jstr(jget(init, "compilerPath"), 0); - if (cc && *cc){ free(g_ludicc); g_ludicc = strdup(cc); } - if (jget(init, "indentSize")) g_indent = jint(jget(init, "indentSize"), 2); - if (jget(init, "compilerDiagnostics")) g_compiler_diags = jbool(jget(init, "compilerDiagnostics"), 1); - - /* find the compiler if nobody told us where it is */ - if (!g_ludicc && X.root){ - char p[PATH_MAX]; - snprintf(p, sizeof(p), "%s/build/ludicc", X.root); - if (!access(p, X_OK)) g_ludicc = strdup(p); - } - if (!g_ludicc && !access("build/ludicc", X_OK)) g_ludicc = strdup("build/ludicc"); - - if (X.root) lw_scan(&X, X.root, 0); - lg("initialize root=%s compiler=%s docs=%d", X.root ? X.root : "-", g_ludicc ? g_ludicc : "-", X.n); - - JSB s = {0}; - jsb_puts(&s, "{\"capabilities\":{"); - jsb_puts(&s, "\"positionEncoding\":"); - jsb_str(&s, g_utf8_positions ? "utf-8" : "utf-16"); - jsb_puts(&s, ",\"textDocumentSync\":{\"openClose\":true,\"change\":1,\"save\":{\"includeText\":false}}"); - jsb_puts(&s, ",\"documentSymbolProvider\":true"); - jsb_puts(&s, ",\"workspaceSymbolProvider\":true"); - jsb_puts(&s, ",\"definitionProvider\":true"); - jsb_puts(&s, ",\"declarationProvider\":true"); - jsb_puts(&s, ",\"referencesProvider\":true"); - jsb_puts(&s, ",\"documentHighlightProvider\":true"); - jsb_puts(&s, ",\"hoverProvider\":true"); - jsb_puts(&s, ",\"renameProvider\":{\"prepareProvider\":true}"); - jsb_puts(&s, ",\"documentFormattingProvider\":true"); - jsb_puts(&s, ",\"documentRangeFormattingProvider\":true"); - jsb_puts(&s, ",\"foldingRangeProvider\":true"); - jsb_puts(&s, ",\"documentLinkProvider\":{\"resolveProvider\":false}"); - jsb_puts(&s, ",\"inlayHintProvider\":true"); - jsb_puts(&s, ",\"completionProvider\":{\"triggerCharacters\":[\".\",\"@\",\"[\",\" \"],\"resolveProvider\":false}"); - jsb_puts(&s, ",\"signatureHelpProvider\":{\"triggerCharacters\":[\"(\",\",\"]}"); - jsb_puts(&s, ",\"semanticTokensProvider\":{\"legend\":{\"tokenTypes\":["); - for (int i = 0; STOK_TYPES[i]; i++){ if (i) jsb_putc(&s, ','); jsb_str(&s, STOK_TYPES[i]); } - jsb_puts(&s, "],\"tokenModifiers\":["); - for (int i = 0; STOK_MODS[i]; i++){ if (i) jsb_putc(&s, ','); jsb_str(&s, STOK_MODS[i]); } - jsb_puts(&s, "]},\"full\":true,\"range\":true}"); - jsb_puts(&s, "},\"serverInfo\":{\"name\":\"ludic-lsp\",\"version\":\"1.0.0\"}}"); - send_result(id, s.b); - free(s.b); -} - -static void on_document_symbol(JVal* msg, JVal* id){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "[]"); return; } - JSB s = {0}; - put_doc_symbols(&s, D, -1); - send_result(id, s.b); - free(s.b); -} - -static void on_workspace_symbol(JVal* msg, JVal* id){ - const char* q = jstr(jpath(msg, "params.query"), ""); - JSB s = {0}; jsb_putc(&s, '['); - int first = 1; - for (int i = 0; i < X.n; i++){ - LDoc* D = X.d[i]; - for (int k = 0; k < D->nsym; k++){ - LSym* y = &D->sym[k]; - if (!sym_is_outline(y->kind) || !y->name[0]) continue; - if (*q && !strcasestr(y->name, q)) continue; - if (!first) jsb_putc(&s, ','); - first = 0; - jsb_puts(&s, "{\"name\":"); jsb_str(&s, y->name); - jsb_putf(&s, ",\"kind\":%d,\"location\":", lsp_symbol_kind(y->kind)); - put_location(&s, D, y->start, y->end); - if (D->unit[0]){ jsb_puts(&s, ",\"containerName\":"); jsb_str(&s, D->unit); } - jsb_putc(&s, '}'); - } - } - jsb_putc(&s, ']'); - send_result(id, s.b); - free(s.b); -} - -/* What does this exact token refer to? Every feature that needs to know two - * occurrences are the same thing — go-to-definition, find-usages, rename, - * highlight — goes through here, so they cannot disagree with each other. */ -static int resolve_tok(LDoc* D, int tok, LDoc** owner, int* symidx){ - *owner = 0; *symidx = -1; - if (tok < 0) return -1; - if (D->lex.v[tok].kind != LT_ID && D->lex.v[tok].kind != LT_STR) return -1; - char name[96]; ltok_text(&D->lex, tok, name, sizeof(name)); - - /* The token may BE a declaration's name — a component, a field, a - * parameter, a query binding. Those resolve to themselves, which is what - * makes hover work on the left-hand side of `for (a, b) in query [...]` - * where the binding is not yet inside its own scope. */ - for (int i = 0; i < D->nsym; i++) - if (D->sym[i].tok == tok){ *owner = D; *symidx = i; return tok; } - - /* a member: resolve through the receiver's component */ - int prev = ltok_prev_sig(&D->lex, tok); - if (prev >= 0 && ltok_is(&D->lex, prev, ".")){ - LDoc* co = 0; - int comp = lw_receiver_component(&X, D, prev, &co); - if (comp >= 0 && co){ - for (int i = 0; i < co->nsym; i++) - if (co->sym[i].kind == LS_FIELD && co->sym[i].parent == comp && !strcmp(co->sym[i].name, name)){ - *owner = co; *symidx = i; return tok; - } - } - return tok; - } - int l = lw_find_local(D, name, D->lex.v[tok].start); - if (l >= 0){ *owner = D; *symidx = l; return tok; } - LDoc* o = 0; int t = lw_find_top(&X, D, name, &o); - if (t >= 0){ *owner = o; *symidx = t; return tok; } - return tok; -} -static int resolve_at(LDoc* D, int off, LDoc** owner, int* symidx){ - return resolve_tok(D, ldoc_tok_at(D, off), owner, symidx); -} -/* Occurrences of one symbol, found by resolving each candidate token rather - * than by matching text. It is the difference between renaming a component - * field `x` and renaming every `x` in the project. */ -typedef void (*OccFn)(void* ctx, LDoc* T, int tok); -static void for_each_occurrence(LDoc* from, LDoc* target_doc, int target_sym, OccFn fn, void* ctx){ - char want[96]; - lcpy(want, sizeof(want), target_doc->text + target_doc->sym[target_sym].start, - target_doc->sym[target_sym].end - target_doc->sym[target_sym].start); - - /* A local binding cannot be referred to from another file, so there is no - * reason to walk the unit for one. */ - LDoc* single[1] = { from }; - LDoc* rel[128]; - int n; - if (lsym_is_local(target_doc->sym[target_sym].kind)){ rel[0] = single[0]; n = 1; } - else n = lw_related(&X, from, rel, 128); - - for (int i = 0; i < n; i++){ - LDoc* T = rel[i]; - for (int k = 0; k < T->lex.n; k++){ - if (T->lex.v[k].kind != LT_ID) continue; - char w[96]; ltok_text(&T->lex, k, w, sizeof(w)); - if (strcmp(w, want)) continue; /* cheap filter first */ - LDoc* o = 0; int sy = -1; - resolve_tok(T, k, &o, &sy); - if (o == target_doc && sy == target_sym) fn(ctx, T, k); - } - } -} - -static void on_definition(JVal* msg, JVal* id){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "null"); return; } - int off = off_of(msg, D, "params.position"); - /* an import string jumps to the file */ - int tok = ldoc_tok_at(D, off); - if (tok >= 0 && D->lex.v[tok].kind == LT_STR){ - int p = ltok_prev_sig(&D->lex, tok); - if (p >= 0 && ltok_is(&D->lex, p, "import")){ - char rel[512]; ltok_text(&D->lex, tok, rel, sizeof(rel)); - int n = (int)strlen(rel); if (n >= 2){ memmove(rel, rel + 1, n - 2); rel[n-2] = 0; } - char* dir = lw_dirname(D->path); - char* full = lw_join(dir, rel); free(dir); - LDoc* T = lw_ensure(&X, full); free(full); - if (T){ JSB s = {0}; put_location(&s, T, 0, 0); send_result(id, s.b); free(s.b); return; } - } - } - LDoc* owner = 0; int sym = -1; - resolve_at(D, off, &owner, &sym); - if (!owner || sym < 0){ send_result(id, "null"); return; } - JSB s = {0}; - put_location(&s, owner, owner->sym[sym].start, owner->sym[sym].end); - send_result(id, s.b); - free(s.b); -} - -static void on_hover(JVal* msg, JVal* id){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "null"); return; } - int off = off_of(msg, D, "params.position"); - int tok = ldoc_tok_at(D, off); - if (tok < 0){ send_result(id, "null"); return; } - char name[128]; ltok_text(&D->lex, tok, name, sizeof(name)); - - LDoc* owner = 0; int sym = -1; - resolve_at(D, off, &owner, &sym); - JSB s = {0}; - if (owner && sym >= 0){ - LSym* y = &owner->sym[sym]; - char code[320]; - snprintf(code, sizeof(code), "%s", y->detail[0] ? y->detail : y->name); - char doc[768]; - snprintf(doc, sizeof(doc), "%s", y->doc); - if (owner != D){ - size_t n = strlen(doc); - snprintf(doc + n, sizeof(doc) - n, "%s_declared in %s_", n ? "\n\n" : "", strrchr(owner->path, '/') ? strrchr(owner->path, '/') + 1 : owner->path); - } - hover_markdown(&s, code, doc); - send_result(id, s.b); free(s.b); return; - } - const LBuiltin* bi = lud_lookup(LUDIC_BUILTINS, name); - const char* origin = "runtime builtin — provided by `rt_` in runtime/native"; - if (!bi){ bi = lud_lookup(LUDIC_INTRINSICS, name); origin = "compiler intrinsic — lowers straight to libc / the OS"; } - if (bi){ - char doc[768]; snprintf(doc, sizeof(doc), "%s\n\n_%s_", bi->doc, origin); - hover_markdown(&s, bi->sig, doc); - send_result(id, s.b); free(s.b); return; - } - if (D->lex.v[tok].kind == LT_PHASE){ - hover_markdown(&s, name, "A system phase. Each frame runs `Input` -> `FixedUpdate` -> `Update` -> `LateUpdate` -> `Render`; `Start` runs once at boot."); - send_result(id, s.b); free(s.b); return; - } - if (D->lex.v[tok].kind == LT_TYPE){ - static const struct { const char* n; const char* d; } TY[] = { - {"int","32-bit integer."}, - {"fixed","Q16.16 fixed-point. `fx(i)` widens an int, `flr(f)` truncates back."}, - {"bool","Boolean."}, - {"entity","An entity handle. `self()` gives the one the current query is on."}, - {"str","A string literal."}, - {"ptr","A raw pointer — the runtime's floor, not for game code."}, - {"void","No value."}, - {0,0} - }; - for (int i = 0; TY[i].n; i++) if (!strcmp(TY[i].n, name)){ - hover_markdown(&s, name, TY[i].d); - send_result(id, s.b); free(s.b); return; - } - } - free(s.b); - send_result(id, "null"); -} - -/* ---------- references, highlight, rename --------------------------------*/ -typedef struct { JSB* s; int first; int mode; const char* newname; LDoc* cur; } OccOut; -enum { OCC_LOCATION, OCC_HIGHLIGHT }; - -static void occ_emit(void* ctx, LDoc* T, int tok){ - OccOut* o = (OccOut*)ctx; - if (o->mode == OCC_HIGHLIGHT && T != o->cur) return; - if (!o->first) jsb_putc(o->s, ','); - o->first = 0; - if (o->mode == OCC_HIGHLIGHT){ - jsb_puts(o->s, "{\"range\":"); - put_range(o->s, T, T->lex.v[tok].start, T->lex.v[tok].end); - jsb_puts(o->s, ",\"kind\":1}"); - } else { - put_location(o->s, T, T->lex.v[tok].start, T->lex.v[tok].end); - } -} - -static void refs_common(JVal* msg, JVal* id, int mode){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "[]"); return; } - int off = off_of(msg, D, "params.position"); - LDoc* owner = 0; int sym = -1; - int tok = resolve_at(D, off, &owner, &sym); - if (tok < 0 || !owner || sym < 0){ send_result(id, "[]"); return; } - JSB s = {0}; jsb_putc(&s, '['); - OccOut o = { &s, 1, mode, 0, D }; - for_each_occurrence(D, owner, sym, occ_emit, &o); - jsb_putc(&s, ']'); - send_result(id, s.b); free(s.b); -} -static void on_references(JVal* msg, JVal* id){ refs_common(msg, id, OCC_LOCATION); } -static void on_document_highlight(JVal* msg, JVal* id){ refs_common(msg, id, OCC_HIGHLIGHT); } - -static void on_prepare_rename(JVal* msg, JVal* id){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "null"); return; } - int off = off_of(msg, D, "params.position"); - LDoc* owner = 0; int sym = -1; - int tok = resolve_at(D, off, &owner, &sym); - /* Refusing beats renaming the wrong thing: if we cannot say what a name - * refers to, we cannot say which occurrences of it mean the same name. */ - if (tok < 0 || !owner || sym < 0 || D->lex.v[tok].kind != LT_ID){ send_result(id, "null"); return; } - JSB s = {0}; - jsb_puts(&s, "{\"range\":"); - put_range(&s, D, D->lex.v[tok].start, D->lex.v[tok].end); - jsb_puts(&s, ",\"placeholder\":"); - { char w[96]; ltok_text(&D->lex, tok, w, sizeof(w)); jsb_str(&s, w); } - jsb_putc(&s, '}'); - send_result(id, s.b); free(s.b); -} - -/* Rename collects per-file edit lists, because the LSP workspace edit is keyed - * by URI and a symbol can occur in several files of one unit. */ -typedef struct { LDoc* doc; JSB edits; int first; } FileEdits; -typedef struct { FileEdits f[64]; int n; const char* newname; } RenameOut; - -static void rename_collect(void* ctx, LDoc* T, int tok){ - RenameOut* r = (RenameOut*)ctx; - FileEdits* fe = 0; - for (int i = 0; i < r->n; i++) if (r->f[i].doc == T) fe = &r->f[i]; - if (!fe){ - if (r->n >= 64) return; - fe = &r->f[r->n++]; - memset(fe, 0, sizeof(*fe)); - fe->doc = T; fe->first = 1; - } - if (!fe->first) jsb_putc(&fe->edits, ','); - fe->first = 0; - jsb_puts(&fe->edits, "{\"range\":"); - put_range(&fe->edits, T, T->lex.v[tok].start, T->lex.v[tok].end); - jsb_puts(&fe->edits, ",\"newText\":"); - jsb_str(&fe->edits, r->newname); - jsb_putc(&fe->edits, '}'); -} - -static void on_rename(JVal* msg, JVal* id){ - LDoc* D = doc_of(msg); - const char* newname = jstr(jpath(msg, "params.newName"), 0); - if (!D || !newname || !*newname){ send_result(id, "null"); return; } - int off = off_of(msg, D, "params.position"); - LDoc* owner = 0; int sym = -1; - int tok = resolve_at(D, off, &owner, &sym); - if (tok < 0 || !owner || sym < 0){ send_result(id, "null"); return; } - - RenameOut r; memset(&r, 0, sizeof(r)); r.newname = newname; - for_each_occurrence(D, owner, sym, rename_collect, &r); - - JSB s = {0}; - jsb_puts(&s, "{\"changes\":{"); - for (int i = 0; i < r.n; i++){ - if (i) jsb_putc(&s, ','); - jsb_str(&s, r.f[i].doc->uri); - jsb_putc(&s, ':'); - jsb_putc(&s, '['); - jsb_puts(&s, r.f[i].edits.b ? r.f[i].edits.b : ""); - jsb_putc(&s, ']'); - free(r.f[i].edits.b); - } - jsb_puts(&s, "}}"); - send_result(id, s.b); free(s.b); -} - -static void on_formatting(JVal* msg, JVal* id, int ranged){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "null"); return; } - int tab = jint(jpath(msg, "params.options.tabSize"), g_indent); - if (tab < 1 || tab > 8) tab = g_indent; - char* out = D->is_markdown ? ludic_format_markdown(D->raw, tab) : ludic_format(D->raw, tab); - /* A whole-document replacement is the honest edit: the formatter's unit of - * work is the file, and a partial rewrite could not fix indentation that - * depends on lines outside the range. Range formatting therefore formats - * the document too — every editor accepts that, and it never surprises. */ - (void)ranged; - int nline = D->lex.nline; - int endline = nline > 0 ? nline - 1 : 0; - int endchar = 0; - { - int s0 = nline ? D->lex.linestart[endline] : 0; - int e0 = (int)strlen(D->text); - endchar = g_utf8_positions ? e0 - s0 : lutf16_len(D->text + s0, e0 - s0); - } - JSB s = {0}; - jsb_putf(&s, "[{\"range\":{\"start\":{\"line\":0,\"character\":0},\"end\":{\"line\":%d,\"character\":%d}},\"newText\":", endline, endchar); - jsb_str(&s, out); - jsb_puts(&s, "}]"); - send_result(id, s.b); - free(s.b); free(out); -} - -static void on_folding(JVal* msg, JVal* id){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "[]"); return; } - JSB s = {0}; jsb_putc(&s, '['); int first = 1; - for (int i = 0; i < D->lex.n; i++){ - const LTok* t = &D->lex.v[i]; - if (t->kind != LT_OP || ltok_len(t) != 1 || D->text[t->start] != '{') continue; - int m = D->match[i]; - if (m < 0) continue; - int a = t->line, b = D->lex.v[m].line; - if (b <= a) continue; - if (!first) jsb_putc(&s, ','); - first = 0; - jsb_putf(&s, "{\"startLine\":%d,\"endLine\":%d,\"kind\":\"region\"}", a, b - 1); - } - /* runs of comment lines fold as one block */ - for (int i = 0; i < D->lex.n; ){ - if (D->lex.v[i].kind != LT_COMMENT || !lw_first_on_line(D, i)){ i++; continue; } - int a = D->lex.v[i].line, last = a, j = i; - while (j < D->lex.n){ - if (D->lex.v[j].kind == LT_NL){ j++; continue; } - if (D->lex.v[j].kind == LT_COMMENT && lw_first_on_line(D, j) && D->lex.v[j].line <= last + 1){ last = D->lex.v[j].line; j++; continue; } - break; - } - if (last > a){ - if (!first) jsb_putc(&s, ','); - first = 0; - jsb_putf(&s, "{\"startLine\":%d,\"endLine\":%d,\"kind\":\"comment\"}", a, last); - } - i = j; - } - jsb_putc(&s, ']'); - send_result(id, s.b); free(s.b); -} - -static void on_document_link(JVal* msg, JVal* id){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "[]"); return; } - JSB s = {0}; jsb_putc(&s, '['); int first = 1; - for (int i = 0; i < D->lex.n; i++){ - if (D->lex.v[i].kind != LT_STR) continue; - int p = ltok_prev_sig(&D->lex, i); - if (p < 0 || !ltok_is(&D->lex, p, "import")) continue; - char rel[512]; ltok_text(&D->lex, i, rel, sizeof(rel)); - int n = (int)strlen(rel); if (n >= 2){ memmove(rel, rel + 1, n - 2); rel[n-2] = 0; } - char* dir = lw_dirname(D->path); - char* full = lw_join(dir, rel); free(dir); - char* uri = lw_path_to_uri(full); - if (!first) jsb_putc(&s, ','); - first = 0; - jsb_puts(&s, "{\"range\":"); - put_range(&s, D, D->lex.v[i].start + 1, D->lex.v[i].end - 1); - jsb_puts(&s, ",\"target\":"); jsb_str(&s, uri); jsb_putc(&s, '}'); - free(uri); free(full); - } - jsb_putc(&s, ']'); - send_result(id, s.b); free(s.b); -} - -/* Query bindings read `for (p, v) in query [Pos, Vel]` — the types are one - * lookup away but invisible at the use site, so show them inline. */ -static void on_inlay_hint(JVal* msg, JVal* id){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "[]"); return; } - JSB s = {0}; jsb_putc(&s, '['); int first = 1; - for (int i = 0; i < D->nsym; i++){ - LSym* y = &D->sym[i]; - if (y->kind != LS_QUERYVAR || !y->type[0]) continue; - if (!first) jsb_putc(&s, ','); - first = 0; - char label[128]; snprintf(label, sizeof(label), ": %s", y->type); - jsb_puts(&s, "{\"position\":"); put_pos(&s, D, y->end); - jsb_puts(&s, ",\"label\":"); jsb_str(&s, label); - jsb_puts(&s, ",\"kind\":1,\"paddingLeft\":false}"); - } - jsb_putc(&s, ']'); - send_result(id, s.b); free(s.b); -} - -static void on_signature_help(JVal* msg, JVal* id){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "null"); return; } - int off = off_of(msg, D, "params.position"); - /* walk out to the call we are inside */ - int depth = 0, callee = -1, arg = 0; - for (int i = D->lex.n - 1; i >= 0; i--){ - const LTok* t = &D->lex.v[i]; - if (t->start >= off) continue; - if (t->kind != LT_OP || ltok_len(t) != 1) continue; - char c = D->text[t->start]; - if (c == ')') depth++; - else if (c == '('){ - if (depth == 0){ callee = ltok_prev_sig(&D->lex, i); - for (int k = i + 1; k < D->lex.n && D->lex.v[k].start < off; k++) - if (ltok_is(&D->lex, k, ",")) arg++; - break; } - depth--; - } - } - if (callee < 0 || D->lex.v[callee].kind != LT_ID){ send_result(id, "null"); return; } - char name[128]; ltok_text(&D->lex, callee, name, sizeof(name)); - const char* sig = 0; const char* doc = ""; - const LBuiltin* bi = lud_lookup(LUDIC_BUILTINS, name); - if (!bi) bi = lud_lookup(LUDIC_INTRINSICS, name); - if (bi){ sig = bi->sig; doc = bi->doc; } - else { - LDoc* o = 0; int t = lw_find_top(&X, D, name, &o); - if (t >= 0 && (o->sym[t].kind == LS_FN || o->sym[t].kind == LS_EXTERN)){ sig = o->sym[t].detail; doc = o->sym[t].doc; } - } - if (!sig){ send_result(id, "null"); return; } - JSB s = {0}; - jsb_puts(&s, "{\"signatures\":[{\"label\":"); jsb_str(&s, sig); - if (doc && *doc){ jsb_puts(&s, ",\"documentation\":"); jsb_str(&s, doc); } - jsb_putf(&s, "}],\"activeSignature\":0,\"activeParameter\":%d}", arg); - send_result(id, s.b); free(s.b); -} - -static void on_completion(JVal* msg, JVal* id){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "[]"); return; } - int off = off_of(msg, D, "params.position"); - JSB s = {0}; - jsb_puts(&s, "{\"isIncomplete\":false,\"items\":["); - CompOut c = { &s, 1 }; - - /* what comes immediately before the cursor decides everything */ - int tok = -1; - for (int i = D->lex.n - 1; i >= 0; i--){ - int k = D->lex.v[i].kind; - if (k == LT_NL || k == LT_EOF || k == LT_COMMENT) continue; - if (D->lex.v[i].end <= off){ tok = i; break; } - } - /* skip the partial word being typed */ - int anchor = tok; - if (anchor >= 0 && D->lex.v[anchor].kind == LT_ID && D->lex.v[anchor].end >= off) anchor = ltok_prev_sig(&D->lex, anchor); - - /* Inside an unclosed `[` we are listing query terms, where the only things - * that can appear are components and archetypes — including after a comma, - * which is why this is a scan rather than a look at the previous token. */ - int in_query_terms = 0; - { - int depth = 0; - for (int i = anchor; i >= 0; i--){ - const LTok* t = &D->lex.v[i]; - if (t->kind != LT_OP || ltok_len(t) != 1) continue; - char ch = D->text[t->start]; - if (ch == ']') depth++; - else if (ch == '['){ if (!depth){ in_query_terms = 1; break; } depth--; } - else if (ch == '{' || ch == '}') break; /* left the clause */ - } - } - - int done = 0; - if (in_query_terms){ comp_scope(&c, D, off, 1); done = 1; } - else if (anchor >= 0){ - /* member access: only that component's fields */ - if (ltok_is(&D->lex, anchor, ".")){ - LDoc* co = 0; - int comp = lw_receiver_component(&X, D, anchor, &co); - if (comp >= 0 && co){ - for (int i = 0; i < co->nsym; i++) - if (co->sym[i].kind == LS_FIELD && co->sym[i].parent == comp) - comp_item(&c, co->sym[i].name, CI_FIELD, co->sym[i].detail, co->sym[i].doc, 0); - } - done = 1; - } - else if (ltok_is(&D->lex, anchor, "phase")){ comp_words(&c, LUDIC_PHASES, CI_ENUM, "system phase"); done = 1; } - else if (ltok_is(&D->lex, anchor, ":") || ltok_is(&D->lex, anchor, "->")){ - comp_words(&c, LUDIC_TYPES, CI_KEYWORD, "built-in type"); - comp_scope(&c, D, off, 1); - done = 1; - } - else if (ltok_is(&D->lex, anchor, "spawn")){ comp_scope(&c, D, off, 1); done = 1; } - else if (ltok_is(&D->lex, anchor, "enter")){ - LDoc* rel[128]; int n = lw_related(&X, D, rel, 128); - for (int i = 0; i < n; i++) - for (int k = 0; k < rel[i]->nsym; k++) - if (rel[i]->sym[k].kind == LS_SCENE) - comp_item(&c, rel[i]->sym[k].name, CI_UNIT, rel[i]->sym[k].detail, rel[i]->sym[k].doc, 0); - done = 1; - } - else if (D->lex.v[anchor].kind == LT_OP && ltok_len(&D->lex.v[anchor]) == 1 && D->text[D->lex.v[anchor].start] == '@'){ - comp_item(&c, "deterministic", CI_KEYWORD, "@deterministic", "Marks a system as reproducible given the same inputs.", 0); - done = 1; - } - } - if (!done && lw_in_ui_body(D, off)){ - comp_words(&c, LUDIC_WIDGETS, CI_CLASS, "widget"); - comp_words(&c, LUDIC_WIDGET_PROPS, CI_PROPERTY, "widget property"); - } - if (!done){ - comp_words(&c, LUDIC_KW_DECL, CI_KEYWORD, "declaration"); - comp_words(&c, LUDIC_KW_STMT, CI_KEYWORD, "statement"); - comp_words(&c, LUDIC_KW_CLAUSE, CI_KEYWORD, "clause"); - comp_words(&c, LUDIC_TYPES, CI_KEYWORD, "built-in type"); - comp_builtins(&c); - comp_scope(&c, D, off, 0); - /* the shapes people actually type */ - comp_item(&c, "handler", CI_SNIPPET, "handler … phase … { }", "A system with a phase and a body.", - "system ${1:Name} phase ${2|Start,Input,FixedUpdate,Update,LateUpdate,Render|} {\n $0\n}"); - comp_item(&c, "system+query", CI_SNIPPET, "handler … query … { }", "A system that runs once per matching entity.", - "system ${1:Name} phase ${2|Update,FixedUpdate,LateUpdate,Render,Input|}\n query (${3:p}) [${4:Pos}]\n{\n $0\n}"); - comp_item(&c, "property", CI_SNIPPET, "property … { }", "A component with typed fields.", - "component ${1:Name} { ${2:x}: ${3:int} = ${4:0} }"); - comp_item(&c, "model", CI_SNIPPET, "archetype … { }", "An entity kind bundling components.", - "archetype ${1:Name} {\n ${2:Pos}\n}"); - comp_item(&c, "for-query", CI_SNIPPET, "for (…) in query […] { }", "Iterate matching entities.", - "for (${1:p}) in query [${2:Pos}] {\n $0\n}"); - comp_item(&c, "scene", CI_SNIPPET, "scene … { layer … }", "A scene with one layer.", - "scene ${1:Name} {\n on enter { $2 }\n layer ${3:Main} {\n $0\n }\n}"); - } - jsb_puts(&s, "]}"); - send_result(id, s.b); - free(s.b); -} - -/* ---------- document lifecycle -------------------------------------------*/ -static void refresh(LDoc* D){ ldoc_reindex(D); lw_classify(&X, D); } - -static void on_did_open(JVal* msg){ - const char* uri = jstr(jpath(msg, "params.textDocument.uri"), 0); - const char* text = jstr(jpath(msg, "params.textDocument.text"), 0); - if (!uri) return; - char* path = lw_uri_to_path(uri); - LDoc* D = lw_by_path(&X, path); - if (!D){ D = lw_new_doc(path, strdup(text ? text : "")); lw_add(&X, D); } - else if (text) ldoc_settext(D, strdup(text)); - free(path); - D->open = 1; - D->version = jint(jpath(msg, "params.textDocument.version"), 0); - refresh(D); - publish_diagnostics(D); -} -static void on_did_change(JVal* msg){ - LDoc* D = doc_of(msg); - if (!D) return; - JVal* changes = jpath(msg, "params.contentChanges"); - JVal* last = jat(changes, changes ? changes->n - 1 : 0); - const char* text = jstr(jget(last, "text"), 0); - if (!text) return; - ldoc_settext(D, strdup(text)); - D->version = jint(jpath(msg, "params.textDocument.version"), D->version + 1); - refresh(D); - /* structural feedback only while typing; the compiler waits for a save, - * because it reads the file from disk and would otherwise report the - * previous save's errors against the current buffer */ - DiagSet ds = {0}; - if (!D->is_markdown) diag_structural(D, &ds); - JSB s = {0}; - jsb_puts(&s, "{\"uri\":"); jsb_str(&s, D->uri); - jsb_puts(&s, ",\"diagnostics\":["); - D->had_diags = ds.n > 0; - for (int i = 0; i < ds.n; i++){ - if (i) jsb_putc(&s, ','); - jsb_putf(&s, "{\"range\":{\"start\":{\"line\":%d,\"character\":%d},\"end\":{\"line\":%d,\"character\":%d}},\"severity\":%d,\"source\":\"ludic\",\"message\":", - ds.v[i].line, ds.v[i].col, ds.v[i].endline, ds.v[i].endcol, ds.v[i].severity); - jsb_str(&s, ds.v[i].msg); - jsb_putc(&s, '}'); - } - jsb_puts(&s, "]}"); - send_notify("textDocument/publishDiagnostics", s.b); - free(s.b); free(ds.v); -} -static void on_did_save(JVal* msg){ - LDoc* D = doc_of(msg); - if (!D) return; - const char* text = jstr(jpath(msg, "params.text"), 0); - if (text) ldoc_settext(D, strdup(text)); - else { char* disk = lw_readfile(D->path, 0); if (disk) ldoc_settext(D, disk); } - refresh(D); - publish_diagnostics(D); -} -static void on_did_close(JVal* msg){ - LDoc* D = doc_of(msg); - if (!D) return; - D->open = 0; - char* disk = lw_readfile(D->path, 0); - if (disk){ ldoc_settext(D, disk); refresh(D); } -} - -/* ---------- dispatch ------------------------------------------------------*/ -static void handle(JVal* msg){ - const char* method = jstr(jget(msg, "method"), 0); - JVal* id = jget(msg, "id"); - if (!method) return; - lg("<- %s", method); - - if (!strcmp(method, "initialize")){ on_initialize(msg, id); return; } - if (!strcmp(method, "initialized")) return; - if (!strcmp(method, "shutdown")){ g_shutdown = 1; send_result(id, "null"); return; } - if (!strcmp(method, "exit")){ exit(g_shutdown ? 0 : 1); } - - if (!strcmp(method, "textDocument/didOpen")){ on_did_open(msg); return; } - if (!strcmp(method, "textDocument/didChange")){ on_did_change(msg); return; } - if (!strcmp(method, "textDocument/didSave")){ on_did_save(msg); return; } - if (!strcmp(method, "textDocument/didClose")){ on_did_close(msg); return; } - if (!strcmp(method, "workspace/didChangeConfiguration")){ - JVal* cfg = jpath(msg, "params.settings.ludic"); - const char* cc = jstr(jget(cfg, "compilerPath"), 0); - if (cc && *cc){ free(g_ludicc); g_ludicc = strdup(cc); } - if (jget(cfg, "indentSize")) g_indent = jint(jget(cfg, "indentSize"), g_indent); - if (jget(cfg, "compilerDiagnostics")) g_compiler_diags = jbool(jget(cfg, "compilerDiagnostics"), 1); - return; - } - if (!strcmp(method, "workspace/didChangeWatchedFiles")){ - JVal* ch = jpath(msg, "params.changes"); - for (int i = 0; ch && i < ch->n; i++){ - const char* u = jstr(jget(jat(ch, i), "uri"), 0); - if (!u) continue; - char* p = lw_uri_to_path(u); - LDoc* D = lw_by_path(&X, p); - if (D && !D->open){ char* disk = lw_readfile(p, 0); if (disk){ ldoc_settext(D, disk); refresh(D); } } - else if (!D) lw_ensure(&X, p); - free(p); - } - return; - } - - if (!strcmp(method, "textDocument/documentSymbol")){ on_document_symbol(msg, id); return; } - if (!strcmp(method, "workspace/symbol")){ on_workspace_symbol(msg, id); return; } - if (!strcmp(method, "textDocument/definition") || - !strcmp(method, "textDocument/declaration") || - !strcmp(method, "textDocument/typeDefinition")){ on_definition(msg, id); return; } - if (!strcmp(method, "textDocument/hover")){ on_hover(msg, id); return; } - if (!strcmp(method, "textDocument/references")){ on_references(msg, id); return; } - if (!strcmp(method, "textDocument/documentHighlight")){ on_document_highlight(msg, id); return; } - if (!strcmp(method, "textDocument/prepareRename")){ on_prepare_rename(msg, id); return; } - if (!strcmp(method, "textDocument/rename")){ on_rename(msg, id); return; } - if (!strcmp(method, "textDocument/formatting")){ on_formatting(msg, id, 0); return; } - if (!strcmp(method, "textDocument/rangeFormatting")){ on_formatting(msg, id, 1); return; } - if (!strcmp(method, "textDocument/foldingRange")){ on_folding(msg, id); return; } - if (!strcmp(method, "textDocument/documentLink")){ on_document_link(msg, id); return; } - if (!strcmp(method, "textDocument/inlayHint")){ on_inlay_hint(msg, id); return; } - if (!strcmp(method, "textDocument/signatureHelp")){ on_signature_help(msg, id); return; } - if (!strcmp(method, "textDocument/completion")){ on_completion(msg, id); return; } - if (!strcmp(method, "textDocument/semanticTokens/full") || - !strcmp(method, "textDocument/semanticTokens/range")){ - LDoc* D = doc_of(msg); - if (!D){ send_result(id, "null"); return; } - int from = 0, to = -1; - JVal* r = jpath(msg, "params.range"); - if (r){ from = jint(jpath(msg, "params.range.start.line"), 0); to = jint(jpath(msg, "params.range.end.line"), -1); } - char* out = semantic_tokens(D, from, to); - send_result(id, out); - free(out); - return; - } - - /* an unknown request still needs an answer, or the client hangs */ - if (id) send_result(id, "null"); -} - -static const char* USAGE = -"ludic-lsp — the Ludic language server (LSP 3.17 over stdio)\n" -"\n" -"usage: ludic-lsp [--stdio] [--compiler PATH] [--log FILE] [--no-compiler-diagnostics]\n" -"\n" -"Editors normally launch this themselves. --stdio is accepted and ignored;\n" -"stdio is the only transport.\n"; - -int main(int argc, char** argv){ - signal(SIGPIPE, SIG_IGN); - for (int i = 1; i < argc; i++){ - if (!strcmp(argv[i], "--compiler") && i + 1 < argc) g_ludicc = strdup(argv[++i]); - else if (!strcmp(argv[i], "--log") && i + 1 < argc) g_log = fopen(argv[++i], "w"); - else if (!strcmp(argv[i], "--no-compiler-diagnostics")) g_compiler_diags = 0; - else if (!strcmp(argv[i], "--indent") && i + 1 < argc) g_indent = atoi(argv[++i]); - else if (!strcmp(argv[i], "--stdio")) ; - else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")){ fputs(USAGE, stdout); return 0; } - else if (!strcmp(argv[i], "--version")){ puts("ludic-lsp 1.0.0"); return 0; } - } - for (;;){ - char* raw = read_message(); - if (!raw) break; - JVal* msg = jparse(raw); - handle(msg); - jfree(msg); - free(raw); - } - return 0; -} diff --git a/tools/ludic-tools/ludic_syntax.h b/tools/ludic-tools/ludic_syntax.h index 9cb89404..9c698219 100644 --- a/tools/ludic-tools/ludic_syntax.h +++ b/tools/ludic-tools/ludic_syntax.h @@ -53,22 +53,22 @@ typedef struct { * declaration keyword, anything stmt() dispatches on is a statement keyword. */ static const char* LUDIC_KW_DECL[] = { "program","import","property","model","enum","ui", - "const","var","fn","extern","handler","entry", 0 + "const","var","fn","extern","handler","entry","event","scene", 0 }; static const char* LUDIC_KW_CLAUSE[] = { - "phase","query","on", 0 + "phase","query","on","cancellable","public","layer","start", 0 }; /* Documented design targets the self-hosted parser does not accept yet. Kept * out of the highlighted vocabulary (they would read as working keywords) until * they are implemented; check-vocabulary.py verifies the lists above are a * subset of what selfhost/parse*.ludic actually dispatches on. */ static const char* LUDIC_KW_RESERVED[] = { - "scene","layer","start", 0 + 0 }; static const char* LUDIC_KW_STMT[] = { "let","return","if","else","while","for","in","spawn","despawn", "enable","disable","match","machine","state","become","where", - "and","or","not","break","continue","new", 0 + "and","or","not","break","continue","new","emit","cancel", 0 }; static const char* LUDIC_TYPES[] = { "int","fixed","bool","entity","str","ptr","byte","words","fixeds","ptrs","void", 0 diff --git a/tools/ludic-tools/ludic_syntax.h.tmp b/tools/ludic-tools/ludic_syntax.h.tmp deleted file mode 100644 index bf2a3fc4..00000000 --- a/tools/ludic-tools/ludic_syntax.h.tmp +++ /dev/null @@ -1,327 +0,0 @@ -/* ============================================================================ - * ludic_syntax.h — the lexical layer shared by every Ludic editor tool. - * - * One lexer, one vocabulary. `ludic-fmt`, `ludic-lsp` and the generated - * TextMate grammar all read their keyword/builtin/type tables from here, so an - * addition to the language shows up in every editor at once instead of drifting - * across six hand-maintained copies. - * - * Unlike the compiler's lexer (compiler/ludicc.c) this one is written for - * editors: it keeps comments, keeps newlines, records byte spans for every - * token, and never exits on bad input — a stray character becomes an LT_ERR - * token and lexing continues, because a file being typed into is malformed most - * of the time. - * ==========================================================================*/ -#ifndef LUDIC_SYNTAX_H -#define LUDIC_SYNTAX_H - -#include -#include -#include -#include - -/* ---------- token kinds ---------------------------------------------------*/ -enum { - LT_EOF, LT_NL, LT_COMMENT, - LT_ID, /* a plain identifier */ - LT_KW, /* a reserved word (see KEYWORDS) */ - LT_TYPE, /* a built-in type name: int fixed bool entity str ptr void */ - LT_PHASE, /* Start Input FixedUpdate Update LateUpdate Render */ - LT_BOOL, /* true false */ - LT_INT, LT_FLOAT, LT_STR, LT_CHAR, - LT_ANNO, /* @deterministic — the '@' and the name as one token */ - LT_OP, - LT_ERR -}; - -typedef struct { - int kind; - int start, end; /* byte offsets into the source buffer */ - int line; /* 0-based */ - int bad; /* set on an unterminated string / stray character */ -} LTok; - -typedef struct { - LTok* v; int n, cap; - const char* src; - int* linestart; int nline, caplin; -} LLex; - -/* ---------- the vocabulary ------------------------------------------------*/ -/* Reserved words, grouped so editors can colour them differently. The groups - * mirror the compiler's parser: anything parse_decl() dispatches on is a - * declaration keyword, anything stmt() dispatches on is a statement keyword. */ -static const char* LUDIC_KW_DECL[] = { - "game","module","import","component","struct","archetype","enum","ui", - "const","var","fn","extern","system","main", 0 -}; -static const char* LUDIC_KW_CLAUSE[] = { - "phase","query","reads","writes", 0 -}; -/* Documented design targets the self-hosted parser does not accept yet. Kept - * out of the highlighted vocabulary (they would read as working keywords) until - * they are implemented; check-vocabulary.py verifies the lists above are a - * subset of what selfhost/parse*.ludic actually dispatches on. */ -static const char* LUDIC_KW_RESERVED[] = { - "scene","layer","on","start", 0 -}; -static const char* LUDIC_KW_STMT[] = { - "let","return","if","else","when","while","for","in","spawn","despawn", - "match","machine","state","become","enter","where","and","or","not", - "break","continue","new", 0 -}; -static const char* LUDIC_TYPES[] = { - "int","fixed","bool","entity","str","ptr","void", 0 -}; -static const char* LUDIC_PHASES[] = { - "Start","Input","FixedUpdate","Update","LateUpdate","Render", 0 -}; -static const char* LUDIC_WIDGETS[] = { - "panel","col","row","label","button","image","spacer", 0 -}; -static const char* LUDIC_WIDGET_PROPS[] = { - "id","text","skin","image","align","w","h","pad","gap","size","font", - "inset","grow","bg","fg","border","focus","x","y", 0 -}; - -/* A builtin is a name the runtime provides (`clear(c)` -> rt_clear). An - * intrinsic is a name the compiler lowers directly to libc/OS. Editors treat - * both as "standard library", but the signatures differ, so they stay apart. */ -typedef struct { const char* name; const char* sig; const char* doc; } LBuiltin; - -static const LBuiltin LUDIC_BUILTINS[] = { - {"min","min(a: int, b: int) -> int","Smaller of two integers."}, - {"max","max(a: int, b: int) -> int","Larger of two integers."}, - {"abs","abs(a: int) -> int","Absolute value."}, - {"clamp","clamp(v: int, lo: int, hi: int) -> int","Constrain v to [lo, hi]."}, - {"seed","seed(i: int)","Seed the deterministic RNG."}, - {"rng_range","rng_range(lo: int, hi: int) -> int","Deterministic integer in [lo, hi]."}, - {"rng_chance","rng_chance(pct: int) -> bool","True pct% of the time, deterministically."}, - {"fx","fx(i: int) -> fixed","Widen an int to Q16.16 fixed-point."}, - {"flr","flr(f: fixed) -> int","Truncate a fixed-point value toward zero."}, - {"map_size","map_size(w: int, h: int)","Set the tilemap dimensions."}, - {"map_row","map_row(y: int, row: str)","Fill one tilemap row from a string."}, - {"tile","tile(x: int, y: int) -> int","Tile code at a map cell."}, - {"clear","clear(color: int)","Clear the framebuffer to a 0xRRGGBB colour."}, - {"present","present()","Push the framebuffer to the window (or out.ppm when headless)."}, - {"fill_rect","fill_rect(x: int, y: int, w: int, h: int, color: int)","Filled rectangle."}, - {"frame_rect","frame_rect(x: int, y: int, w: int, h: int, color: int)","One-pixel rectangle outline."}, - {"put_px","put_px(x: int, y: int, color: int)","Write a single pixel."}, - {"text","text(x: int, y: int, s: str, color: int, scale: int)","Draw text with the built-in 5x7 bitmap font."}, - {"text_int","text_int(x: int, y: int, n: int, color: int, scale: int)","Draw an integer with the 5x7 bitmap font."}, - {"font_load","font_load(path: str) -> int","Load a TrueType .ttf/.ttc; returns a font id."}, - {"text_ttf","text_ttf(font: int, x: int, y: int, utf8: str, color: int, px: int)","Draw UTF-8 text with a TrueType font."}, - {"text_w","text_w(font: int, utf8: str, px: int) -> int","Advance width of the string, in pixels."}, - {"text_h","text_h(font: int, px: int) -> int","Line height of the font, in pixels."}, - {"image_load","image_load(path: str) -> int","Decode a PNG into an image id."}, - {"draw_image","draw_image(id: int, x: int, y: int)","Blit an image at its natural size."}, - {"draw_image_scaled","draw_image_scaled(id: int, x: int, y: int, w: int, h: int)","Blit an image stretched to w x h."}, - {"draw_9slice","draw_9slice(id: int, x: int, y: int, w: int, h: int, inset: int)","Nine-slice an image across a w x h box."}, - {"load_png","load_png(path: str) -> int","Decode a PNG as a 16x16 sprite sheet; returns the first sprite id."}, - {"load_sprites","load_sprites(path: str)","Load the sprite sheet used by draw_sprite."}, - {"draw_sprite","draw_sprite(id: int, x: int, y: int)","Blit a sprite."}, - {"draw_sprite_scaled","draw_sprite_scaled(id: int, x: int, y: int, scale: int)","Blit a sprite at an integer scale."}, - {"ui_build","ui_build()","Construct every declared `ui` tree (loads skins and images)."}, - {"ui_open","ui_open(id: int)","Make a ui tree active and focus its first button."}, - {"ui_tick","ui_tick(key: int)","Feed a key to the UI: w/s move focus, space/enter activate."}, - {"ui_render","ui_render()","Lay out and draw the active ui tree."}, - {"ui_clicked","ui_clicked(id: int) -> bool","True on the frame a widget was activated."}, - {"ui_set_text","ui_set_text(id: int, s: str)","Replace a widget's text."}, - {"ui_set_int","ui_set_int(id: int, n: int)","Replace a widget's text with a number."}, - {"ui_focus","ui_focus(id: int)","Move keyboard focus to a widget."}, - {"ui_focused","ui_focused() -> int","Id of the focused widget."}, - {"ui_visible","ui_visible(id: int, on: bool)","Show or hide a widget subtree."}, - {"key","key() -> int","Key code pressed this frame, 0 if none."}, - {"reg","reg(i: int) -> int","Read one of the 64 integer resources shared by systems."}, - {"setreg","setreg(i: int, v: int)","Write one of the 64 integer resources."}, - {"self","self() -> entity","The entity of the innermost query loop."}, - {"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."}, - {"quit","quit()","Stop the frame loop and exit."}, - {0,0,0} -}; - -static const LBuiltin LUDIC_INTRINSICS[] = { - {"mem_alloc","mem_alloc(n: int) -> ptr","Allocate n bytes (malloc)."}, - {"mem_realloc","mem_realloc(p: ptr, n: int) -> ptr","Resize a block to n bytes, preserving its contents (realloc)."}, - {"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."}, - {"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."}, - {"peek8","peek8(p: ptr, off: int) -> int","Read one byte."}, - {"poke8","poke8(p: ptr, off: int, v: int)","Write one byte."}, - {"peek32","peek32(p: ptr, off: int) -> int","Read a 32-bit word."}, - {"poke32","poke32(p: ptr, off: int, v: int)","Write a 32-bit word."}, - {"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."}, - {"ptr_null","ptr_null() -> ptr","The null pointer."}, - {"ptr_is_null","ptr_is_null(p: ptr) -> bool","Null test."}, - {"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)."}, - {"file_open","file_open(path: str, mode: str) -> ptr","fopen."}, - {"file_read","file_read(f: ptr, buf: ptr, n: int) -> int","fread."}, - {"file_write","file_write(f: ptr, buf: ptr, n: int) -> int","fwrite."}, - {"file_seek","file_seek(f: ptr, off: int, whence: int) -> int","fseek."}, - {"file_tell","file_tell(f: ptr) -> int","ftell."}, - {"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."}, - {"shl","shl(v: int, n: int) -> int","Shift left."}, - {"shr","shr(v: int, n: int) -> int","Logical shift right."}, - {"band","band(a: int, b: int) -> int","Bitwise and."}, - {"bor","bor(a: int, b: int) -> int","Bitwise or."}, - {"bxor","bxor(a: int, b: int) -> int","Bitwise xor."}, - {"bnot","bnot(a: int) -> int","Bitwise not."}, - {"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."}, - {"game_title","game_title() -> str","The name from the `game` declaration."}, - {"win_open","win_open(title: str, w: int, h: int, scale: int)","Open the platform window."}, - {"win_poll","win_poll() -> int","Pump the event queue; returns a key code."}, - {"win_present","win_present(px: ptr, w: int, h: int)","Blit a framebuffer to the window."}, - {"win_running","win_running() -> bool","False once the window has been closed."}, - {"win_close","win_close()","Close the platform window."}, - {0,0,0} -}; - -static int lud_in(const char** set, const char* s){ - for (int i = 0; set[i]; i++) if (!strcmp(set[i], s)) return 1; - return 0; -} -static const LBuiltin* lud_lookup(const LBuiltin* t, const char* s){ - for (int i = 0; t[i].name; i++) if (!strcmp(t[i].name, s)) return &t[i]; - return 0; -} -static int lud_is_keyword(const char* s){ - return lud_in(LUDIC_KW_DECL, s) || lud_in(LUDIC_KW_CLAUSE, s) || lud_in(LUDIC_KW_STMT, s); -} - -/* ---------- lexing --------------------------------------------------------*/ -static void ltok_push(LLex* L, int kind, int start, int end, int line, int bad){ - if (L->n >= L->cap){ L->cap = L->cap ? L->cap * 2 : 512; L->v = realloc(L->v, L->cap * sizeof(LTok)); } - L->v[L->n++] = (LTok){ kind, start, end, line, bad }; -} -static void lline_push(LLex* L, int off){ - if (L->nline >= L->caplin){ L->caplin = L->caplin ? L->caplin * 2 : 256; L->linestart = realloc(L->linestart, L->caplin * sizeof(int)); } - L->linestart[L->nline++] = off; -} - -static const char* LUDIC_OPS2[] = { "->","+=","-=","*=","/=","==","!=","<=",">=","&&","||","..","=>", 0 }; - -/* Lex the whole buffer. Comments and newlines are kept — the formatter needs - * both, and a highlighter needs the comments. */ -static void lud_lex(LLex* L, const char* src){ - memset(L, 0, sizeof(*L)); - L->src = src; - lline_push(L, 0); - int i = 0, line = 0; - while (src[i]){ - char c = src[i]; - if (c == '\n'){ ltok_push(L, LT_NL, i, i + 1, line, 0); i++; line++; lline_push(L, i); continue; } - if (c == ' ' || c == '\t' || c == '\r'){ i++; continue; } - if (c == '#'){ int s = i; while (src[i] && src[i] != '\n') i++; ltok_push(L, LT_COMMENT, s, i, line, 0); continue; } - if (c == '"'){ - int s = i; i++; int bad = 0; - while (src[i] && src[i] != '"' && src[i] != '\n'){ if (src[i] == '\\' && src[i+1]) i += 2; else i++; } - if (src[i] == '"') i++; else bad = 1; - ltok_push(L, LT_STR, s, i, line, bad); continue; - } - if (c == '\''){ - int s = i; i++; int bad = 0; - if (src[i] == '\\' && src[i+1]) i += 2; else if (src[i] && src[i] != '\n') i++; - if (src[i] == '\'') i++; else bad = 1; - ltok_push(L, LT_CHAR, s, i, line, bad); continue; - } - if (isdigit((unsigned char)c)){ - int s = i; - if (c == '0' && (src[i+1] == 'x' || src[i+1] == 'X')){ - i += 2; while (isxdigit((unsigned char)src[i])) i++; - ltok_push(L, LT_INT, s, i, line, 0); continue; - } - while (isdigit((unsigned char)src[i])) i++; - if (src[i] == '.' && isdigit((unsigned char)src[i+1])){ - i++; while (isdigit((unsigned char)src[i])) i++; - ltok_push(L, LT_FLOAT, s, i, line, 0); continue; - } - ltok_push(L, LT_INT, s, i, line, 0); continue; - } - /* @name is one token: an annotation reads as a unit, and the formatter - * must never put a space between the sigil and the name. */ - if (c == '@' && (isalpha((unsigned char)src[i+1]) || src[i+1] == '_')){ - int s = i; i++; while (isalnum((unsigned char)src[i]) || src[i] == '_') i++; - ltok_push(L, LT_ANNO, s, i, line, 0); continue; - } - if (isalpha((unsigned char)c) || c == '_'){ - int s = i; while (isalnum((unsigned char)src[i]) || src[i] == '_') i++; - int len = i - s; char w[128]; - if (len < (int)sizeof(w)){ memcpy(w, src + s, len); w[len] = 0; } else { w[0] = 0; } - int k = LT_ID; - if (!strcmp(w, "true") || !strcmp(w, "false")) k = LT_BOOL; - else if (lud_in(LUDIC_TYPES, w)) k = LT_TYPE; - else if (lud_in(LUDIC_PHASES, w)) k = LT_PHASE; - else if (lud_is_keyword(w)) k = LT_KW; - ltok_push(L, k, s, i, line, 0); continue; - } - { - int matched = 0; - for (int k = 0; LUDIC_OPS2[k]; k++) - if (src[i] == LUDIC_OPS2[k][0] && src[i+1] == LUDIC_OPS2[k][1]){ - ltok_push(L, LT_OP, i, i + 2, line, 0); i += 2; matched = 1; break; - } - if (matched) continue; - } - if (c == ';'){ ltok_push(L, LT_OP, i, i + 1, line, 0); i++; continue; } - if (strchr("+-*/%<>=(){}[],:.!@", c)){ ltok_push(L, LT_OP, i, i + 1, line, 0); i++; continue; } - /* Anything else is an error token — but a whole UTF-8 character's worth - * at a time. Splitting a multi-byte character into one token per byte - * would let a consumer that re-emits tokens (the formatter) put spaces - * inside it and corrupt the file. */ - { - unsigned char u = (unsigned char)c; - int len = u < 0x80 ? 1 : u < 0xE0 ? 2 : u < 0xF0 ? 3 : 4; - for (int k = 1; k < len; k++) if (!src[i + k] || ((unsigned char)src[i + k] & 0xC0) != 0x80){ len = k; break; } - ltok_push(L, LT_ERR, i, i + len, line, 1); i += len; - } - } - ltok_push(L, LT_EOF, i, i, line, 0); -} -static void lud_lex_free(LLex* L){ free(L->v); free(L->linestart); memset(L, 0, sizeof(*L)); } - -/* ---------- helpers over the token stream --------------------------------*/ -static int ltok_len(const LTok* t){ return t->end - t->start; } -static int ltok_is(const LLex* L, int i, const char* s){ - if (i < 0 || i >= L->n) return 0; - const LTok* t = &L->v[i]; int n = ltok_len(t); - return (int)strlen(s) == n && !strncmp(L->src + t->start, s, n); -} -/* Copy a token's text into a caller buffer; returns buf. */ -static char* ltok_text(const LLex* L, int i, char* buf, int cap){ - const LTok* t = &L->v[i]; int n = ltok_len(t); - if (n >= cap) n = cap - 1; - memcpy(buf, L->src + t->start, n); buf[n] = 0; return buf; -} -/* Index of the next token that is not a newline or comment, or -1. */ -static int ltok_next_sig(const LLex* L, int i){ - for (int j = i + 1; j < L->n; j++){ - int k = L->v[j].kind; - if (k != LT_NL && k != LT_COMMENT) return j; - } - return -1; -} -static int ltok_prev_sig(const LLex* L, int i){ - for (int j = i - 1; j >= 0; j--){ - int k = L->v[j].kind; - if (k != LT_NL && k != LT_COMMENT) return j; - } - return -1; -} -#endif /* LUDIC_SYNTAX_H */ diff --git a/tools/ludic-tools/ludic_workspace.h b/tools/ludic-tools/ludic_workspace.h deleted file mode 100644 index c1a6a855..00000000 --- a/tools/ludic-tools/ludic_workspace.h +++ /dev/null @@ -1,405 +0,0 @@ -/* ============================================================================ - * ludic_workspace.h — many documents, one project. - * - * Ludic programs are multi-file: `import "rules.ludic"` splices a fragment into - * whichever `game`/`module` file pulled it in. An imported fragment is NOT a - * standalone program — it has no `game` block — so running the compiler on it - * directly is meaningless. This layer keeps that straight: it knows which files - * form a compilation unit, which file is its root, and it resolves a name - * against the whole unit rather than one buffer. - * ==========================================================================*/ -#ifndef LUDIC_WORKSPACE_H -#define LUDIC_WORKSPACE_H - -#include "ludic_index.h" -#include -#include -#include -#include - -/* ---------- paths & URIs --------------------------------------------------*/ -static char* lw_readfile(const char* path, long* out_n){ - FILE* f = fopen(path, "rb"); if (!f) return 0; - fseek(f, 0, SEEK_END); long n = ftell(f); fseek(f, 0, SEEK_SET); - char* b = malloc(n + 1); - if (fread(b, 1, n, f) != (size_t)n){ fclose(f); free(b); return 0; } - b[n] = 0; fclose(f); - if (out_n) *out_n = n; - return b; -} -static int lw_hex(int c){ return c >= '0' && c <= '9' ? c - '0' : (c | 32) >= 'a' && (c | 32) <= 'f' ? (c | 32) - 'a' + 10 : -1; } -static char* lw_uri_to_path(const char* uri){ - if (strncmp(uri, "file://", 7)) return strdup(uri); - const char* s = uri + 7; - /* file://host/path is not something an editor sends for local files */ - char* out = malloc(strlen(s) + 1); int j = 0; - for (int i = 0; s[i]; ){ - if (s[i] == '%' && lw_hex(s[i+1]) >= 0 && lw_hex(s[i+2]) >= 0){ - out[j++] = (char)(lw_hex(s[i+1]) * 16 + lw_hex(s[i+2])); i += 3; - } else out[j++] = s[i++]; - } - out[j] = 0; - return out; -} -static char* lw_path_to_uri(const char* path){ - static const char* safe = "-_.~/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - size_t cap = strlen(path) * 3 + 16; - char* out = malloc(cap); - strcpy(out, "file://"); - int j = 7; - for (int i = 0; path[i]; i++){ - unsigned char c = (unsigned char)path[i]; - if (strchr(safe, c)) out[j++] = c; - else j += sprintf(out + j, "%%%02X", c); - } - out[j] = 0; - return out; -} -static char* lw_dirname(const char* p){ - char* d = strdup(p); char* s = strrchr(d, '/'); - if (s) *s = 0; else { free(d); d = strdup("."); } - return d; -} -static char* lw_join(const char* dir, const char* rel){ - if (rel[0] == '/') return strdup(rel); - size_t n = strlen(dir) + strlen(rel) + 2; - char* p = malloc(n); snprintf(p, n, "%s/%s", dir, rel); - char real[PATH_MAX]; - if (realpath(p, real)){ free(p); return strdup(real); } - return p; -} -static int lw_ends(const char* s, const char* suf){ - size_t a = strlen(s), b = strlen(suf); - return a >= b && !strcmp(s + a - b, suf); -} - -/* ---------- Markdown ------------------------------------------------------ - * Fenced Ludic inside prose is real Ludic and deserves the same treatment. The - * trick that makes it free: copy the document and blank out every byte that is - * not inside a ```ludic fence. Offsets, lines and columns still match the file - * on disk exactly, so every feature built on top — highlighting, hover, - * go-to-definition, diagnostics — works on a .md without knowing about it. */ -static char* lw_scrub_markdown(const char* src){ - char* out = strdup(src); - int i = 0, n = (int)strlen(src); - while (i < n){ - int ls = i, le = i; - while (le < n && src[le] != '\n') le++; - int ind = 0; while (ls + ind < le && src[ls + ind] == ' ') ind++; - int j = ls + ind; char m = j < le ? src[j] : 0; - int run = 0; while (j + run < le && src[j + run] == m) run++; - int fenced = (m == '`' || m == '~') && run >= 3; - int info = j + run; - int is_ludic = 0; - if (fenced){ - int k = info; while (k < le && (src[k] == ' ' || src[k] == '\t')) k++; - is_ludic = (le - k >= 5) && !strncasecmp(src + k, "ludic", 5) && - (le - k == 5 || src[k+5] == ' ' || src[k+5] == '\t' || src[k+5] == '\r'); - } - /* blank the fence line itself either way */ - for (int k = ls; k < le; k++) out[k] = ' '; - i = le < n ? le + 1 : n; - if (!fenced) continue; - /* inside a fence: keep the body only when the info string says ludic */ - while (i < n){ - int bs = i, be = i; - while (be < n && src[be] != '\n') be++; - int bi = 0; while (bs + bi < be && src[bs + bi] == ' ') bi++; - int cj = bs + bi, crun = 0; - while (cj + crun < be && src[cj + crun] == m) crun++; - int only = 1; - for (int k = cj + crun; k < be; k++) if (src[k] != ' ' && src[k] != '\r'){ only = 0; break; } - if (crun >= run && only){ - for (int k = bs; k < be; k++) out[k] = ' '; - i = be < n ? be + 1 : n; - break; - } - if (!is_ludic) for (int k = bs; k < be; k++) out[k] = ' '; - i = be < n ? be + 1 : n; - } - } - return out; -} - -/* ---------- documents -----------------------------------------------------*/ -static void ldoc_settext(LDoc* D, char* raw){ - if (D->text != D->raw) free(D->text); - free(D->raw); - D->raw = raw; - D->text = D->is_markdown ? lw_scrub_markdown(raw) : raw; -} -static void ldoc_reindex(LDoc* D){ - lud_lex_free(&D->lex); - lud_lex(&D->lex, D->text); - ldoc_match_braces(D); - ldoc_parse(D); - free(D->cls); - D->cls = calloc(D->lex.n + 1, 1); -} -static LDoc* lw_new_doc(const char* path, char* text){ - LDoc* D = calloc(1, sizeof(LDoc)); - char real[PATH_MAX]; - D->path = realpath(path, real) ? strdup(real) : strdup(path); - D->uri = lw_path_to_uri(D->path); - D->is_markdown = lw_ends(D->path, ".md") || lw_ends(D->path, ".markdown"); - ldoc_settext(D, text); - ldoc_reindex(D); - return D; -} -static void lw_add(LIndex* X, LDoc* D){ - if (X->n >= X->cap){ X->cap = X->cap ? X->cap * 2 : 32; X->d = realloc(X->d, X->cap * sizeof(LDoc*)); } - X->d[X->n++] = D; -} -static LDoc* lw_by_path(LIndex* X, const char* path){ - char real[PATH_MAX]; - const char* p = realpath(path, real) ? real : path; - for (int i = 0; i < X->n; i++) if (!strcmp(X->d[i]->path, p)) return X->d[i]; - return 0; -} -static LDoc* lw_by_uri(LIndex* X, const char* uri){ - char* p = lw_uri_to_path(uri); - LDoc* D = lw_by_path(X, p); - if (!D) for (int i = 0; i < X->n; i++) if (!strcmp(X->d[i]->uri, uri)){ D = X->d[i]; break; } - free(p); - return D; -} -/* Load a file into the index if it is not there yet. */ -static LDoc* lw_ensure(LIndex* X, const char* path){ - LDoc* D = lw_by_path(X, path); - if (D) return D; - char* text = lw_readfile(path, 0); - if (!text) return 0; - D = lw_new_doc(path, text); - lw_add(X, D); - return D; -} - -/* Walk the workspace once at startup so that go-to-definition works across - * files the editor has never opened. Skips the usual noise directories. */ -static void lw_scan(LIndex* X, const char* dir, int depth){ - if (depth > 8) return; - DIR* d = opendir(dir); if (!d) return; - struct dirent* e; - while ((e = readdir(d))){ - if (e->d_name[0] == '.') continue; - if (!strcmp(e->d_name, "build") || !strcmp(e->d_name, "node_modules") || - !strcmp(e->d_name, "target") || !strcmp(e->d_name, "out")) continue; - char p[PATH_MAX]; snprintf(p, sizeof(p), "%s/%s", dir, e->d_name); - struct stat st; if (stat(p, &st)) continue; - if (S_ISDIR(st.st_mode)) lw_scan(X, p, depth + 1); - else if (lw_ends(e->d_name, ".ludic")) lw_ensure(X, p); - } - closedir(d); -} - -/* ---------- compilation units -------------------------------------------- - * `related` = every document that shares a compilation unit with D: the unit - * root that (transitively) imports D, plus everything that root imports. */ -static void lw_imports_of(LIndex* X, LDoc* D, LDoc** out, int* n, int max){ - for (int i = 0; i < D->nimport; i++){ - char* dir = lw_dirname(D->path); - char* full = lw_join(dir, D->imports[i]); - free(dir); - LDoc* I = lw_ensure(X, full); - free(full); - if (!I) continue; - int seen = 0; for (int k = 0; k < *n; k++) if (out[k] == I) seen = 1; - if (seen || *n >= max) continue; - out[(*n)++] = I; - lw_imports_of(X, I, out, n, max); - } -} -static int lw_related(LIndex* X, LDoc* D, LDoc** out, int max){ - int n = 0; - if (!D) return 0; - out[n++] = D; - lw_imports_of(X, D, out, &n, max); - /* pull in any unit root that reaches D, and that root's other imports */ - for (int i = 0; i < X->n && n < max; i++){ - LDoc* R = X->d[i]; - if (!R->is_unit || R == D) continue; - LDoc* reach[128]; int rn = 0; - lw_imports_of(X, R, reach, &rn, 128); - int hits = 0; for (int k = 0; k < rn; k++) if (reach[k] == D) hits = 1; - if (!hits) continue; - int seen = 0; for (int k = 0; k < n; k++) if (out[k] == R) seen = 1; - if (!seen && n < max) out[n++] = R; - for (int k = 0; k < rn && n < max; k++){ - int s2 = 0; for (int q = 0; q < n; q++) if (out[q] == reach[k]) s2 = 1; - if (!s2) out[n++] = reach[k]; - } - } - return n; -} -/* The file `ludicc` should actually be pointed at when checking D. */ -static LDoc* lw_unit_root(LIndex* X, LDoc* D){ - if (!D || D->is_markdown) return 0; - if (D->is_unit) return D; - LDoc* rel[128]; int n = lw_related(X, D, rel, 128); - /* a `game` beats a `module`: it is the one that actually compiles */ - for (int i = 0; i < n; i++) if (rel[i]->is_unit && !rel[i]->is_module && !rel[i]->is_markdown) return rel[i]; - for (int i = 0; i < n; i++) if (rel[i]->is_unit && !rel[i]->is_markdown) return rel[i]; - return 0; -} - -/* ---------- name resolution ----------------------------------------------*/ -static int lsym_is_toplevel(int kind){ - switch (kind){ - case LS_COMPONENT: case LS_ARCHETYPE: case LS_CONST: case LS_VAR: - case LS_FN: case LS_EXTERN: case LS_SYSTEM: case LS_UI: case LS_WIDGET: - case LS_SCENE: case LS_LAYER: case LS_UNIT: - return 1; - default: return 0; - } -} -static int lsym_is_local(int kind){ - return kind == LS_LOCAL || kind == LS_PARAM || kind == LS_QUERYVAR || kind == LS_STATE; -} -/* The innermost local binding of `name` visible at byte offset `off`. */ -static int lw_find_local(LDoc* D, const char* name, int off){ - int best = -1; - for (int i = 0; i < D->nsym; i++){ - LSym* s = &D->sym[i]; - if (!lsym_is_local(s->kind) || strcmp(s->name, name)) continue; - if (off < s->body_start || off > s->body_end) continue; - if (best < 0 || s->body_start >= D->sym[best].body_start) best = i; - } - return best; -} -static int lw_find_top(LIndex* X, LDoc* D, const char* name, LDoc** owner){ - LDoc* rel[128]; int n = lw_related(X, D, rel, 128); - for (int i = 0; i < n; i++) - for (int k = 0; k < rel[i]->nsym; k++) - if (lsym_is_toplevel(rel[i]->sym[k].kind) && !strcmp(rel[i]->sym[k].name, name)){ - *owner = rel[i]; return k; - } - /* fall back to the whole workspace — better a cross-unit jump than none */ - for (int i = 0; i < X->n; i++) - for (int k = 0; k < X->d[i]->nsym; k++) - if (lsym_is_toplevel(X->d[i]->sym[k].kind) && !strcmp(X->d[i]->sym[k].name, name)){ - *owner = X->d[i]; return k; - } - return -1; -} -/* The component a dotted receiver has, e.g. `p` in `p.x` when p came from a - * query binding or a typed parameter. Returns the component symbol or -1. */ -static int lw_receiver_component(LIndex* X, LDoc* D, int dot_tok, LDoc** owner){ - int recv = ltok_prev_sig(&D->lex, dot_tok); - if (recv < 0 || D->lex.v[recv].kind != LT_ID) return -1; - char name[96]; ltok_text(&D->lex, recv, name, sizeof(name)); - int l = lw_find_local(D, name, D->lex.v[recv].start); - const char* ty = 0; - if (l >= 0) ty = D->sym[l].type; - else { - LDoc* o; int t = lw_find_top(X, D, name, &o); - if (t >= 0) ty = o->sym[t].type; - } - if (!ty || !ty[0]) return -1; - return lw_find_top(X, D, ty, owner); -} - -/* ---------- semantic classification --------------------------------------*/ -static int lw_first_on_line(LDoc* D, int tok){ - int p = ltok_prev_sig(&D->lex, tok); - return p < 0 || D->lex.v[p].line != D->lex.v[tok].line; -} -static int lw_in_ui_body(LDoc* D, int off){ - for (int i = 0; i < D->nsym; i++) - if (D->sym[i].kind == LS_UI && off > D->sym[i].body_start && off < D->sym[i].body_end) return 1; - return 0; -} -static void lw_classify(LIndex* X, LDoc* D){ - if (!D->cls) D->cls = calloc(D->lex.n + 1, 1); - for (int i = 0; i < D->lex.n; i++){ - const LTok* t = &D->lex.v[i]; - int c = SC_NONE; - switch (t->kind){ - case LT_COMMENT: c = SC_COMMENT; break; - case LT_STR: case LT_CHAR: c = SC_STRING; break; - case LT_INT: case LT_FLOAT: c = SC_NUMBER; break; - case LT_BOOL: case LT_KW: c = SC_KEYWORD; break; - case LT_TYPE: c = SC_TYPE; break; - case LT_PHASE: c = SC_PHASE; break; - case LT_ANNO: c = SC_ANNOTATION; break; - case LT_OP: c = SC_OPERATOR; break; - case LT_ID: c = SC_UNKNOWN; break; - default: c = SC_NONE; break; - } - if (t->kind != LT_ID){ D->cls[i] = (unsigned char)c; continue; } - - char name[96]; ltok_text(&D->lex, i, name, sizeof(name)); - - /* 1. the token IS a declaration's name */ - int decl = -1; - for (int s = 0; s < D->nsym; s++) if (D->sym[s].tok == i){ decl = s; break; } - if (decl >= 0){ - switch (D->sym[decl].kind){ - case LS_COMPONENT: c = SC_COMPONENT; break; - case LS_ARCHETYPE: c = SC_ARCHETYPE; break; - case LS_FIELD: c = SC_FIELD; break; - case LS_CONST: c = SC_CONST; break; - case LS_VAR: c = SC_MODVAR; break; - case LS_FN: case LS_EXTERN: c = SC_FUNCTION; break; - case LS_SYSTEM: c = SC_SYSTEM; break; - case LS_UI: c = SC_UI; break; - case LS_WIDGET: c = SC_CONST; break; /* UI_Foo is a handle */ - case LS_SCENE: c = SC_SCENE; break; - case LS_LAYER: c = SC_LAYER; break; - case LS_PARAM: c = SC_PARAM; break; - case LS_QUERYVAR: case LS_LOCAL: case LS_STATE: c = SC_VARIABLE; break; - case LS_UNIT: c = SC_UI; break; - default: c = SC_UNKNOWN; - } - D->cls[i] = (unsigned char)c; continue; - } - - /* 2. member access: `p.x` */ - int prev = ltok_prev_sig(&D->lex, i); - if (prev >= 0 && ltok_is(&D->lex, prev, ".")){ D->cls[i] = SC_FIELD; continue; } - - int next = ltok_next_sig(&D->lex, i); - int followed_by_eq = next >= 0 && ltok_is(&D->lex, next, "="); - - /* 3. inside a `ui` block a bare word is a widget type and `k=` a prop — - * and those names (text, image, size) collide with builtins, so this - * has to be decided before the builtin table is consulted. */ - if (lw_in_ui_body(D, t->start)){ - if (followed_by_eq){ D->cls[i] = SC_PROP; continue; } - if (lw_first_on_line(D, i) || (prev >= 0 && (ltok_is(&D->lex, prev, "{") || ltok_is(&D->lex, prev, "}")))){ - D->cls[i] = lud_in(LUDIC_WIDGETS, name) ? SC_WIDGET : SC_UI; continue; - } - } - - /* 4. a local binding in scope */ - int l = lw_find_local(D, name, t->start); - if (l >= 0){ D->cls[i] = D->sym[l].kind == LS_PARAM ? SC_PARAM : SC_VARIABLE; continue; } - - /* 5. a declaration somewhere in the compilation unit */ - LDoc* owner = 0; int top = lw_find_top(X, D, name, &owner); - if (top >= 0){ - switch (owner->sym[top].kind){ - case LS_COMPONENT: c = SC_COMPONENT; break; - case LS_ARCHETYPE: c = SC_ARCHETYPE; break; - case LS_CONST: c = SC_CONST; break; - case LS_VAR: c = SC_MODVAR; break; - case LS_FN: case LS_EXTERN: c = SC_FUNCTION; break; - case LS_SYSTEM: c = SC_SYSTEM; break; - case LS_UI: c = SC_UI; break; - case LS_WIDGET: c = SC_CONST; break; - case LS_SCENE: c = SC_SCENE; break; - case LS_LAYER: c = SC_LAYER; break; - default: c = SC_UNKNOWN; - } - D->cls[i] = (unsigned char)c; continue; - } - - /* 6. the runtime surface */ - if (lud_lookup(LUDIC_BUILTINS, name) || lud_lookup(LUDIC_INTRINSICS, name)){ D->cls[i] = SC_BUILTIN; continue; } - - /* 7. a record field initialiser: `Pos = { x = 10 }` */ - if (followed_by_eq){ D->cls[i] = SC_FIELD; continue; } - - D->cls[i] = SC_UNKNOWN; - } -} -#endif /* LUDIC_WORKSPACE_H */ diff --git a/tools/ludic-tools/migrate_records.c b/tools/ludic-tools/migrate_records.c deleted file mode 100644 index db9ccc6e..00000000 --- a/tools/ludic-tools/migrate_records.c +++ /dev/null @@ -1,59 +0,0 @@ -/* migrate_records.c — one-time migration for Rule A (named fields use ':'). - * Records appear ONLY inside `spawn` blocks, so we track spawn context and, for - * every single '=' inside one: - * - '=' followed by '{' is a component init `Comp = { … }` -> delete it (`Comp { … }`) - * - otherwise is a field binding `field = value` -> rewrite to ':' - * A '=' at a real boundary is a pure re-spelling; the driver's IR-identity check - * (migrated program compiles to the same IR) is the proof. - * usage: migrate_records -> migrated source to stdout - */ -#include -#include -#include -#include "ludic_syntax.h" - -int main(int argc, char** argv){ - if (argc < 2){ fprintf(stderr, "usage: migrate_records \n"); return 2; } - FILE* f = fopen(argv[1], "rb"); - if (!f){ fprintf(stderr, "cannot open %s\n", argv[1]); return 2; } - fseek(f, 0, SEEK_END); long n = ftell(f); fseek(f, 0, SEEK_SET); - char* src = malloc(n + 1); fread(src, 1, n, f); src[n] = 0; fclose(f); - - LLex L; lud_lex(&L, src); - char* rep = calloc(L.n, 1); /* '=' -> ':' */ - char* del = calloc(L.n, 1); /* drop the '=' (component init) */ - - int sp_stack[1024]; int bp = 0; int spawn_active = 0; int pendingSpawn = 0; - for (int i = 0; i < L.n; i++){ - int k = L.v[i].kind; if (k == LT_EOF) break; - if (k == LT_NL || k == LT_COMMENT) continue; - if (k == LT_KW && ltok_is(&L, i, "spawn")) pendingSpawn = 1; - int op1 = (k == LT_OP && ltok_len(&L.v[i]) == 1); - char c0 = L.src[L.v[i].start]; - if (op1 && c0 == '{'){ - if (bp < 1024){ sp_stack[bp] = (pendingSpawn || spawn_active > 0) ? 1 : 0; if (sp_stack[bp]) spawn_active++; bp++; } - pendingSpawn = 0; - } else if (op1 && c0 == '}'){ - if (bp > 0){ bp--; if (sp_stack[bp] && spawn_active > 0) spawn_active--; } - } else if (op1 && c0 == '='){ - if (spawn_active > 0){ - int nx = ltok_next_sig(&L, i); - if (nx >= 0 && L.v[nx].kind == LT_OP && ltok_len(&L.v[nx]) == 1 && L.src[L.v[nx].start] == '{') del[i] = 1; - else rep[i] = 1; - } - } - } - - /* map flags onto byte positions so the rebuild can peek one char ahead */ - char* repb = calloc(n + 1, 1); char* delb = calloc(n + 1, 1); - for (int i = 0; i < L.n; i++){ if (rep[i]) repb[L.v[i].start] = 1; if (del[i]) delb[L.v[i].start] = 1; } - for (int b = 0; b < n; ){ - if (repb[b]){ putchar(':'); b++; continue; } /* '=' -> ':' */ - if (delb[b]){ b++; if (b < n && src[b] == ' ') b++; continue; } /* drop '=' and one space */ - if (src[b] == ' ' && b + 1 < n && repb[b + 1]){ b++; continue; } /* drop the space before ':' -> `field: v` */ - putchar(src[b]); b++; - } - free(repb); free(delb); - lud_lex_free(&L); free(rep); free(del); free(src); - return 0; -} diff --git a/tools/ludic-tools/migrate_separators.c b/tools/ludic-tools/migrate_separators.c deleted file mode 100644 index 88bbd728..00000000 --- a/tools/ludic-tools/migrate_separators.c +++ /dev/null @@ -1,119 +0,0 @@ -/* sepfix.c — one-time migration for Rule B: insert `;` at statement boundaries - * that are currently spelled with only whitespace. Reuses the toolchain lexer. - * - * A boundary is inserted between two significant, same-line tokens prev,cur when - * - we are at paren/bracket depth 0 (not inside a call's args or an index), AND - * - we are NOT inside a `ui` block (widget props are `k=v`, space-separated, - * and the parser does not skip newlines between them), AND - * - prev can END an operand/statement, AND cur can START a statement. - * Inserting `;` (which the lexer maps to a newline token) at a REAL boundary is - * a semantic no-op under today's permissive parser — the IR-identity check in - * the driver is the proof. Wrong insertions change the IR and are rejected. - * - * usage: sepfix -> writes migrated source to stdout - */ -#include -#include -#include -#include "ludic_syntax.h" - -static const char* STMT_START[] = { - "let","return","if","when","while","for","spawn","despawn", - "match","machine","become","enter","break","continue", 0 -}; - -static int ender(const LLex* L, int i){ - const LTok* t = &L->v[i]; - switch (t->kind){ - case LT_ID: case LT_INT: case LT_FLOAT: case LT_STR: case LT_CHAR: - case LT_BOOL: case LT_TYPE: case LT_PHASE: return 1; - case LT_OP: { - if (ltok_len(t) != 1) return 0; - char c = L->src[t->start]; - if (c == ']'){ - /* `]` closing an empty `[]` is a slice-TYPE marker (`[]Node`), - * not an operand end — the type name that follows continues it. */ - int p = ltok_prev_sig(L, i); - if (p >= 0 && L->v[p].kind == LT_OP && ltok_len(&L->v[p]) == 1 && L->src[L->v[p].start] == '[') return 0; - return 1; - } - return (c == ')' || c == '}'); } - case LT_KW: { char b[32]; ltok_text(L, i, b, sizeof b); - return !strcmp(b, "break") || !strcmp(b, "continue"); } - default: return 0; - } -} -static int starter(const LLex* L, int i){ - const LTok* t = &L->v[i]; - if (t->kind == LT_ID || t->kind == LT_INT || t->kind == LT_FLOAT || - t->kind == LT_STR || t->kind == LT_CHAR || t->kind == LT_BOOL) return 1; - if (t->kind == LT_KW){ char b[32]; ltok_text(L, i, b, sizeof b); return lud_in(STMT_START, b); } - return 0; /* an operator never starts a statement here */ -} - -int main(int argc, char** argv){ - if (argc < 2){ fprintf(stderr, "usage: sepfix \n"); return 2; } - FILE* f = fopen(argv[1], "rb"); - if (!f){ fprintf(stderr, "sepfix: cannot open %s\n", argv[1]); return 2; } - fseek(f, 0, SEEK_END); long n = ftell(f); fseek(f, 0, SEEK_SET); - char* src = malloc(n + 1); fread(src, 1, n, f); src[n] = 0; fclose(f); - - LLex L; lud_lex(&L, src); - - /* insert[k] = 1 means: emit a ';' immediately after token k's bytes */ - char* insert = calloc(L.n, 1); - - int paren = 0; /* unclosed ( or [ */ - /* ui suppression: brace depth stack, marking which open braces are ui/widget */ - int ui_stack[512]; int bp = 0; int ui_active = 0; - int pendingUiOpen = 0; /* saw `ui` or a widget word; the next { is a ui brace */ - - int prev = -1; /* previous significant token index */ - for (int i = 0; i < L.n; i++){ - int k = L.v[i].kind; - if (k == LT_EOF) break; - if (k == LT_NL || k == LT_COMMENT) continue; - - char c0 = L.src[L.v[i].start]; - int op1 = (k == LT_OP && ltok_len(&L.v[i]) == 1); - - /* track ui context by the `ui` KEYWORD only — it brackets the whole - * widget tree via its root brace, so every nested widget brace is - * already inside ui_active. (Do NOT key off widget words like col/row/ - * image/label: those are also ordinary variable names, and matching them - * would wrongly suppress real statement boundaries.) */ - if (k == LT_KW && ltok_is(&L, i, "ui")) pendingUiOpen = 1; - - if (op1 && c0 == '{'){ - if (bp < 512){ ui_stack[bp] = pendingUiOpen; bp++; if (pendingUiOpen) ui_active++; } - pendingUiOpen = 0; - } else if (op1 && c0 == '}'){ - if (bp > 0){ bp--; if (ui_stack[bp]) { if (ui_active) ui_active--; } } - } else if (op1 && (c0 == '(' || c0 == '[')){ paren++; if (getenv("SEPFIX_TRACE")) fprintf(stderr, " L%d '%c' -> paren=%d\n", L.v[i].line + 1, c0, paren); } - else if (op1 && (c0 == ')' || c0 == ']')){ if (paren > 0) paren--; if (getenv("SEPFIX_TRACE")) fprintf(stderr, " L%d '%c' -> paren=%d\n", L.v[i].line + 1, c0, paren); } - - /* candidate boundary between prev and this token */ - if (prev >= 0 && paren == 0 && !ui_active && - L.v[prev].line == L.v[i].line && - ender(&L, prev) && starter(&L, i)){ - insert[prev] = 1; - } - prev = i; - } - - if (getenv("SEPFIX_DEBUG")) fprintf(stderr, "END STATE %s: paren=%d ui_active=%d bp=%d\n", argv[1], paren, ui_active, bp); - - /* rebuild: copy bytes, dropping in ';' right after any token flagged */ - for (int i = 0, t = 0; i < n; ){ - /* find if a token ends exactly at i and is flagged */ - putchar(src[i]); - i++; - /* emit ';' after the last byte of a flagged token */ - for (; t < L.n; t++){ - if (L.v[t].end == i && insert[t]){ putchar(';'); break; } - if (L.v[t].end > i) break; - } - } - lud_lex_free(&L); free(insert); free(src); - return 0; -} diff --git a/tools/ludic-tools/migrate_ui.c b/tools/ludic-tools/migrate_ui.c deleted file mode 100644 index df8711aa..00000000 --- a/tools/ludic-tools/migrate_ui.c +++ /dev/null @@ -1,52 +0,0 @@ -/* migrate_ui.c — one-time migration for Rule A in `ui` blocks: widget props go - * from `key=value` to `key: value`. Every '=' inside a `ui` block is a prop - * separator (values are expressions, never contain a top-level '='), so we track - * ui context (armed by the `ui` keyword's root brace) and rewrite each '=' to a - * ':' with canonical spacing (`id: Root`). The driver's IR-identity check proves - * it is a pure re-spelling (the parser builds the same E_FINIT nodes). - * usage: migrate_ui -> migrated source to stdout - */ -#include -#include -#include -#include "ludic_syntax.h" - -int main(int argc, char** argv){ - if (argc < 2){ fprintf(stderr, "usage: migrate_ui \n"); return 2; } - FILE* f = fopen(argv[1], "rb"); - if (!f){ fprintf(stderr, "cannot open %s\n", argv[1]); return 2; } - fseek(f, 0, SEEK_END); long n = ftell(f); fseek(f, 0, SEEK_SET); - char* src = malloc(n + 1); fread(src, 1, n, f); src[n] = 0; fclose(f); - - LLex L; lud_lex(&L, src); - char* repb = calloc(n + 1, 1); /* byte position of a '=' to rewrite as ':' */ - - int ui_stack[1024]; int bp = 0; int ui_active = 0; int pendingUi = 0; - for (int i = 0; i < L.n; i++){ - int k = L.v[i].kind; if (k == LT_EOF) break; - if (k == LT_NL || k == LT_COMMENT) continue; - if (k == LT_KW && ltok_is(&L, i, "ui")) pendingUi = 1; - int op1 = (k == LT_OP && ltok_len(&L.v[i]) == 1); - char c0 = L.src[L.v[i].start]; - if (op1 && c0 == '{'){ - if (bp < 1024){ ui_stack[bp] = (pendingUi || ui_active > 0) ? 1 : 0; if (ui_stack[bp]) ui_active++; bp++; } - pendingUi = 0; - } else if (op1 && c0 == '}'){ - if (bp > 0){ bp--; if (ui_stack[bp] && ui_active > 0) ui_active--; } - } else if (op1 && c0 == '=' && ui_active > 0){ - repb[L.v[i].start] = 1; - } - } - - for (int b = 0; b < n; ){ - if (repb[b]){ /* '=' -> ': ' with a single trailing space */ - putchar(':'); b++; - if (b < n && src[b] != ' ' && src[b] != '\n') putchar(' '); - continue; - } - if (src[b] == ' ' && b + 1 < n && repb[b + 1]){ b++; continue; } /* drop the space before ':' */ - putchar(src[b]); b++; - } - lud_lex_free(&L); free(repb); free(src); - return 0; -}