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(" LuxMap* result = lux_map_new(map->capacity);");
|
||||||
self.writeln(" result->length = map->length;");
|
self.writeln(" result->length = map->length;");
|
||||||
self.writeln(" for (int64_t i = 0; i < map->length; i++) {");
|
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(" result->values[i] = map->values[i];");
|
||||||
self.writeln(" lux_incref(map->values[i]);");
|
self.writeln(" lux_incref(map->values[i]);");
|
||||||
self.writeln(" }");
|
self.writeln(" }");
|
||||||
@@ -2092,7 +2092,7 @@ impl CBackend {
|
|||||||
self.writeln(" result->keys = (LuxString*)realloc(result->keys, sizeof(LuxString) * result->capacity);");
|
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(" result->values = (void**)realloc(result->values, sizeof(void*) * result->capacity);");
|
||||||
self.writeln(" }");
|
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(" result->values[result->length] = value;");
|
||||||
self.writeln(" lux_incref(value);");
|
self.writeln(" lux_incref(value);");
|
||||||
self.writeln(" result->length++;");
|
self.writeln(" result->length++;");
|
||||||
@@ -2111,7 +2111,7 @@ impl CBackend {
|
|||||||
self.writeln(" LuxMap* result = lux_map_new(map->capacity);");
|
self.writeln(" LuxMap* result = lux_map_new(map->capacity);");
|
||||||
self.writeln(" for (int64_t i = 0; i < map->length; i++) {");
|
self.writeln(" for (int64_t i = 0; i < map->length; i++) {");
|
||||||
self.writeln(" if (strcmp(map->keys[i], key) != 0) {");
|
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(" result->values[result->length] = map->values[i];");
|
||||||
self.writeln(" lux_incref(map->values[i]);");
|
self.writeln(" lux_incref(map->values[i]);");
|
||||||
self.writeln(" result->length++;");
|
self.writeln(" result->length++;");
|
||||||
@@ -4677,7 +4677,7 @@ impl CBackend {
|
|||||||
// Sort keys: simple insertion sort
|
// Sort keys: simple insertion sort
|
||||||
self.writeln(&format!("for (int64_t _i = 0; _i < {}->length; _i++) {{", map));
|
self.writeln(&format!("for (int64_t _i = 0; _i < {}->length; _i++) {{", map));
|
||||||
self.indent += 1;
|
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.writeln(&format!("lux_list_push({}, _ks);", temp));
|
||||||
self.indent -= 1;
|
self.indent -= 1;
|
||||||
self.writeln("}");
|
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::Field { object, field, .. } = func.as_ref() {
|
||||||
if let Expr::Var(module_name) = object.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])?;
|
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])?;
|
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
|
// Special case: Int module operations
|
||||||
if effect.name == "Int" && operation.name == "toFloat" {
|
if effect.name == "Int" {
|
||||||
let arg = self.emit_expr(&args[0])?;
|
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
|
// Special case: Float module operations
|
||||||
if effect.name == "Float" && operation.name == "toInt" {
|
if effect.name == "Float" {
|
||||||
let arg = self.emit_expr(&args[0])?;
|
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)
|
// Special case: Result module operations (not an effect)
|
||||||
|
|||||||
Reference in New Issue
Block a user