From e157df3480e057d7fe61da96afedac9734854237 Mon Sep 17 00:00:00 2001
From: Enrico Zandomeni Borba <enricozb@gmail.com>
Date: Tue, 23 Apr 2024 12:19:55 +0200
Subject: [PATCH] fixes and ERA f32 compilations

---
 src/compile.rs  | 16 +++++++++++++---
 src/run/port.rs |  6 ++++++
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/compile.rs b/src/compile.rs
index 7574cdf1..bc2f9401 100644
--- a/src/compile.rs
+++ b/src/compile.rs
@@ -93,7 +93,7 @@ fn refs<'a>(host: &'a Host, instructions: &'a [Instruction]) -> BTreeSet<&'a str
 
   for instr in instructions {
     if let Instruction::Const { port, .. } | Instruction::LinkConst { port, .. } = instr {
-      if port.tag() == Tag::Ref {
+      if port.tag() == Tag::Ref && !port.is_era() {
         refs.insert(host.back[&port.addr()].as_str());
       }
     }
@@ -143,7 +143,7 @@ fn compile_struct(
         writeln!(code, "let ({rhs}, {out}) = net.do_op({op:?}, {trg});")
       }
       Instruction::OpNum { op, trg, rhs, out } => {
-        writeln!(code, "let {out} = net.do_op_num({op:?}, {trg}, {rhs:?});")
+        writeln!(code, "let {out} = net.do_op_num({op:?}, {trg}, {});", compile_port(host, rhs))
       }
       Instruction::Mat { trg, lft, rgt } => {
         writeln!(code, "let ({lft}, {rgt}) = net.do_mat({trg});")
@@ -168,7 +168,17 @@ fn compile_port(host: &Host, port: &Port) -> String {
   } else if port.tag() == Tag::Int {
     format!("Port::new_int({})", port.int())
   } else if port.tag() == Tag::F32 {
-    format!("Port::new_float({:?})", port.float())
+    let float = port.float();
+
+    if float.is_nan() {
+      "Port::new_float(f32::NAN)".to_string()
+    } else if float.is_infinite() && float > 0.0 {
+      "Port::new_float(f32::INFINITY)".to_string()
+    } else if float.is_infinite() {
+      "Port::new_float(f32::NEG_INFINITY)".to_string()
+    } else {
+      format!("Port::new_float({float:?})")
+    }
   } else {
     unreachable!()
   }
diff --git a/src/run/port.rs b/src/run/port.rs
index 6db0d0a8..dddf14f9 100644
--- a/src/run/port.rs
+++ b/src/run/port.rs
@@ -181,6 +181,12 @@ impl Port {
     self.tag() == Tag::Int || self.tag() == Tag::F32
   }
 
+  /// Whether this port is an [`ERA`] port.
+  #[inline(always)]
+  pub fn is_era(&self) -> bool {
+    matches!(*self, Port::ERA)
+  }
+
   /// Accesses the label of this port; this is valid for all non-numeric ports.
   #[inline(always)]
   pub const fn lab(&self) -> Lab {