-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #51 from mangolang/wasm-target
Add representation of wasm as compile target (proof of concept)
- Loading branch information
Showing
27 changed files
with
1,095 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,4 +26,7 @@ pub mod mango { | |
pub mod reducing; | ||
pub mod semanticating; | ||
pub mod typing; | ||
|
||
// Targets | ||
pub mod towasm; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// The unsigned integers etc are not included. | ||
// They're also not data types in wasm, the operation can choose signed/unsigned. | ||
// The reason they're not included though, is that I don't expect to use them. | ||
// If I do use them, I should probably add them here and break wasm 1-1. | ||
|
||
use mango::towasm::Wasm; | ||
use std::fs::File; | ||
use std::io; | ||
|
||
#[derive(PartialEq, Eq, Clone, Copy)] | ||
pub enum Type { | ||
Int32, | ||
Int64, | ||
Float32, | ||
Float64, | ||
Bool, | ||
} | ||
|
||
impl Wasm for Type { | ||
fn as_wat(&self) -> String { | ||
match self { | ||
Type::Int32 => "i32", | ||
Type::Int64 => "i64", | ||
Type::Float32 => "f32", | ||
Type::Float64 => "f64", | ||
Type::Bool => "i32", | ||
}.to_owned() | ||
} | ||
|
||
fn write_wasm(&self, file: &mut File) -> io::Result<()> { | ||
unimplemented!() | ||
} | ||
} | ||
|
||
pub enum Value { | ||
Int(i64), | ||
Float(f64), | ||
} | ||
|
||
impl Value { | ||
pub fn is_type(&self, typ: &Type) -> bool { | ||
match self { | ||
Value::Int(_) => { | ||
match typ { | ||
Type::Bool => false, | ||
_ => true, // int value can be stored in int or float | ||
} | ||
} | ||
Value::Float(_) => match typ { | ||
Type::Float32 => true, | ||
Type::Float64 => true, | ||
_ => false, | ||
}, | ||
} | ||
} | ||
} | ||
|
||
impl Wasm for Value { | ||
fn as_wat(&self) -> String { | ||
match self { | ||
Value::Int(val) => format!("{}", val), | ||
Value::Float(val) => format!("{}", val), | ||
}.to_owned() | ||
} | ||
|
||
fn write_wasm(&self, file: &mut File) -> io::Result<()> { | ||
unimplemented!() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
pub mod typ; | ||
pub use self::typ::Wasm; | ||
|
||
pub mod datatype; | ||
pub use self::datatype::Type; | ||
|
||
pub mod statement; | ||
pub use self::statement::Statement; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
use mango::towasm::Wasm; | ||
|
||
pub trait Statement: Wasm {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
use std::fs::File; | ||
use std::io; | ||
|
||
/// WASM type | ||
pub trait Wasm { | ||
fn as_wat(&self) -> String; | ||
fn write_wasm(&self, file: &mut File) -> io::Result<()>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use mango::towasm::collect::Statement; | ||
use mango::towasm::control::Label; | ||
use mango::towasm::util::Name; | ||
use mango::towasm::Wasm; | ||
use std::fs::File; | ||
use std::io; | ||
use std::io::Write; | ||
use std::rc::Rc; | ||
|
||
pub struct Group { | ||
statements: Vec<Box<Statement>>, | ||
} | ||
|
||
impl Group { | ||
pub fn new<F>(label: Label, statements_gen: F) -> Self | ||
where | ||
F: FnOnce(Label) -> Vec<Box<Statement>>, | ||
{ | ||
Group { | ||
statements: statements_gen(label), | ||
} | ||
} | ||
} | ||
|
||
impl Wasm for Group { | ||
fn as_wat(&self) -> String { | ||
self.statements | ||
.iter() | ||
.map(|statement| statement.as_wat()) | ||
.collect::<Vec<_>>() | ||
.join("\n") | ||
} | ||
|
||
fn write_wasm(&self, file: &mut File) -> io::Result<()> { | ||
file.write(b" block ")?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
pub struct Block { | ||
name: Rc<Name>, | ||
group: Group, | ||
} | ||
|
||
impl Block { | ||
pub fn new<F>(statements_gen: F) -> Box<Self> | ||
where | ||
F: FnOnce(Label) -> Vec<Box<Statement>>, | ||
{ | ||
// todo: determine name automatically | ||
Block::new_named(Name::new("b".to_owned()).unwrap(), statements_gen) | ||
} | ||
|
||
pub fn new_named<F>(name: Rc<Name>, statements_gen: F) -> Box<Self> | ||
where | ||
F: FnOnce(Label) -> Vec<Box<Statement>>, | ||
{ | ||
Box::new(Block { | ||
name: name.clone(), | ||
group: Group::new(Label::internal(name), statements_gen), | ||
}) | ||
} | ||
} | ||
|
||
impl Wasm for Block { | ||
fn as_wat(&self) -> String { | ||
format!( | ||
"(block {0:}\n{1:}\n) ;; block {0:}", | ||
self.name.as_wat(), | ||
self.group.as_wat() | ||
) | ||
} | ||
|
||
fn write_wasm(&self, file: &mut File) -> io::Result<()> { | ||
file.write(b" block ")?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl Statement for Block {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
use mango::towasm::collect::Statement; | ||
use mango::towasm::collect::Type; | ||
use mango::towasm::util::Name; | ||
use mango::towasm::values::Expression; | ||
use mango::towasm::Wasm; | ||
use std::fs::File; | ||
use std::io; | ||
use std::io::Write; | ||
use std::rc::Rc; | ||
|
||
/// Label for a block, if or loop | ||
pub struct Label { | ||
name: Rc<Name>, | ||
} | ||
|
||
impl Label { | ||
/// This constructor should not be called directly; blocks should create their own references. | ||
pub fn internal(name: Rc<Name>) -> Self { | ||
Label { name } | ||
} | ||
} | ||
|
||
impl Wasm for Label { | ||
fn as_wat(&self) -> String { | ||
self.name.as_wat() | ||
} | ||
|
||
fn write_wasm(&self, file: &mut File) -> io::Result<()> { | ||
unimplemented!() | ||
} | ||
} | ||
|
||
pub struct Branch {} | ||
|
||
impl Branch { | ||
pub fn new() -> Box<Self> { | ||
Box::new(Branch {}) | ||
} | ||
} | ||
|
||
impl Wasm for Branch { | ||
fn as_wat(&self) -> String { | ||
" br ".to_owned() | ||
// format!(" add ") | ||
} | ||
|
||
fn write_wasm(&self, file: &mut File) -> io::Result<()> { | ||
file.write(b" call ")?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
pub struct BranchIf { | ||
condition: Box<Expression>, | ||
label: Label, | ||
} | ||
|
||
impl BranchIf { | ||
pub fn new(condition: Box<Expression>, label: Label) -> Box<Self> { | ||
assert!(condition.typ() == &Type::Bool); | ||
Box::new(BranchIf { condition, label }) | ||
} | ||
} | ||
|
||
impl Wasm for BranchIf { | ||
fn as_wat(&self) -> String { | ||
format!("{}\nbr_if {}", self.condition.as_wat(), self.label.as_wat()) | ||
} | ||
|
||
fn write_wasm(&self, file: &mut File) -> io::Result<()> { | ||
file.write(b" call ")?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
impl Statement for BranchIf {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
use mango::towasm::collect::Statement; | ||
use mango::towasm::control::Label; | ||
use mango::towasm::values::Expression; | ||
use mango::towasm::Wasm; | ||
use std::fs::File; | ||
use std::io; | ||
use std::io::Write; | ||
|
||
// todo: call_indirect | ||
|
||
pub struct Call {} | ||
|
||
impl Call { | ||
pub fn new() -> Box<Self> { | ||
Box::new(Call {}) | ||
} | ||
} | ||
|
||
impl Wasm for Call { | ||
fn as_wat(&self) -> String { | ||
" call ".to_owned() | ||
// format!(" add ") | ||
} | ||
|
||
fn write_wasm(&self, file: &mut File) -> io::Result<()> { | ||
file.write(b" call ")?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
pub struct Return { | ||
expression: Box<Expression>, | ||
} | ||
|
||
impl Return { | ||
// Take label to make sure this inside a function, might be used in the future, or removed... | ||
pub fn new(_label: Label, expression: Box<Expression>) -> Box<Self> { | ||
Box::new(Return { expression }) | ||
} | ||
} | ||
|
||
impl Wasm for Return { | ||
fn as_wat(&self) -> String { | ||
self.expression.as_wat() | ||
} | ||
|
||
fn write_wasm(&self, file: &mut File) -> io::Result<()> { | ||
unimplemented!(); | ||
} | ||
} | ||
|
||
impl Statement for Return {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
pub mod block; | ||
pub use self::block::Block; | ||
pub use self::block::Group; | ||
|
||
pub mod branch; | ||
pub use self::branch::Branch; | ||
pub use self::branch::BranchIf; | ||
pub use self::branch::Label; | ||
|
||
pub mod repeat; | ||
pub use self::repeat::Loop; | ||
|
||
pub mod function; | ||
pub use self::function::Call; | ||
pub use self::function::Return; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use mango::towasm::collect::Statement; | ||
use mango::towasm::control::Group; | ||
use mango::towasm::control::Label; | ||
use mango::towasm::util::Name; | ||
use mango::towasm::Wasm; | ||
use std::fs::File; | ||
use std::io; | ||
use std::rc::Rc; | ||
|
||
pub struct Loop { | ||
name: Rc<Name>, | ||
group: Group, | ||
} | ||
|
||
impl Loop { | ||
pub fn new<F>(statements_gen: F) -> Box<Self> | ||
where | ||
F: FnOnce(Label) -> Vec<Box<Statement>>, | ||
{ | ||
// todo: determine name automatically | ||
Loop::new_named(Name::new("l".to_owned()).unwrap(), statements_gen) | ||
} | ||
|
||
pub fn new_named<F>(name: Rc<Name>, statements_gen: F) -> Box<Self> | ||
where | ||
F: FnOnce(Label) -> Vec<Box<Statement>>, | ||
{ | ||
Box::new(Loop { | ||
name: name.clone(), | ||
group: Group::new(Label::internal(name), statements_gen), | ||
}) | ||
} | ||
} | ||
|
||
impl Wasm for Loop { | ||
fn as_wat(&self) -> String { | ||
format!( | ||
"loop {0:}\n{1:}\nend ;; loop {0:}", | ||
self.name.as_wat(), | ||
self.group.as_wat() | ||
) | ||
} | ||
|
||
fn write_wasm(&self, file: &mut File) -> io::Result<()> { | ||
unimplemented!() | ||
} | ||
} | ||
|
||
impl Statement for Loop {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// TODO: possibly extract this to a separate crate | ||
|
||
pub mod collect; | ||
pub use self::collect::Wasm; | ||
|
||
pub mod numeric; | ||
pub use self::numeric::*; | ||
|
||
pub mod control; | ||
pub use self::control::*; | ||
|
||
pub mod scope; | ||
pub use self::scope::*; | ||
|
||
pub mod util; | ||
pub use self::util::*; | ||
|
||
pub mod values; | ||
pub use self::values::*; | ||
|
||
#[cfg(test)] | ||
mod tests; |
Oops, something went wrong.