Skip to content

Commit

Permalink
f32 operators, reinterpret numeric bits
Browse files Browse the repository at this point in the history
  • Loading branch information
enricozb committed Apr 9, 2024
1 parent 88f5e2c commit 966d051
Show file tree
Hide file tree
Showing 12 changed files with 503 additions and 391 deletions.
17 changes: 11 additions & 6 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,15 +309,20 @@ impl<'i> Parser<'i> {
Ok(Tree::Ref { nam })
}
// Int = "#" Int
// TODO: accept fractional and exponential inputs eg 1.5, 1.5e32
// F32 = "#f" Int
// F32 = "#" Int "." Int
Some('#') => {
self.advance_char();
let is_float = self.consume("f").is_ok();
let is_neg = self.consume("-").is_ok();
let int_val = if is_neg { -(self.parse_int()? as i64) } else { self.parse_int()? as i64 };

if is_float { Ok(Tree::F32 { val: (int_val as f32).into() }) } else { Ok(Tree::Int { val: int_val }) }
if self.consume(".").is_ok() {
let frac_val = self.parse_int()?;
let frac_len = frac_val.checked_ilog10().unwrap_or(0) + 1;

Ok(Tree::F32 { val: (int_val as f32 + frac_val as f32 / 10f32.powi(frac_len as i32)).into() })

Check warning on line 322 in src/ast.rs

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (powi)
} else {
Ok(Tree::Int { val: int_val })
}
}
// Op = "<" Op Tree Tree ">"
Some('<') => {
Expand Down Expand Up @@ -386,7 +391,7 @@ impl<'i> Parser<'i> {

/// See `ops.rs` for the available operators.
fn parse_op(&mut self) -> Result<Op, String> {
let op = self.take_while(|c| "ui0123456789.+-=*/%<>|&^!?$".contains(c));
let op = self.take_while(|c| "fui0123456789.+-=*/%<>|&^!?$".contains(c));
op.parse().map_err(|_| format!("Unknown operator: {op:?}"))
}

Expand Down Expand Up @@ -538,7 +543,7 @@ impl fmt::Display for Tree {
Tree::Var { nam } => write!(f, "{nam}"),
Tree::Ref { nam } => write!(f, "@{nam}"),
Tree::Int { val } => write!(f, "#{val}"),
Tree::F32 { val } => write!(f, "#f{val}"),
Tree::F32 { val } => write!(f, "#{val}"),
Tree::Op { op, rhs, out } => write!(f, "<{op} {rhs} {out}>"),
Tree::Mat { zero, succ, out } => write!(f, "?<{zero} {succ} {out}>"),
})
Expand Down
11 changes: 4 additions & 7 deletions src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn _compile_host(host: &Host) -> Result<String, fmt::Error> {
.map(|(raw_name, def)| (raw_name, sanitize_name(raw_name), def));

writeln!(code, "#![allow(non_upper_case_globals, unused_imports)]")?;
writeln!(code, "use crate::{{host::{{Host, DefRef}}, run::*, ops::{{Op, Ty::*, BinOp::*}}}};")?;
writeln!(code, "use crate::{{host::{{Host, DefRef}}, run::*, ops::{{Num::*, Op, Ty::*, BinOp::*}}}};")?;
writeln!(code)?;

writeln!(code, "pub fn host() -> Host {{")?;
Expand Down Expand Up @@ -72,11 +72,8 @@ fn compile_def(code: &mut String, host: &Host, name: &str, instr: &[Instruction]
Instruction::Op { op, trg, rhs, out } => {
writeln!(code, "let ({rhs}, {out}) = net.do_op({op:?}, {trg});")
}
Instruction::OpInt { op, trg, rhs, out } => {
writeln!(code, "let {out} = net.do_op_int({op:?}, {trg}, {rhs});")
}
Instruction::OpF32 { op, trg, rhs, out } => {
writeln!(code, "let {out} = net.do_op_float({op:?}, {trg}, {rhs});")
Instruction::OpNum { op, trg, rhs, out } => {
writeln!(code, "let {out} = net.do_op_num({op:?}, {trg}, {rhs:?});")
}
Instruction::Mat { trg, lft, rgt } => {
writeln!(code, "let ({lft}, {rgt}) = net.do_mat({trg});")
Expand All @@ -99,7 +96,7 @@ fn compile_port(host: &Host, port: &Port) -> String {
let name = sanitize_name(&host.back[&port.addr()]);
format!("Port::new_ref(unsafe {{ &*DEF_{name} }})")
} else if port.tag() == Tag::Int {
format!("Port::new_num({})", port.int())
format!("Port::new_int({})", port.int())
} else {
unreachable!()
}
Expand Down
40 changes: 20 additions & 20 deletions src/host/encode.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use super::*;
use crate::{ops::Op, run::Lab, util::maybe_grow};
use crate::{
ops::{Num, Op},
run::Lab,
util::maybe_grow,
};

impl Host {
/// Converts an ast net to a list of instructions to create the net.
Expand Down Expand Up @@ -99,16 +103,21 @@ impl<'a, E: Encoder> State<'a, E> {
}
self.encoder.link(l, r);
}
Tree::Op { op, rhs: lft, out: rgt } => {
if let Tree::Int { val } = &**lft {
let o = self.encoder.op_int(*op, trg, *val);
Tree::Op { op, rhs: lft, out: rgt } => match &**lft {
Tree::Int { val } => {
let o = self.encoder.op_num(*op, trg, Num::Int(*val));
self.visit_tree(rgt, o);
} else {
}
Tree::F32 { val } => {
let o = self.encoder.op_num(*op, trg, Num::Float(val.0));
self.visit_tree(rgt, o);
}
_ => {
let (l, r) = self.encoder.op(*op, trg);
self.visit_tree(lft, l);
self.visit_tree(rgt, r);
}
}
},
Tree::Mat { zero, succ, out } => {
let (a, o) = self.encoder.mat(trg);
let (z, s) = self.encoder.ctr(0, a);
Expand All @@ -133,8 +142,7 @@ trait Encoder {
fn make_const(&mut self, port: Port) -> Self::Trg;
fn ctr(&mut self, lab: Lab, trg: Self::Trg) -> (Self::Trg, Self::Trg);
fn op(&mut self, op: Op, trg: Self::Trg) -> (Self::Trg, Self::Trg);
fn op_int(&mut self, op: Op, trg: Self::Trg, rhs: i64) -> Self::Trg;
fn op_float(&mut self, op: Op, trg: Self::Trg, rhs: f32) -> Self::Trg;
fn op_num(&mut self, op: Op, trg: Self::Trg, rhs: Num) -> Self::Trg;
fn mat(&mut self, trg: Self::Trg) -> (Self::Trg, Self::Trg);
fn wires(&mut self) -> (Self::Trg, Self::Trg, Self::Trg, Self::Trg);
}
Expand Down Expand Up @@ -172,14 +180,9 @@ impl Encoder for InterpretedDef {
self.instr.push(Instruction::Op { op, trg, rhs, out });
(rhs, out)
}
fn op_int(&mut self, op: Op, trg: Self::Trg, rhs: i64) -> Self::Trg {
fn op_num(&mut self, op: Op, trg: Self::Trg, rhs: Num) -> Self::Trg {
let out = self.new_trg_id();
self.instr.push(Instruction::OpInt { op, trg, rhs, out });
out
}
fn op_float(&mut self, op: Op, trg: Self::Trg, rhs: f32) -> Self::Trg {
let out = self.new_trg_id();
self.instr.push(Instruction::OpF32 { op, trg, rhs, out });
self.instr.push(Instruction::OpNum { op, trg, rhs, out });
out
}
fn mat(&mut self, trg: Self::Trg) -> (Self::Trg, Self::Trg) {
Expand Down Expand Up @@ -215,11 +218,8 @@ impl<'a, M: Mode> Encoder for run::Net<'a, M> {
fn op(&mut self, op: Op, trg: Self::Trg) -> (Self::Trg, Self::Trg) {
self.do_op(op, trg)
}
fn op_int(&mut self, op: Op, trg: Self::Trg, rhs: i64) -> Self::Trg {
self.do_op_int(op, trg, rhs)
}
fn op_float(&mut self, op: Op, trg: Self::Trg, rhs: f32) -> Self::Trg {
self.do_op_float(op, trg, rhs)
fn op_num(&mut self, op: Op, trg: Self::Trg, rhs: Num) -> Self::Trg {
self.do_op_num(op, trg, rhs)
}
fn mat(&mut self, trg: Self::Trg) -> (Self::Trg, Self::Trg) {
self.do_mat(trg)
Expand Down
5 changes: 4 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,10 @@ fn compile_executable(target: &str, host: Arc<Mutex<host::Host>>) -> Result<(),
}
lib
main
ops
ops {
int
float
}
run {
addr
allocator
Expand Down
Loading

0 comments on commit 966d051

Please sign in to comment.