From 9a5511018303ac1790c527ad400cc2fe187d7d87 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 14 Apr 2026 02:38:52 +0200 Subject: [PATCH] Simple parser --- src/parser/grammar.pest | 15 ++++--- src/parser/mod.rs | 92 +++++++++++++++++++++++++++++++++-------- test/src/main.ms | 4 +- 3 files changed, 87 insertions(+), 24 deletions(-) diff --git a/src/parser/grammar.pest b/src/parser/grammar.pest index 53e39ea..032281a 100644 --- a/src/parser/grammar.pest +++ b/src/parser/grammar.pest @@ -1,8 +1,7 @@ WHITESPACE = _{ " " | "\t" | "\r" | "\n" } COMMENT = _{ "//" ~ (!"\n" ~ ANY)* } -program = { SOI ~ item* ~ EOI } -item = _{ import_decl | function_decl } +program = { SOI ~ top_level* ~ EOI } // primitives identifier = @{ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* } @@ -14,9 +13,11 @@ inner_str = @{ (!"\"" ~ ANY)* } // ================= TOP LEVEL ================= +top_level = _{ import | function_decl } + export = { "export"? } -import_decl = { "import" ~ string_lit ~ ";" } +import = { "import" ~ string_lit ~ ";" } param_list = { param ~ ("," ~ param)* ~ ","? } param = { identifier ~ ":" ~ type_expr } @@ -26,9 +27,13 @@ function_decl = { // ================= STATEMENTS ================= -block = { "{" ~ "}" } +block = { "{" ~ statement_list ~ "}" } -statement = _{ "idk" } +statement_list = { statement* } + +statement = _{ expr_stmt } + +expr_stmt = { expr ~ ";" } // ================= EXPRESSIONS ================= type_expr = _{ identifier } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 0aa6a79..1b3f177 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -16,30 +16,86 @@ pub fn parse(source: &str) -> Result, ParseError> { let mut statements = vec![]; - // pairs is an iterator over the top-level program pair - // we need to get its inner children for pair in pairs { - match pair.as_rule() { - Rule::program => { - for inner in pair.into_inner() { - match inner.as_rule() { - Rule::import_decl => { - let path = inner.into_inner().next().unwrap().as_str().to_string(); - statements.push(TopLevel::Import(path)); - } - Rule::EOI => {} - _ => {} - } - } - } - Rule::EOI => {} - _ => {} - } + statements.push(TopLevel::from_pair(pair)); } Ok(statements) } +impl TypeExpr { + pub fn from_pair(pair: pest::iterators::Pair) -> Self { + match pair.as_rule() { + Rule::type_expr => { + let inner = pair.into_inner().next().unwrap(); + TypeExpr::from_pair(inner) + } + Rule::identifier => TypeExpr::Identifier(pair.as_str().to_string()), + _ => unimplemented!("TypeExpr parsing not implemented yet"), + } + } +} + +impl TopLevel { + pub fn from_pair(pair: pest::iterators::Pair) -> Self { + match pair.as_rule() { + Rule::program => { + let inner = pair.into_inner().next().unwrap(); + TopLevel::from_pair(inner) + } + Rule::import => { + let path = pair.into_inner().next().unwrap().as_str().to_string(); + TopLevel::Import(path) + } + 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(); + true + } else { + false + } + } else { + false + }; + let name = inner.next().unwrap().as_str().to_string(); + let params_pair = inner.next().unwrap(); + let params = if params_pair.as_rule() == Rule::param_list { + params_pair + .into_inner() + .map(|p| { + let mut param_inner = p.into_inner(); + let param_name = param_inner.next().unwrap().as_str().to_string(); + let param_type = TypeExpr::from_pair(param_inner.next().unwrap()); + (param_name, param_type) + }) + .collect() + } else { + vec![] + }; + let return_type = if let Some(next) = inner.peek() { + if next.as_rule() == Rule::type_expr { + Some(TypeExpr::from_pair(inner.next().unwrap())) + } else { + None + } + } else { + None + }; + // For now, we'll just ignore the function body and return an empty vector + TopLevel::FunctionDecl { + name, + params, + return_type, + body: vec![], + } + } + _ => unimplemented!("TopLevel 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 9e8fa56..bcc1da0 100644 --- a/test/src/main.ms +++ b/test/src/main.ms @@ -1,3 +1,5 @@ import "fmt"; -function add(a: int, b: int): int {} +function add(a: int, b: int): int { + hello; +}