From 826092c54bcf629b27808bc1f11244acd60d7a73 Mon Sep 17 00:00:00 2001 From: Natapat Samutpong Date: Sat, 12 Feb 2022 18:29:10 +0700 Subject: [PATCH] call stmt in root --- example/hello_world.hyc | 9 ++- src/front/model.rs | 1 + src/front/parser.rs | 137 ++++++++++++++++++++++++++-------------- src/main.rs | 2 + 4 files changed, 95 insertions(+), 54 deletions(-) diff --git a/example/hello_world.hyc b/example/hello_world.hyc index 870e631..f9e2be9 100644 --- a/example/hello_world.hyc +++ b/example/hello_world.hyc @@ -1,5 +1,4 @@ -let foo :: String = "foo"; -let bar :: String = "bar"; -func join :: (a , b) = { - let baz :: String = "yay"; -}; \ No newline at end of file +func join :: (a, b) = { + let result :: String = from(a, b); +}; +let foo :: String = join("f", "oo"); \ No newline at end of file diff --git a/src/front/model.rs b/src/front/model.rs index 235efb6..2aa7bc1 100644 --- a/src/front/model.rs +++ b/src/front/model.rs @@ -102,6 +102,7 @@ pub type Program = Vec; pub enum Stmt { Let(Ident, Ident, Expr), Func(Ident, Vec, Vec), + Call(Ident, Vec), } #[derive(Clone, Debug, PartialEq)] diff --git a/src/front/parser.rs b/src/front/parser.rs index c761a1d..cf866b7 100644 --- a/src/front/parser.rs +++ b/src/front/parser.rs @@ -1,8 +1,12 @@ use nom::{ + branch::alt, bytes::complete::take, combinator::{verify, map}, Err, - IResult, sequence::{terminated, tuple, pair, preceded, delimited}, multi::many0, branch::alt, error::{Error, ErrorKind}, + error::{Error, ErrorKind}, + IResult, + multi::many0, + sequence::{terminated, tuple, pair, preceded, delimited}, }; use super::model::{Token, Tokens, Precedence, Infix, Program, Stmt, Expr, Ident, Literal}; @@ -83,21 +87,6 @@ fn parse_ident_expr(input: Tokens) -> IResult { map(parse_ident, Expr::Ident)(input) } -fn parse_let_stmt(input: Tokens) -> IResult { - 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> { map( pair(parse_ident, many0(preceded(tag_comma, parse_ident))), @@ -107,6 +96,75 @@ fn parse_params(input: Tokens) -> IResult> { fn empty_params(input: Tokens) -> IResult> { Ok((input, vec![])) } +fn parse_call_expr(input: Tokens, func_handle: Expr) -> IResult { + 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 { + 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 { + preceded(tag_comma, parse_expr_lowest)(input) +} + +fn parse_exprs(input: Tokens) -> IResult> { + 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 { + let (i1, left) = parse_atom_expr(input)?; + parse_expr(i1, precedence, left) +} + +fn parse_expr_lowest(input: Tokens) -> IResult { + parse_expr_with(input, Precedence::Lowest) +} + +fn parse_call_stmt(input: Tokens) -> IResult { + map( + tuple(( + parse_ident, + tag_lparen, + parse_exprs, + tag_rparen, + tag_semicolon, + )), + |(ident, _, args, _, _)| Stmt::Call(ident, args), + )(input) +} + +fn parse_block_stmt(input: Tokens) -> IResult { + delimited(tag_lbrace, many0(parse_stmt), tag_rbrace)(input) +} + fn parse_func_stmt(input: Tokens) -> IResult { map( tuple(( @@ -124,45 +182,26 @@ fn parse_func_stmt(input: Tokens) -> IResult { )(input) } -fn parse_expr(input: Tokens, precedence: Precedence, left: Expr) -> IResult { - 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) - todo!() - }, - (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 { - let (i1, left) = parse_atom_expr(input)?; - parse_expr(i1, precedence, left) -} - -fn parse_expr_lowest(input: Tokens) -> IResult { - parse_expr_with(input, Precedence::Lowest) -} - -fn parse_block_stmt(input: Tokens) -> IResult { - delimited(tag_lbrace, many0(parse_stmt), tag_rbrace)(input) +fn parse_let_stmt(input: Tokens) -> IResult { + 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_stmt(input: Tokens) -> IResult { alt(( parse_let_stmt, parse_func_stmt, + parse_call_stmt, ))(input) } diff --git a/src/main.rs b/src/main.rs index 895aaeb..963701a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,8 @@ use clap::Parser as ArgParser; pub mod args; use args::{Args, Options}; +/// Front-end of the language. +/// Contains lexer, parser and token types. pub mod front; use front::{lex::Lexer, parser::Parser, model::Tokens};