fix(argus-parser): correctly type variables under relationals

Also accept unicode symbols for temporal operations
This commit is contained in:
Anand Balakrishnan 2023-10-04 14:36:47 -07:00
parent f6b26b61ab
commit 1b3512543e
3 changed files with 25 additions and 9 deletions

View file

@ -23,7 +23,7 @@ fn main() {
.with_color(Color::Yellow)
}))
.finish()
.print(sources([(src.clone(), src.clone())]))
.eprint(sources([(src.clone(), src.clone())]))
.unwrap()
});
}

View file

@ -151,6 +151,13 @@ pub fn lexer<'src>() -> impl Parser<'src, &'src str, Output<'src>, Error<'src>>
just("=").to(Token::Assign),
));
let temporal_op = choice((
just("\u{25cb}").to(Token::Next), // ○
just("\u{25ef}").to(Token::Next), // ◯
just("\u{25c7}").to(Token::Eventually), // ◇
just("\u{25a1}").to(Token::Always), // □
));
// A parser for strings
// Strings in our grammar are identifiers too
let quoted_ident = just('"')
@ -178,7 +185,7 @@ pub fn lexer<'src>() -> impl Parser<'src, &'src str, Output<'src>, Error<'src>>
});
// A single token can be one of the above
let token = choice((op, ctrl, quoted_ident, ident, number));
let token = choice((op, temporal_op, ctrl, quoted_ident, ident, number)).boxed();
let comment = just("//").then(any().and_is(just('\n').not()).repeated()).padded();

View file

@ -51,7 +51,7 @@ pub enum UnaryOps {
}
impl UnaryOps {
fn default_type(&self) -> Type {
fn default_args_type(&self) -> Type {
match self {
UnaryOps::Neg => Type::Float,
_ => Type::Bool,
@ -80,9 +80,18 @@ pub enum BinaryOps {
}
impl BinaryOps {
fn default_type(&self) -> Type {
fn default_args_type(&self) -> Type {
match self {
BinaryOps::Add | BinaryOps::Sub | BinaryOps::Mul | BinaryOps::Div => Type::Float,
BinaryOps::Add
| BinaryOps::Sub
| BinaryOps::Mul
| BinaryOps::Div
| BinaryOps::Lt
| BinaryOps::Le
| BinaryOps::Gt
| BinaryOps::Ge
| BinaryOps::Eq
| BinaryOps::Neq => Type::Float,
_ => Type::Bool,
}
}
@ -124,12 +133,12 @@ impl<'src> Expr<'src> {
op,
interval: _,
arg: _,
} => op.default_type(),
} => op.default_args_type(),
Expr::Binary {
op,
interval: _,
args: _,
} => op.default_type(),
} => op.default_args_type(),
}
}
@ -142,7 +151,7 @@ impl<'src> Expr<'src> {
}
fn unary_op(op: UnaryOps, arg: Spanned<Self>, interval: Option<Spanned<Interval<'src>>>) -> Self {
let arg = Box::new((arg.0.make_typed(op.default_type()), arg.1));
let arg = Box::new((arg.0.make_typed(op.default_args_type()), arg.1));
Self::Unary { op, interval, arg }
}
@ -156,7 +165,7 @@ impl<'src> Expr<'src> {
let common_type = lhs.get_type().get_common_cast(rhs.get_type());
let common_type = if Type::Unknown == common_type {
op.default_type()
op.default_args_type()
} else {
common_type
};