cl-ast: Add float support

- Smuggle floats as integers to maintain `eq`
- This is bad, but not terrible for spec-compliant floats. Might have issues with NaN.

cl_parser: Smuggle floats

cl_interpret: unpack smuggled floats in float literal node
This commit is contained in:
John 2024-09-19 13:20:19 -05:00
parent 56e71d6782
commit 5deb585054
6 changed files with 10 additions and 2 deletions

View File

@ -36,6 +36,7 @@ pub enum Literal {
Bool(bool), Bool(bool),
Char(char), Char(char),
Int(u128), Int(u128),
Float(u64),
String(String), String(String),
} }

View File

@ -50,6 +50,7 @@ mod display {
Literal::Bool(v) => v.fmt(f), Literal::Bool(v) => v.fmt(f),
Literal::Char(v) => write!(f, "'{}'", v.escape_debug()), Literal::Char(v) => write!(f, "'{}'", v.escape_debug()),
Literal::Int(v) => v.fmt(f), Literal::Int(v) => v.fmt(f),
Literal::Float(v) => f64::from_bits(*v).fmt(f),
Literal::String(v) => write!(f, "\"{}\"", v.escape_debug()), Literal::String(v) => write!(f, "\"{}\"", v.escape_debug()),
} }
} }

View File

@ -37,6 +37,9 @@ pub trait Fold {
fn fold_int(&mut self, i: u128) -> u128 { fn fold_int(&mut self, i: u128) -> u128 {
i i
} }
fn fold_smuggled_float(&mut self, f: u64) -> u64 {
f
}
fn fold_string(&mut self, s: String) -> String { fn fold_string(&mut self, s: String) -> String {
s s
} }
@ -384,6 +387,7 @@ pub fn or_fold_literal<F: Fold + ?Sized>(folder: &mut F, lit: Literal) -> Litera
Literal::Bool(b) => Literal::Bool(folder.fold_bool(b)), Literal::Bool(b) => Literal::Bool(folder.fold_bool(b)),
Literal::Char(c) => Literal::Char(folder.fold_char(c)), Literal::Char(c) => Literal::Char(folder.fold_char(c)),
Literal::Int(i) => Literal::Int(folder.fold_int(i)), Literal::Int(i) => Literal::Int(folder.fold_int(i)),
Literal::Float(f) => Literal::Float(folder.fold_smuggled_float(f)),
Literal::String(s) => Literal::String(folder.fold_string(s)), Literal::String(s) => Literal::String(folder.fold_string(s)),
} }
} }

View File

@ -23,6 +23,7 @@ pub trait Visit<'a>: Sized {
fn visit_bool(&mut self, _b: &'a bool) {} fn visit_bool(&mut self, _b: &'a bool) {}
fn visit_char(&mut self, _c: &'a char) {} fn visit_char(&mut self, _c: &'a char) {}
fn visit_int(&mut self, _i: &'a u128) {} fn visit_int(&mut self, _i: &'a u128) {}
fn visit_smuggled_float(&mut self, _f: &'a u64) {}
fn visit_string(&mut self, _s: &'a str) {} fn visit_string(&mut self, _s: &'a str) {}
fn visit_file(&mut self, f: &'a File) { fn visit_file(&mut self, f: &'a File) {
let File { items } = f; let File { items } = f;
@ -339,6 +340,7 @@ pub fn or_visit_literal<'a, V: Visit<'a>>(visitor: &mut V, l: &'a Literal) {
Literal::Bool(b) => visitor.visit_bool(b), Literal::Bool(b) => visitor.visit_bool(b),
Literal::Char(c) => visitor.visit_char(c), Literal::Char(c) => visitor.visit_char(c),
Literal::Int(i) => visitor.visit_int(i), Literal::Int(i) => visitor.visit_int(i),
Literal::Float(f) => visitor.visit_smuggled_float(f),
Literal::String(s) => visitor.visit_string(s), Literal::String(s) => visitor.visit_string(s),
} }
} }

View File

@ -453,7 +453,7 @@ impl Interpret for Literal {
Literal::String(value) => ConValue::from(value.as_str()), Literal::String(value) => ConValue::from(value.as_str()),
Literal::Char(value) => ConValue::Char(*value), Literal::Char(value) => ConValue::Char(*value),
Literal::Bool(value) => ConValue::Bool(*value), Literal::Bool(value) => ConValue::Bool(*value),
// Literal::Float(value) => todo!("Float values in interpreter: {value:?}"), Literal::Float(value) => ConValue::Float(f64::from_bits(*value)),
Literal::Int(value) => ConValue::Int(*value as _), Literal::Int(value) => ConValue::Int(*value as _),
}) })
} }

View File

@ -245,7 +245,7 @@ impl Parse<'_> for Literal {
TokenData::String(v) => Literal::String(v), TokenData::String(v) => Literal::String(v),
TokenData::Character(v) => Literal::Char(v), TokenData::Character(v) => Literal::Char(v),
TokenData::Integer(v) => Literal::Int(v), TokenData::Integer(v) => Literal::Int(v),
TokenData::Float(v) => todo!("Literal::Float({v})"), TokenData::Float(v) => Literal::Float(v.to_bits()),
_ => panic!("Expected token data for {ty:?}"), _ => panic!("Expected token data for {ty:?}"),
}) })
} }