Splitting vweb into multiple modules

This commit is contained in:
2023-12-09 13:12:38 -06:00
parent 66e7e1884e
commit ca79642e43
8 changed files with 193 additions and 171 deletions
Generated
+1
View File
@@ -1513,6 +1513,7 @@ dependencies = [
name = "vweb"
version = "0.1.0"
dependencies = [
"forge_core",
"serde",
"serde-wasm-bindgen",
"vasm_core",
+2 -2
View File
@@ -18,7 +18,7 @@ impl Compilable for Global {
state.init.emit_arg("storew", label.clone());
}
state.add_global(&self.name, |s| Variable::IndirectLabel(label.clone()))
state.add_global(&self.name, |_| Variable::IndirectLabel(label.clone()))
}
}
@@ -52,7 +52,7 @@ mod test {
#[test]
fn test_init() {
let mut state = state_for("global a = 5 + 3;");
let state = state_for("global a = 5 + 3;");
assert_eq!(
state.init.0.join("\n"),
vec![
+1
View File
@@ -12,6 +12,7 @@ crate-type = ["cdylib"]
vcore = { path = "../vcore" }
vgfx = { path = "../vgfx" }
vasm_core = { path = "../vasm_core" }
forge_core = { path = "../forge_core" }
wasm-bindgen = "0.2"
serde = { version = "1.0", features = ["derive"] }
serde-wasm-bindgen = "0.4"
+23
View File
@@ -0,0 +1,23 @@
use wasm_bindgen::{Clamped, JsValue};
use wasm_bindgen::prelude::wasm_bindgen;
use web_sys::{CanvasRenderingContext2d, ImageData};
use vgfx::display;
use crate::wasm_cpu::WasmCPU;
// This has to contain a Box or else it'll use up all the wasm_bindgen stack space
#[wasm_bindgen]
pub struct Display(Box<[u8; 640 * 480 * 4]>);
#[wasm_bindgen]
impl Display {
#[wasm_bindgen(constructor)]
pub fn new() -> Display {
Display([0u8; 640 * 480 * 4].into())
}
pub fn draw(&mut self, cpu: &WasmCPU, ctx: &CanvasRenderingContext2d) -> Result<(), JsValue> {
display::draw(cpu.cpu(), self.0.as_mut());
let image_data = ImageData::new_with_u8_clamped_array(Clamped(self.0.as_mut()), 640)?;
ctx.put_image_data(&image_data, 0.0, 0.0)
}
}
+31
View File
@@ -0,0 +1,31 @@
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::wasm_bindgen;
use vasm_core::parse_error::AssembleError;
#[wasm_bindgen(inspectable, getter_with_clone)]
#[derive(Serialize, Deserialize)]
pub struct JsVasmError {
pub line_number: usize,
pub message: String
}
impl From<AssembleError> for JsVasmError {
fn from(value: AssembleError) -> Self {
let line = match value.clone() {
AssembleError::ParseError(loc, _) => loc.line_num,
AssembleError::EquResolveError(loc, _, _) => loc.line_num,
AssembleError::EquDuplicateError(loc, _) => loc.line_num,
AssembleError::OrgResolveError(loc, _) => loc.line_num,
AssembleError::ArgError(loc, _) => loc.line_num,
AssembleError::NoCode => 0,
AssembleError::IncludeError(loc, _) => loc.line_num,
AssembleError::FileError(_) => 0,
AssembleError::MacroError(loc) => loc.line_num,
};
return JsVasmError {
line_number: line,
message: value.message()
}
}
}
+6 -169
View File
@@ -1,61 +1,12 @@
mod display;
mod wasm_cpu;
mod nova_forth;
mod error;
use wasm_bindgen::prelude::*;
use vcore::{CPU, Word};
use vcore::memory::{PeekPoke, PeekPokeExt};
use vasm_core::parse_error::AssembleError;
use vgfx::display;
use serde::{ Deserialize, Serialize };
use wasm_bindgen::Clamped;
use web_sys::{CanvasRenderingContext2d, ImageData};
#[wasm_bindgen]
pub struct NovaForth;
#[wasm_bindgen]
impl NovaForth {
pub fn rom() -> Vec<u8> {
Vec::from(*include_bytes!("../4th/4th.rom"))
}
pub fn symbols() -> String {
include_str!("../4th/4th.rom.sym").into()
}
pub fn prelude() -> String { include_str!("../4th/prelude.f").into() }
}
#[wasm_bindgen]
pub struct WasmCPU(CPU);
// This has to contain a Box or else it'll use up all the wasm_bindgen stack space
#[wasm_bindgen]
pub struct Display(Box<[u8; 640 * 480 * 4]>);
#[wasm_bindgen(inspectable, getter_with_clone)]
#[derive(Serialize, Deserialize)]
pub struct JsVasmError {
pub line_number: usize,
pub message: String
}
impl From<AssembleError> for JsVasmError {
fn from(value: AssembleError) -> Self {
let line = match value.clone() {
AssembleError::ParseError(loc, _) => loc.line_num,
AssembleError::EquResolveError(loc, _, _) => loc.line_num,
AssembleError::EquDuplicateError(loc, _) => loc.line_num,
AssembleError::OrgResolveError(loc, _) => loc.line_num,
AssembleError::ArgError(loc, _) => loc.line_num,
AssembleError::NoCode => 0,
AssembleError::IncludeError(loc, _) => loc.line_num,
AssembleError::FileError(_) => 0,
AssembleError::MacroError(loc) => loc.line_num,
};
return JsVasmError {
line_number: line,
message: value.message()
}
}
}
use crate::error::JsVasmError;
#[wasm_bindgen]
pub fn assemble_snippet(snippet: String) -> Result<Vec<u8>, JsVasmError> {
@@ -67,117 +18,3 @@ pub fn source_map(snippet: String) -> JsValue {
let source_map = vasm_core::snippet_source_map(snippet.lines().map(String::from)).map_err(|err| JsVasmError::from(err));
serde_wasm_bindgen::to_value(&source_map).unwrap()
}
#[wasm_bindgen]
impl WasmCPU {
#[wasm_bindgen(constructor)]
pub fn new() -> WasmCPU {
let mut cpu = CPU::new_random();
display::init_gfx(&mut cpu);
WasmCPU(cpu)
}
pub fn push_data(&mut self, data: i32) {
self.0.push_data(data)
}
pub fn pop_data(&mut self) -> i32 {
self.0.pop_data().into()
}
pub fn push_call(&mut self, data: i32) {
self.0.push_call(data)
}
pub fn pop_call(&mut self) -> i32 {
self.0.pop_call().into()
}
pub fn poke(&mut self, addr: u32, val: u8) {
self.0.poke(addr.into(), val.into())
}
pub fn peek(&self, addr: u32) -> u8 {
self.0.peek(addr.into()).into()
}
pub fn poke24(&mut self, addr: u32, val: i32) {
self.0.poke24(Word::from(addr), Word::from(val))
}
pub fn peek24(&self, addr: u32) -> i32 {
self.0.peek24(Word::from(addr)).into()
}
pub fn pc(&self) -> u32 {
self.0.pc().into()
}
pub fn sp(&self) -> u32 {
self.0.sp().into()
}
pub fn dp(&self) -> u32 {
self.0.dp().into()
}
pub fn halted(&self) -> bool { self.0.halted() }
pub fn get_stack(&self) -> Vec<i32> {
self.0.get_stack().into_iter().map(i32::from).collect()
}
pub fn get_call(&self) -> Vec<i32> {
self.0.get_call().into_iter().map(i32::from).collect()
}
pub fn set_pc(&mut self, val: u32) {
self.0.set_pc(Word::from(val))
}
pub fn run(&mut self) {
self.0.run_to_halt()
}
pub fn safe_run(&mut self, max_ticks: usize) {
let mut current = 0;
while !self.0.halted() && current < max_ticks {
current += 1;
self.tick()
}
}
pub fn load(&mut self, rom: Vec<u8>) {
for (i, b) in rom.iter().enumerate() {
self.poke(0x400 + i as u32, *b)
}
self.set_pc(0x400)
}
pub fn reset(&mut self) {
self.0.reset()
}
pub fn start(&mut self) {
self.0.start()
}
pub fn tick(&mut self) {
self.0.tick()
}
}
#[wasm_bindgen]
impl Display {
#[wasm_bindgen(constructor)]
pub fn new() -> Display {
Display([0u8; 640 * 480 * 4].into())
}
pub fn draw(&mut self, cpu: &WasmCPU, ctx: &CanvasRenderingContext2d) -> Result<(), JsValue> {
display::draw(&cpu.0, self.0.as_mut());
let image_data = ImageData::new_with_u8_clamped_array(Clamped(self.0.as_mut()), 640)?;
ctx.put_image_data(&image_data, 0.0, 0.0)
}
}
+16
View File
@@ -0,0 +1,16 @@
use wasm_bindgen::prelude::wasm_bindgen;
#[wasm_bindgen]
pub struct NovaForth;
#[wasm_bindgen]
impl NovaForth {
pub fn rom() -> Vec<u8> {
Vec::from(*include_bytes!("../4th/4th.rom"))
}
pub fn symbols() -> String {
include_str!("../4th/4th.rom.sym").into()
}
pub fn prelude() -> String { include_str!("../4th/prelude.f").into() }
}
+113
View File
@@ -0,0 +1,113 @@
use wasm_bindgen::prelude::wasm_bindgen;
use vcore::{CPU, Word};
use vcore::memory::{PeekPoke, PeekPokeExt};
use vgfx::display;
#[wasm_bindgen]
pub struct WasmCPU(CPU);
#[wasm_bindgen]
impl WasmCPU {
#[wasm_bindgen(constructor)]
pub fn new() -> WasmCPU {
let mut cpu = CPU::new_random();
display::init_gfx(&mut cpu);
WasmCPU(cpu)
}
pub fn push_data(&mut self, data: i32) {
self.0.push_data(data)
}
pub fn pop_data(&mut self) -> i32 {
self.0.pop_data().into()
}
pub fn push_call(&mut self, data: i32) {
self.0.push_call(data)
}
pub fn pop_call(&mut self) -> i32 {
self.0.pop_call().into()
}
pub fn poke(&mut self, addr: u32, val: u8) {
self.0.poke(addr.into(), val.into())
}
pub fn peek(&self, addr: u32) -> u8 {
self.0.peek(addr.into()).into()
}
pub fn poke24(&mut self, addr: u32, val: i32) {
self.0.poke24(Word::from(addr), Word::from(val))
}
pub fn peek24(&self, addr: u32) -> i32 {
self.0.peek24(Word::from(addr)).into()
}
pub fn pc(&self) -> u32 {
self.0.pc().into()
}
pub fn sp(&self) -> u32 {
self.0.sp().into()
}
pub fn dp(&self) -> u32 {
self.0.dp().into()
}
pub fn halted(&self) -> bool { self.0.halted() }
pub fn get_stack(&self) -> Vec<i32> {
self.0.get_stack().into_iter().map(i32::from).collect()
}
pub fn get_call(&self) -> Vec<i32> {
self.0.get_call().into_iter().map(i32::from).collect()
}
pub fn set_pc(&mut self, val: u32) {
self.0.set_pc(Word::from(val))
}
pub fn run(&mut self) {
self.0.run_to_halt()
}
pub fn safe_run(&mut self, max_ticks: usize) {
let mut current = 0;
while !self.0.halted() && current < max_ticks {
current += 1;
self.tick()
}
}
pub fn load(&mut self, rom: Vec<u8>) {
for (i, b) in rom.iter().enumerate() {
self.poke(0x400 + i as u32, *b)
}
self.set_pc(0x400)
}
pub fn reset(&mut self) {
self.0.reset()
}
pub fn start(&mut self) {
self.0.start()
}
pub fn tick(&mut self) {
self.0.tick()
}
}
impl WasmCPU {
pub fn cpu(&self) -> &CPU {
&self.0
}
}