diff --git a/src/parser/ast.rs b/src/parser/ast.rs index 28939c3..3978138 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -20,14 +20,14 @@ pub enum TopLevel { name: String, params: ParamList, return_type: Option, - body: Vec, + body: Block, }, } #[derive(Debug, Clone, Serialize)] #[serde(tag = "type", content = "value")] pub enum Statement { - Expression(String), + Expression(Expression), } #[derive(Debug, Clone, Serialize)] @@ -46,3 +46,6 @@ pub enum Expression { #[derive(Debug, Clone, Serialize)] pub struct ParamList(pub Vec<(String, TypeExpr)>); + +#[derive(Debug, Clone, Serialize)] +pub struct Block(pub Vec); diff --git a/src/parser/grammar.pest b/src/parser/grammar.pest index 4fac1c4..9c9afd5 100644 --- a/src/parser/grammar.pest +++ b/src/parser/grammar.pest @@ -15,7 +15,7 @@ inner_str = @{ (!"\"" ~ ANY)* } top_level = _{ import | function_decl | struct_decl } -export = { "export"? } +export = { "export" } import = { "import" ~ string_lit ~ ";" } @@ -23,11 +23,11 @@ param_list = { param ~ ("," ~ param)* ~ ","? } param = { identifier ~ ":" ~ type_expr } struct_decl = { - export ~ "struct" ~ identifier ~ "{" ~ param_list? ~ "}" + export? ~ "struct" ~ identifier ~ "{" ~ param_list? ~ "}" } function_decl = { - export ~ "function" ~ identifier ~ "(" ~ param_list? ~ ")" ~ (":" ~ type_expr)? ~ block + export? ~ "function" ~ identifier ~ "(" ~ param_list? ~ ")" ~ (":" ~ type_expr)? ~ block } // ================= STATEMENTS ================= @@ -41,6 +41,6 @@ statement = _{ expr_stmt } expr_stmt = { expr ~ ";" } // ================= EXPRESSIONS ================= -type_expr = _{ identifier } +type_expr = { identifier } expr = { identifier | integer | float | boolean | string_lit } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index ead59f9..9477df1 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -63,6 +63,7 @@ impl TopLevel { } Rule::function_decl => { let mut inner = pair.into_inner(); + let export = if let Some(first) = inner.peek() { if first.as_rule() == Rule::export { inner.next(); @@ -90,13 +91,14 @@ impl TopLevel { None }; - // For now, we'll just ignore the function body and return an empty vector + let body = Block::from_pair(inner.next().unwrap()); + Some(TopLevel::FunctionDecl { export, name, params, return_type, - body: vec![], + body, }) } @@ -129,6 +131,41 @@ impl TopLevel { } } +impl Block { + pub fn from_pair(pair: pest::iterators::Pair) -> Self { + let statements = pair + .into_inner() + .flat_map(|pair| { + if pair.as_rule() == Rule::statement_list { + pair.into_inner().map(Statement::from_pair).collect() + } else { + vec![Statement::from_pair(pair)] + } + }) + .collect(); + Block(statements) + } +} + +impl Statement { + pub fn from_pair(pair: pest::iterators::Pair) -> Self { + match pair.as_rule() { + Rule::statement => { + let inner = pair.into_inner().next().unwrap(); + Statement::from_pair(inner) + } + Rule::expr_stmt => { + let expr_pair = pair.into_inner().next().unwrap(); + Statement::Expression(Expression::from_pair(expr_pair)) + } + _ => unimplemented!( + "Statement parsing not implemented yet: {:?}", + pair.as_rule() + ), + } + } +} + impl Expression { pub fn from_pair(pair: pest::iterators::Pair) -> Self { match pair.as_rule() { diff --git a/test/src/main.ms b/test/src/main.ms index 4cdfd6a..3932a50 100644 --- a/test/src/main.ms +++ b/test/src/main.ms @@ -5,4 +5,6 @@ struct Point { y: int } -function add(a: int, b: int): int {} +function add(a: int, b: int): int { + do_something; +}