diff --git a/src/parser/ast.rs b/src/parser/ast.rs index 3978138..9e63b3b 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -38,12 +38,19 @@ pub enum Expression { FloatLiteral(f64), BoolLiteral(bool), StringLiteral(String), - FunctionCall { - callee: Box, - args: Vec, + Postfix { + initial: Box, + postfixes: Vec, }, } +#[derive(Debug, Clone, Serialize)] +#[serde(tag = "type", content = "value")] +pub enum Postfix { + FieldAccess(String), + FunctionCall(Vec), +} + #[derive(Debug, Clone, Serialize)] pub struct ParamList(pub Vec<(String, TypeExpr)>); diff --git a/src/parser/grammar.pest b/src/parser/grammar.pest index 8c62804..5258991 100644 --- a/src/parser/grammar.pest +++ b/src/parser/grammar.pest @@ -43,21 +43,19 @@ expr_stmt = { expr ~ ";" } // ================= EXPRESSIONS ================= type_expr = { identifier } -var_path = { identifier ~ ("." ~ identifier)* } - -term = { +primary = { integer | float | boolean | string_lit - | var_path + | identifier } -func_call = { - var_path ~ "(" ~ (expr ~ ("," ~ expr)*)? ~ ")" +postfix = { + ("." ~ identifier) + | ("(" ~ (expr ~ ("," ~ expr)*)? ~ ")") } expr = { - func_call - | term + primary ~ postfix* } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 22721b4..60af79d 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -169,11 +169,20 @@ impl Statement { impl Expression { pub fn from_pair(pair: pest::iterators::Pair) -> Self { match pair.as_rule() { - Rule::expr | Rule::term => { - let inner = pair.into_inner().next().unwrap(); - Expression::from_pair(inner) + Rule::expr => { + let mut inner = pair.into_inner(); + let exp = Expression::from_pair(inner.next().unwrap()); + + if inner.len() > 0 { + Expression::Postfix { + initial: Box::new(exp), + postfixes: inner.map(|p| Postfix::from_pair(p)).collect(), + } + } else { + exp + } } - Rule::var_path => Expression::Identifier(pair.as_str().to_string()), + Rule::primary => Expression::from_pair(pair.into_inner().next().unwrap()), Rule::identifier => Expression::Identifier(pair.as_str().to_string()), Rule::integer => { let value = pair.as_str().parse::().unwrap(); @@ -192,16 +201,6 @@ impl Expression { Expression::StringLiteral(inner_str.to_string()) } - Rule::func_call => { - let mut inner = pair.into_inner(); - let callee = Expression::from_pair(inner.next().unwrap()); - let args = inner.map(Expression::from_pair).collect(); - Expression::FunctionCall { - callee: Box::new(callee), - args, - } - } - _ => unimplemented!( "Expression parsing not implemented yet {:?}", pair.as_rule() @@ -209,3 +208,23 @@ impl Expression { } } } + +impl Postfix { + pub fn from_pair(pair: pest::iterators::Pair) -> Self { + match pair.as_rule() { + Rule::postfix => { + let inner = pair.into_inner(); + if let Some(field) = inner.peek() { + if field.as_rule() == Rule::identifier { + Postfix::FieldAccess(field.as_str().to_string()) + } else { + Postfix::FunctionCall(inner.map(|p| Expression::from_pair(p)).collect()) + } + } else { + Postfix::FunctionCall(vec![]) + } + } + _ => unimplemented!("Postfix parsing not implemented yet {:?}", pair.as_rule()), + } + } +} diff --git a/test/src/main.ms b/test/src/main.ms index eb93632..2e183dd 100644 --- a/test/src/main.ms +++ b/test/src/main.ms @@ -6,5 +6,5 @@ struct Point { } function add(a: int, b: int): int { - idk.do_something(); + idk.do_something(123, "abc"); }