Refactor editions

This commit is contained in:
Rerumu 2021-11-17 21:33:03 -05:00
parent 97c0ce7419
commit 2d9c994917
11 changed files with 191 additions and 173 deletions

View File

@ -0,0 +1,48 @@
use super::{luajit::LuaJIT, luau::Luau};
use crate::backend::helper::writer::Writer;
use std::{fmt::Display, io::Result};
pub struct Infix<T> {
rhs: &'static str,
inner: T,
}
impl<T> Infix<T> {
pub fn new(rhs: &'static str, inner: T) -> Self {
Infix { rhs, inner }
}
}
impl<T> Display for Infix<T>
where
T: Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)?;
self.rhs.fmt(f)
}
}
pub trait Edition {
fn runtime(&self) -> &'static str;
fn start_block(&self, w: Writer) -> Result<()>;
fn start_loop(&self, level: usize, w: Writer) -> Result<()>;
fn start_if(&self, cond: &str, w: Writer) -> Result<()>;
fn end_block(&self, level: usize, w: Writer) -> Result<()>;
fn end_loop(&self, w: Writer) -> Result<()>;
fn end_if(&self, level: usize, w: Writer) -> Result<()>;
fn br_target(&self, level: usize, in_loop: bool, w: Writer) -> Result<()>;
fn br_to_level(&self, level: usize, up: usize, is_loop: bool, w: Writer) -> Result<()>;
fn i64(&self, i: i64) -> Infix<i64>;
}
pub fn from_string(name: &str) -> Option<&'static dyn Edition> {
match name.to_ascii_lowercase().as_str() {
"luau" => Some(&Luau),
"luajit" => Some(&LuaJIT),
_ => None,
}
}

View File

@ -0,0 +1,50 @@
use super::data::{Edition, Infix};
use crate::backend::helper::writer::Writer;
use std::io::Result;
pub struct LuaJIT;
impl Edition for LuaJIT {
fn runtime(&self) -> &'static str {
"'luajit'"
}
fn start_block(&self, w: Writer) -> Result<()> {
write!(w, "do ")
}
fn start_loop(&self, level: usize, w: Writer) -> Result<()> {
write!(w, "do ")?;
write!(w, "::continue_at_{}::", level)
}
fn start_if(&self, cond: &str, w: Writer) -> Result<()> {
write!(w, "if {} ~= 0 then ", cond)
}
fn end_block(&self, level: usize, w: Writer) -> Result<()> {
write!(w, "::continue_at_{}::", level)?;
write!(w, "end ")
}
fn end_loop(&self, w: Writer) -> Result<()> {
write!(w, "end ")
}
fn end_if(&self, level: usize, w: Writer) -> Result<()> {
write!(w, "::continue_at_{}::", level)?;
write!(w, "end ")
}
fn br_target(&self, _level: usize, _in_loop: bool, _w: Writer) -> Result<()> {
Ok(())
}
fn br_to_level(&self, level: usize, up: usize, _is_loop: bool, w: Writer) -> Result<()> {
write!(w, "goto continue_at_{} ", level - up)
}
fn i64(&self, i: i64) -> Infix<i64> {
Infix::new("LL", i)
}
}

View File

@ -0,0 +1,75 @@
use super::data::{Edition, Infix};
use crate::backend::helper::writer::Writer;
use std::io::Result;
pub struct Luau;
impl Edition for Luau {
fn runtime(&self) -> &'static str {
"script.Runtime"
}
fn start_block(&self, w: Writer) -> Result<()> {
write!(w, "while true do ")
}
fn start_loop(&self, _level: usize, w: Writer) -> Result<()> {
write!(w, "while true do ")
}
fn start_if(&self, cond: &str, w: Writer) -> Result<()> {
write!(w, "while true do ")?;
write!(w, "if {} ~= 0 then ", cond)
}
fn end_block(&self, _level: usize, w: Writer) -> Result<()> {
write!(w, "break ")?;
write!(w, "end ")
}
fn end_loop(&self, w: Writer) -> Result<()> {
write!(w, "break ")?;
write!(w, "end ")
}
fn end_if(&self, _level: usize, w: Writer) -> Result<()> {
write!(w, "end ")?;
write!(w, "break ")?;
write!(w, "end ")
}
fn br_target(&self, level: usize, in_loop: bool, w: Writer) -> Result<()> {
write!(w, "if desired then ")?;
write!(w, "if desired == {} then ", level)?;
write!(w, "desired = nil ")?;
if in_loop {
write!(w, "continue ")?;
}
write!(w, "end ")?;
write!(w, "break ")?;
write!(w, "end ")
}
fn br_to_level(&self, level: usize, up: usize, is_loop: bool, w: Writer) -> Result<()> {
write!(w, "do ")?;
if up == 0 {
if is_loop {
write!(w, "continue ")?;
} else {
write!(w, "break ")?;
}
} else {
write!(w, "desired = {} ", level - up)?;
write!(w, "break ")?;
}
write!(w, "end ")
}
fn i64(&self, i: i64) -> Infix<i64> {
Infix::new("", i)
}
}

View File

@ -0,0 +1,3 @@
pub mod data;
pub mod luajit;
pub mod luau;

View File

@ -1,155 +0,0 @@
use super::writer::Writer;
use std::{fmt::Display, io::Result};
pub struct Infix<T> {
rhs: &'static str,
inner: T,
}
impl<T> Display for Infix<T>
where
T: Display,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)?;
self.rhs.fmt(f)
}
}
pub trait Edition {
fn runtime(&self) -> &'static str;
fn start_block(&self, w: Writer) -> Result<()>;
fn start_loop(&self, level: usize, w: Writer) -> Result<()>;
fn start_if(&self, cond: &str, w: Writer) -> Result<()>;
fn end_block(&self, level: usize, w: Writer) -> Result<()>;
fn end_loop(&self, w: Writer) -> Result<()>;
fn end_if(&self, level: usize, w: Writer) -> Result<()>;
fn br_target(&self, level: usize, in_loop: bool, w: Writer) -> Result<()>;
fn br_to_level(&self, level: usize, up: usize, is_loop: bool, w: Writer) -> Result<()>;
fn i64(&self, i: i64) -> Infix<i64>;
}
pub struct LuaJIT;
impl Edition for LuaJIT {
fn runtime(&self) -> &'static str {
"'luajit'"
}
fn start_block(&self, w: Writer) -> Result<()> {
write!(w, "do ")
}
fn start_loop(&self, level: usize, w: Writer) -> Result<()> {
write!(w, "do ")?;
write!(w, "::continue_at_{}::", level)
}
fn start_if(&self, cond: &str, w: Writer) -> Result<()> {
write!(w, "if {} ~= 0 then ", cond)
}
fn end_block(&self, level: usize, w: Writer) -> Result<()> {
write!(w, "::continue_at_{}::", level)?;
write!(w, "end ")
}
fn end_loop(&self, w: Writer) -> Result<()> {
write!(w, "end ")
}
fn end_if(&self, level: usize, w: Writer) -> Result<()> {
write!(w, "::continue_at_{}::", level)?;
write!(w, "end ")
}
fn br_target(&self, _level: usize, _in_loop: bool, _w: Writer) -> Result<()> {
Ok(())
}
fn br_to_level(&self, level: usize, up: usize, _is_loop: bool, w: Writer) -> Result<()> {
write!(w, "goto continue_at_{} ", level - up)
}
fn i64(&self, i: i64) -> Infix<i64> {
Infix {
rhs: "LL",
inner: i,
}
}
}
pub struct Luau;
impl Edition for Luau {
fn runtime(&self) -> &'static str {
"script.Runtime"
}
fn start_block(&self, w: Writer) -> Result<()> {
write!(w, "while true do ")
}
fn start_loop(&self, _level: usize, w: Writer) -> Result<()> {
write!(w, "while true do ")
}
fn start_if(&self, cond: &str, w: Writer) -> Result<()> {
write!(w, "while true do ")?;
write!(w, "if {} ~= 0 then ", cond)
}
fn end_block(&self, _level: usize, w: Writer) -> Result<()> {
write!(w, "break ")?;
write!(w, "end ")
}
fn end_loop(&self, w: Writer) -> Result<()> {
write!(w, "break ")?;
write!(w, "end ")
}
fn end_if(&self, _level: usize, w: Writer) -> Result<()> {
write!(w, "end ")?;
write!(w, "break ")?;
write!(w, "end ")
}
fn br_target(&self, level: usize, in_loop: bool, w: Writer) -> Result<()> {
write!(w, "if desired then ")?;
write!(w, "if desired == {} then ", level)?;
write!(w, "desired = nil ")?;
if in_loop {
write!(w, "continue ")?;
}
write!(w, "end ")?;
write!(w, "break ")?;
write!(w, "end ")
}
fn br_to_level(&self, level: usize, up: usize, is_loop: bool, w: Writer) -> Result<()> {
write!(w, "do ")?;
if up == 0 {
if is_loop {
write!(w, "continue ")?;
} else {
write!(w, "break ")?;
}
} else {
write!(w, "desired = {} ", level - up)?;
write!(w, "break ")?;
}
write!(w, "end ")
}
fn i64(&self, i: i64) -> Infix<i64> {
Infix { rhs: "", inner: i }
}
}

View File

@ -1,3 +1,2 @@
pub mod edition;
pub mod register; pub mod register;
pub mod writer; pub mod writer;

View File

@ -1,2 +1,3 @@
pub mod edition;
pub mod helper; pub mod helper;
pub mod translation; pub mod translation;

View File

@ -1,6 +1,9 @@
use super::level_2::list_to_range; use super::level_2::list_to_range;
use crate::{ use crate::{
backend::helper::{edition::Edition, register::Register, writer::Writer}, backend::{
edition::data::Edition,
helper::{register::Register, writer::Writer},
},
data::{Arity, Code, Module}, data::{Arity, Code, Module},
}; };
use parity_wasm::elements::{BrTableData, Instruction}; use parity_wasm::elements::{BrTableData, Instruction};

View File

@ -1,8 +1,8 @@
use super::level_1::Body; use super::level_1::Body;
use crate::{ use crate::{
backend::helper::{ backend::{
edition::Edition, edition::data::Edition,
writer::{write_ordered, Writer}, helper::writer::{write_ordered, Writer},
}, },
data::Module, data::Module,
}; };

View File

@ -1,6 +1,6 @@
use super::level_2::{gen_function, gen_init_expression}; use super::level_2::{gen_function, gen_init_expression};
use crate::{ use crate::{
backend::helper::{edition::Edition, writer::Writer}, backend::{edition::data::Edition, helper::writer::Writer},
data::Module, data::Module,
}; };
use parity_wasm::elements::{External, ImportCountType, Internal, ResizableLimits}; use parity_wasm::elements::{External, ImportCountType, Internal, ResizableLimits};

View File

@ -1,7 +1,4 @@
use backend::{ use backend::{edition::data::from_string, translation::level_3};
helper::edition::{Edition, LuaJIT, Luau},
translation::level_3,
};
use data::Module; use data::Module;
use parity_wasm::elements::deserialize_file; use parity_wasm::elements::deserialize_file;
@ -10,14 +7,11 @@ mod data;
fn main() { fn main() {
let mut args = std::env::args().skip(1); let mut args = std::env::args().skip(1);
let spec: &dyn Edition = match args.next().as_deref().map(str::to_lowercase).as_deref() { let spec = args
Some("luau") => &Luau, .next()
Some("luajit") => &LuaJIT, .as_deref()
_ => { .and_then(from_string)
println!("expected either 'luau' or 'luajit' option"); .expect("No language argument provided");
return;
}
};
let output = std::io::stdout(); let output = std::io::stdout();