Enum cranelift_isle::ast::Expr
source · pub enum Expr {
Term {
sym: Ident,
args: Vec<Expr>,
pos: Pos,
},
Var {
name: Ident,
pos: Pos,
},
ConstInt {
val: i128,
pos: Pos,
},
ConstPrim {
val: Ident,
pos: Pos,
},
Let {
defs: Vec<LetDef>,
body: Box<Expr>,
pos: Pos,
},
}
Expand description
An expression: the right-hand side of a rule.
Note that this almost looks like a core Lisp or lambda calculus, except that there is no abstraction (lambda). This first-order limit is what makes it analyzable.
Variants§
Term
A term: (sym args...)
.
Var
A variable use.
ConstInt
A constant integer.
ConstPrim
A constant of some other primitive type.
Let
The (let ((var ty val)*) body)
form.
Implementations§
source§impl Expr
impl Expr
sourcepub fn pos(&self) -> Pos
pub fn pos(&self) -> Pos
Examples found in repository?
src/sema.rs (line 2043)
2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053
fn maybe_implicit_convert_expr(
&self,
tyenv: &mut TypeEnv,
expr: &ast::Expr,
inner_ty: TypeId,
outer_ty: TypeId,
) -> Option<ast::Expr> {
// Is there a converter for this type mismatch?
if let Some(converter_term) = self.converters.get(&(inner_ty, outer_ty)) {
if self.terms[converter_term.index()].has_constructor() {
let converter_ident = ast::Ident(
tyenv.syms[self.terms[converter_term.index()].name.index()].clone(),
expr.pos(),
);
return Some(ast::Expr::Term {
sym: converter_ident,
pos: expr.pos(),
args: vec![expr.clone()],
});
}
}
None
}
sourcepub fn terms(&self, f: &mut dyn FnMut(Pos, &Ident))
pub fn terms(&self, f: &mut dyn FnMut(Pos, &Ident))
Call f
for each of the terms in this expression.
Examples found in repository?
src/ast.rs (line 347)
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
pub fn terms(&self, f: &mut dyn FnMut(Pos, &Ident)) {
match self {
Expr::Term { sym, args, pos } => {
f(*pos, sym);
for arg in args {
arg.terms(f);
}
}
Expr::Let { defs, body, .. } => {
for def in defs {
def.val.terms(f);
}
body.terms(f);
}
Expr::Var { .. } | Expr::ConstInt { .. } | Expr::ConstPrim { .. } => {}
}
}
More examples
src/sema.rs (lines 1727-1746)
1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749
fn check_for_expr_terms_without_constructors(&self, tyenv: &mut TypeEnv, defs: &ast::Defs) {
for def in &defs.defs {
if let ast::Def::Rule(rule) = def {
rule.expr.terms(&mut |pos, ident| {
let term = match self.get_term_by_name(tyenv, ident) {
None => {
debug_assert!(!tyenv.errors.is_empty());
return;
}
Some(t) => t,
};
let term = &self.terms[term.index()];
if !term.has_constructor() {
tyenv.report_error(
pos,
format!(
"term `{}` cannot be used in an expression because \
it does not have a constructor",
ident.0
),
)
}
});
}
}
}