Commit Graph

17 Commits

Author SHA1 Message Date
694e4ec999 feat: add Ref cells for mutable state (Ref.new, Ref.get, Ref.set, Ref.update)
Implements WISH-013 mutable state primitives. Ref<T> is a mutable container
using existing module call syntax. Supported across interpreter, JS, and C backends.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:01:29 -05:00
667a94b4dc feat: add extern let declarations for JS FFI
Add support for `extern let name: Type` and `extern let name: Type = "jsName"`
syntax for declaring external JavaScript values. This follows the same pattern
as extern fn across all compiler passes: parser, typechecker, interpreter
(runtime error placeholder), JS backend (emits JS name directly without
mangling), formatter, linter, modules, and symbol table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:29:44 -05:00
1b629aaae4 feat: add 10 missing List operations to JS backend
Add find, findIndex, any, all, zip, flatten, contains, take, drop,
and forEach to the JS backend's emit_list_operation function. These
operations previously worked in the interpreter and C backend but
caused "Unknown List operation" errors when compiled to JS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 19:21:26 -05:00
fbb7ddb6c3 feat: add extern fn declarations for JS FFI
Adds `extern fn` syntax for declaring external JavaScript functions:
  extern fn getElementById(id: String): Element
  extern fn getContext(el: Element, kind: String): CanvasCtx = "getContext"
  pub extern fn alert(msg: String): Unit

Changes across 11 files:
- Lexer: `extern` keyword
- AST: `ExternFnDecl` struct + `Declaration::ExternFn` variant
- Parser: parse `extern fn` with optional `= "jsName"` override
- Typechecker: register extern fn type signatures
- Interpreter: ExternFn value with clear error on call
- JS backend: emit extern fn calls using JS name (no _lux suffix)
- C backend: silently skips extern fns
- Formatter, linter, modules, symbol_table: handle new variant

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 18:38:42 -05:00
091ff1e422 feat: add List.sort and List.sortBy functions (issue 9)
Add sorting support to the List module across all backends:
- List.sort for natural ordering (Int, Float, String, Bool, Char)
- List.sortBy for custom comparator-based sorting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 10:02:21 -05:00
c67e3f31c3 feat: add and/or keywords, handle alias, --watch flag, JS tree-shaking
- WISH-008: `and`/`or` as aliases for `&&`/`||` boolean operators
- WISH-006: `handle` as alias for `run ... with` (same AST output)
- WISH-005: `--watch` flag for `lux compile` recompiles on file change
- WISH-009: Tree-shake unused runtime sections from JS output based on
  which effects are actually used (Console, Random, Time, Http, Dom)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 03:35:47 -05:00
3cdde02eb2 feat: add Int.toFloat/Float.toInt JS backend support and fix Map C codegen
- JS backend: Add Int/Float module dispatch in both Call and EffectOp paths
  for toFloat, toInt, and toString operations
- C backend: Fix lux_strdup → lux_string_dup in Map module codegen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 02:05:40 -05:00
a5762d0397 feat: add built-in Map type with String keys
Add Map<String, V> as a first-class built-in type for key-value storage,
needed for self-hosting the compiler (parser/typechecker/interpreter all
rely heavily on hashmaps).

- types.rs: Type::Map(K,V) variant, all match arms (unify, apply, etc.)
- interpreter.rs: Value::Map, 12 BuiltinFn variants (new/set/get/contains/
  remove/keys/values/size/isEmpty/fromList/toList/merge), immutable semantics
- typechecker.rs: Map<K,V> resolution in resolve_type
- js_backend.rs: Map as JS Map with emit_map_operation()
- c_backend.rs: LuxMap struct (linear-scan), runtime fns, emit_map_operation()
- main.rs: 12 tests covering all Map operations
- validate.sh: now checks all projects/ directories too

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:45:13 -05:00
a0fff1814e fix: JS backend scoping for let/match/if inside closures
Three related bugs fixed:
- BUG-009: let bindings inside lambdas hoisted to top-level
- BUG-011: match expressions inside lambdas hoisted to top-level
- BUG-012: variable name deduplication leaked across function scopes

Root cause: emit_expr() uses writeln() for statements, but lambdas
captured only the return value, not the emitted statements. Also,
var_substitutions from emit_function() leaked to subsequent code.

Fix: Lambda handler now captures all output emitted during body
evaluation and places it inside the function body. Both emit_function
and Lambda save/restore var_substitutions to prevent cross-scope leaks.
Lambda params are registered as identity substitutions to override any
outer bindings with the same name.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 01:10:55 -05:00
b56c5461f1 fix: JS const _ duplication and hardcoded version string
- JS backend now emits wildcard let bindings as side-effect statements
  instead of const _ declarations, fixing SyntaxError on multiple let _ = ...
- Version string now uses env!("CARGO_PKG_VERSION") to auto-sync with Cargo.toml
- Add -lm linker flag for math library support

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 23:05:03 -05:00
61e1469845 feat: add ++ concat operator and auto-invoke main
BUG-004: Add ++ operator for string and list concatenation across all
backends (interpreter, C, JS) with type checking and formatting support.

BUG-001: Auto-invoke top-level `let main = fn () => ...` when main is
a zero-parameter function, instead of just printing the function value.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 22:01:41 -05:00
d05b13d840 fix: JS backend compiles print() to console.log()
Bare `print()` calls in Lux now emit `console.log()` in JS output
instead of undefined `print()`. Fixes BUG-006.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:09:07 -05:00
542255780d feat: add tuple index access, multiline args, and effect unification fix
- Tuple index: `pair.0`, `pair.1` syntax across parser, typechecker,
  interpreter, C/JS backends, formatter, linter, and symbol table
- Multi-line function args: allow newlines inside argument lists
- Fix effect unification for callback parameters (empty expected
  effects means "no constraint", not "must be pure")

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:21:48 -05:00
40c9b4d894 feat: complete JS backend with Dom effect and Html module
- Add full Dom effect: querySelector, createElement, addEventListener,
  setAttribute, classList, styles, forms, scrolling, etc.
- Add Html module for type-safe HTML construction (Elm-style)
- Add TEA (The Elm Architecture) runtime for browser apps
- Add view dependency analysis for Svelte-style optimizations
- Support both browser and Node.js environments

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-15 03:54:04 -05:00
38bf825134 feat: add effects to JS backend and fix code generation bugs
Phase 2 of JS backend: implement effect handlers in runtime

Effects added:
- Console: print, readLine, readInt
- Random: int, bool, float
- Time: now, sleep
- Http: get, post, postJson (async with fetch)

Bug fixes:
- Fix if-else with blocks executing both branches (use if-else
  statement instead of ternary for branches with statements)
- Fix main function being called twice when top-level let binding
  already invokes it
- Fix List module operations incorrectly treated as effect operations

New tests:
- test_js_random_int
- test_js_random_bool
- test_js_random_float
- test_js_time_now

All 19 JS backend tests pass.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 21:34:07 -05:00
ce4344810d test: add comprehensive integration tests for JS backend
Add 10 integration tests that compile Lux to JavaScript and verify
correct execution in Node.js:

- test_js_factorial: Recursion and effects
- test_js_fibonacci: Classic recursive algorithm
- test_js_adt_and_pattern_matching: Custom ADTs with match
- test_js_option_type: Built-in Option type handling
- test_js_closures: Closure creation and variable capture
- test_js_higher_order_functions: Functions as values
- test_js_list_operations: List.map, List.foldl
- test_js_pipe_operator: Pipe (|>) operator
- test_js_records: Record literal and field access
- test_js_string_concatenation: String operations

Also fix List module operations being incorrectly treated as effects
by adding special-case handling in EffectOp emission.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 21:28:07 -05:00
10ff8dc6ad feat: add JavaScript backend for browser/Node.js compilation
Implement Phase 1 of the browser/frontend plan with a complete JS
code generator that compiles Lux programs to JavaScript:

- Basic types: Int, Float, Bool, String, Unit → JS primitives
- Functions and closures → native JS functions with closure capture
- Pattern matching → if/else chains with tag checks
- ADT definitions → tagged object constructors
- Built-in types (Option, Result) → Lux.Some/None/Ok/Err helpers
- Effects → handler objects passed as parameters
- List operations → Array methods (map, filter, reduce, etc.)
- Top-level let bindings and run expressions

CLI usage:
  lux compile app.lux --target js -o app.js
  lux compile app.lux --target js --run

Tested with factorial, datatypes, functional, tailcall, and hello
examples - all producing correct output when run in Node.js.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-14 21:22:43 -05:00