From c82384764c70212f880b08289559c9e379cca765 Mon Sep 17 00:00:00 2001 From: supersurviveur Date: Tue, 10 Feb 2026 22:18:51 +0100 Subject: [PATCH] Use custom operators --- src/ast.rs | 32 +++++++++++------- src/main.rs | 11 ++++-- src/parsing.rs | 92 ++++++++++++++++++++++++-------------------------- 3 files changed, 72 insertions(+), 63 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 55da5a5..77ea103 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -38,12 +38,23 @@ pub enum Functor } #[derive(Clone, Debug, PartialEq)] -pub enum Operator +pub struct Operator { - Plus, - Minus, - Cons, - Custom(String, usize, OperatorType), + pub op: String, + pub precedence: usize, + pub op_type: OperatorType, +} + +impl Operator +{ + pub fn new(op: String, precedence: usize, op_type: OperatorType) -> Self + { + Self { + op, + precedence, + op_type, + } + } } #[derive(Clone, Debug, PartialEq, Eq, Hash)] @@ -51,7 +62,8 @@ pub enum OperatorType { Prefix, Postfix, - Infix, + LeftInfix, + RightInfix, } impl Display for Body @@ -150,12 +162,6 @@ impl Display for Operator { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self - { - Operator::Plus => write!(f, "+"), - Operator::Minus => write!(f, "-"), - Operator::Cons => write!(f, "::"), - Operator::Custom(string, _, _) => write!(f, "{}", string), - } + write!(f, "{}", self.op) } } diff --git a/src/main.rs b/src/main.rs index 06727e0..c1ffc3d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,12 +18,17 @@ fn main() mult(zero, X, zero). mult(s(Y), X, Z) :- mult(Y, X, W), add(W, X, Z). + op(10, yfx, +). + op(8, yfx, ^). + op(6, xfy, ::). + op(2, fx, [). + op(2, xf, ]). + op(3, yfx, |). + A + B :- test. - op(8, xfx, ^). - A ^ B + C :- test. - (A::B)::C :- A. + A::B::C :- A. [Hd|Tl] :- Hd::Tl. " .into(); diff --git a/src/parsing.rs b/src/parsing.rs index 9ee938f..9d3f058 100644 --- a/src/parsing.rs +++ b/src/parsing.rs @@ -21,11 +21,25 @@ impl Operator { pub fn get_precedence(&self) -> usize { - match self + self.precedence + } + pub fn make_infix_operator<'a>(self) -> Infix, Predicate, Operator, ContextError> + { + fn make_predicate( + _: &mut Stream, + a: Predicate, + op: Operator, + b: Predicate, + ) -> Result { - Operator::Plus | Operator::Minus => 10, - Operator::Cons => 12, - Operator::Custom(_, precedence, _) => *precedence, + Ok(Predicate::Fixed(Functor::Operator(op), vec![a, b])) + } + let precedence = self.get_precedence() as i64; + match self.op_type + { + OperatorType::LeftInfix => Infix::Left(precedence, self, make_predicate), + OperatorType::RightInfix => Infix::Right(precedence, self, make_predicate), + _ => unreachable!(), } } } @@ -34,38 +48,32 @@ impl Operator { fn infix(value: String, state: &State) -> Result { - match value.as_str() - { - "+" => Ok(Operator::Plus), - "::" => Ok(Operator::Cons), - _ => state - .custom_operators - .get(&(value, OperatorType::Infix)) - .ok_or(ContextError::new()) - .cloned(), - } + state + .custom_operators + .get(&(value.clone(), OperatorType::RightInfix)) + .or_else(|| { + state + .custom_operators + .get(&(value, OperatorType::LeftInfix)) + }) + .ok_or(ContextError::new()) + .cloned() } fn prefix(value: String, state: &State) -> Result { - match value.as_str() - { - _ => state - .custom_operators - .get(&(value, OperatorType::Prefix)) - .ok_or(ContextError::new()) - .cloned(), - } + state + .custom_operators + .get(&(value, OperatorType::Prefix)) + .ok_or(ContextError::new()) + .cloned() } fn postfix(value: String, state: &State) -> Result { - match value.as_str() - { - _ => state - .custom_operators - .get(&(value, OperatorType::Postfix)) - .ok_or(ContextError::new()) - .cloned(), - } + state + .custom_operators + .get(&(value, OperatorType::Postfix)) + .ok_or(ContextError::new()) + .cloned() } } @@ -138,12 +146,14 @@ pub fn operator_definition_parse(input: &mut Stream) -> Result<()> { "xf" | "yf" => OperatorType::Postfix, "fx" | "fy" => OperatorType::Prefix, - "xfx" | "xfy" | "yfx" => OperatorType::Infix, + "xfx" => unimplemented!(), + "yfx" => OperatorType::LeftInfix, + "xfy" => OperatorType::RightInfix, _ => unreachable!(), }; input.state.custom_operators.insert( (op.clone(), op_type.clone()), - Operator::Custom(op, precedence, op_type), + Operator::new(op, precedence, op_type), ); Ok(()) } @@ -153,13 +163,7 @@ pub fn predicate_parse_infix_expression<'a>( ) -> Result, Predicate, Operator, ContextError>> { let op = operator_parse_infix.parse_next(input)?; - let precedence = op.get_precedence() as i64; - Ok(Infix::Left(precedence, op, |_, a, op, b| { - Ok(Predicate::Fixed( - Functor::Operator(op), - vec![a, b], - )) - })) + Ok(op.make_infix_operator()) } pub fn predicate_parse_prefix_expression<'a>( @@ -169,10 +173,7 @@ pub fn predicate_parse_prefix_expression<'a>( let op = operator_parse_prefix.parse_next(input)?; let precedence = op.get_precedence() as i64; Ok(Prefix(precedence, op, |_, op, a| { - Ok(Predicate::Fixed( - Functor::Operator(op), - vec![a], - )) + Ok(Predicate::Fixed(Functor::Operator(op), vec![a])) })) } pub fn predicate_parse_postfix_expression<'a>( @@ -182,10 +183,7 @@ pub fn predicate_parse_postfix_expression<'a>( let op = operator_parse_postfix.parse_next(input)?; let precedence = op.get_precedence() as i64; Ok(Postfix(precedence, op, |_, a, op| { - Ok(Predicate::Fixed( - Functor::Operator(op), - vec![a], - )) + Ok(Predicate::Fixed(Functor::Operator(op), vec![a])) })) }