diff --git a/parser/src/ast.rs b/parser/src/ast.rs index 5256592..83637e7 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -3,7 +3,10 @@ use std::collections::HashMap; use serde::Serialize; #[derive(Debug, Clone, Serialize)] -pub struct ParamList(pub HashMap); +pub struct FieldList(pub HashMap); + +#[derive(Debug, Clone, Serialize)] +pub struct ParamList(pub Vec); #[derive(Debug, Clone, Serialize)] pub struct Block(pub Vec); @@ -34,7 +37,7 @@ pub enum TopLevel { StructDecl { export: bool, name: String, - fields: ParamList, + fields: FieldList, }, FunctionDecl { export: bool, @@ -71,13 +74,18 @@ pub enum Statement { } #[derive(Debug, Clone, Serialize)] -pub struct VarDeclStmt { +pub struct VarDecl { pub mutable: bool, pub name: String, - pub init: Option, pub type_: Option, } +#[derive(Debug, Clone, Serialize)] +pub struct VarDeclStmt { + pub decl: VarDecl, + pub init: Option, +} + #[derive(Debug, Clone, Serialize)] pub struct VarAssignStmt { pub target: Expression, diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 3ab17af..4a61fbb 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use pest::Parser; use pest_derive::Parser; @@ -17,8 +15,6 @@ pub type ParseError = pest::error::Error; pub fn parse(source: &str) -> Result, ParseError> { let mut pairs = MistParser::parse(Rule::program, source)?; - println!("{pairs:#?}"); - let mut statements = vec![]; for pair in pairs.next().unwrap().into_inner() { @@ -49,25 +45,32 @@ impl TryFrom> for TypeExpr { } } -impl From<(bool, pest::iterators::Pair<'_, Rule>)> for ParamList { - fn from((export_allowed, pair): (bool, pest::iterators::Pair)) -> Self { +impl From> for FieldList { + fn from(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 export = if param_inner.peek().unwrap().as_rule() == Rule::export { + param_inner.next().unwrap(); + true + } else { + false + }; let param_type = TypeExpr::try_from(param_inner.next().unwrap()).unwrap(); let param_name = param_inner.next().unwrap().as_str().to_string(); (param_name, (export, param_type)) }) .collect(); + FieldList(params) + } +} + +impl From> for ParamList { + fn from(pair: pest::iterators::Pair) -> Self { + let params = pair.into_inner().map(VarDecl::from).collect(); + ParamList(params) } } @@ -106,9 +109,9 @@ impl TryFrom> for TopLevel { let name = inner.next().unwrap().as_str().to_string(); let params = if inner.peek().unwrap().as_rule() == Rule::param_list { - ParamList::from((false, inner.next().unwrap())) + ParamList::from(inner.next().unwrap()) } else { - ParamList(HashMap::new()) + ParamList(Vec::new()) }; let body = Block::from(inner.next().unwrap()); @@ -136,7 +139,7 @@ impl TryFrom> for TopLevel { }; let name = inner.next().unwrap().as_str().to_string(); let fields_pair = inner.next().unwrap(); - let fields = ParamList::from((true, fields_pair)); + let fields = FieldList::from(fields_pair); Ok(TopLevel::StructDecl { export, @@ -182,28 +185,7 @@ impl From> for Statement { Rule::block => Statement::Block(Block::from(pair.into_inner().next().unwrap())), - Rule::var_decl_statement => { - let mut inner = pair.into_inner(); - - let mut var_decl = inner.next().unwrap().into_inner(); - - let type_ = var_decl.next().map(TypeExpr::try_from).unwrap().ok(); - let mutable = if var_decl.peek().unwrap().as_rule() == Rule::mutable { - var_decl.next(); - true - } else { - false - }; - let name = var_decl.next().unwrap().as_str().to_string(); - let init = inner.next().map(Expression::from); - - Statement::VarDecl(VarDeclStmt { - mutable, - name: name.as_str().to_string(), - init, - type_, - }) - } + Rule::var_decl_statement => Statement::VarDecl(VarDeclStmt::from(pair)), Rule::return_stmt => { let mut inner = pair.into_inner(); @@ -348,3 +330,48 @@ impl From> for Postfix { } } } + +impl From> for VarDeclStmt { + fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self { + match pair.as_rule() { + Rule::var_decl_statement => { + let mut inner = pair.into_inner(); + + let decl = VarDecl::from(inner.next().unwrap()); + + let init = inner.next().map(Expression::from); + + VarDeclStmt { decl, init } + } + + _ => unimplemented!(), + } + } +} + +impl From> for VarDecl { + fn from(pair: pest::iterators::Pair<'_, Rule>) -> Self { + match pair.as_rule() { + Rule::var_decl => { + let mut inner = pair.into_inner(); + + let type_ = inner.next().map(TypeExpr::try_from).unwrap().ok(); + let mutable = if inner.peek().unwrap().as_rule() == Rule::mutable { + inner.next(); + true + } else { + false + }; + let name = inner.next().unwrap().as_str().to_string(); + + VarDecl { + mutable, + name: name.as_str().to_string(), + type_, + } + } + + _ => unimplemented!("{:?}", pair.as_rule()), + } + } +} diff --git a/src/codegen.rs b/src/codegen.rs index 7c8330f..9ad548c 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -78,7 +78,15 @@ impl RustCodegen { let params_str = params .0 .iter() - .map(|(n, (_, t))| format!("{}: {}", n, self.translate_type(t))) + .map(|v| { + format!( + "{name}{}", + v.type_ + .as_ref() + .map(|t| format!(": {}", self.translate_type(t))) + .unwrap_or_default() + ) + }) .collect::>() .join(", "); @@ -131,15 +139,11 @@ impl RustCodegen { self.add_indentedln("}"); } - Statement::VarDecl(VarDeclStmt { - mutable, - name, - init, - type_, - }) => { - let mutability = if *mutable { "mut " } else { "" }; + Statement::VarDecl(VarDeclStmt { decl, init }) => { + let mutability = if decl.mutable { "mut " } else { "" }; - let ty = type_ + let ty = decl + .type_ .as_ref() .map(|t| format!(": {}", self.translate_type(t))) .unwrap_or_default(); @@ -149,7 +153,7 @@ impl RustCodegen { .map(|e| format!(" = {}", self.generate_expression(e))) .unwrap_or_default(); - self.add_indentedln(&format!("let {}{}{}{};", mutability, name, ty, init)); + self.add_indentedln(&format!("let {}{}{}{};", mutability, decl.name, ty, init)); } Statement::VarAssign(VarAssignStmt { target, value }) => { diff --git a/test/src/main.mist b/test/src/main.mist index a4ec76f..1aa1923 100644 --- a/test/src/main.mist +++ b/test/src/main.mist @@ -1,3 +1,3 @@ -int test() { +int test(int mut b) { int mut a = 10; }