mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
feat: funcs ast
This commit is contained in:
parent
028c58980c
commit
b455c661a0
|
@ -1,2 +1,5 @@
|
|||
let foo :: String = "Hello, ";
|
||||
let bar :: String = "World!";
|
||||
let foo :: String = "foo";
|
||||
let bar :: String = "bar";
|
||||
func join :: (a , b) = {
|
||||
let baz :: String = "yay";
|
||||
};
|
|
@ -34,8 +34,11 @@ syntax! { not_operator , "!", Token::Not }
|
|||
syntax! { typehint_punctuation , "::", Token::Typehint }
|
||||
syntax! { lparen_punctuation , "(", Token::LParen }
|
||||
syntax! { rparen_punctuation , ")", Token::RParen }
|
||||
syntax! { lbrace_punctuation , "{", Token::LBrace }
|
||||
syntax! { rbrace_punctuation , "}", Token::RBrace }
|
||||
syntax! { semicolon_punctuation , ";", Token::Semicolon }
|
||||
syntax! { colon_punctuation , ":", Token::Colon }
|
||||
syntax! { comma_punctuation , ",", Token::Comma }
|
||||
|
||||
// Operator & Punctuation
|
||||
fn lex_operator_punctuation(input: &Bytes) -> IResult<&Bytes, Token> {
|
||||
|
@ -50,7 +53,8 @@ fn lex_operator_punctuation(input: &Bytes) -> IResult<&Bytes, Token> {
|
|||
|
||||
typehint_punctuation,
|
||||
lparen_punctuation, rparen_punctuation,
|
||||
semicolon_punctuation, colon_punctuation,
|
||||
lbrace_punctuation, rbrace_punctuation,
|
||||
semicolon_punctuation, colon_punctuation, comma_punctuation,
|
||||
))(input)
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@ pub enum Token {
|
|||
Plus, Minus, Mul, Div, Not,
|
||||
Eq, NEq, Lt, Gt, Lte, Gte,
|
||||
|
||||
LParen, RParen, Semicolon, Colon,
|
||||
LParen, RParen,
|
||||
LBrace, RBrace,
|
||||
Semicolon, Colon, Comma,
|
||||
|
||||
If, Else, Let, Func,
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use nom::{
|
|||
bytes::complete::take,
|
||||
combinator::{verify, map},
|
||||
Err,
|
||||
IResult, sequence::{terminated, tuple}, multi::many0, branch::alt, error::{Error, ErrorKind},
|
||||
IResult, sequence::{terminated, tuple, pair, preceded, delimited}, multi::many0, branch::alt, error::{Error, ErrorKind},
|
||||
};
|
||||
|
||||
use super::model::{Token, Tokens, Precedence, Infix, Program, Stmt, Expr, Ident, Literal};
|
||||
|
@ -16,9 +16,15 @@ macro_rules! tag_token (
|
|||
);
|
||||
|
||||
tag_token!(tag_let, Token::Let);
|
||||
tag_token!(tag_func, Token::Func);
|
||||
tag_token!(tag_assign, Token::Assign);
|
||||
tag_token!(tag_typehint, Token::Typehint);
|
||||
tag_token!(tag_semicolon, Token::Semicolon);
|
||||
tag_token!(tag_lparen, Token::LParen);
|
||||
tag_token!(tag_rparen, Token::RParen);
|
||||
tag_token!(tag_lbrace, Token::LBrace);
|
||||
tag_token!(tag_rbrace, Token::RBrace);
|
||||
tag_token!(tag_comma, Token::Comma);
|
||||
tag_token!(tag_end_of_file, Token::EndOfFile);
|
||||
|
||||
fn infix_operator(token: &Token) -> (Precedence, Option<Infix>) {
|
||||
|
@ -77,7 +83,7 @@ fn parse_ident_expr(input: Tokens) -> IResult<Tokens, Expr> {
|
|||
map(parse_ident, Expr::Ident)(input)
|
||||
}
|
||||
|
||||
fn parse_let(input: Tokens) -> IResult<Tokens, Stmt> {
|
||||
fn parse_let_stmt(input: Tokens) -> IResult<Tokens, Stmt> {
|
||||
map(
|
||||
tuple((
|
||||
tag_let,
|
||||
|
@ -92,6 +98,32 @@ fn parse_let(input: Tokens) -> IResult<Tokens, Stmt> {
|
|||
)(input)
|
||||
}
|
||||
|
||||
fn parse_params(input: Tokens) -> IResult<Tokens, Vec<Ident>> {
|
||||
map(
|
||||
pair(parse_ident, many0(preceded(tag_comma, parse_ident))),
|
||||
|(p, ps)| [&vec![p][..], &ps[..]].concat(),
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn empty_params(input: Tokens) -> IResult<Tokens, Vec<Ident>> { Ok((input, vec![])) }
|
||||
|
||||
fn parse_func_stmt(input: Tokens) -> IResult<Tokens, Stmt> {
|
||||
map(
|
||||
tuple((
|
||||
tag_func,
|
||||
parse_ident,
|
||||
tag_typehint,
|
||||
tag_lparen,
|
||||
alt((parse_params, empty_params)),
|
||||
tag_rparen,
|
||||
tag_assign,
|
||||
parse_block_stmt,
|
||||
tag_semicolon,
|
||||
)),
|
||||
|(_, ident, _, _, params, _, _, block, _)| Stmt::Func(ident, params, block),
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn parse_expr(input: Tokens, precedence: Precedence, left: Expr) -> IResult<Tokens, Expr> {
|
||||
let (i1, t1) = take(1usize)(input)?;
|
||||
|
||||
|
@ -123,9 +155,14 @@ fn parse_expr_lowest(input: Tokens) -> IResult<Tokens, Expr> {
|
|||
parse_expr_with(input, Precedence::Lowest)
|
||||
}
|
||||
|
||||
fn parse_block_stmt(input: Tokens) -> IResult<Tokens, Program> {
|
||||
delimited(tag_lbrace, many0(parse_stmt), tag_rbrace)(input)
|
||||
}
|
||||
|
||||
fn parse_stmt(input: Tokens) -> IResult<Tokens, Stmt> {
|
||||
alt((
|
||||
parse_let,
|
||||
parse_let_stmt,
|
||||
parse_func_stmt,
|
||||
))(input)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,15 @@ fn main() {
|
|||
let bytes: Vec<u8> = fs::read(src).unwrap();
|
||||
let (_errs_, tokens) = Lexer::lex_tokens(&bytes).unwrap();
|
||||
let tokens = Tokens::new(&tokens);
|
||||
let (_errs_, ast) = Parser::parse(tokens).unwrap();
|
||||
let ast = Parser::parse(tokens);
|
||||
match ast {
|
||||
Ok(ast) => {
|
||||
println!("{:#?}", ast);
|
||||
}
|
||||
Err(err) => {
|
||||
println!("{:#?}", err);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue