wagen 0.3.0

A library to help generate WebAssembly
Documentation
use crate::*;

#[derive(Default, Debug, Clone)]
pub struct Builder<'a> {
    pub instrs: Vec<Instr<'a>>,
}

impl<'a> From<Vec<Instr<'a>>> for Builder<'a> {
    fn from(instrs: Vec<Instr<'a>>) -> Self {
        Builder { instrs }
    }
}

impl<'a> Builder<'a> {
    pub fn new(init: impl IntoIterator<Item = Instr<'a>>) -> Self {
        Builder {
            instrs: init.into_iter().collect(),
        }
    }

    pub fn push(&mut self, x: impl Expr<'a>) -> &mut Self {
        x.expr(self);
        self
    }

    pub fn extend(&mut self, x: impl IntoIterator<Item = Instr<'a>>) -> &mut Self {
        self.instrs.extend(x);
        self
    }

    pub fn local_incr(&mut self, local: Local, ty: ValType) -> &mut Self {
        self.push(Instr::LocalGet(local.0));
        match ty {
            ValType::I64 => {
                self.push([Instr::I64Const(1), Instr::I64Add]);
            }
            ValType::I32 => {
                self.push([Instr::I32Const(1), Instr::I32Add]);
            }
            ValType::F64 => {
                self.push([Instr::F64Const(1.0), Instr::F64Add]);
            }
            ValType::F32 => {
                self.push([Instr::F32Const(1.0), Instr::F32Add]);
            }
            x => panic!("Invalid type in `local_incr`: {x:?}"),
        }
        self.push(Instr::LocalSet(local.0));
        self
    }

    pub fn block<F: Expr<'a>>(&mut self, bt: BlockType, expr: F) -> &mut Self {
        self.push(Instr::Block(bt));
        self.push(expr);
        self.push(Instr::End)
    }

    pub fn loop_<F: Expr<'a>>(&mut self, bt: BlockType, expr: F) -> &mut Self {
        self.push(Instr::Loop(bt));
        self.push(expr);
        self.push(Instr::End)
    }

    pub fn loop_while<C: Expr<'a>, F: Expr<'a>>(
        &mut self,
        bt: BlockType,
        cond: C,
        expr: F,
    ) -> &mut Self {
        self.push(Instr::Loop(bt));
        self.push(cond);
        self.push(expr);
        self.push(Instr::BrIf(0));
        self.push(Instr::End)
    }

    pub fn if_then<F: Expr<'a>>(
        &mut self,
        bt: BlockType,
        cond: impl Expr<'a>,
        expr: F,
    ) -> &mut Self {
        self.push(cond);
        self.push(Instr::If(bt));
        self.push(expr);
        self.push(Instr::End)
    }

    pub fn if_then_else<F: Expr<'a>, G: Expr<'a>>(
        &mut self,
        bt: BlockType,
        cond: impl Expr<'a>,
        expr: F,
        else_: G,
    ) -> &mut Self {
        self.push(cond);
        self.push(Instr::If(bt));
        self.push(expr);
        self.push(Instr::Else);
        self.push(else_);
        self.push(Instr::End)
    }

    pub fn return_(&mut self) {
        self.push(Instr::Return);
    }
}