From 18fedba1192692af70d065c67ab9d25d3f52b359 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 21 Apr 2026 11:28:26 +0200 Subject: [PATCH] Package --- codegen/src/lib.rs | 57 ++++++++++++++++++--------------------- parser/src/ast.rs | 1 + parser/src/grammar.pest | 4 ++- parser/src/lib.rs | 4 +++ semantic/src/lib.rs | 1 + semantic/src/top_level.rs | 1 + test/src/main.ms | 2 ++ 7 files changed, 38 insertions(+), 32 deletions(-) diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 306c744..4b01aef 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -1,6 +1,4 @@ -use parser::ast::{ - BinaryOp, Block, Expression, Postfix, Statement, TopLevel, TypeExpr, VarKind, -}; +use parser::ast::{BinaryOp, Block, Expression, Postfix, Statement, TopLevel, TypeExpr, VarKind}; pub struct GoCodegen { output: String, @@ -55,7 +53,11 @@ impl GoCodegen { } self.addln(""); } - TopLevel::StructDecl { export, name, fields } => { + TopLevel::StructDecl { + export, + name, + fields, + } => { let name = if *export { name } else { name }; self.addln(&format!("type {} struct {{", name)); self.indent += 1; @@ -73,7 +75,11 @@ impl GoCodegen { return_type, body, } => { - let name = if *export { format!("{}", name) } else { name.clone() }; + let name = if *export { + format!("{}", name) + } else { + name.clone() + }; let params_str = params .0 .iter() @@ -96,6 +102,10 @@ impl GoCodegen { self.indent -= 1; self.addln("}\n"); } + TopLevel::Package(pkg) => { + self.addln(&format!("package {}", pkg)); + self.addln(""); + } } } @@ -155,24 +165,15 @@ impl GoCodegen { then_branch, else_branch, } => { - self.add_indented(&format!( - "if {} ", - self.generate_expression(condition) - )); + self.add_indented(&format!("if {} ", self.generate_expression(condition))); self.generate_statement(then_branch); if let Some(else_br) = else_branch { self.add_indented("else "); self.generate_statement(else_br); } } - Statement::While { - condition, - body, - } => { - self.add_indented(&format!( - "for {} ", - self.generate_expression(condition) - )); + Statement::While { condition, body } => { + self.add_indented(&format!("for {} ", self.generate_expression(condition))); self.generate_statement(body); } Statement::For { @@ -258,11 +259,7 @@ impl GoCodegen { .join(", "); format!("{}({})", result, args_str) } - Postfix::Index(idx) => format!( - "{}[{}]", - result, - self.generate_expression(idx) - ), + Postfix::Index(idx) => format!("{}[{}]", result, self.generate_expression(idx)), Postfix::Binary(op, rhs) => { let op_str = match op { BinaryOp::Plus => "+", @@ -277,12 +274,7 @@ impl GoCodegen { BinaryOp::LessThanOrEqual => "<=", BinaryOp::GreaterThanOrEqual => ">=", }; - format!( - "{} {} {}", - result, - op_str, - self.generate_expression(rhs) - ) + format!("{} {} {}", result, op_str, self.generate_expression(rhs)) } }; } @@ -299,8 +291,8 @@ impl Default for GoCodegen { #[cfg(test)] mod tests { use super::*; + use parser::ast::{Block, Expression, ParamList, Statement, TopLevel, TypeExpr}; use std::collections::HashMap; - use parser::ast::{ParamList, TypeExpr, Block, Statement, Expression, TopLevel}; #[test] fn test_int_literal() { @@ -337,7 +329,10 @@ mod tests { fn test_struct_decl() { let mut cg = GoCodegen::new(); let mut fields = HashMap::new(); - fields.insert("x".to_string(), (true, TypeExpr::Identifier("int".to_string()))); + fields.insert( + "x".to_string(), + (true, TypeExpr::Identifier("int".to_string())), + ); let toplevel = TopLevel::StructDecl { export: true, name: "Point".to_string(), @@ -361,4 +356,4 @@ mod tests { let output = cg.output.clone(); assert!(output.contains("if x")); } -} \ No newline at end of file +} diff --git a/parser/src/ast.rs b/parser/src/ast.rs index a84e4a9..0313478 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -31,6 +31,7 @@ pub enum BinaryOp { #[derive(Debug, Clone, Serialize)] pub enum TopLevel { Import(String), + Package(String), StructDecl { export: bool, name: String, diff --git a/parser/src/grammar.pest b/parser/src/grammar.pest index ec4c62e..4cc1a94 100644 --- a/parser/src/grammar.pest +++ b/parser/src/grammar.pest @@ -13,7 +13,9 @@ inner_str = @{ (!"\"" ~ ANY)* } // ================= TOP LEVEL ================= -top_level = _{ import | function_decl | struct_decl } +top_level = _{ import | function_decl | struct_decl | package } + +package = { "package" ~ identifier ~ ";" } export = { "export" } diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 7e48fab..2dbe131 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -70,6 +70,10 @@ impl TopLevel { let path = pair.into_inner().next().unwrap().as_str().to_string(); Some(TopLevel::Import(path)) } + Rule::package => { + let name = pair.into_inner().next().unwrap().as_str().to_string(); + Some(TopLevel::Package(name)) + } Rule::function_decl => { let mut inner = pair.into_inner(); diff --git a/semantic/src/lib.rs b/semantic/src/lib.rs index 24057de..40735a5 100644 --- a/semantic/src/lib.rs +++ b/semantic/src/lib.rs @@ -15,6 +15,7 @@ pub fn walk_ast(top_scope: Arc, tl: &mut Vec) { for tl in tl { match tl { parser::ast::TopLevel::Import(_) => unimplemented!(), + parser::ast::TopLevel::Package(_) => {} parser::ast::TopLevel::FunctionDecl { params, body, name, .. diff --git a/semantic/src/top_level.rs b/semantic/src/top_level.rs index f58fa96..b1e85cb 100644 --- a/semantic/src/top_level.rs +++ b/semantic/src/top_level.rs @@ -112,6 +112,7 @@ impl TopLevelSymbolScope { for top in top_level { match top { TopLevel::Import(_) => unimplemented!(), + TopLevel::Package(_) => {} TopLevel::FunctionDecl { export, diff --git a/test/src/main.ms b/test/src/main.ms index 59ea0e1..c183302 100644 --- a/test/src/main.ms +++ b/test/src/main.ms @@ -1,3 +1,5 @@ +package main; + export struct MyType { export x: int, }