mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-14 17:35:03 +01:00
parse calls
This commit is contained in:
parent
7cba55578a
commit
031217f6c6
2 changed files with 52 additions and 4 deletions
15
src/ast.rs
15
src/ast.rs
|
|
@ -93,6 +93,7 @@ pub enum Expr {
|
|||
Literal(Literal),
|
||||
UnaryOp(Box<UnaryOp>),
|
||||
BinaryOp(Box<BinaryOp>),
|
||||
Call(Box<Call>),
|
||||
}
|
||||
|
||||
impl Expr {
|
||||
|
|
@ -102,6 +103,7 @@ impl Expr {
|
|||
Expr::UnaryOp(unary) => unary.span,
|
||||
Expr::BinaryOp(binary) => binary.span,
|
||||
Expr::Ident(Ident { span, .. }) => *span,
|
||||
Expr::Call(call) => call.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -166,3 +168,16 @@ pub enum BinaryOpKind {
|
|||
Div,
|
||||
Mod,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Call {
|
||||
pub callee: Expr,
|
||||
pub span: Span,
|
||||
pub kind: CallKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum CallKind {
|
||||
Field(Ident),
|
||||
Fn(Vec<Expr>),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ impl<'code> Parser<'code> {
|
|||
match self.peek_kind() {
|
||||
Some(TokenType::Not) => {
|
||||
let unary_op_span = self.next().unwrap().span;
|
||||
let expr = self.unary()?;
|
||||
let expr = self.call()?;
|
||||
Ok(Expr::UnaryOp(Box::new(UnaryOp {
|
||||
span: unary_op_span.extend(expr.span()),
|
||||
expr,
|
||||
|
|
@ -295,18 +295,51 @@ impl<'code> Parser<'code> {
|
|||
}
|
||||
Some(TokenType::Minus) => {
|
||||
let unary_op_span = self.next().unwrap().span;
|
||||
let expr = self.unary()?;
|
||||
let expr = self.call()?;
|
||||
Ok(Expr::UnaryOp(Box::new(UnaryOp {
|
||||
span: unary_op_span.extend(expr.span()),
|
||||
expr,
|
||||
kind: UnaryOpKind::Neg,
|
||||
})))
|
||||
}
|
||||
_ => self.primary(),
|
||||
_ => self.call(),
|
||||
}
|
||||
}
|
||||
|
||||
fn primary<'parser>(&'parser mut self) -> ParseResult<'code, Expr> {
|
||||
fn call(&mut self) -> ParseResult<'code, Expr> {
|
||||
let mut expr = self.primary()?;
|
||||
|
||||
loop {
|
||||
expr = match self.peek_kind() {
|
||||
Some(TokenType::ParenO) => {
|
||||
let open_span = self.expect(TokenType::ParenO)?.span;
|
||||
let args = self.parse_list(TokenType::ParenC, Self::expression)?;
|
||||
let close_span = self.expect(TokenType::ParenC)?.span;
|
||||
|
||||
Expr::Call(Box::new(Call {
|
||||
callee: expr,
|
||||
span: open_span.extend(close_span),
|
||||
kind: CallKind::Fn(args),
|
||||
}))
|
||||
}
|
||||
Some(TokenType::Dot) => {
|
||||
let dot_span = self.expect(TokenType::Dot)?.span;
|
||||
let field = self.ident()?;
|
||||
|
||||
Expr::Call(Box::new(Call {
|
||||
callee: expr,
|
||||
span: dot_span.extend(field.span),
|
||||
kind: CallKind::Field(field),
|
||||
}))
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
|
||||
Ok(expr)
|
||||
}
|
||||
|
||||
fn primary(&mut self) -> ParseResult<'code, Expr> {
|
||||
let next = self.next().ok_or(ParseErr::Eof("primary"))?;
|
||||
match next.kind {
|
||||
TokenType::String(literal) => Ok(Expr::Literal(Literal::String(literal, next.span))),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue