use crate::towasm::collect::Statement;
use crate::towasm::collect::Type;
use crate::towasm::control::Group;
use crate::towasm::control::Label;
use crate::towasm::values::DeclareLocal;
use crate::towasm::values::Local;
use crate::towasm::Wasm;
use crate::util::strtype::Name;
use std::fs::File;
use std::io;
use std::io::Write;
pub struct Parameter {
declare_local: DeclareLocal,
}
impl Parameter {
pub fn new(name: Name, typ: Type) -> Self {
let declare_local = DeclareLocal::new_unboxed(name, typ);
Parameter { declare_local }
}
pub fn name(&self) -> &Name {
self.declare_local.name()
}
pub fn typ(&self) -> &Type {
self.declare_local.typ()
}
pub fn local(&self) -> Local {
self.declare_local.local()
}
}
impl Wasm for Parameter {
fn as_wat(&self) -> String {
format!("(param {} {})", self.name().as_wat(), self.typ().as_wat())
}
fn write_wasm(&self, _file: &mut File) -> io::Result<()> {
unimplemented!()
}
}
pub struct Output {
typ: Type,
}
impl Output {
pub fn new(typ: Type) -> Self {
Output { typ }
}
}
impl Wasm for Output {
fn as_wat(&self) -> String {
format!("(result {})", self.typ.as_wat())
}
fn write_wasm(&self, _file: &mut File) -> io::Result<()> {
unimplemented!()
}
}
pub struct FunctionSignature {
name: Name,
parameters: Vec<Parameter>,
results: Vec<Output>,
}
impl FunctionSignature {
pub fn new(name: Name, parameters: Vec<Parameter>, results: Vec<Output>) -> Self {
assert!(results.len() <= 1); FunctionSignature { name, parameters, results }
}
}
impl Wasm for FunctionSignature {
fn as_wat(&self) -> String {
format!(
"func {} (export \"{}\") {} {}",
self.name.as_wat(),
self.name,
self.parameters.iter().map(Wasm::as_wat).collect::<Vec<_>>().join("\n"),
self.results.iter().map(Wasm::as_wat).collect::<Vec<_>>().join("\n")
)
}
fn write_wasm(&self, _file: &mut File) -> io::Result<()> {
unimplemented!()
}
}
pub struct Function {
signature: FunctionSignature,
body: Group,
}
impl Function {
pub fn new<F>(name: Name, parameters: Vec<Parameter>, results: Vec<Output>, statements_gen: F) -> Self
where
F: FnOnce(Label) -> Vec<Box<dyn Statement>>,
{
Function {
signature: FunctionSignature { name, parameters, results },
body: Group::new(Label::internal(name), statements_gen),
}
}
}
impl Wasm for Function {
fn as_wat(&self) -> String {
format!(
"({}\n{}\n) ;; func {}",
self.signature.as_wat(),
self.body.as_wat(),
self.signature.name.as_wat()
)
}
fn write_wasm(&self, file: &mut File) -> io::Result<()> {
file.write_all(b" func ")?;
Ok(())
}
}