Skip to content

Commit 49a33aa

Browse files
author
Arnaud Riess
committed
feat: enhance code generation with new utility functions and memory ownership model
1 parent 4fb8fc8 commit 49a33aa

3 files changed

Lines changed: 194 additions & 171 deletions

File tree

crates/herkos/src/backend/safe.rs

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,46 @@
66
use crate::backend::Backend;
77
use crate::ir::*;
88

9+
const INDENT: &str = " ";
10+
11+
/// Format a function call result assignment.
12+
fn emit_call_result(dest: Option<VarId>, call_expr: &str) -> String {
13+
match dest {
14+
Some(d) => format!("{}{} = {};", INDENT, d, call_expr),
15+
None => format!("{}{};", INDENT, call_expr),
16+
}
17+
}
18+
19+
/// Emit a f32 const, handling NaN and infinity special values.
20+
fn emit_f32_const(dest: VarId, value: f32) -> String {
21+
if value.is_nan() {
22+
format!("{}{dest} = f32::NAN;", INDENT)
23+
} else if value.is_infinite() {
24+
if value.is_sign_positive() {
25+
format!("{}{dest} = f32::INFINITY;", INDENT)
26+
} else {
27+
format!("{}{dest} = f32::NEG_INFINITY;", INDENT)
28+
}
29+
} else {
30+
format!("{}{dest} = {value}f32;", INDENT)
31+
}
32+
}
33+
34+
/// Emit a f64 const, handling NaN and infinity special values.
35+
fn emit_f64_const(dest: VarId, value: f64) -> String {
36+
if value.is_nan() {
37+
format!("{}{dest} = f64::NAN;", INDENT)
38+
} else if value.is_infinite() {
39+
if value.is_sign_positive() {
40+
format!("{}{dest} = f64::INFINITY;", INDENT)
41+
} else {
42+
format!("{}{dest} = f64::NEG_INFINITY;", INDENT)
43+
}
44+
} else {
45+
format!("{}{dest} = {value}f64;", INDENT)
46+
}
47+
}
48+
949
/// Safe code generation backend.
1050
pub struct SafeBackend;
1151

@@ -26,33 +66,8 @@ impl Backend for SafeBackend {
2666
match value {
2767
IrValue::I32(v) => format!(" {dest} = {v}i32;"),
2868
IrValue::I64(v) => format!(" {dest} = {v}i64;"),
29-
IrValue::F32(v) => {
30-
// Handle special float values
31-
if v.is_nan() {
32-
format!(" {dest} = f32::NAN;")
33-
} else if v.is_infinite() {
34-
if v.is_sign_positive() {
35-
format!(" {dest} = f32::INFINITY;")
36-
} else {
37-
format!(" {dest} = f32::NEG_INFINITY;")
38-
}
39-
} else {
40-
format!(" {dest} = {v}f32;")
41-
}
42-
}
43-
IrValue::F64(v) => {
44-
if v.is_nan() {
45-
format!(" {dest} = f64::NAN;")
46-
} else if v.is_infinite() {
47-
if v.is_sign_positive() {
48-
format!(" {dest} = f64::INFINITY;")
49-
} else {
50-
format!(" {dest} = f64::NEG_INFINITY;")
51-
}
52-
} else {
53-
format!(" {dest} = {v}f64;")
54-
}
55-
}
69+
IrValue::F32(v) => emit_f32_const(dest, *v),
70+
IrValue::F64(v) => emit_f64_const(dest, *v),
5671
}
5772
}
5873

@@ -490,10 +505,7 @@ impl Backend for SafeBackend {
490505
call_args.push("table".to_string());
491506
}
492507
let call_expr = format!("func_{}({})?", func_idx, call_args.join(", "));
493-
match dest {
494-
Some(d) => format!(" {} = {};", d, call_expr),
495-
None => format!(" {};", call_expr),
496-
}
508+
emit_call_result(dest, &call_expr)
497509
}
498510

499511
fn emit_call_import(
@@ -507,10 +519,7 @@ impl Backend for SafeBackend {
507519
// Note: module_name is ignored for now (Milestone 3 will use it for trait names)
508520
let args_str: Vec<String> = args.iter().map(|a| a.to_string()).collect();
509521
let call_expr = format!("host.{}({})?", func_name, args_str.join(", "));
510-
match dest {
511-
Some(d) => format!(" {} = {};", d, call_expr),
512-
None => format!(" {};", call_expr),
513-
}
522+
emit_call_result(dest, &call_expr)
514523
}
515524

516525
fn emit_global_get(&self, dest: VarId, index: usize, is_mutable: bool) -> String {

0 commit comments

Comments
 (0)