diff --git a/crates/analyzer/src/transpiler.rs b/crates/analyzer/src/transpiler.rs index 581ae12..cf0807c 100644 --- a/crates/analyzer/src/transpiler.rs +++ b/crates/analyzer/src/transpiler.rs @@ -1,8 +1,8 @@ use std::path::{Path, PathBuf}; use mist_codegen::RustCodegen; -use mist_parser::rev_mapper::Mapping; use mist_parser::parse; +use mist_parser::rev_mapper::Mapping; pub struct TranspiledFile { pub mist_path: PathBuf, @@ -26,20 +26,23 @@ pub fn transpile_mist( let parsed = parse(source).map_err(|e| format!("parse error: {e:?}"))?; - for item in &parsed { + for item in &parsed.items { mist_parser::semantics::check_class_semantics(item) .map_err(|e| format!("semantic error: {}", e[0].error_message))?; } let mut codegen = RustCodegen::new(mist_path.to_path_buf()); - let output = codegen.generate(parsed); - codegen.mapping.shift_rust(extra_mod_decl.lines().count() as isize, 0); + codegen.generate(parsed.mod_attributes); + + codegen.add(extra_mod_decl); + + let output = codegen.generate(parsed.items); Ok(TranspiledFile { mist_path: mist_path.to_path_buf(), rust_path, - rust_content: format!("{}{}", extra_mod_decl, output), + rust_content: output, mapping: codegen.mapping, }) } diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index 7c806f4..83217fb 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -48,7 +48,7 @@ impl RustCodegen { " ".repeat(self.indent) } - fn add(&mut self, s: &str) { + pub fn add(&mut self, s: &str) { let newline_count = bytecount::count(s.as_bytes(), b'\n'); if newline_count == 0 { @@ -63,17 +63,17 @@ impl RustCodegen { self.output.push_str(s); } - fn addln(&mut self, s: &str) { + pub fn addln(&mut self, s: &str) { self.add(s); self.add("\n"); } - fn add_indented(&mut self, s: &str) { + pub fn add_indented(&mut self, s: &str) { let line = format!("{}{}", self.indent_str(), s); self.add(&line); } - fn add_indentedln(&mut self, s: &str) { + pub fn add_indentedln(&mut self, s: &str) { let line = format!("{}{}\n", self.indent_str(), s); self.add(&line); } diff --git a/crates/mist-api/src/transpiler.mist b/crates/mist-api/src/transpiler.mist index 5bbed65..83ea5ed 100644 --- a/crates/mist-api/src/transpiler.mist +++ b/crates/mist-api/src/transpiler.mist @@ -212,13 +212,15 @@ pub fn Result<(PathBuf, mist_codegen::RustCodegen, String), TranspileError<'a>> let parsed = mist_parser::parse(source).map_err(TranspileError::Parse)?; - for i in &parsed { + for i in &parsed.items { let _ = mist_parser::semantics::check_class_semantics(i).map_err(TranspileError::Semantic)?; } - let output = gc.generate(parsed); + gc.generate(parsed.mod_attributes); - gc.mapping.shift_rust(mod_decl.lines().count() as isize, 0); + gc.add(mod_decl); + + let output = gc.generate(parsed.items); Ok((output_file, gc, output)) } @@ -232,7 +234,7 @@ pub fn void transpile_file(path *PathBuf, source *str, output_file PathBuf, mod_ } }; - let res = fs::write(&output_file, format!("{mod_decl}{output}")); + let res = fs::write(&output_file, output); let output_file_map = output_file.with_extension("map.json"); diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index cf905f0..7c6a1d1 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -15,7 +15,12 @@ use crate::error::{IntoErr, ParseError}; #[grammar = "./src/grammar.pest"] pub struct MistParser; -pub fn parse<'a>(source: &'a str) -> Result, ParseError<'a, Vec>> { +pub struct Program { + pub mod_attributes: Vec, + pub items: Vec, +} + +pub fn parse<'a>(source: &'a str) -> Result>> { let mut pairs = MistParser::parse(Rule::program, source)?; let mut statements = vec![]; @@ -29,7 +34,16 @@ pub fn parse<'a>(source: &'a str) -> Result, ParseError<'a, Vec Ok(v), + Ok(v) => { + let (mod_attributes, items): (Vec<_>, Vec<_>) = v + .into_iter() + .partition(|item| matches!(item.0.item, TopLevelKind::ModAttribute)); + + Ok(Program { + items, + mod_attributes, + }) + } Err(e) => { let rec = e.recovered.clone();