diff --git a/crates/dreammaker/src/ast.rs b/crates/dreammaker/src/ast.rs index 5f250118..8693035f 100644 --- a/crates/dreammaker/src/ast.rs +++ b/crates/dreammaker/src/ast.rs @@ -26,6 +26,8 @@ pub enum UnaryOp { PostIncr, PreDecr, PostDecr, + Reference, + Dereference, } impl UnaryOp { @@ -49,6 +51,8 @@ impl UnaryOp { PostIncr => write!(f, "{}++", self.expr), PreDecr => write!(f, "--{}", self.expr), PostDecr => write!(f, "{}--", self.expr), + Reference => write!(f, "&{}", self.expr), + Dereference => write!(f, "*{}", self.expr), } } } @@ -65,6 +69,8 @@ impl UnaryOp { BitNot => "~", PreIncr | PostIncr => "++", PreDecr | PostDecr => "--", + Reference => "&", + Dereference => "*", } } } diff --git a/crates/dreammaker/src/parser.rs b/crates/dreammaker/src/parser.rs index 7a3d95ac..49b16c0c 100644 --- a/crates/dreammaker/src/parser.rs +++ b/crates/dreammaker/src/parser.rs @@ -1858,6 +1858,8 @@ impl<'ctx, 'an, 'inp> Parser<'ctx, 'an, 'inp> { Token::Punct(Punctuation::BitNot) => unary_ops.push(Spanned::new(self.location, Follow::Unary(UnaryOp::BitNot))), Token::Punct(Punctuation::PlusPlus) => unary_ops.push(Spanned::new(self.location, Follow::Unary(UnaryOp::PreIncr))), Token::Punct(Punctuation::MinusMinus) => unary_ops.push(Spanned::new(self.location, Follow::Unary(UnaryOp::PreDecr))), + Token::Punct(Punctuation::BitAnd) => unary_ops.push(Spanned::new(self.location, Follow::Unary(UnaryOp::Reference))), + Token::Punct(Punctuation::Mul) => unary_ops.push(Spanned::new(self.location, Follow::Unary(UnaryOp::Dereference))), other => { self.put_back(other); break; diff --git a/crates/dreammaker/tests/expression_tests.rs b/crates/dreammaker/tests/expression_tests.rs index 727b340d..f8cb4bb7 100644 --- a/crates/dreammaker/tests/expression_tests.rs +++ b/crates/dreammaker/tests/expression_tests.rs @@ -114,3 +114,17 @@ fn bitop_precedence() { } ); } + +#[test] +fn pointer_ops() { + assert_eq!( + parse_expr("*&1"), + Expression::Base { + term: Box::new(Spanned::new(Default::default(), Term::Int(1))), + follow: vec![ + Spanned::new(Default::default(), Follow::Unary(UnaryOp::Reference)), + Spanned::new(Default::default(), Follow::Unary(UnaryOp::Dereference)), + ].into_boxed_slice(), + } + ) +}