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 var_name = &let_decl.name.name;
|
||||
|
||||
// Check if this is a run expression (often results in undefined)
|
||||
// We still want to execute it for its side effects
|
||||
if var_name == "_" {
|
||||
// Wildcard binding: just execute for side effects
|
||||
self.writeln(&format!("{};", val));
|
||||
} else {
|
||||
self.writeln(&format!("const {} = {};", var_name, val));
|
||||
|
||||
// Register the variable for future use
|
||||
self.var_substitutions
|
||||
.insert(var_name.clone(), var_name.clone());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1040,6 +1043,11 @@ impl JsBackend {
|
||||
name, value, body, ..
|
||||
} => {
|
||||
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());
|
||||
|
||||
self.writeln(&format!("const {} = {};", var_name, val));
|
||||
@@ -1047,11 +1055,14 @@ impl JsBackend {
|
||||
// Add substitution
|
||||
self.var_substitutions
|
||||
.insert(name.name.clone(), var_name.clone());
|
||||
}
|
||||
|
||||
let body_result = self.emit_expr(body)?;
|
||||
|
||||
// Remove substitution
|
||||
if name.name != "_" {
|
||||
self.var_substitutions.remove(&name.name);
|
||||
}
|
||||
|
||||
Ok(body_result)
|
||||
}
|
||||
@@ -1238,27 +1249,36 @@ impl JsBackend {
|
||||
}
|
||||
Statement::Let { name, 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.var_substitutions
|
||||
.insert(name.name.clone(), var_name.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Emit result
|
||||
self.emit_expr(result)
|
||||
}
|
||||
|
||||
Expr::Record { fields, .. } => {
|
||||
let field_strs: Result<Vec<_>, _> = fields
|
||||
.iter()
|
||||
.map(|(name, expr)| {
|
||||
Expr::Record {
|
||||
spread, fields, ..
|
||||
} => {
|
||||
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)?;
|
||||
Ok(format!("{}: {}", name.name, val))
|
||||
})
|
||||
.collect();
|
||||
Ok(format!("{{ {} }}", field_strs?.join(", ")))
|
||||
parts.push(format!("{}: {}", name.name, val));
|
||||
}
|
||||
Ok(format!("{{ {} }}", parts.join(", ")))
|
||||
}
|
||||
|
||||
Expr::Tuple { elements, .. } => {
|
||||
|
||||
@@ -37,7 +37,7 @@ use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use typechecker::TypeChecker;
|
||||
|
||||
const VERSION: &str = "0.1.0";
|
||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
const HELP: &str = r#"
|
||||
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"])
|
||||
.arg(&output_bin)
|
||||
.arg(&temp_c)
|
||||
.arg("-lm")
|
||||
.output();
|
||||
|
||||
match compile_result {
|
||||
|
||||
Reference in New Issue
Block a user