tamer: NIR->xmli: Initial classify, any, all support
Just as `rate` is a `sum`, `classify` is an `all` by default. The `@any` attribute will change that interpretation, though I only intend to recognize that in parsing later on, not emit that in XMLI. DEV-13708main
parent
d5cf276de2
commit
98fcb115da
|
@ -90,8 +90,14 @@ impl Display for Expr {
|
|||
/// as was the original plan with TAMER.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum ExprOp {
|
||||
// Summation (+)
|
||||
Sum,
|
||||
// Product (×)
|
||||
Product,
|
||||
// Logical conjunction (∧)
|
||||
Conj,
|
||||
// Logical disjunction (∨)
|
||||
Disj,
|
||||
}
|
||||
|
||||
impl Display for ExprOp {
|
||||
|
@ -99,8 +105,10 @@ impl Display for ExprOp {
|
|||
use ExprOp::*;
|
||||
|
||||
match self {
|
||||
Sum => write!(f, "sum"),
|
||||
Product => write!(f, "product"),
|
||||
Sum => write!(f, "sum (+)"),
|
||||
Product => write!(f, "product (×)"),
|
||||
Conj => write!(f, "conjunctive (∧)"),
|
||||
Disj => write!(f, "disjunctive (∨)"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,11 +36,11 @@ use super::object::{
|
|||
use crate::{
|
||||
asg::{
|
||||
visit::{Depth, TreeWalkRel},
|
||||
Asg, ExprOp,
|
||||
Asg, ExprOp, Ident,
|
||||
},
|
||||
diagnose::Annotate,
|
||||
diagnostic_panic, diagnostic_unreachable,
|
||||
parse::{prelude::*, util::SPair, Transitionable},
|
||||
parse::{prelude::*, Transitionable},
|
||||
span::{Span, UNKNOWN_SPAN},
|
||||
sym::{
|
||||
st::{URI_LV_CALC, URI_LV_RATER, URI_LV_TPL},
|
||||
|
@ -230,13 +230,39 @@ impl<'a> TreeContext<'a> {
|
|||
) -> Option<Xirf> {
|
||||
match src {
|
||||
Object::Ident((ident, _)) => {
|
||||
self.push(yields(ident.name(), expr.span()));
|
||||
Some(stmt(expr, depth))
|
||||
self.emit_expr_ident(expr, ident, depth)
|
||||
}
|
||||
_ => Some(expr_ele(expr, depth)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit an identified expression.
|
||||
///
|
||||
/// Legacy TAME is only able to bind certain identifiers via statements
|
||||
/// such as `rate` and `classify`.
|
||||
fn emit_expr_ident(
|
||||
&mut self,
|
||||
expr: &Expr,
|
||||
ident: &Ident,
|
||||
depth: Depth,
|
||||
) -> Option<Xirf> {
|
||||
let (qname, ident_qname) = match expr.op() {
|
||||
ExprOp::Sum => (QN_RATE, QN_YIELDS),
|
||||
ExprOp::Conj => (QN_CLASSIFY, QN_AS),
|
||||
|
||||
ExprOp::Product | ExprOp::Disj => todo!("stmt: {expr:?}"),
|
||||
};
|
||||
|
||||
let ispan = ident.span();
|
||||
self.push(Xirf::attr(ident_qname, ident.name(), (ispan, ispan)));
|
||||
|
||||
Some(Xirf::open(
|
||||
qname,
|
||||
OpenSpan::without_name_span(expr.span()),
|
||||
depth,
|
||||
))
|
||||
}
|
||||
|
||||
fn push(&mut self, tok: Xirf) {
|
||||
if self.stack.is_full() {
|
||||
diagnostic_panic!(
|
||||
|
@ -292,24 +318,14 @@ fn ns(qname: QName, uri: UriStaticSymbolId, span: Span) -> Xirf {
|
|||
Xirf::attr(qname, uri, (span, span))
|
||||
}
|
||||
|
||||
fn stmt(expr: &Expr, depth: Depth) -> Xirf {
|
||||
match expr.op() {
|
||||
ExprOp::Sum => {
|
||||
Xirf::open(QN_RATE, OpenSpan::without_name_span(expr.span()), depth)
|
||||
}
|
||||
|
||||
_ => todo!("stmt: {expr:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn yields(name: SPair, span: Span) -> Xirf {
|
||||
Xirf::attr(QN_YIELDS, name, (span, name))
|
||||
}
|
||||
|
||||
fn expr_ele(expr: &Expr, depth: Depth) -> Xirf {
|
||||
use ExprOp::*;
|
||||
|
||||
let qname = match expr.op() {
|
||||
ExprOp::Sum => QN_C_SUM,
|
||||
ExprOp::Product => QN_C_PRODUCT,
|
||||
Sum => QN_C_SUM,
|
||||
Product => QN_C_PRODUCT,
|
||||
Conj => QN_ALL,
|
||||
Disj => QN_ANY,
|
||||
};
|
||||
|
||||
Xirf::open(qname, OpenSpan::without_name_span(expr.span()), depth)
|
||||
|
|
|
@ -183,12 +183,18 @@ pub enum NirEntity {
|
|||
/// Rate (verb) block,
|
||||
/// representing a calculation with a scalar result.
|
||||
Rate,
|
||||
|
||||
/// Summation (Σ) expression.
|
||||
Sum,
|
||||
/// Product (Π) expression.
|
||||
Product,
|
||||
|
||||
// Classification.
|
||||
Classify,
|
||||
/// Conjunctive (∧) expression.
|
||||
All,
|
||||
/// Disjunctive (∨) expression.
|
||||
Any,
|
||||
|
||||
/// Template parameter (metavariable).
|
||||
TplParam,
|
||||
}
|
||||
|
@ -209,9 +215,15 @@ impl Display for NirEntity {
|
|||
|
||||
match self {
|
||||
Package => write!(f, "package"),
|
||||
|
||||
Rate => write!(f, "rate block"),
|
||||
Sum => write!(f, "sum (∑) expression"),
|
||||
Product => write!(f, "product (Π) expression"),
|
||||
|
||||
Classify => write!(f, "classification"),
|
||||
All => write!(f, "conjunctive (∧) expression"),
|
||||
Any => write!(f, "disjunctive (∨) expression"),
|
||||
|
||||
TplParam => write!(f, "template param (metavariable)"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,11 +80,22 @@ impl ParseState for NirToAir {
|
|||
(Ready, Nir::Open(NirEntity::Product, span)) => {
|
||||
Transition(Ready).ok(Air::ExprOpen(ExprOp::Product, span))
|
||||
}
|
||||
(Ready, Nir::Open(NirEntity::Classify | NirEntity::All, span)) => {
|
||||
Transition(Ready).ok(Air::ExprOpen(ExprOp::Conj, span))
|
||||
}
|
||||
(Ready, Nir::Open(NirEntity::Any, span)) => {
|
||||
Transition(Ready).ok(Air::ExprOpen(ExprOp::Disj, span))
|
||||
}
|
||||
|
||||
(
|
||||
Ready,
|
||||
Nir::Close(
|
||||
NirEntity::Rate | NirEntity::Sum | NirEntity::Product,
|
||||
NirEntity::Rate
|
||||
| NirEntity::Sum
|
||||
| NirEntity::Product
|
||||
| NirEntity::Classify
|
||||
| NirEntity::All
|
||||
| NirEntity::Any,
|
||||
span,
|
||||
),
|
||||
) => Transition(Ready).ok(Air::ExprClose(span)),
|
||||
|
|
|
@ -76,3 +76,43 @@ fn calc_exprs() {
|
|||
Sut::parse(toks.into_iter()).collect(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn classify_to_conj_expr() {
|
||||
let id = SPair("always".into(), S2);
|
||||
|
||||
let toks = vec![
|
||||
Nir::Open(NirEntity::Classify, S1),
|
||||
Nir::BindIdent(id),
|
||||
Nir::Close(NirEntity::Classify, S3),
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
O(Air::ExprOpen(ExprOp::Conj, S1)),
|
||||
O(Air::ExprIdent(id)),
|
||||
O(Air::ExprClose(S3)),
|
||||
]),
|
||||
Sut::parse(toks.into_iter()).collect(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn logic_exprs() {
|
||||
let toks = vec![
|
||||
Nir::Open(NirEntity::All, S1),
|
||||
Nir::Open(NirEntity::Any, S2),
|
||||
Nir::Close(NirEntity::Any, S3),
|
||||
Nir::Close(NirEntity::All, S4),
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
O(Air::ExprOpen(ExprOp::Conj, S1)),
|
||||
O(Air::ExprOpen(ExprOp::Disj, S2)),
|
||||
O(Air::ExprClose(S3)),
|
||||
O(Air::ExprClose(S4)),
|
||||
]),
|
||||
Sut::parse(toks.into_iter()).collect(),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -389,15 +389,16 @@ ele_parse! {
|
|||
/// A classification is a logic expression yielding a boolean result
|
||||
/// with the dimensionality matching the largest dimensionality of its
|
||||
/// inputs.
|
||||
ClassifyStmt := QN_CLASSIFY {
|
||||
ClassifyStmt := QN_CLASSIFY(_, ospan) {
|
||||
@ {
|
||||
QN_AS => TodoAttr,
|
||||
QN_AS => BindIdent,
|
||||
QN_DESC => TodoAttr,
|
||||
QN_ANY => TodoAttr,
|
||||
QN_YIELDS => TodoAttr,
|
||||
QN_SYM => TodoAttr,
|
||||
QN_TERMINATE => TodoAttr,
|
||||
} => Todo,
|
||||
} => NirEntity::Classify.open(ospan),
|
||||
/(cspan) => NirEntity::Classify.close(cspan),
|
||||
|
||||
LogExpr,
|
||||
};
|
||||
|
@ -595,8 +596,9 @@ ele_parse! {
|
|||
///
|
||||
/// This represents an expression that matches when _any_ of its inner
|
||||
/// [`LogExpr`] expressions match.
|
||||
AnyExpr := QN_ANY {
|
||||
@ {} => Todo,
|
||||
AnyExpr := QN_ANY(_, ospan) {
|
||||
@ {} => NirEntity::Any.open(ospan),
|
||||
/(cspan) => NirEntity::Any.close(cspan),
|
||||
|
||||
LogExpr,
|
||||
};
|
||||
|
@ -605,8 +607,9 @@ ele_parse! {
|
|||
///
|
||||
/// This represents an expression that matches when _all_ of its inner
|
||||
/// [`LogExpr`] expressions match.
|
||||
AllExpr := QN_ALL {
|
||||
@ {} => Todo,
|
||||
AllExpr := QN_ALL(_, ospan) {
|
||||
@ {} => NirEntity::All.open(ospan),
|
||||
/(cspan) => NirEntity::All.close(cspan),
|
||||
|
||||
LogExpr,
|
||||
};
|
||||
|
|
|
@ -11,12 +11,24 @@
|
|||
|
||||
<rate yields="rateBaz">
|
||||
<c:sum>
|
||||
<c:product />
|
||||
<c:sum />
|
||||
</c:sum>
|
||||
<c:sum>
|
||||
<c:product>
|
||||
<c:sum />
|
||||
<c:product />
|
||||
<c:sum />
|
||||
</c:sum>
|
||||
</c:product>
|
||||
</rate>
|
||||
</package>
|
||||
|
||||
<classify as="always" />
|
||||
|
||||
<classify as="sometimes">
|
||||
<any>
|
||||
<all />
|
||||
<any />
|
||||
<all />
|
||||
</any>
|
||||
<any />
|
||||
</classify>
|
||||
</package>
|
||||
|
|
|
@ -15,12 +15,25 @@
|
|||
|
||||
<rate yields="rateBaz">
|
||||
<c:sum>
|
||||
<c:product />
|
||||
<c:sum />
|
||||
</c:sum>
|
||||
<c:sum>
|
||||
<c:product>
|
||||
<c:sum />
|
||||
<c:product />
|
||||
<c:sum />
|
||||
</c:sum>
|
||||
</c:product>
|
||||
</rate>
|
||||
|
||||
<classify as="always" />
|
||||
|
||||
<classify as="sometimes">
|
||||
<any>
|
||||
<all />
|
||||
<any />
|
||||
<all />
|
||||
</any>
|
||||
<any />
|
||||
</classify>
|
||||
</package>
|
||||
|
||||
|
|
Loading…
Reference in New Issue