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:
@@ -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, .. } => {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user