Skip to content

Move UI asset loading to Lisp-first flow, route binding execution through Binding objects, and migrate the Example application runtime flow from XML assets to Lisp assets#337

Draft
corepunch with Copilot wants to merge 11 commits into
mainfrom
copilot/replace-xml-with-lisp
Draft

Conversation

Copilot AI commented May 22, 2026

Copy link
Copy Markdown
Contributor

This PR advances the Lisp-first UI loading work and updates binding execution to a message-driven object flow, then applies follow-up feedback to remove legacy binding markup compatibility and switch the active Example app runtime flow to Lisp assets.

Changes Made

  • Added Lisp UI asset loading support and Lisp binding syntax translation compatibility in the runtime binding compile path.
  • Added Binding.Evaluate as a message-driven execution step so binding computation can run through Binding objects.
  • Updated property binding runtime to dispatch evaluation through Binding objects.
  • Removed legacy binding-markup normalization from binding compile handling ({Binding ...} rewrite path), aligning runtime behavior with the non-legacy binding format.
  • Migrated Example prefab bindings from legacy {Binding Path} to non-legacy {Path} syntax and updated corresponding layout assertions.
  • Added Lisp prefab templates for the Example application and updated active Example runtime references to use .lisp assets:
    • StartupScreen now points to Example/Screens/Application.lisp
    • PlaceholderTemplate references in Application.lisp now point to Example/Prefabs/*.lisp
    • modal path now points to Example/Screens/GetStartedPopup.lisp
  • Renamed the metric prefab Lisp asset to Metric.lisp and updated references.
  • Regenerated core generated files (core.h, core_properties.h, core_export.c) for the new Binding message and fields.

Validation

  • Investigated branch CI workflow runs and failure status.
  • Ran local validation:
    • make unite
    • make test-headless
  • Ran parallel validation and addressed actionable review findings in follow-up commits.

Copilot AI and others added 2 commits May 22, 2026 19:17
…xml file-loader registration

Agent-Logs-Url: https://github.com/corepunch/orca/sessions/c1a79acc-0829-49bb-bc49-027298f41560

Co-authored-by: corepunch <83646194+corepunch@users.noreply.github.com>
Agent-Logs-Url: https://github.com/corepunch/orca/sessions/c1a79acc-0829-49bb-bc49-027298f41560

Co-authored-by: corepunch <83646194+corepunch@users.noreply.github.com>
@corepunch

Copy link
Copy Markdown
Owner

@copilot You added Lisp files, where you use strings:
(Screen Name="Application" Width="1280" Height="800" ClearColor="$surface"
1280 and 800 shall just be numbers, not strings - and this would also remove the need to parse properties!

…s to bare literals

Agent-Logs-Url: https://github.com/corepunch/orca/sessions/26175dcf-d875-4d38-8302-ce38bf303643

Co-authored-by: corepunch <83646194+corepunch@users.noreply.github.com>

Copilot AI commented May 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot You added Lisp files, where you use strings:
(Screen Name="Application" Width="1280" Height="800" ClearColor="$surface"
1280 and 800 shall just be numbers, not strings - and this would also...

Updated in commit 0bdb6c7.

  • Lisp parser now supports inline atom assignments like Width=1280 / Height=800.
  • Converted numeric properties in Application.lisp and GetStartedPopup.lisp from quoted strings to bare numbers.
  • Added test coverage to enforce this style in tests/test_lisp.lua.

… step titles

Agent-Logs-Url: https://github.com/corepunch/orca/sessions/26175dcf-d875-4d38-8302-ce38bf303643

Co-authored-by: corepunch <83646194+corepunch@users.noreply.github.com>
Copilot AI changed the title Add Lisp UI asset format loader as parallel format alongside XML Move UI asset loading to Lisp-first flow and unify Lisp binding parsing May 22, 2026
@corepunch corepunch requested a review from Copilot May 22, 2026 19:34
@corepunch

Copy link
Copy Markdown
Owner

@copilot Check Weather app, I believe we can totally use Lisp to replace moonscript and lua too
it will be the one way to do stuff, I think it's great?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR shifts UI asset loading toward a Lisp-first workflow by adding a Lisp UI loader (.lisp), exposing Lisp loading to Lua, and teaching the runtime binding compiler to accept Lisp-style S-expressions (e.g. (if ...), (bind ...)) by translating them into the existing expression syntax.

Changes:

  • Added Lisp → ORCA expression translation in Token_Create and introduced new runtime tests for Lisp-style bindings.
  • Added a new Lisp UI asset loader (fs_lisp.c) plus a Lua entry point (filesystem.loadObjectFromLispString) and .lisp file loader registration.
  • Added/updated sample .lisp screen assets and integrated Lisp loader coverage into headless test runs.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/test_properties.c Adds runtime coverage for Token_Create and IF evaluation when expressions are written in Lisp form.
tests/test_lisp.lua New headless Lua tests for the Lisp UI loader, bindings, and sample asset parsing.
source/filesystem/w_filesystem.c Registers .lisp loader and exposes loadObjectFromLispString to Lua; removes .xml loader registration.
source/filesystem/fs_local.h Declares FS_LoadObjectFromLisp* APIs.
source/filesystem/fs_lisp.c New Lisp parser + object factory, including binding translation and attribute parsing changes.
source/core/property/property_program.c Adds Lisp binding translation and invokes it from Token_Create as a front-end feature.
samples/Example/Screens/GetStartedPopup.lisp Adds a Lisp popup template so extensionless modal paths can resolve via .lisp.
samples/Example/Screens/Application.lisp Adds Lisp-form sample screen (and updates numeric atom style) used by tests and loader validation.
Makefile Adds test-lisp target and includes Lisp tests in test-headless.

Comment on lines +45 to +51
if (b->n + len + 1 > b->cap) {
size_t need = b->n + len + 1;
b->cap = b->cap ? b->cap * 2 : 256;
if (b->cap < need) b->cap = need;
b->s = realloc(b->s, b->cap);
}
if (!b->s) return;
Comment on lines +389 to +396
if (eq && eq > l->str && eq[1] != '\0') {
/* Inline atom assignment, e.g. Width=1280 */
char *key = strndup(l->str, (size_t)(eq - l->str));
if (!key) {
Con_Error("Lisp: out of memory parsing attribute key (line %d)", l->line);
lsp_next(l);
continue;
}
Comment on lines +417 to +420
} else if (alen > 1 && l->str[alen - 1] == '=') {
char *key = strndup(l->str, alen - 1);
lsp_next(l);

Comment on lines +341 to +351
char *expr = lsp_translate_binding(l);
if (target && expr) {
struct lisp_attr *a = calloc(1, sizeof(*a));
a->key = target;
a->binding = expr;
*attr_tail = a;
attr_tail = &a->next;
} else {
free(target);
free(expr);
}
Comment on lines 392 to 396
void on_filesystem_module_registered(lua_State* L)
{
OBJ_RegisterFileLoader(".xml", _xml_file_loader);
OBJ_RegisterFileLoader(".css", _css_file_loader);
OBJ_RegisterFileLoader(".lisp", _lisp_file_loader);

Comment on lines +651 to +659
lpcString_t p = _lisp_skip(code);
if (*p == '(') {
char *lisp = PROP_TranslateLispBinding(code);
if (lisp) {
struct token *result = _compile(lisp, "binding");
free(lisp);
return result;
}
}
Comment thread tests/test_lisp.lua
Comment on lines +8 to +10
-- * Prefab placeholders (LayerPrefabPlaceholder) load templates correctly.
-- * Full parity check: Application.lisp produces the same named objects as
-- Application.xml when parsed.

Copilot AI commented May 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Check Weather app, I believe we can totally use Lisp to replace moonscript and lua too
it will be the one way to do stuff, I think it's great?

Checked in 4446bdd: Weather is still MoonScript-first (samples/Weather/App.moon + views/*.moon). I did not migrate it in this PR to keep scope focused, but we can do a follow-up PR to convert Weather views/app flow to Lisp-first.

@corepunch

Copy link
Copy Markdown
Owner

@copilot bindings (tokens) shall become Objects too, and process a message like ID_Binding_Evaluate when computing
This way, our parser just parses everything as one type - Object
Also, no longer need the <Node.Visible>...
As it's now just Visible=(if (step ...
Right in node args

Copilot AI commented May 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot bindings (tokens) shall become Objects too, and process a message like ID_Binding_Evaluate when computing
This way, our parser just parses everything as one type - Object
Also, no longer need...

I can do this, but it’s a large architectural refactor beyond this PR’s scope. Please confirm you want a follow-up PR that introduces a Binding object/class (message-driven ID_Binding_Evaluate) and migrates token evaluation to that object pipeline while keeping current bindings backward-compatible during transition.

@corepunch

Copy link
Copy Markdown
Owner

@copilot yes proceed, this will remove the binding parser code and streamline its execution

@corepunch

Copy link
Copy Markdown
Owner

@copilot don't worry about backwards compatibility, redo binding in example app

Copilot AI and others added 2 commits May 23, 2026 11:55

Copilot AI commented May 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot yes proceed, this will remove the binding parser code and streamline its execution

Implemented in b95fe08 (with core wiring in 991913a): binding computation now runs through a message-driven object path via Binding.Evaluate, and property runtime dispatches evaluation to Binding objects when available, with safe fallback in class-unregistered contexts.

Copilot AI changed the title Move UI asset loading to Lisp-first flow and unify Lisp binding parsing Move UI asset loading to Lisp-first flow, unify Lisp binding parsing, and route binding execution through Binding objects May 23, 2026

Copilot AI commented May 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot don't worry about backwards compatibility, redo binding in example app

Done in ccf7bda: I redid Example app bindings to the non-legacy form ({Path} instead of {Binding Path}), updated the related layout assertions, and removed legacy binding-markup normalization from Binding compile handling.

Copilot AI changed the title Move UI asset loading to Lisp-first flow, unify Lisp binding parsing, and route binding execution through Binding objects Move UI asset loading to Lisp-first flow, unify Lisp binding parsing, route binding execution through Binding objects, and migrate Example bindings to non-legacy syntax May 23, 2026
@corepunch

Copy link
Copy Markdown
Owner

@copilot Replace xml with lisp in Example application

Copilot AI and others added 2 commits May 23, 2026 13:20

Copilot AI commented May 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Replace xml with lisp in Example application

Done in 6f377e7: Example now runs on Lisp assets by default (StartupScreen points to Application.lisp, PlaceholderTemplate paths in Application.lisp point to .lisp prefabs, and the modal action targets GetStartedPopup.lisp). Screenshot note: this is a format/path migration only; visual UI output is unchanged.

Copilot AI changed the title Move UI asset loading to Lisp-first flow, unify Lisp binding parsing, route binding execution through Binding objects, and migrate Example bindings to non-legacy syntax Move UI asset loading to Lisp-first flow, route binding execution through Binding objects, and migrate the Example application runtime flow from XML assets to Lisp assets May 23, 2026
Both now translate to {path}:
  (bind "Card.Title")    → {Card.Title}
  (Binding "Card.Title") → {Card.Title}  (new alias)

Example usage:
  (TextBlock Name="Title" Text=(Binding "Card.Title"))
  (TextBlock Name="Value" ForegroundColor=(Binding "Card.PrimaryColor"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants