restructure: move el compiler content into lang/

This commit is contained in:
Will Anderson
2026-05-05 01:38:51 -05:00
parent ce68f91a38
commit 1ae68962cf
143 changed files with 0 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
// activate.el The `activate` construct: spreading activation over the type graph.
//
// The `activate` keyword is the most novel feature of the Engram language.
// Instead of querying a database with SQL or a key lookup, you query the
// *type graph* using a natural language description. The result is
// statically typed the compiler knows you get [User] back, not Any.
//
// How it works:
//
// 1. At compile time, the type checker verifies that `User` is a registered
// type with a corresponding Engram node mapping.
//
// 2. At runtime, the Engram runtime performs spreading activation over
// the knowledge graph, starting from the User node, propagating to
// semantically related nodes with co-activation energy proportional
// to edge weights and node salience.
//
// 3. The query string "customer who purchased recently" is embedded
// and used as a semantic filter: only nodes whose embeddings are
// within cosine-similarity threshold of the query embedding are returned.
//
// 4. The result is type-safe: [User]. You don't get back Any or a JSON blob.
// The type checker enforces this at compile time.
type User {
id: Uuid
name: String
email: String
}
type Order {
id: Uuid
user_id: Uuid
amount: Float
status: String
}
// Query: find all users who are semantically related to "customer who purchased recently"
// The result type is [User] an array of User nodes from the knowledge graph.
let recent_buyers: [User] = activate User where "customer who purchased recently"
// You can also activate on other types:
let pending_orders: [Order] = activate Order where "order awaiting fulfillment"
// Spreading activation respects the type graph edges.
// If User and Customer share an Engram node type (e.g. "Entity"),
// they are semantically compatible the type checker allows
// treating one as the other when they map to the same Engram node class.
fn process_buyers(users: [User]) -> String {
return "processing users"
}
let result: String = process_buyers(recent_buyers)
+200
View File
@@ -0,0 +1,200 @@
// browser-auth.el -- El-compiled auth flow using Supabase
//
// Compile: elc --target=js --bundle examples/browser-auth.el > auth.js
// (requires el_runtime.js in the same directory as browser-auth.el)
//
// Demonstrates:
// - extern fn for declaring Supabase client constructor
// - anonymous function literals for callbacks
// - method call syntax on Any-typed values (client.auth.signInWithOtp)
// - try/catch for error handling
// - @async functions with DOM interaction
// - DOM bridge: dom_get_element, dom_get_value, dom_set_text, dom_add_class
// dom_remove_class, dom_show, dom_hide, dom_is_null
// - window_set to expose El functions to the browser global scope
// - local_storage_set/get for session hints
// - set_timeout for transient UI state
// - state_set/get for component state
//
// Expected HTML elements:
// #acct-email-input -- email text input
// #send-link-btn -- submit button
// #auth-message -- status message container
// #auth-form -- the form to hide after success
//
// The Supabase JS SDK is loaded from CDN via a <script> tag before auth.js.
// supabase_create_client is declared extern: the runtime provides it via
// the global supabase.createClient function exposed by the CDN bundle.
// External declarations
//
// These functions are provided by the JS environment (CDN script tags).
// No body is emitted -- the compiler just records the names.
extern fn supabase_create_client(url: String, key: String) -> Any
// UI helpers
fn show_message(text: String, is_error: Bool) -> Void {
let msg_el = dom_get_element("auth-message")
if !dom_is_null(msg_el) {
dom_set_text(msg_el, text)
dom_remove_class(msg_el, "hidden")
if is_error {
dom_add_class(msg_el, "error")
dom_remove_class(msg_el, "success")
} else {
dom_add_class(msg_el, "success")
dom_remove_class(msg_el, "error")
}
}
}
fn set_button_loading(loading: Bool) -> Void {
let btn = dom_get_element("send-link-btn")
if !dom_is_null(btn) {
if loading {
dom_set_text(btn, "Sending...")
dom_set_attr(btn, "disabled", "true")
} else {
dom_set_text(btn, "Send Magic Link")
dom_remove_attr(btn, "disabled")
}
}
}
fn clear_message() -> Void {
let msg_el = dom_get_element("auth-message")
if !dom_is_null(msg_el) {
dom_add_class(msg_el, "hidden")
dom_set_text(msg_el, "")
}
}
// Email validation
fn is_valid_email(email: String) -> Bool {
let trimmed: String = str_trim(email)
if str_len(trimmed) < 5 { return false }
let at_pos: Int = str_index_of(trimmed, "@")
if at_pos < 1 { return false }
let dot_pos: Int = str_index_of(trimmed, ".")
if dot_pos < at_pos + 2 { return false }
return true
}
// Supabase client construction
//
// Build a Supabase client from config injected into the page as NEURON_CFG.
// The extern fn supabase_create_client maps to supabase.createClient on
// the global object exposed by the CDN bundle.
fn get_supabase_client() -> Any {
let cfg = window_get("NEURON_CFG")
if dom_is_null(cfg) {
return null
}
let url: String = cfg["supabaseUrl"]
let key: String = cfg["supabaseAnonKey"]
supabase_create_client(url, key)
}
// Auth flow
@async
fn send_magic_link() -> Void {
let email_el = dom_get_element("acct-email-input")
if dom_is_null(email_el) {
show_message("Could not find email input", true)
return null
}
let email: String = str_trim(dom_get_value(email_el))
if !is_valid_email(email) {
show_message("Please enter a valid email address", true)
return null
}
clear_message()
set_button_loading(true)
state_set("auth_email", email)
// Build the Supabase client and call auth.signInWithOtp directly.
// Method call syntax on Any-typed values: client.auth.signInWithOtp(opts)
// No native_js_call required.
let client = get_supabase_client()
if dom_is_null(client) {
show_message("Auth service not configured", true)
set_button_loading(false)
return null
}
try {
let opts: Map<String, Any> = { "email": email }
// client is Any-typed; .auth returns the auth sub-client (also Any).
// .signInWithOtp(opts) returns a Promise. @async + await handles it.
let resp = client.auth.signInWithOtp(opts)
let err = resp["error"]
if !dom_is_null(err) {
let msg: String = err["message"]
show_message("Error: " + msg, true)
} else {
local_storage_set("auth_pending_email", email)
show_message("Magic link sent! Check your inbox for " + email, false)
let form = dom_get_element("auth-form")
if !dom_is_null(form) {
dom_hide(form)
}
}
} catch (err: Any) {
show_message("Unexpected error. Please try again.", true)
}
set_button_loading(false)
}
// Keyboard support
fn handle_email_keydown(event: Any) -> Void {
let key: String = dom_get_prop(event, "key")
if str_eq(key, "Enter") {
send_magic_link()
}
}
// Initialization
fn init_auth() -> Void {
let email_el = dom_get_element("acct-email-input")
if !dom_is_null(email_el) {
// Pre-fill from local storage if a pending send was interrupted.
let pending: String = local_storage_get("auth_pending_email")
if !str_eq(pending, "") {
dom_set_value(email_el, pending)
}
// Anonymous function literal for inline event handler.
dom_listen(email_el, "keydown", fn(event: Any) -> Void {
let key: String = dom_get_prop(event, "key")
if str_eq(key, "Enter") {
send_magic_link()
}
})
}
let btn = dom_get_element("send-link-btn")
if !dom_is_null(btn) {
dom_listen(btn, "click", fn(event: Any) -> Void {
send_magic_link()
})
}
state_set("auth_initialized", "true")
}
fn main() -> Void {
// Expose send_magic_link globally so inline event handlers can call it.
window_set("sendMagicLink", send_magic_link)
window_set("initAuth", init_auth)
// Run init when DOM is ready.
window_on_load(init_auth)
}
+41
View File
@@ -0,0 +1,41 @@
// browser-counter.el canonical browser DOM bridge example
//
// Compile with: elc --target=js examples/browser-counter.el > counter.js
//
// Then include in an HTML page that has a <span id="count-display"> element.
// The page can call window.increment() from any onclick handler, e.g.:
// <button onclick="increment()">+1</button>
//
// On load the display is initialised to "0". Each call to increment()
// adds 1 and updates the display text.
//
// Demonstrates:
// - dom_get_element to locate a DOM node by id
// - dom_set_text to update visible text content
// - dom_is_null to guard against missing elements
// - window_set to expose an El function for inline event handlers
// - state_set/get for in-memory counter state (survives calls, resets
// on page reload same semantics as the C state_* API)
fn init() -> Void {
state_set("counter", 0)
let display = dom_get_element("count-display")
if !dom_is_null(display) {
dom_set_text(display, "0")
}
}
fn increment() -> Void {
let current = str_to_int(state_get("counter"))
let next = current + 1
state_set("counter", next)
let display = dom_get_element("count-display")
if !dom_is_null(display) {
dom_set_text(display, int_to_str(next))
}
}
fn main() -> Void {
init()
window_set("increment", increment)
}
+57
View File
@@ -0,0 +1,57 @@
// Engram language example test file
// Run with: el test-file examples/hello-project/src/tests.el
test "basic arithmetic" {
let x: Int = 6
let y: Int = 7
let result: Int = x * y
assert result == 42
}
test "string operations" {
let greeting: String = "Hello"
let name: String = "Engram"
let full: String = greeting + ", " + name
assert full == "Hello, Engram"
}
test "type graph has Point type" {
seed Node {
type: "Point"
content: "A 2D coordinate"
importance: 0.8
tier: Semantic
}
let results = activate Point where "coordinate"
assert results.len() > 0
}
test "empty graph" {
let results = activate Customer where "anything"
assert results.len() == 0
}
test "empty graph returns insufficient" {
let result = reason("Is there a customer named Will?")
assert result.verdict == "Insufficient"
}
test "seeded graph reasoning" {
seed Node {
type: "Customer"
content: "Will Anderson, founding member"
importance: 0.9
tier: Semantic
}
let result = reason("founding member")
assert result.verdict == "Supported"
}
test "production customer lookup" target: e2e {
// No seeds uses the real Engram database
// (skipped when ENGRAM_URL is not set)
let results = activate Customer where "founding member"
assert results.len() > 0
}
+8
View File
@@ -0,0 +1,8 @@
// hello.el The simplest Engram program.
// Run with: el run hello.el
fn greet(name: String) -> String {
return "Hello, " + name
}
let message: String = greet("World")
+40
View File
@@ -0,0 +1,40 @@
// html-page.el Example of native HTML template syntax in El.
//
// El HTML templates let you write HTML directly in expression position.
// Interpolated values are automatically HTML-escaped.
// Use raw(expr) to bypass escaping when you know the content is safe.
//
// Compile and run:
// ./dist/platform/elc examples/html-page.el > /tmp/html-page.c
// cc -std=c11 -I el-compiler/runtime -lcurl -lpthread \
// -o /tmp/html-page /tmp/html-page.c el-compiler/runtime/el_runtime.c
// /tmp/html-page
fn render_item(item: String) -> String {
return <li class="item">{item}</li>
}
fn render_page(title: String, items: [String]) -> String {
return <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{title}</title>
</head>
<body>
<h1>{title}</h1>
<ul>
{#each items as item}
<li class="item">{item}</li>
{/each}
</ul>
<p>Built with El HTML templates</p>
</body>
</html>
}
fn main() -> Void {
let items: [String] = ["Lexer", "Parser", "Codegen", "Runtime"]
let page: String = render_page("El Compiler Stages", items)
println(page)
}
+33
View File
@@ -0,0 +1,33 @@
// http-status-envelope.el acceptance test for the __status__ HTTP envelope.
//
// Before fix: a handler returning {"__status__":401,"error":"unauthorized"}
// went out as an HTTP 200 with the JSON body verbatim, so Cloud Run logs were
// full of 200s for what should have been 4xx/5xx.
//
// After fix: when the response body's FIRST key is __status__, the runtime
// reads the integer value as the HTTP status code and strips the marker from
// the body before sending it to the client.
//
// Verify with curl:
// curl -i http://localhost:8081/auth -> HTTP/1.1 401 Unauthorized
// curl -i http://localhost:8081/health -> HTTP/1.1 200 OK
// curl -i http://localhost:8081/oops -> HTTP/1.1 503 Service Unavailable
fn handle(method: String, path: String, body: String) -> String {
if path == "/auth" {
return "{\"__status__\":401,\"error\":\"unauthorized\"}"
}
if path == "/oops" {
return "{\"__status__\":503,\"error\":\"degraded\"}"
}
if path == "/health" {
return "{\"ok\":true}"
}
return "{\"__status__\":404,\"error\":\"not found\"}"
}
fn main() -> Int {
http_set_handler("handle")
http_serve(8081, "handle")
return 0
}
+21
View File
@@ -0,0 +1,21 @@
// json-array-traversal.el acceptance test for json_get dot-path with array
// indices.
//
// Before fix: json_get("...", "0.field") would substring-search for a literal
// key named `"0.field"` and find nothing, returning "".
//
// After fix: dot-path segments that are all digits are treated as array
// indices and the walker descends into the array.
fn test_array_traversal() -> String {
let s: String = "[{\"name\":\"alice\"},{\"name\":\"bob\"}]"
let a: String = json_get(s, "0.name")
let b: String = json_get(s, "1.name")
return a + "," + b
}
fn main() -> Int {
let r: String = test_array_traversal()
print(r)
return 0
}
+22
View File
@@ -0,0 +1,22 @@
// reassign-in-if.el acceptance test for bare reassignment inside if-body.
//
// Before fix: parser dropped `x = "override"` on the floor and codegen emitted
// three orphan expressions (`x; EL_NULL; EL_STR("override");`). Effective store
// was lost, so the function returned "default".
//
// After fix: parse_stmt recognises `Ident "=" Expr` as an Assign statement and
// codegen emits a real C assignment, so the function returns "override".
fn test_reassign() -> String {
let x: String = "default"
if true {
x = "override"
}
return x
}
fn main() -> Int {
let r: String = test_reassign()
print(r)
return 0
}
+40
View File
@@ -0,0 +1,40 @@
// types.el Type definitions and pattern matching.
//
// Demonstrates:
// - type (struct) definitions
// - enum definitions with payloads
// - match expressions with enum patterns
// A user-defined struct type.
// Every field is typed; the type name maps to an Engram graph node.
type User {
id: Uuid
name: String
email: String
}
// An enum with a payload variant.
enum Status {
Active
Inactive
Pending(String)
}
// A function that takes a Status and returns a human-readable string.
fn describe_status(s: Status) -> String {
return match s {
Status::Active => "user is active"
Status::Inactive => "user is inactive"
Status::Pending(reason) => "pending: " + reason
}
}
// Sealed blocks protect sensitive values even in debug builds.
// The runtime enforces that values in sealed blocks are never
// observable through a debugger or memory dump.
sealed {
let api_key: String = "sk-prod-12345"
}
let status: Status = Status::Pending("email not verified")
let description: String = describe_status(status)