punk_parser 0.0.0

Parser for Punk language.
Documentation
use crate::lexer;
use crate::location;
use crate::src::SrcExpr;
use crate::src::SrcItem;
use crate::src::SrcModule;
use crate::src::SrcType;
use crate::src::SrcIdent;
use crate::src::SrcStmt;

grammar;

pub Expr: Box<SrcExpr> = {
    <int_literal> => Box::new(SrcExpr::IntegerLiteral(<>.parse::<i64>().unwrap())),
    <string_literal> => Box::new(SrcExpr::StringLiteral(<>)),
    "(" <Expr> ")" => Box::new(SrcExpr::ParenExpr(<>)),
};

pub Ident: SrcIdent = {
    <ident> => SrcIdent(<>)
}

Comma<T>: Vec<T> = {
    <v:(<T> ",")*> <e:T?> => match e {
        None => v,
        Some(e) => {
            let mut v = v;
            v.push(e);
            v
        }
    }
}

Decl: (SrcIdent, SrcType) = {
    <v:Ident> ":" <t:Type> => (v, t)
}

pub Block: SrcStmt = {
    "{" <Stmt*> "}" => SrcStmt::BlockStmt(<>),
}

pub Stmt: Box<SrcStmt> = {
    <Block> => Box::new(<>),
    <Expr> ";" => Box::new(SrcStmt::ExprStmt(<>)),
}

pub Item: SrcItem = {
    "def" <f:Ident> "(" <xs:Comma<Decl>> ")" ":" <r:Type> <b:Block> =>
    SrcItem::Def(
        f,
        None,
        Some(SrcExpr::FunctionExpr(xs, r, b))
    ),
}

pub Module: SrcModule = {
    <Item+> => SrcModule(<>),
}

pub Type: SrcType = {
    <Ident> => SrcType::NamedType(<>),
}

extern {
    type Location = location::Location;
    type Error = lexer::LexicalError;

    enum lexer::Tok {
        "def" => lexer::Tok::Def,
        ";" => lexer::Tok::Semi,
        ":" => lexer::Tok::Colon,
        "(" => lexer::Tok::LeftParen,
        ")" => lexer::Tok::RightParen,
        "-" => lexer::Tok::Minus,
        "+" => lexer::Tok::Plus,
        "," => lexer::Tok::Comma,
        "{" => lexer::Tok::LeftBracket,
        "}" => lexer::Tok::RightBracket,
        ident => lexer::Tok::Ident(<String>),
        string_literal => lexer::Tok::Str(<String>),
        int_literal => lexer::Tok::Int(<String>),
    }
}