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>
This commit is contained in:
@@ -2072,7 +2072,7 @@ impl CBackend {
|
||||
self.writeln(" LuxMap* result = lux_map_new(map->capacity);");
|
||||
self.writeln(" result->length = map->length;");
|
||||
self.writeln(" for (int64_t i = 0; i < map->length; i++) {");
|
||||
self.writeln(" result->keys[i] = lux_strdup(map->keys[i]);");
|
||||
self.writeln(" result->keys[i] = lux_string_dup(map->keys[i]);");
|
||||
self.writeln(" result->values[i] = map->values[i];");
|
||||
self.writeln(" lux_incref(map->values[i]);");
|
||||
self.writeln(" }");
|
||||
@@ -2092,7 +2092,7 @@ impl CBackend {
|
||||
self.writeln(" result->keys = (LuxString*)realloc(result->keys, sizeof(LuxString) * result->capacity);");
|
||||
self.writeln(" result->values = (void**)realloc(result->values, sizeof(void*) * result->capacity);");
|
||||
self.writeln(" }");
|
||||
self.writeln(" result->keys[result->length] = lux_strdup(key);");
|
||||
self.writeln(" result->keys[result->length] = lux_string_dup(key);");
|
||||
self.writeln(" result->values[result->length] = value;");
|
||||
self.writeln(" lux_incref(value);");
|
||||
self.writeln(" result->length++;");
|
||||
@@ -2111,7 +2111,7 @@ impl CBackend {
|
||||
self.writeln(" LuxMap* result = lux_map_new(map->capacity);");
|
||||
self.writeln(" for (int64_t i = 0; i < map->length; i++) {");
|
||||
self.writeln(" if (strcmp(map->keys[i], key) != 0) {");
|
||||
self.writeln(" result->keys[result->length] = lux_strdup(map->keys[i]);");
|
||||
self.writeln(" result->keys[result->length] = lux_string_dup(map->keys[i]);");
|
||||
self.writeln(" result->values[result->length] = map->values[i];");
|
||||
self.writeln(" lux_incref(map->values[i]);");
|
||||
self.writeln(" result->length++;");
|
||||
@@ -4677,7 +4677,7 @@ impl CBackend {
|
||||
// Sort keys: simple insertion sort
|
||||
self.writeln(&format!("for (int64_t _i = 0; _i < {}->length; _i++) {{", map));
|
||||
self.indent += 1;
|
||||
self.writeln(&format!("LuxString _ks = lux_strdup({}->keys[_i]);", map));
|
||||
self.writeln(&format!("LuxString _ks = lux_string_dup({}->keys[_i]);", map));
|
||||
self.writeln(&format!("lux_list_push({}, _ks);", temp));
|
||||
self.indent -= 1;
|
||||
self.writeln("}");
|
||||
|
||||
@@ -1082,16 +1082,24 @@ impl JsBackend {
|
||||
}
|
||||
}
|
||||
|
||||
// Int module
|
||||
// Int/Float module operations
|
||||
if let Expr::Field { object, field, .. } = func.as_ref() {
|
||||
if let Expr::Var(module_name) = object.as_ref() {
|
||||
if module_name.name == "Int" && field.name == "toFloat" {
|
||||
if module_name.name == "Int" {
|
||||
let arg = self.emit_expr(&args[0])?;
|
||||
return Ok(arg); // JS numbers are already floats
|
||||
match field.name.as_str() {
|
||||
"toFloat" => return Ok(arg),
|
||||
"toString" => return Ok(format!("String({})", arg)),
|
||||
_ => {}
|
||||
}
|
||||
if module_name.name == "Float" && field.name == "toInt" {
|
||||
}
|
||||
if module_name.name == "Float" {
|
||||
let arg = self.emit_expr(&args[0])?;
|
||||
return Ok(format!("Math.trunc({})", arg));
|
||||
match field.name.as_str() {
|
||||
"toInt" => return Ok(format!("Math.trunc({})", arg)),
|
||||
"toString" => return Ok(format!("String({})", arg)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1183,15 +1191,23 @@ impl JsBackend {
|
||||
}
|
||||
|
||||
// Special case: Int module operations
|
||||
if effect.name == "Int" && operation.name == "toFloat" {
|
||||
if effect.name == "Int" {
|
||||
let arg = self.emit_expr(&args[0])?;
|
||||
return Ok(arg); // JS numbers are already floats
|
||||
match operation.name.as_str() {
|
||||
"toFloat" => return Ok(arg), // JS numbers are already floats
|
||||
"toString" => return Ok(format!("String({})", arg)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Special case: Float module operations
|
||||
if effect.name == "Float" && operation.name == "toInt" {
|
||||
if effect.name == "Float" {
|
||||
let arg = self.emit_expr(&args[0])?;
|
||||
return Ok(format!("Math.trunc({})", arg));
|
||||
match operation.name.as_str() {
|
||||
"toInt" => return Ok(format!("Math.trunc({})", arg)),
|
||||
"toString" => return Ok(format!("String({})", arg)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Special case: Result module operations (not an effect)
|
||||
|
||||
Reference in New Issue
Block a user