use std::borrow::Borrow;
use std::fs::File;
use std::io;
use std::io::Write;
use crate::towasm::collect::Statement;
use crate::towasm::control::Label;
use crate::towasm::scope::module::Scope;
use crate::towasm::typ::Wasm;
use crate::util::strtype::typ::StrType;
use crate::util::strtype::Name;
pub struct Group {
statements: Vec<Box<dyn Statement>>,
}
impl Group {
pub fn new<F>(label: Label, statements_gen: F) -> Self
where
F: FnOnce(Label) -> Vec<Box<dyn Statement>>,
{
Group {
statements: statements_gen(label),
}
}
}
#[allow(clippy::redundant_closure)]
impl Wasm for Group {
fn as_wat(&self) -> String {
self.statements
.iter()
.map(|statement| statement.as_wat())
.collect::<Vec<_>>()
.as_slice()
.join("\n")
}
fn write_wasm(&self, file: &mut File) -> io::Result<()> {
file.write_all(b" block ")?;
Ok(())
}
}
pub struct Block {
name: Name,
group: Group,
_scope: Scope,
}
impl Block {
pub fn new<F>(statements_gen: F, parent: &mut Scope) -> Box<Self>
where
F: FnOnce(Label) -> Vec<Box<dyn Statement>>,
{
Block::new_named(Name::from_valid("0"), statements_gen, parent)
}
pub fn new_named<F>(name: Name, statements_gen: F, parent: &mut Scope) -> Box<Self>
where
F: FnOnce(Label) -> Vec<Box<dyn Statement>>,
{
let scope = Scope::new(parent);
Box::new(Block {
name,
group: Group::new(Label::internal(name), statements_gen),
_scope: scope,
})
}
}
impl Wasm for Block {
fn as_wat(&self) -> String {
format!(
"(block {0:}\n{1:}\n) ;; block {0:}",
self.name.borrow(), self.group.as_wat()
)
}
fn write_wasm(&self, file: &mut File) -> io::Result<()> {
file.write_all(b" block ")?;
Ok(())
}
}
impl Statement for Block {}