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),
|
Literal(Literal),
|
||||||
UnaryOp(Box<UnaryOp>),
|
UnaryOp(Box<UnaryOp>),
|
||||||
BinaryOp(Box<BinaryOp>),
|
BinaryOp(Box<BinaryOp>),
|
||||||
|
Call(Box<Call>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Expr {
|
impl Expr {
|
||||||
|
|
@ -102,6 +103,7 @@ impl Expr {
|
||||||
Expr::UnaryOp(unary) => unary.span,
|
Expr::UnaryOp(unary) => unary.span,
|
||||||
Expr::BinaryOp(binary) => binary.span,
|
Expr::BinaryOp(binary) => binary.span,
|
||||||
Expr::Ident(Ident { span, .. }) => *span,
|
Expr::Ident(Ident { span, .. }) => *span,
|
||||||
|
Expr::Call(call) => call.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,3 +168,16 @@ pub enum BinaryOpKind {
|
||||||
Div,
|
Div,
|
||||||
Mod,
|
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() {
|
match self.peek_kind() {
|
||||||
Some(TokenType::Not) => {
|
Some(TokenType::Not) => {
|
||||||
let unary_op_span = self.next().unwrap().span;
|
let unary_op_span = self.next().unwrap().span;
|
||||||
let expr = self.unary()?;
|
let expr = self.call()?;
|
||||||
Ok(Expr::UnaryOp(Box::new(UnaryOp {
|
Ok(Expr::UnaryOp(Box::new(UnaryOp {
|
||||||
span: unary_op_span.extend(expr.span()),
|
span: unary_op_span.extend(expr.span()),
|
||||||
expr,
|
expr,
|
||||||
|
|
@ -295,18 +295,51 @@ impl<'code> Parser<'code> {
|
||||||
}
|
}
|
||||||
Some(TokenType::Minus) => {
|
Some(TokenType::Minus) => {
|
||||||
let unary_op_span = self.next().unwrap().span;
|
let unary_op_span = self.next().unwrap().span;
|
||||||
let expr = self.unary()?;
|
let expr = self.call()?;
|
||||||
Ok(Expr::UnaryOp(Box::new(UnaryOp {
|
Ok(Expr::UnaryOp(Box::new(UnaryOp {
|
||||||
span: unary_op_span.extend(expr.span()),
|
span: unary_op_span.extend(expr.span()),
|
||||||
expr,
|
expr,
|
||||||
kind: UnaryOpKind::Neg,
|
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"))?;
|
let next = self.next().ok_or(ParseErr::Eof("primary"))?;
|
||||||
match next.kind {
|
match next.kind {
|
||||||
TokenType::String(literal) => Ok(Expr::Literal(Literal::String(literal, next.span))),
|
TokenType::String(literal) => Ok(Expr::Literal(Literal::String(literal, next.span))),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue