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),
Char(char),
Int(u128),
Float(u64),
String(String),
}

View File

@ -50,6 +50,7 @@ mod display {
Literal::Bool(v) => v.fmt(f),
Literal::Char(v) => write!(f, "'{}'", v.escape_debug()),
Literal::Int(v) => v.fmt(f),
Literal::Float(v) => f64::from_bits(*v).fmt(f),
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 {
i
}
fn fold_smuggled_float(&mut self, f: u64) -> u64 {
f
}
fn fold_string(&mut self, s: String) -> String {
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::Char(c) => Literal::Char(folder.fold_char(c)),
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)),
}
}

View File

@ -23,6 +23,7 @@ pub trait Visit<'a>: Sized {
fn visit_bool(&mut self, _b: &'a bool) {}
fn visit_char(&mut self, _c: &'a char) {}
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_file(&mut self, f: &'a File) {
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::Char(c) => visitor.visit_char(c),
Literal::Int(i) => visitor.visit_int(i),
Literal::Float(f) => visitor.visit_smuggled_float(f),
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::Char(value) => ConValue::Char(*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 _),
})
}

View File

@ -245,7 +245,7 @@ impl Parse<'_> for Literal {
TokenData::String(v) => Literal::String(v),
TokenData::Character(v) => Literal::Char(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:?}"),
})
}