Skip to content

Commit

Permalink
fix: conditioning should never be mixed
Browse files Browse the repository at this point in the history
  • Loading branch information
delehef committed Dec 21, 2023
1 parent 0f666d0 commit 63661cd
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 47 deletions.
12 changes: 6 additions & 6 deletions src/compiler/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,28 +73,28 @@ impl Intrinsic {
}
}

pub fn typing(&self, argtype: &[Type]) -> Type {
match self {
pub fn typing(&self, argtype: &[Type]) -> Result<Type> {
Ok(match self {
Intrinsic::Inv => argtype[0],
Intrinsic::Normalize => argtype[0].with_raw_magma(RawMagma::Binary),
Intrinsic::Add | Intrinsic::Sub | Intrinsic::Neg => {
// Boolean is a corner case, as it is not stable under these operations
let max_t = max_type(argtype);
let max_t = max_type(argtype)?;
match max_t.m().rm() {
RawMagma::Binary => max_t.with_raw_magma(RawMagma::Native),
_ => max_t,
}
}
Intrinsic::VectorAdd | Intrinsic::VectorSub | Intrinsic::VectorMul => {
super::max_type(argtype.iter())
super::max_type(argtype.iter())?
}
Intrinsic::Exp => argtype[0],
Intrinsic::Mul => argtype.iter().max().cloned().unwrap_or(Type::INFIMUM),
Intrinsic::IfZero | Intrinsic::IfNotZero => {
argtype[1].max(argtype.get(2).cloned().unwrap_or(Type::INFIMUM))
}
Intrinsic::Begin => Type::List(max_type(argtype).m()),
}
Intrinsic::Begin => Type::List(max_type(argtype)?.m()),
})
}
}
impl std::fmt::Display for Intrinsic {
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,7 @@ fn apply_intrinsic(
}
},
)))
.with_type(super::max_type(&traversed_args_t)),
.with_type(super::max_type(&traversed_args_t)?),
)),

b @ Intrinsic::IfZero | b @ Intrinsic::IfNotZero => {
Expand Down
18 changes: 9 additions & 9 deletions src/compiler/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,13 @@ impl From<Expression> for Node {
impl Node {
pub fn from_expr(e: Expression) -> Node {
Node {
/// the expresssion contained within the node
// the expresssion contained within the node
_e: e,
/// if set, the type of the node; it wil be computed on the fly
/// otherwise
// if set, the type of the node; it will be computed on the fly
// otherwise
_t: None,
/// if set, a string containing the original code of the node for
/// debugging purposes
// if set, a string containing the original code of the node for
// debugging purposes
dbg: None,
}
}
Expand Down Expand Up @@ -336,9 +336,9 @@ impl Node {
pub fn t(&self) -> Type {
self._t
.unwrap_or_else(|| match &self.e() {
Expression::Funcall { func, args } => {
func.typing(&args.iter().map(|a| a.t()).collect::<Vec<_>>())
}
Expression::Funcall { func, args } => func
.typing(&args.iter().map(|a| a.t()).collect::<Vec<_>>())
.unwrap(),
Expression::Const(ref x) => {
if x.is_zero() || x.is_one() {
Type::Scalar(Magma::binary())
Expand All @@ -353,7 +353,7 @@ impl Node {
Expression::ArrayColumn { .. } => unreachable!("ARRAYCOLUMN SHOULD BE TYPED"),
Expression::List(xs) => {
let l_types = xs.iter().map(|x| x.t()).collect::<Vec<_>>();
super::max_type(l_types.iter())
super::max_type(l_types.iter()).unwrap()
}
Expression::Void => Type::Void,
})
Expand Down
55 changes: 33 additions & 22 deletions src/compiler/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use std::{cmp::Ordering, sync::OnceLock};

use crate::{column::Value, errors::RuntimeError};

pub fn max_type<'a, TS: IntoIterator<Item = &'a Type>>(ts: TS) -> Type {
ts.into_iter().fold(Type::INFIMUM, |a, b| a.maxed(b))
pub fn max_type<'a, TS: IntoIterator<Item = &'a Type>>(ts: TS) -> Result<Type> {
ts.into_iter().try_fold(Type::INFIMUM, |a, b| a.maxed(b))
}

/// The type of a column in the IR. This struct contains both the dimensionality
Expand Down Expand Up @@ -85,8 +85,7 @@ impl Type {
bail!("should never happen");
}

let larger_conditioning = self.c().max(other.c());
Ok(self.with_magma(self.m().with_conditioning(larger_conditioning)))
Ok(self.with_magma(self.m().with_conditioning(self.c().max(&other.c())?)))
}

pub(crate) fn force_with_conditioning_of(self, other: &Type) -> Type {
Expand Down Expand Up @@ -177,8 +176,8 @@ impl Type {
}
}

pub(crate) fn maxed(&self, other: &Type) -> Type {
self.max(other).with_magma(self.m().maxed(&other.m()))
pub(crate) fn maxed(&self, other: &Type) -> Result<Type> {
Ok(self.max(other).with_magma(self.m().maxed(&other.m())?))
}
}
impl std::cmp::PartialOrd for Type {
Expand Down Expand Up @@ -234,24 +233,36 @@ impl std::cmp::Ord for Type {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash, PartialOrd)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub enum Conditioning {
None,
Boolean,
Loobean,
}
impl std::cmp::Ord for Conditioning {
fn cmp(&self, other: &Self) -> Ordering {
impl Conditioning {
fn max(&self, other: &Conditioning) -> Result<Conditioning> {
if let Some(ord) = self.partial_cmp(other) {
Ok(match ord {
Ordering::Less => *other,
_ => *self,
})
} else {
Err(anyhow!("unable to mix conditionings"))
}
}
}
impl std::cmp::PartialOrd for Conditioning {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match (self, other) {
(Conditioning::None, Conditioning::None) => Ordering::Equal,
(Conditioning::None, Conditioning::Boolean) => Ordering::Less,
(Conditioning::None, Conditioning::Loobean) => Ordering::Less,
(Conditioning::Boolean, Conditioning::None) => Ordering::Greater,
(Conditioning::Boolean, Conditioning::Boolean) => Ordering::Equal,
(Conditioning::Boolean, Conditioning::Loobean) => unreachable!(),
(Conditioning::Loobean, Conditioning::None) => Ordering::Greater,
(Conditioning::Loobean, Conditioning::Boolean) => unreachable!(),
(Conditioning::Loobean, Conditioning::Loobean) => Ordering::Equal,
(Conditioning::None, Conditioning::None) => Some(Ordering::Equal),
(Conditioning::None, Conditioning::Boolean) => Some(Ordering::Less),
(Conditioning::None, Conditioning::Loobean) => Some(Ordering::Less),
(Conditioning::Boolean, Conditioning::None) => Some(Ordering::Greater),
(Conditioning::Boolean, Conditioning::Boolean) => Some(Ordering::Equal),
(Conditioning::Boolean, Conditioning::Loobean) => None,
(Conditioning::Loobean, Conditioning::None) => Some(Ordering::Greater),
(Conditioning::Loobean, Conditioning::Boolean) => None,
(Conditioning::Loobean, Conditioning::Loobean) => Some(Ordering::Equal),
}
}
}
Expand Down Expand Up @@ -526,11 +537,11 @@ impl Magma {
pub fn any() -> Magma {
RawMagma::Any.into()
}
pub(crate) fn maxed(&self, other: &Magma) -> Magma {
Magma {
pub(crate) fn maxed(&self, other: &Magma) -> Result<Magma> {
Ok(Magma {
m: self.m.max(other.m),
c: self.c.max(other.c),
}
c: self.c.max(&other.c)?,
})
}
}
impl std::convert::TryFrom<&str> for Magma {
Expand Down
13 changes: 6 additions & 7 deletions src/inspect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,6 @@ impl ModuleView {
let mut maxes = vec![3; span.len() + 1];

let block = Block::new().borders(Borders::NONE);

let widths = maxes
.iter()
.map(|w| Constraint::Length(*w as u16))
.collect::<Vec<_>>();

let rows = self
.current_columns()
.skip(self.v_shift as usize)
Expand Down Expand Up @@ -221,7 +215,12 @@ impl ModuleView {
})),
)
.style(Style::default().white())
});
})
.collect::<Vec<_>>();
let widths = maxes
.iter()
.map(|w| Constraint::Length(*w as u16))
.collect::<Vec<_>>();

let table = Table::new(rows, widths)
.header(
Expand Down
5 changes: 3 additions & 2 deletions src/stdlib.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@
(defunalias all! +)

;; Boolean functions
(defpurefun ((is-not-zero :binary@boolean) e0) (~ e0))
(defpurefun ((is-zero :binary@boolean :nowarn) e0) (- 1 (~ e0)))
(defpurefun ((is-not-zero :binary@boolean) x) (~ x))
(defpurefun ((is-not-zero! :binary@loobean :nowarn) x) (- 1 (is-not-zero x)))
(defpurefun ((is-zero :binary@boolean :nowarn) x) (- 1 (~ x)))



Expand Down

0 comments on commit 63661cd

Please sign in to comment.