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>
This commit is contained in:
2026-02-18 23:05:03 -05:00
parent 61e1469845
commit b56c5461f1
2 changed files with 47 additions and 26 deletions

View File

@@ -909,13 +909,16 @@ impl JsBackend {
let val = self.emit_expr(&let_decl.value)?; let val = self.emit_expr(&let_decl.value)?;
let var_name = &let_decl.name.name; let var_name = &let_decl.name.name;
// Check if this is a run expression (often results in undefined) if var_name == "_" {
// We still want to execute it for its side effects // Wildcard binding: just execute for side effects
self.writeln(&format!("{};", val));
} else {
self.writeln(&format!("const {} = {};", var_name, val)); self.writeln(&format!("const {} = {};", var_name, val));
// Register the variable for future use // Register the variable for future use
self.var_substitutions self.var_substitutions
.insert(var_name.clone(), var_name.clone()); .insert(var_name.clone(), var_name.clone());
}
Ok(()) Ok(())
} }
@@ -1040,6 +1043,11 @@ impl JsBackend {
name, value, body, .. name, value, body, ..
} => { } => {
let val = self.emit_expr(value)?; let val = self.emit_expr(value)?;
if name.name == "_" {
// Wildcard binding: just execute for side effects
self.writeln(&format!("{};", val));
} else {
let var_name = format!("{}_{}", name.name, self.fresh_name()); let var_name = format!("{}_{}", name.name, self.fresh_name());
self.writeln(&format!("const {} = {};", var_name, val)); self.writeln(&format!("const {} = {};", var_name, val));
@@ -1047,11 +1055,14 @@ impl JsBackend {
// Add substitution // Add substitution
self.var_substitutions self.var_substitutions
.insert(name.name.clone(), var_name.clone()); .insert(name.name.clone(), var_name.clone());
}
let body_result = self.emit_expr(body)?; let body_result = self.emit_expr(body)?;
// Remove substitution // Remove substitution
if name.name != "_" {
self.var_substitutions.remove(&name.name); self.var_substitutions.remove(&name.name);
}
Ok(body_result) Ok(body_result)
} }
@@ -1238,27 +1249,36 @@ impl JsBackend {
} }
Statement::Let { name, value, .. } => { Statement::Let { name, value, .. } => {
let val = self.emit_expr(value)?; let val = self.emit_expr(value)?;
let var_name = format!("{}_{}", name.name, self.fresh_name()); if name.name == "_" {
self.writeln(&format!("{};", val));
} else {
let var_name =
format!("{}_{}", name.name, self.fresh_name());
self.writeln(&format!("const {} = {};", var_name, val)); self.writeln(&format!("const {} = {};", var_name, val));
self.var_substitutions self.var_substitutions
.insert(name.name.clone(), var_name.clone()); .insert(name.name.clone(), var_name.clone());
} }
} }
} }
}
// Emit result // Emit result
self.emit_expr(result) self.emit_expr(result)
} }
Expr::Record { fields, .. } => { Expr::Record {
let field_strs: Result<Vec<_>, _> = fields spread, fields, ..
.iter() } => {
.map(|(name, expr)| { let mut parts = Vec::new();
if let Some(spread_expr) = spread {
let spread_code = self.emit_expr(spread_expr)?;
parts.push(format!("...{}", spread_code));
}
for (name, expr) in fields {
let val = self.emit_expr(expr)?; let val = self.emit_expr(expr)?;
Ok(format!("{}: {}", name.name, val)) parts.push(format!("{}: {}", name.name, val));
}) }
.collect(); Ok(format!("{{ {} }}", parts.join(", ")))
Ok(format!("{{ {} }}", field_strs?.join(", ")))
} }
Expr::Tuple { elements, .. } => { Expr::Tuple { elements, .. } => {

View File

@@ -37,7 +37,7 @@ use std::borrow::Cow;
use std::collections::HashSet; use std::collections::HashSet;
use typechecker::TypeChecker; use typechecker::TypeChecker;
const VERSION: &str = "0.1.0"; const VERSION: &str = env!("CARGO_PKG_VERSION");
const HELP: &str = r#" const HELP: &str = r#"
Lux - A functional language with first-class effects Lux - A functional language with first-class effects
@@ -902,6 +902,7 @@ fn compile_to_c(path: &str, output_path: Option<&str>, run_after: bool, emit_c:
.args(["-O2", "-o"]) .args(["-O2", "-o"])
.arg(&output_bin) .arg(&output_bin)
.arg(&temp_c) .arg(&temp_c)
.arg("-lm")
.output(); .output();
match compile_result { match compile_result {