From 00569da11d4320d4616a2b2260cd5858c56fb833 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 14 Apr 2026 02:58:51 +0200 Subject: [PATCH] Struct decleration --- src/parser/ast.rs | 7 ++++-- src/parser/grammar.pest | 11 +++++++--- src/parser/mod.rs | 47 ++++++++++++++++++++++++++++++++--------- test/src/main.ms | 5 +++++ 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/parser/ast.rs b/src/parser/ast.rs index fb249e2..55dc6bf 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -12,11 +12,11 @@ pub enum TopLevel { Import(String), StructDecl { name: String, - fields: Vec<(String, TypeExpr)>, + fields: ParamList, }, FunctionDecl { name: String, - params: Vec<(String, TypeExpr)>, + params: ParamList, return_type: Option, body: Vec, }, @@ -41,3 +41,6 @@ pub enum Expression { args: Vec, }, } + +#[derive(Debug, Clone, Serialize)] +pub struct ParamList(pub Vec<(String, TypeExpr)>); diff --git a/src/parser/grammar.pest b/src/parser/grammar.pest index 032281a..4fac1c4 100644 --- a/src/parser/grammar.pest +++ b/src/parser/grammar.pest @@ -13,14 +13,19 @@ inner_str = @{ (!"\"" ~ ANY)* } // ================= TOP LEVEL ================= -top_level = _{ import | function_decl } +top_level = _{ import | function_decl | struct_decl } export = { "export"? } import = { "import" ~ string_lit ~ ";" } -param_list = { param ~ ("," ~ param)* ~ ","? } -param = { identifier ~ ":" ~ type_expr } +param_list = { param ~ ("," ~ param)* ~ ","? } +param = { identifier ~ ":" ~ type_expr } + +struct_decl = { + export ~ "struct" ~ identifier ~ "{" ~ param_list? ~ "}" +} + function_decl = { export ~ "function" ~ identifier ~ "(" ~ param_list? ~ ")" ~ (":" ~ type_expr)? ~ block } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 02c4a55..935f198 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -38,6 +38,22 @@ impl TypeExpr { } } +impl ParamList { + pub fn from_pair(pair: pest::iterators::Pair) -> Self { + let 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(); + + ParamList(params) + } +} + impl TopLevel { pub fn from_pair(pair: pest::iterators::Pair) -> Option { match pair.as_rule() { @@ -60,17 +76,9 @@ impl TopLevel { 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() + ParamList::from_pair(params_pair) } else { - vec![] + ParamList(vec![]) }; let return_type = if let Some(next) = inner.peek() { if next.as_rule() == Rule::type_expr { @@ -91,6 +99,25 @@ impl TopLevel { }) } + Rule::struct_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 fields_pair = inner.next().unwrap(); + let fields = ParamList::from_pair(fields_pair); + + Some(TopLevel::StructDecl { name, fields }) + } + Rule::EOI => None, _ => unimplemented!("TopLevel parsing not implemented yet {:?}", pair.as_rule()), } diff --git a/test/src/main.ms b/test/src/main.ms index 9e8fa56..4cdfd6a 100644 --- a/test/src/main.ms +++ b/test/src/main.ms @@ -1,3 +1,8 @@ import "fmt"; +struct Point { + x: int, + y: int +} + function add(a: int, b: int): int {}