@@ -3,7 +3,7 @@ pub mod expr;
|
||||
pub mod statement;
|
||||
pub mod top_level;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use mist_parser::{
|
||||
ast::*,
|
||||
@@ -26,9 +26,15 @@ pub trait GetRust {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Include {
|
||||
Glob(Path),
|
||||
Use(Visibility, Path),
|
||||
}
|
||||
|
||||
pub struct RustCodegen {
|
||||
output: String,
|
||||
indent: usize,
|
||||
pub crates: HashMap<Identifier, Vec<Include>>,
|
||||
pub mapping: Mapping,
|
||||
position: RustMap,
|
||||
}
|
||||
@@ -38,6 +44,7 @@ impl RustCodegen {
|
||||
Self {
|
||||
output: String::new(),
|
||||
indent: 0,
|
||||
crates: HashMap::new(),
|
||||
mapping: Mapping::new(mist_path),
|
||||
position: RustMap(1, 0),
|
||||
}
|
||||
@@ -84,6 +91,39 @@ impl RustCodegen {
|
||||
tl.gen_rust(&mut ctx, self);
|
||||
}
|
||||
|
||||
let mut crates = HashMap::new();
|
||||
std::mem::swap(&mut self.crates, &mut crates);
|
||||
|
||||
for (c, items) in crates {
|
||||
self.add("mod ");
|
||||
c.gen_rust(&mut ctx, self);
|
||||
self.addln(" {");
|
||||
self.indent += 1;
|
||||
|
||||
self.add_indented("extern crate ");
|
||||
c.gen_rust(&mut ctx, self);
|
||||
self.addln(";");
|
||||
|
||||
for item in items {
|
||||
self.add_indentedln("#[doc(inline)]");
|
||||
self.add_indented("pub use ");
|
||||
match item {
|
||||
Include::Glob(item) => {
|
||||
item.gen_rust(&mut ctx, self);
|
||||
self.add("::*");
|
||||
}
|
||||
Include::Use(vis, item) => {
|
||||
vis.gen_rust(&mut ctx, self);
|
||||
item.gen_rust(&mut ctx, self);
|
||||
}
|
||||
}
|
||||
self.addln(";");
|
||||
}
|
||||
|
||||
self.indent -= 1;
|
||||
self.addln("}");
|
||||
}
|
||||
|
||||
self.output.clone()
|
||||
}
|
||||
|
||||
|
||||
@@ -326,6 +326,23 @@ impl GenRust for TopLevelKind {
|
||||
constructor,
|
||||
items,
|
||||
),
|
||||
Self::IncludeGlobal(incl) => {
|
||||
cg.crates
|
||||
.entry(incl.0[0].clone())
|
||||
.or_insert(Vec::new())
|
||||
.push(crate::Include::Glob(incl.clone()));
|
||||
}
|
||||
Self::IncludeUse(vis, incl) => {
|
||||
cg.crates
|
||||
.entry(incl.0[0].clone())
|
||||
.or_insert(Vec::new())
|
||||
.push(crate::Include::Use(vis.clone(), incl.clone()));
|
||||
}
|
||||
Self::IncludeLocal(path) => {
|
||||
cg.add("include!(\"");
|
||||
cg.add(&path.replace(".mist", ".rs"));
|
||||
cg.add("\");");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ pub struct TopLevel(pub Spanned<TopLevelKind>, pub Vec<Attribute>);
|
||||
pub enum TopLevelKind {
|
||||
ModAttribute,
|
||||
Import(Visibility, Path),
|
||||
IncludeGlobal(Path),
|
||||
IncludeUse(Visibility, Path),
|
||||
IncludeLocal(String),
|
||||
DeclareModule(Visibility, Identifier),
|
||||
ImplDecl(ImplDecl),
|
||||
StaticDecl(VarDeclStmt),
|
||||
|
||||
@@ -258,6 +258,18 @@ param_list = {
|
||||
// IMPORTS / MODULES
|
||||
// ======================================================
|
||||
|
||||
include_global = {
|
||||
"#" ~ "include" ~ "<" ~ identifier ~ ("/" ~ identifier)* ~ ">"
|
||||
}
|
||||
|
||||
include_use_global = {
|
||||
visibility? ~ "#" ~ "use" ~ static_path ~ semicolon
|
||||
}
|
||||
|
||||
include_local = {
|
||||
"#" ~ "include" ~ string_lit
|
||||
}
|
||||
|
||||
import = {
|
||||
visibility? ~ "use" ~ static_path ~ semicolon
|
||||
}
|
||||
@@ -384,7 +396,7 @@ type_alias = { "type" ~ identifier ~ generics_decl? ~ "=" ~ type_expr ~ ";" }
|
||||
|
||||
top_level = {
|
||||
mod_attribute
|
||||
| (attributes ~ (import | impl_for_decl | impl_decl | trait_decl | struct_decl | enum_decl | class_decl | declare_module | function_decl | const_decl | static_decl | type_alias))
|
||||
| (attributes ~ (include_global | include_local | include_use_global | import | impl_for_decl | impl_decl | trait_decl | struct_decl | enum_decl | class_decl | declare_module | function_decl | const_decl | static_decl | type_alias))
|
||||
}
|
||||
|
||||
// ======================================================
|
||||
|
||||
@@ -129,6 +129,25 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for TopLevelKind {
|
||||
ty: inner.next().unwrap().try_into()?,
|
||||
}),
|
||||
|
||||
Rule::include_global => Ok(TopLevelKind::IncludeGlobal(Path(collect_recovered(
|
||||
&mut inner,
|
||||
)?))),
|
||||
|
||||
Rule::include_use_global => Ok(TopLevelKind::IncludeUse(
|
||||
Visibility::try_from(&mut inner)?,
|
||||
Path::try_from(inner.next().unwrap())?,
|
||||
)),
|
||||
|
||||
Rule::include_local => Ok(TopLevelKind::IncludeLocal(
|
||||
inner
|
||||
.next()
|
||||
.unwrap()
|
||||
.into_inner()
|
||||
.next()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
)),
|
||||
|
||||
_ => AstError::bug_unimplemented(pair),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user