Skip to content

Commit

Permalink
and/or
Browse files Browse the repository at this point in the history
  • Loading branch information
kuviman committed Dec 3, 2024
1 parent 016644e commit 9c66ff6
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 2 deletions.
62 changes: 62 additions & 0 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ impl Cache {
macro_list,
macro_mutable_pattern,
macro_assign,
macro_and,
macro_or,
);
Self {
builtin_macros,
Expand Down Expand Up @@ -1585,6 +1587,34 @@ impl Kast {
kast.compiler.bindings_mutable = true;
kast.compile_into(cty, pattern).await
}
async fn macro_or(&mut self, cty: CompiledType, ast: &Ast) -> eyre::Result<Compiled> {
assert_eq!(cty, CompiledType::Expr);
let (values, span) = get_complex(ast);
let [lhs, rhs] = values.as_ref().into_named(["lhs", "rhs"])?;
Ok(Compiled::Expr(
Expr::Or {
lhs: Box::new(self.compile(lhs).await?),
rhs: Box::new(self.compile(rhs).await?),
data: span,
}
.init(self)
.await?,
))
}
async fn macro_and(&mut self, cty: CompiledType, ast: &Ast) -> eyre::Result<Compiled> {
assert_eq!(cty, CompiledType::Expr);
let (values, span) = get_complex(ast);
let [lhs, rhs] = values.as_ref().into_named(["lhs", "rhs"])?;
Ok(Compiled::Expr(
Expr::And {
lhs: Box::new(self.compile(lhs).await?),
rhs: Box::new(self.compile(rhs).await?),
data: span,
}
.init(self)
.await?,
))
}
async fn macro_assign(&mut self, cty: CompiledType, ast: &Ast) -> eyre::Result<Compiled> {
assert_eq!(cty, CompiledType::Expr);
let (values, span) = get_complex(ast);
Expand Down Expand Up @@ -1735,6 +1765,38 @@ impl Expr<Span> {
pub fn init(self, kast: &Kast) -> BoxFuture<'_, eyre::Result<Expr>> {
let r#impl = async {
Ok(match self {
Expr::And {
lhs,
rhs,
data: span,
} => {
lhs.data().ty.expect_inferred(TypeShape::Bool)?;
rhs.data().ty.expect_inferred(TypeShape::Bool)?;
Expr::And {
lhs,
rhs,
data: ExprData {
ty: TypeShape::Bool.into(),
span,
},
}
}
Expr::Or {
lhs,
rhs,
data: span,
} => {
lhs.data().ty.expect_inferred(TypeShape::Bool)?;
rhs.data().ty.expect_inferred(TypeShape::Bool)?;
Expr::Or {
lhs,
rhs,
data: ExprData {
ty: TypeShape::Bool.into(),
span,
},
}
}
Expr::Assign {
pattern,
value,
Expand Down
18 changes: 18 additions & 0 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,22 @@ impl Kast {
tracing::trace!("as {expected_ty}");
let r#impl = async move {
let result = match expr {
Expr::And { lhs, rhs, data: _ } => {
let lhs = self.eval(lhs).await?.expect_bool()?;
if lhs {
self.eval(rhs).await?
} else {
Value::Bool(false)
}
}
Expr::Or { lhs, rhs, data: _ } => {
let lhs = self.eval(lhs).await?.expect_bool()?;
if !lhs {
self.eval(rhs).await?
} else {
Value::Bool(true)
}
}
Expr::List {
values: values_exprs,
data,
Expand Down Expand Up @@ -1086,6 +1102,8 @@ impl Kast {
};
let should_check_result_ty = match expr {
Expr::Unit { .. }
| Expr::And { .. }
| Expr::Or { .. }
| Expr::List { .. }
| Expr::Unwind { .. }
| Expr::Unwindable { .. }
Expand Down
18 changes: 18 additions & 0 deletions src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ pub struct MatchBranch {

#[derive(Clone)]
pub enum Expr<Data = ExprData> {
And {
lhs: Box<Expr>,
rhs: Box<Expr>,
data: Data,
},
Or {
lhs: Box<Expr>,
rhs: Box<Expr>,
data: Data,
},
Assign {
pattern: Pattern,
value: Box<Expr>,
Expand Down Expand Up @@ -180,6 +190,8 @@ impl Expr {
) {
match self {
Expr::Binding { .. }
| Expr::And { .. }
| Expr::Or { .. }
| Expr::List { .. }
| Expr::Assign { .. }
| Expr::Unwind { .. }
Expand Down Expand Up @@ -251,6 +263,8 @@ impl<Data: std::borrow::Borrow<Span>> Expr<Data> {
impl<Data: std::borrow::Borrow<Span>> std::fmt::Display for Show<'_, Data> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.0 {
Expr::And { .. } => write!(f, "and expr")?,
Expr::Or { .. } => write!(f, "or expr")?,
Expr::Assign { .. } => write!(f, "assign expr")?,
Expr::Unwind { .. } => write!(f, "unwind expr")?,
Expr::List { .. } => write!(f, "list expr")?,
Expand Down Expand Up @@ -296,6 +310,8 @@ impl<Data: std::borrow::Borrow<Span>> Expr<Data> {
impl<Data> Expr<Data> {
pub fn data(&self) -> &Data {
let (Expr::Binding { data, .. }
| Expr::And { data, .. }
| Expr::Or { data, .. }
| Expr::Assign { data, .. }
| Expr::Unwind { data, .. }
| Expr::List { data, .. }
Expand Down Expand Up @@ -331,6 +347,8 @@ impl<Data> Expr<Data> {
}
pub fn data_mut(&mut self) -> &mut Data {
let (Expr::Binding { data, .. }
| Expr::And { data, .. }
| Expr::Or { data, .. }
| Expr::Assign { data, .. }
| Expr::List { data, .. }
| Expr::Unwind { data, .. }
Expand Down
4 changes: 2 additions & 2 deletions std/syntax.ks
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ syntax_module {
syntax catch_impl <- 16 = expr "catch" e "{" catch_block "}";
syntax catch_impl <- 16 = expr "catch" e "(" catch_block ")";

syntax @"builtin fn or" <- 17 = lhs "or" rhs;
syntax @"builtin fn and" <- 18 = lhs "and" rhs;
syntax @"builtin macro or" <- 17 = lhs "or" rhs;
syntax @"builtin macro and" <- 18 = lhs "and" rhs;

syntax @"builtin macro is" <- 18.5 = value "is" pattern;

Expand Down

0 comments on commit 9c66ff6

Please sign in to comment.