Add wasm build script and configuration for web compiler

This commit is contained in:
Moritz Hölting 2024-04-10 19:14:58 +02:00
parent 8dacaa4011
commit 6e79b6209c
7 changed files with 123 additions and 3 deletions

2
.gitignore vendored
View File

@ -19,3 +19,5 @@ pnpm-debug.log*
# macOS-specific files
.DS_Store
/wasm-pkg/

View File

@ -1,5 +1,5 @@
{
"name": "",
"name": "shulkerscript-webpage",
"type": "module",
"version": "0.0.1",
"scripts": {
@ -7,7 +7,8 @@
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
"astro": "astro",
"build-wasm": "cargo build -r && wasm-bindgen --target web --out-dir ./wasm-pkg --out-name shulkerscript ./wasm/target/wasm32-unknown-unknown/release/shulkerscript_wasm.wasm"
},
"dependencies": {
"@astrojs/check": "^0.5.10",

View File

@ -139,7 +139,7 @@ group {
## Run
The `run` keyword is used to evaluate the following expression and include the resulting command in the output.
```shulkerscript
run "say Hello, world!"
run "say Hello, world!";
```
:::tip

3
wasm/.cargo/config.toml Normal file
View File

@ -0,0 +1,3 @@
[build]
target = "wasm32-unknown-unknown"
target-dir = "target"

1
wasm/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
target

15
wasm/Cargo.toml Normal file
View File

@ -0,0 +1,15 @@
[package]
name = "shulkerscript-wasm"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
wasm-bindgen = "0.2.92"
shulkerscript-lang ={ path = "../../shulkerscript-lang", default-features = false, features = ["shulkerbox", "serde", "wasm"]}
serde = "1.0"
serde-wasm-bindgen = "0.6.5"

98
wasm/src/lib.rs Normal file
View File

@ -0,0 +1,98 @@
use std::{cell::Cell, fmt::Display, path::Path};
use shulkerscript_lang::{
base::{file_provider::FileProvider, source_file::SourceFile, Error, Handler, Result},
lexical::token_stream::TokenStream,
shulkerbox::{util::compile::CompileOptions, virtual_fs::VFolder},
syntax::parser::Parser,
transpile::transpiler::Transpiler,
};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
#[wasm_bindgen]
pub fn compile(source_text: &str) -> JsValue {
let datapack = internal_compile(source_text).ok().map(|folder| {
folder
.flatten()
.into_iter()
.map(|(path, file)| (path, file.clone()))
.collect::<Vec<_>>()
});
serde_wasm_bindgen::to_value(&datapack).unwrap()
}
struct DummyFileProvider {
content: String,
}
impl DummyFileProvider {
pub fn new(content: String) -> Self {
Self { content }
}
}
impl FileProvider for DummyFileProvider {
fn load(&self, _path: &Path) -> Option<String> {
Some(self.content.clone())
}
}
struct Printer {
printed: Cell<bool>,
}
impl<E: Display> Handler<E> for Printer {
fn receive(&self, error: E) {
log(&error.to_string());
self.printed.set(true);
}
}
impl Printer {
/// Creates a new [`Printer`].
fn new() -> Self {
Self {
printed: Cell::new(false),
}
}
fn has_printed(&self) -> bool {
self.printed.get()
}
}
fn internal_compile(source_text: &str) -> Result<VFolder> {
let file_provider = DummyFileProvider::new(source_text.to_string());
let source_file = SourceFile::load(&file_provider, Path::new("input.shu"))?;
let printer = Printer::new();
let tokens = TokenStream::tokenize(&source_file, &printer);
if printer.has_printed() {
return Err(Error::Other(
"An error occurred while tokenizing the source code.",
));
}
let mut parser = Parser::new(&tokens);
let program = parser.parse_program(&printer).ok_or(Error::Other(
"An error occured while parsing the source code.",
))?;
if printer.has_printed() {
return Err(Error::Other(
"An error occurred while parsing the source code.",
));
}
let mut transpiler = Transpiler::new("shulkerscript-pack", 27);
transpiler.transpile(&program, &printer)?;
let datapack = transpiler.into_datapack();
Ok(datapack.compile(&CompileOptions::default()))
}