Commit Graph

198 Commits

Author SHA1 Message Date
Will Anderson 6ced0f8009 fix: double-free in engram_neighbors_json BFS + rebuild engram.c
el_strdup tracks pointers in the arena. The BFS arrays in
engram_neighbors_json are manually freed — using el_strdup caused a
double-free when the arena was later popped. Changed to plain strdup
for those allocations.

engram/dist/engram.c rebuilt from engram/src/server.el with current
elc (minor codegen diff: parenthesisation and _argc/_argv rename).
2026-05-06 14:11:40 -05:00
Will Anderson bd7303447b fix: skip test blocks in codegen to prevent OOM on test files
test "name" { ... } blocks were not recognized by the self-hosted
compiler. The body { } was parsed as a Map literal, creating a huge
AST with O(n²) string concatenation in the toplevel_exec_stmts loop
(which had no arena scope). A 272-line test file would consume 400MB+
and a 720-line file importing the full compiler source caused 150GB
usage and crashed the machine.

Two fixes:
1. Skip Test tokens in codegen_streaming before parse_one() —
   advance past "name" and skip_to_rbrace on the body block.
   Test blocks are never compiled; self-hosted compiler has no test runner.

2. Add per-statement arena scope to toplevel_exec_stmts emission loop,
   matching the el_main_body loop. Frees intermediate strings after
   each statement to prevent O(n²) accumulation from any unrecognized
   construct that reaches that path.

Result: test_string.el (272 lines, 27 test blocks): 0MB peak (was 400MB+).
        test_compiler.el (720 lines + 8728 imported): 15MB peak (was 150GB).
2026-05-06 13:34:03 -05:00
Will Anderson e8f6765750 fix: arena leak in compile() — token/sig strings now tracked
Wrapped compile() body in el_arena_push/pop so the arena is active
before lex() and scan_fn_sigs(). Previously both ran with
_tl_arena_active=0, leaking all token and signature strings permanently.
Also prevents inner pop(mark=0) calls from deactivating the arena
between per-function scopes. Verified: self-host PASS, RSS stable.
2026-05-06 10:53:12 -05:00
Will Anderson 3726f69435 perf: 81% RSS reduction — el_release, arena scoping, streaming codegen, libcurl stub
Chain of optimizations from swarm rounds 4-7:
- Flat stride-2 token list: eliminate per-token Map allocation (~112B each × N tokens)
- Systematic el_release() in parser.el: eagerly free intermediate parse result maps
- Per-function and per-statement arena scoping in codegen_streaming()
- Streaming codegen pipeline: parse one fn at a time, emit C, discard AST
- HAVE_CURL guard: elc CLI binary drops libcurl, eliminating SSL/TLS init overhead
- HTML codegen parts-list: O(n) instead of O(n²) string growth for nested templates
- Batch c_escape: str_slice clean runs instead of char-at per byte

Result: 33.4MB → 6.5MB RSS on web/src/main.el (-81%). Self-host: PASS.
2026-05-05 20:39:38 -05:00
Will Anderson ee86736eab merge round-4-delta: flat stride-2 token list + str_char_code dispatch + batch c_escape
- Flat token list: lexer emits [kind0, val0, kind1, val1, ...] instead of [{kind,val}, ...]
  Eliminates per-token ElMap allocation (~112B × N tokens)
- str_char_code hot loop: char classification via Int codes, no strdup per char
- Batch c_escape: str_slice clean runs instead of char-at per byte
- Parser updated to use tok_at/tok_kind/tok_value stride-2 accessors
2026-05-05 20:29:35 -05:00
Will Anderson eb52be4ade runtime: add EL_TRUE/EL_FALSE macros and scoped arena for CLI
Adds EL_TRUE/EL_FALSE convenience macros to el_runtime.h alongside the
existing EL_NULL, making boolean-returning builtins readable without
raw (el_val_t) casts. Documents all value macros in the header comment.

Also lands el_arena_push/el_arena_pop — a scoped string arena for CLI
programs that never call el_request_start/end. The compiler can push a
mark before a compilation unit and pop it after to free intermediate
strings, reducing peak RSS during long compile runs.
2026-05-05 19:15:49 -05:00
Will Anderson e587bedf30 round-3-gamma: combine c_escape + scan_interp_string batching — max round-3 savings
Combines two orthogonal optimizations:
1. c_escape batching (from alpha): ASCII runs emitted as str_slice segments instead
   of one str_char_at string per byte. O(N) allocs → O(K) where K = special chars.

2. scan_interp_string batching (from beta): char dispatch via str_char_code (Int)
   + clean_start tracking to flush plain runs as str_slice. Eliminates per-char
   string allocations in the string-literal scanning hot path.

Result on web/src/main.el: 14.5MB -> 13.4MB peak RSS (-7.6%).
Self-hosting: PASS.
2026-05-05 16:01:05 -05:00
Will Anderson 1eef9928f4 round-2-gamma: combine flat token list + char code dispatch — max round-2 savings
Combines two orthogonal optimizations:
1. Flat token list (from beta): lex() returns [Any] with alternating kind/value
   pairs instead of [Map], eliminating one ElMap per token (~3 mallocs each).
   Parser updated: tok_kind(t,i) = t[2*i], tok_value(t,i) = t[2*i+1].

2. Char code dispatch (from alpha): lex() hot loop uses str_char_code -> Int
   instead of str_char_at -> strdup String for all character classification.
   Eliminates ~400K x 16B = 6.4MB of temporary string allocations.

scan_digits and scan_ident also updated to use str_char_code.

Result on main.el: 17.1MB -> 14.4MB peak RSS (-16%).
Self-hosting: PASS.
2026-05-05 15:46:20 -05:00
Will Anderson 1e67544c88 round-2-alpha: char code ops in lex() hot loop — eliminate str_char_at allocations
Replace str_char_at (returns strdup String) with str_char_code (returns Int)
in the main lex() while loop and scan_digits/scan_ident helpers.

For a 400KB combined source, str_char_at was allocating ~400K x 16B = 6.4MB
of transient 2-byte strings for the ch variable alone. str_char_code returns
an integer directly — zero allocation.

Add Int-based helpers: is_digit_code, is_alpha_code, is_ws_code,
is_alnum_or_underscore_code. Rewrite lex() operator dispatch using char
code constants (e.g. '/'=47, '"'=34, '='=61).

Result on main.el: 17.1MB -> 15.4MB peak RSS (-10%).
Self-hosting: PASS.
2026-05-05 15:43:29 -05:00
Will Anderson 2ac11a67b1 beta: replace native_string_chars with str_char_at/str_slice in lexer — 49% memory reduction on large files 2026-05-05 15:19:59 -05:00
Will Anderson 7f295bffe9 fix: codegen O(n²) HTML memory leak + elb stderr surface + runtime dir path 2026-05-05 14:40:15 -05:00
Will Anderson 962c8cbe57 dist: add linux/amd64 binaries and el_runtime.js 2026-05-05 09:44:25 -05:00
Will Anderson b580a63540 release: el-install binary and SDK bundle 2026-05-05 03:03:06 -05:00
Will Anderson bdd7b56703 feat: el-install binary + SDK bundle release 2026-05-05 03:03:01 -05:00
Will Anderson 592f8f482a add el-install binary and SDK bundle to release pipeline
- lang/tools/install/el-install.el: El program that fetches the latest
  release from the Gitea API, downloads el-sdk-latest.tar.gz, and
  extracts it into ~/.el (or a custom prefix passed as argv[1])
- lang/tools/install/manifest.el: build manifest for the el-install package
- .gitea/workflows/sdk-release.yaml: build elb, epm, and el-install
  binaries; bundle elc + elb + epm + runtime files into el-sdk-latest.tar.gz;
  attach both the tarball and el-install binary to the Gitea release
  alongside the existing per-file GCP uploads
2026-05-05 03:02:56 -05:00
Will Anderson 8524479f89 sync CI fixes and pre-commit hook from main 2026-05-05 02:38:01 -05:00
Will Anderson b2775b9228 fix CI paths for monorepo lang/ layout; add pre-commit hook 2026-05-05 02:37:56 -05:00
Will Anderson 52d0dd4225 release: monorepo restructure — foundation repos unified under el/ 2026-05-05 02:25:53 -05:00
Will Anderson d7d7852f2e monorepo: fold engram, elp, el-ui, elql, el-ide into el (history preserved) 2026-05-05 02:25:34 -05:00
Will Anderson 27f99f4053 monorepo: fold el-ide into ide/ (history preserved) 2026-05-05 01:40:49 -05:00
Will Anderson f1c0604ed8 monorepo: fold elql into ql/ (history preserved) 2026-05-05 01:40:45 -05:00
Will Anderson 4395d551c4 monorepo: fold el-ui into ui/ (history preserved) 2026-05-05 01:40:41 -05:00
Will Anderson 4a3f53cae6 monorepo: fold elp into elp/ (history preserved) 2026-05-05 01:40:34 -05:00
Will Anderson f51daa6ba0 monorepo: fold engram into engram/ (history preserved) 2026-05-05 01:40:30 -05:00
Will Anderson 1ae68962cf restructure: move el compiler content into lang/ 2026-05-05 01:38:51 -05:00
Will Anderson ce68f91a38 merge integrate/el-html-templates: add HTML template parser and codegen 2026-05-05 00:18:03 -05:00
Will Anderson 3e7d316c65 feat: extract HTML template parser/codegen from feat/el-html-templates
Parser additions (parser.el, no existing features removed):
- HTML template parser functions: is_html_tag_name, is_void_element,
  parse_html_text_tokens, parse_html_attrs, parse_html_children,
  parse_html_each_body, parse_html_element, parse_html_template
- HtmlTemplate detection in parse_primary (<tagname> and <!doctype>)
- Lambda fn literal expression node (parse_primary)
- Enum::Variant pattern matching (parse_pattern)
- type definition optional = before {
- try/catch statement (TryCatch AST node)

Codegen additions (codegen.el, no existing features removed):
- HTML template C codegen: cg_html_template, cg_html_parts,
  cg_html_attrs_str, cg_html_element_str, cg_html_each, next_html_id
- HtmlTemplate and Lambda dispatch in cg_expr
- Variant pattern support in cg_match
- TryCatch lowering in cg_stmt (C: runs try body, ignores catch)
- builtin_arity entries: getpid_now, stdout_to_file, stdout_restore

JS codegen additions (codegen-js.el, pure additions only):
- JS HTML template codegen: js_cg_html_template and helpers
- HtmlTemplate dispatch in js_cg_expr

Example: examples/html-page.el
2026-05-05 00:17:59 -05:00
Will Anderson 847f556ee3 merge integrate/js-browser-runtime: add JS compilation target 2026-05-05 00:11:07 -05:00
Will Anderson 92f393afd8 feat: extract JS browser runtime from feat/js-browser-runtime
- Update el-compiler/src/codegen-js.el to Phase 5 (1245 lines, up from 926)
  Adds: lambda literals, try/catch, extern fn, JS method call, Promise helpers,
  Object/Array utils, URL import declarations
- Update el-compiler/runtime/el_runtime.js (1049 lines, up from 679)
- Add examples/browser-counter.el, examples/browser-auth.el
- Update spec/codegen-js.md to Phase 5 status
- Update el-compiler/src/compiler.el: add --bundle, --minify, --obfuscate flags,
  bundled IIFE mode, terser/javascript-obfuscator post-processing pipeline
- No lexer.el or parser.el taken from this branch
2026-05-05 00:11:03 -05:00
Will Anderson 3fbfe76f14 merge integrate/native-testing: add native El test suite 2026-05-05 00:10:00 -05:00
Will Anderson 9013e241c3 feat: extract native El test suite from feat/native-testing
- Add tests/native/test_{core,text,string,math,state,time,json,env,fs}.el
- test_codegen_js.el renamed to test_core.el per dev convention
- Add native test CI steps to ci-dev.yaml (compile-link-run pattern)
- No lexer.el/parser.el/codegen.el changes taken from this branch
2026-05-05 00:09:57 -05:00
Will Anderson f9406afc83 merge ci/add-release-workflow into dev 2026-05-05 00:04:51 -05:00
Will Anderson e16f18b409 merge ci/wire-engram-elql-dispatch into dev 2026-05-05 00:02:41 -05:00
Will Anderson 507b220518 merge runtime/integrate into dev 2026-05-05 00:01:16 -05:00
Will Anderson 4e79edbe81 ci: retrigger after ci-base image rebuild 2026-05-04 20:17:16 -05:00
Will Anderson deb7faba7f ci: retrigger after ci-base image rebuild 2026-05-04 20:17:14 -05:00
Will Anderson e8b22e16a2 add el-tests vessel: manifest-based test suite under tests/suite/
Restructures the test suite as a proper El vessel with manifest.el and
src/ layout, eliminating the bash run.sh harness. CI runs the suite with
two commands: `cd tests/suite && elb && ./dist/el-tests`. Exit code is
the fail count (0 = all pass).

163 test cases across 7 modules: string (52), math (13), json (26),
state (11), time (25), fs (16), collections (19).
2026-05-04 19:53:35 -05:00
Will Anderson 26e327ac62 enforce source branch in CI: stage←dev, main←stage 2026-05-04 19:34:51 -05:00
Will Anderson c704e53102 enforce source branch in CI: stage←dev, main←stage 2026-05-04 19:34:45 -05:00
Will Anderson 3086a56b5c enforce source branch in CI: stage←dev, main←stage 2026-05-04 19:34:34 -05:00
Will Anderson 2eebd13221 Add release workflow listening to el-sdk-updated and engram-updated
Triggers on push to main plus repository_dispatch for both el-sdk-updated
and engram-updated. Installs El SDK from foundation-prod, compile-checks all
standalone .el programs, and includes elql-updated dispatch placeholder for
future downstream consumers.
2026-05-04 19:32:23 -05:00
Will Anderson 38d1905f1d Wire engram-updated dispatch to elql
Replace placeholder comment with actual curl dispatch call that fires
engram-updated to neuron-technologies/elql on every Engram release.
2026-05-04 19:32:08 -05:00
Will Anderson 7c644b8d89 Add dev/stage CI pipelines and expand sdk-release to full prod pipeline
- Add ci-dev.yaml: builds elc gen2→gen3, runs 4 test suites, publishes
  el/elc + el_runtime.c + el_runtime.h to foundation-dev Artifact Registry
- Add ci-stage.yaml: same as dev but targets foundation-stage registry
- Update sdk-release.yaml: publish 3 SDK artifacts to foundation-prod
  Artifact Registry after Gitea release; expand dispatch list from 2 to 6
  downstream repos (el-ui, elp, elql, el-ide added alongside engram/forge)
2026-05-04 19:32:05 -05:00
Will Anderson 9e8d23bcd9 add epm — El Package Manager
Introduces epm/, a new component written entirely in native El.
epm manages vessels (El's deployable package format): publish to Engram,
install with full dependency resolution, list registry contents, and
inspect vessel metadata.

- epm/manifest.el         — package manifest
- epm/src/manifest.el     — vessel/package manifest parser (line-by-line,
                            same approach as elb.el)
- epm/src/registry.el     — Engram-backed vessel registry (POST /api/nodes,
                            GET /api/search); vessels stored as Entity nodes
                            with label "vessel:<name>:<version>"
- epm/src/install.el      — topological dependency resolver with cycle
                            detection; installs to .epm/vessels/<name>/
- epm/src/epm.el          — main entry point: publish / install / list / info
2026-05-04 19:31:24 -05:00
Will Anderson 0791fda43e elb: add -lm to link flags — el_runtime.c uses math.h functions
el_runtime.c includes <math.h> and calls pow(), sqrt(), log() in several
places (math operations, engram dampening, float formatting). Without -lm
the linker fails on Linux when linking programs built with elb.
2026-05-04 19:14:09 -05:00
Will Anderson 53f2df500d runtime: add dharma-required functions to el_runtime.c and runtime/*.el
Add the following functions that dharma registry calls but were missing
from the El runtime:

el_runtime.c (consumed by the old build system via released SDK):
  - list_len, list_get — aliases for el_list_len/el_list_get (handlers.el)
  - json_array_push — append pre-encoded element to JSON array string
  - now_millis, unix_timestamp_ms, time_now_ms — ms-since-epoch aliases
  - log_info, log_warn — structured stderr log helpers
  - config — reads config from environment (alias for getenv)
  - http_patch — HTTP PATCH with Content-Type: application/json
  - http_post_engram — HTTP POST with optional X-API-Key header
  - http_get_engram — HTTP GET with optional X-API-Key header
  - str_to_bytes — encode string as JSON byte array [72,101,...]
  - bytes_to_str — decode JSON byte array back to string
  - hash_sha256 — SHA-256 hex digest using built-in sha256 impl

runtime/*.el (consumed by the new build system):
  - http.el: http_patch, http_post_engram, http_get_engram
  - time.el: now_millis, unix_timestamp_ms, time_now_ms
  - env.el: config, log_info, log_warn, list_len, list_get
  - json.el: json_array_push, bytes_to_str
  - string.el: str_to_bytes, hash_sha256 (via __sha256_hex seed)

el_seed.h / el_seed.c:
  - __sha256_hex primitive with self-contained SHA-256 implementation
2026-05-04 19:07:08 -05:00
Will Anderson b0d0f18524 ci: fix YAML in workflow
El CI -dev / build-and-test (push) Failing after 35s
2026-05-04 14:33:33 -05:00
Will Anderson 24ccef820c ci: add workflow_dispatch trigger 2026-05-04 14:32:48 -05:00
Will Anderson eb282d8c0c ci: add El CI dev pipeline 2026-05-04 14:22:10 -05:00
Will Anderson cd164debb8 add /nodes/list as alias for GET /nodes
Dharma's EngramDB client calls /nodes/list to retrieve all nodes.
Add this as an alias for the existing /nodes (and /api/nodes) route
so downstream clients don't need to be updated when the API drifts.

Also update dist/engram.c to match server.el.
2026-05-04 11:44:22 -05:00