1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-10-16 02:37:40 -05:00

Compare commits

..

No commits in common. "20decd8677debaed05f28cbf950eb25d3be6422e" and "b455c661a0712ee4488300ca4a3390aa6ce6d7de" have entirely different histories.

5 changed files with 56 additions and 119 deletions

View file

@ -1,10 +1,5 @@
let foo :: String = "foo";
let bar :: String = "bar";
func join :: (a , b) = { func join :: (a , b) = {
let result :: String = from(a, b); let baz :: String = "yay";
return result
};
func main :: () = {
let foo :: String = join("f", "oo");
print(foo);
return 0
}; };

View file

@ -94,7 +94,6 @@ fn lex_reserved_identifier(input: &Bytes) -> IResult<&Bytes, Token> {
"else" => Token::Else, "else" => Token::Else,
"let" => Token::Let, "let" => Token::Let,
"func" => Token::Func, "func" => Token::Func,
"return" => Token::Return,
"true" => Token::Bool(true), "true" => Token::Bool(true),
"false" => Token::Bool(false), "false" => Token::Bool(false),
_ => Token::Identifier(syntax.to_string()), _ => Token::Identifier(syntax.to_string()),

View file

@ -18,7 +18,7 @@ pub enum Token {
LBrace, RBrace, LBrace, RBrace,
Semicolon, Colon, Comma, Semicolon, Colon, Comma,
If, Else, Let, Func, Return, If, Else, Let, Func,
} }
/// Token struct with position information. /// Token struct with position information.
@ -102,8 +102,6 @@ pub type Program = Vec<Stmt>;
pub enum Stmt { pub enum Stmt {
Let(Ident, Ident, Expr), Let(Ident, Ident, Expr),
Func(Ident, Vec<Ident>, Vec<Stmt>), Func(Ident, Vec<Ident>, Vec<Stmt>),
Call(Ident, Vec<Expr>),
Return(Expr),
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]

View file

@ -1,12 +1,8 @@
use nom::{ use nom::{
branch::alt,
bytes::complete::take, bytes::complete::take,
combinator::{verify, map, opt}, combinator::{verify, map},
Err, Err,
error::{Error, ErrorKind}, IResult, sequence::{terminated, tuple, pair, preceded, delimited}, multi::many0, branch::alt, error::{Error, ErrorKind},
IResult,
multi::many0,
sequence::{terminated, tuple, pair, preceded, delimited},
}; };
use super::model::{Token, Tokens, Precedence, Infix, Program, Stmt, Expr, Ident, Literal}; use super::model::{Token, Tokens, Precedence, Infix, Program, Stmt, Expr, Ident, Literal};
@ -21,8 +17,6 @@ macro_rules! tag_token (
tag_token!(tag_let, Token::Let); tag_token!(tag_let, Token::Let);
tag_token!(tag_func, Token::Func); tag_token!(tag_func, Token::Func);
tag_token!(tag_return, Token::Return);
tag_token!(tag_assign, Token::Assign); tag_token!(tag_assign, Token::Assign);
tag_token!(tag_typehint, Token::Typehint); tag_token!(tag_typehint, Token::Typehint);
tag_token!(tag_semicolon, Token::Semicolon); tag_token!(tag_semicolon, Token::Semicolon);
@ -89,6 +83,21 @@ fn parse_ident_expr(input: Tokens) -> IResult<Tokens, Expr> {
map(parse_ident, Expr::Ident)(input) map(parse_ident, Expr::Ident)(input)
} }
fn parse_let_stmt(input: Tokens) -> IResult<Tokens, Stmt> {
map(
tuple((
tag_let,
parse_ident,
tag_typehint,
parse_ident,
tag_assign,
parse_expr_lowest,
tag_semicolon,
)),
|(_, ident, _, typehint, _, expr, _)| Stmt::Let(ident, typehint, expr),
)(input)
}
fn parse_params(input: Tokens) -> IResult<Tokens, Vec<Ident>> { fn parse_params(input: Tokens) -> IResult<Tokens, Vec<Ident>> {
map( map(
pair(parse_ident, many0(preceded(tag_comma, parse_ident))), pair(parse_ident, many0(preceded(tag_comma, parse_ident))),
@ -98,86 +107,6 @@ fn parse_params(input: Tokens) -> IResult<Tokens, Vec<Ident>> {
fn empty_params(input: Tokens) -> IResult<Tokens, Vec<Ident>> { Ok((input, vec![])) } fn empty_params(input: Tokens) -> IResult<Tokens, Vec<Ident>> { Ok((input, vec![])) }
fn parse_call_expr(input: Tokens, func_handle: Expr) -> IResult<Tokens, Expr> {
map(
delimited(
tag_lparen,
parse_exprs,
tag_rparen,
),
|e| Expr::Call { func: Box::new(func_handle.clone()), args: e },
)(input)
}
fn parse_expr(input: Tokens, precedence: Precedence, left: Expr) -> IResult<Tokens, Expr> {
let (i1, t1) = take(1usize)(input)?;
if t1.tokens.is_empty() { Ok((i1, left)) }
else {
let p = infix_operator(&t1.tokens[0]);
match p {
(Precedence::Call, _) if precedence < Precedence::Call => {
let (i2, left2) = parse_call_expr(input, left)?;
parse_expr(i2, precedence, left2)
},
(ref peek, _) if precedence < *peek => {
// let (i2, left2) = parse_infix_expr(input, left)?;
// parse_expr(i2, precedence, left2)
todo!()
},
_ => Ok((input, left)),
}
}
}
fn parse_comma_exprs(input: Tokens) -> IResult<Tokens, Expr> {
preceded(tag_comma, parse_expr_lowest)(input)
}
fn parse_exprs(input: Tokens) -> IResult<Tokens, Vec<Expr>> {
map(
pair(parse_expr_lowest, many0(parse_comma_exprs)),
|(first, second)| [&vec![first][..], &second[..]].concat(),
)(input)
}
fn parse_expr_with(input: Tokens, precedence: Precedence) -> IResult<Tokens, Expr> {
let (i1, left) = parse_atom_expr(input)?;
parse_expr(i1, precedence, left)
}
fn parse_expr_lowest(input: Tokens) -> IResult<Tokens, Expr> {
parse_expr_with(input, Precedence::Lowest)
}
fn parse_return_stmt(input: Tokens) -> IResult<Tokens, Stmt> {
map(
delimited(
tag_return,
parse_expr_lowest,
opt(tag_semicolon),
),
Stmt::Return,
)(input)
}
fn parse_call_stmt(input: Tokens) -> IResult<Tokens, Stmt> {
map(
tuple((
parse_ident,
tag_lparen,
parse_exprs,
tag_rparen,
opt(tag_semicolon),
)),
|(ident, _, args, _, _)| Stmt::Call(ident, args),
)(input)
}
fn parse_block_stmt(input: Tokens) -> IResult<Tokens, Program> {
delimited(tag_lbrace, many0(parse_stmt), tag_rbrace)(input)
}
fn parse_func_stmt(input: Tokens) -> IResult<Tokens, Stmt> { fn parse_func_stmt(input: Tokens) -> IResult<Tokens, Stmt> {
map( map(
tuple(( tuple((
@ -189,33 +118,51 @@ fn parse_func_stmt(input: Tokens) -> IResult<Tokens, Stmt> {
tag_rparen, tag_rparen,
tag_assign, tag_assign,
parse_block_stmt, parse_block_stmt,
opt(tag_semicolon), tag_semicolon,
)), )),
|(_, ident, _, _, params, _, _, block, _)| Stmt::Func(ident, params, block), |(_, ident, _, _, params, _, _, block, _)| Stmt::Func(ident, params, block),
)(input) )(input)
} }
fn parse_let_stmt(input: Tokens) -> IResult<Tokens, Stmt> { fn parse_expr(input: Tokens, precedence: Precedence, left: Expr) -> IResult<Tokens, Expr> {
map( let (i1, t1) = take(1usize)(input)?;
tuple((
tag_let, if t1.tokens.is_empty() { Ok((i1, left)) }
parse_ident, else {
tag_typehint, let p = infix_operator(&t1.tokens[0]);
parse_ident, match p {
tag_assign, (Precedence::Call, _) if precedence < Precedence::Call => {
parse_expr_lowest, // let (i2, left2) = parse_call_expr(input, left)?;
opt(tag_semicolon), // parse_expr(i2, precedence, left2)
)), todo!()
|(_, ident, _, typehint, _, expr, _)| Stmt::Let(ident, typehint, expr), },
)(input) (ref peek, _) if precedence < *peek => {
// let (i2, left2) = parse_infix_expr(input, left)?;
// parse_expr(i2, precedence, left2)
todo!()
},
_ => Ok((input, left)),
}
}
}
fn parse_expr_with(input: Tokens, precedence: Precedence) -> IResult<Tokens, Expr> {
let (i1, left) = parse_atom_expr(input)?;
parse_expr(i1, precedence, left)
}
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> { fn parse_stmt(input: Tokens) -> IResult<Tokens, Stmt> {
alt(( alt((
parse_let_stmt, parse_let_stmt,
parse_func_stmt, parse_func_stmt,
parse_call_stmt,
parse_return_stmt,
))(input) ))(input)
} }

View file

@ -6,8 +6,6 @@ use clap::Parser as ArgParser;
pub mod args; pub mod args;
use args::{Args, Options}; use args::{Args, Options};
/// Front-end of the language.
/// Contains lexer, parser and token types.
pub mod front; pub mod front;
use front::{lex::Lexer, parser::Parser, model::Tokens}; use front::{lex::Lexer, parser::Parser, model::Tokens};