From ec30d18e15708f3e121d4114e89c89ef43bcfbe6 Mon Sep 17 00:00:00 2001 From: Selimaj Dev Date: Fri, 17 Apr 2026 12:56:08 +0200 Subject: [PATCH] field exporting --- parser/src/ast.rs | 8 +------- parser/src/grammar.pest | 2 +- parser/src/lib.rs | 19 +++++++++++++----- semantic/src/lib.rs | 12 +++++++---- semantic/src/scope.rs | 2 +- semantic/src/top_level.rs | 42 ++++++++++++++++++++++++++++----------- test/src/main.ms | 2 +- 7 files changed, 56 insertions(+), 31 deletions(-) diff --git a/parser/src/ast.rs b/parser/src/ast.rs index 2f9aa4f..a84e4a9 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use serde::Serialize; #[derive(Debug, Clone, Serialize)] -pub struct ParamList(pub Vec<(String, TypeExpr)>); +pub struct ParamList(pub HashMap); #[derive(Debug, Clone, Serialize)] pub struct Block(pub Vec); @@ -120,9 +120,3 @@ pub enum VarKind { Const, Var, } - -impl ParamList { - pub fn to_hashmap(&self, f: impl Fn(&String, &TypeExpr) -> T) -> HashMap { - self.0.iter().map(|(k, v)| (k.clone(), f(k, v))).collect() - } -} diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index ef15bad..ec4c62e 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -20,7 +20,7 @@ export = { "export" } import = { "import" ~ string_lit ~ ";" } param_list = { param ~ ("," ~ param)* ~ ","? } -param = { identifier ~ ":" ~ type_expr } +param = { export? ~ identifier ~ ":" ~ type_expr } struct_decl = { export? ~ "struct" ~ identifier ~ "{" ~ param_list? ~ "}" diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 81cfb67..7e48fab 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use pest::Parser; use pest_derive::Parser; @@ -39,14 +41,21 @@ impl TypeExpr { } impl ParamList { - pub fn from_pair(pair: pest::iterators::Pair) -> Self { + pub fn from_pair(export_allowed: bool, pair: pest::iterators::Pair) -> Self { let params = pair .into_inner() .map(|p| { let mut param_inner = p.into_inner(); + let export = + if export_allowed && param_inner.peek().unwrap().as_rule() == Rule::export { + param_inner.next().unwrap(); + true + } else { + false + }; 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) + (param_name, (export, param_type)) }) .collect(); @@ -76,9 +85,9 @@ impl TopLevel { }; let name = inner.next().unwrap().as_str().to_string(); let params = if inner.peek().unwrap().as_rule() == Rule::param_list { - ParamList::from_pair(inner.next().unwrap()) + ParamList::from_pair(false, inner.next().unwrap()) } else { - ParamList(vec![]) + ParamList(HashMap::new()) }; let return_type = if let Some(next) = inner.peek() { if next.as_rule() == Rule::type_expr { @@ -115,7 +124,7 @@ impl TopLevel { }; let name = inner.next().unwrap().as_str().to_string(); let fields_pair = inner.next().unwrap(); - let fields = ParamList::from_pair(fields_pair); + let fields = ParamList::from_pair(true, fields_pair); Some(TopLevel::StructDecl { export, diff --git a/semantic/src/lib.rs b/semantic/src/lib.rs index 14851bc..24057de 100644 --- a/semantic/src/lib.rs +++ b/semantic/src/lib.rs @@ -48,12 +48,16 @@ pub fn walk_ast(top_scope: Arc, tl: &mut Vec) { } pub fn walk_param_list(fields: &HashMap>, param_list: &mut ParamList) { + let old_param_list = param_list.clone(); param_list.0.clear(); - for (_, param) in fields { - param_list.0.push(( + for (name, param) in fields { + param_list.0.insert( param.name.clone(), - TypeExpr::Identifier(param.var_type.get_name()), - )); + ( + old_param_list.0.get(name).map(|a| a.0).unwrap_or_default(), + TypeExpr::Identifier(param.var_type.get_name()), + ), + ); } } diff --git a/semantic/src/scope.rs b/semantic/src/scope.rs index a395701..f733d0a 100644 --- a/semantic/src/scope.rs +++ b/semantic/src/scope.rs @@ -151,7 +151,7 @@ impl LocalScope { } pub fn with_params(self: &Arc, param_list: &ParamList) { - for (param_name, type_expr) in ¶m_list.0 { + for (param_name, (_, type_expr)) in ¶m_list.0 { match type_expr { parser::ast::TypeExpr::Identifier(id) => { if let Some(var_type) = diff --git a/semantic/src/top_level.rs b/semantic/src/top_level.rs index ffcd52d..8e6e1e8 100644 --- a/semantic/src/top_level.rs +++ b/semantic/src/top_level.rs @@ -47,12 +47,21 @@ impl FunctionSymbol { Self { export: export, name: name.clone(), - params: params.to_hashmap(|name, v| VarSymbol { - name: name.clone(), - var_type: TypeSymbol(match v { - TypeExpr::Identifier(i) => i.to_string(), - }), - }), + params: params + .0 + .iter() + .map(|(name, (_, v))| { + ( + name.clone(), + VarSymbol { + name: name.clone(), + var_type: TypeSymbol(match v { + TypeExpr::Identifier(i) => i.to_string(), + }), + }, + ) + }) + .collect(), return_type: return_type.map(TypeSymbol::from_ast), } } @@ -63,12 +72,21 @@ impl StructSymbol { Self { export, name, - fields: fields.to_hashmap(|name, v| VarSymbol { - name: name.clone(), - var_type: TypeSymbol(match v { - TypeExpr::Identifier(i) => i.to_string(), - }), - }), + fields: fields + .0 + .iter() + .map(|(name, (_, v))| { + ( + name.clone(), + VarSymbol { + name: name.clone(), + var_type: TypeSymbol(match v { + TypeExpr::Identifier(i) => i.to_string(), + }), + }, + ) + }) + .collect(), // TODO - parse struct methods methods: HashMap::new(), } diff --git a/test/src/main.ms b/test/src/main.ms index f84ddbd..59ea0e1 100644 --- a/test/src/main.ms +++ b/test/src/main.ms @@ -1,5 +1,5 @@ export struct MyType { - x: int, + export x: int, } export function test(a: MyType) { }