Restructuring into multiple crates and projects

This commit is contained in:
Henrik Böving
2021-03-05 19:10:18 +01:00
parent 00d0d7aba3
commit d67eda2edc
26 changed files with 6467 additions and 76 deletions

2
.gitignore vendored
View File

@@ -1 +1,3 @@
/target
hm-asm-web/pkg
node_modules

162
Cargo.lock generated
View File

@@ -21,6 +21,12 @@ dependencies = [
"byte-tools",
]
[[package]]
name = "bumpalo"
version = "3.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
[[package]]
name = "byte-tools"
version = "0.3.1"
@@ -29,9 +35,15 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "byteorder"
version = "1.3.4"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "digest"
@@ -50,19 +62,58 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "generic-array"
version = "0.12.3"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
dependencies = [
"typenum",
]
[[package]]
name = "hm-asm"
name = "hm-asm-cli"
version = "0.1.0"
dependencies = [
"hm-asm-simulator",
"pest",
]
[[package]]
name = "hm-asm-simulator"
version = "0.1.0"
dependencies = [
"pest",
"pest_derive",
"serde",
]
[[package]]
name = "hm-asm-web"
version = "0.1.0"
dependencies = [
"hm-asm-simulator",
"pest",
"wasm-bindgen",
]
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
@@ -131,13 +182,50 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.7"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "serde"
version = "1.0.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.123"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha-1"
version = "0.8.2"
@@ -152,9 +240,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.52"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c1e438504729046a5cfae47f97c30d6d083c7d91d94603efdae3477fc070d4c"
checksum = "ed22b90a0e734a23a7610f4283ac9e5acfb96cbb30dfefa540d66f866f1c09c5"
dependencies = [
"proc-macro2",
"quote",
@@ -178,3 +266,59 @@ name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "wasm-bindgen"
version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7"
dependencies = [
"cfg-if",
"serde",
"serde_json",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5ac38da8ef716661f0f36c0d8320b89028efe10c7c0afde65baffb496ce0d3b"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc053ec74d454df287b9374ee8abb36ffd5acb95ba87da3ba5b7d3fe20eb401e"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1"

View File

@@ -1,11 +1,6 @@
[package]
name = "hm-asm"
version = "0.1.0"
authors = ["Henrik Boeving <boeving@hm.edu>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
pest = "2.0"
pest_derive = "2.0"
[workspace]
members = [
"hm-asm-cli/",
"hm-asm-simulator/",
"hm-asm-web/"
]

View File

@@ -4,30 +4,6 @@ W. Hoffmann.
This microprocessor has a single accumulator register that calculations use.
## How does it work?
You can generate the data and program memory for a program like this:
```
$ cargo run -- generate examples/add_endless.asm
Data Memory:
0 1 1 0
0 0 0 0
0 0 0 0
0 0 0 0
Program Memory:
1 4 8 0
0 0 0 0
0 0 0 0
0 0 0 0
And that's your program!
```
Alternatively you can simulate an asm program for n clock cycles like this:
```
$ cargo run -- simulate examples/add_endless.asm 4
```
It is going to proceed and print an HTML table of all states since the only purpose of this tool is to avoid using
mahara as an in browser lab book -> we just autogenerate the tables.
## Syntax
The processor supports the following commands:
@@ -57,3 +33,11 @@ You can find some syntax examples for the assembler in `examples/`
The operand size of four bits limits the directly addressable memory to 16 instructions. This generally limits the memory size, while large program memory is supported. Furthermore since the operands of the instructions are stored in the same part of memory as where you
can store values with the `STA` instruction it is technically possible to overwrite your program operands at runtime and do a
sort of self modifying programming style, this assembler does not warn you if you do this as of now.
## Project structure
The project consists of 3 main components:
- `hm-asm-simulator` is a Rust library that contains the parsing, compilation and simulation logic
- `hm-asm-cli` is a CLI frontend for `hm-asm-simulator`
- `hm-asm-web` is a WebAssemly library frontend for `hm-asm-simulator`
For more information regarding the specific sub components refer to their individual READMEs

11
hm-asm-cli/Cargo.toml Normal file
View File

@@ -0,0 +1,11 @@
[package]
name = "hm-asm-cli"
version = "0.1.0"
authors = ["Henrik Böving <hargonix@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
hm-asm-simulator = { path = "../hm-asm-simulator", version = "0.1.0" }
pest = "2.0"

28
hm-asm-cli/README.md Normal file
View File

@@ -0,0 +1,28 @@
# hm-asm-cli
A CLI frontend for `hm-asm-simulate`, it provides two commands:
## Generate
You can generate the data and program memory for a program like this
```
$ cargo run -- generate examples/add_endless.asm
Data Memory:
0 1 1 0
0 0 0 0
0 0 0 0
0 0 0 0
Program Memory:
1 4 8 0
0 0 0 0
0 0 0 0
0 0 0 0
And that's your program!
```
## Simulate
Alternatively you can simulate an asm program for n clock cycles like this:
```
$ cargo run -- simulate examples/add_endless.asm 4
```
It is going to proceed and print an HTML table of all states since the only purpose of this tool is to avoid using
mahara as an in browser lab book -> we just autogenerate the tables.

View File

@@ -1,4 +1,4 @@
use crate::simulate::State;
use hm_asm_simulator::simulate::State;
use std::fmt::Write;
static TABLE_HEADER: &str = "

View File

@@ -1,19 +1,15 @@
use std::env;
use std::fs;
#[macro_use]
extern crate pest_derive;
use hm_asm_simulator::{
generate::generate_binary,
parse::{parse_asm, AsmParser, Rule},
simulate::simulate
};
use pest::Parser;
mod asm;
mod generate;
mod parse;
mod simulate;
mod html;
use generate::generate_binary;
use parse::{parse_asm, AsmParser};
use html::html_state_table;
@@ -34,7 +30,7 @@ fn main() {
};
let instructions = parse_asm(
AsmParser::parse(parse::Rule::program, &file_content).unwrap_or_else(|e| panic!("{}", e)),
AsmParser::parse(Rule::program, &file_content).unwrap_or_else(|e| panic!("{}", e)),
);
if sub_cmd == "generate" {
@@ -43,11 +39,12 @@ fn main() {
}
else if sub_cmd == "simulate" {
if let Some(steps) = steps {
let states = simulate::simulate(instructions, steps.parse::<usize>().unwrap());
let states = simulate(instructions, steps.parse::<usize>().unwrap());
//println!("{:#?}", states);
println!("{}", html_state_table(states));
}
}
} else {
println!("No argument was passed, exiting");
}
}

View File

@@ -0,0 +1,12 @@
[package]
name = "hm-asm-simulator"
version = "0.1.0"
authors = ["Henrik Boeving <boeving@hm.edu>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
pest = "2.0"
pest_derive = "2.0"
serde = { version = "1.0", features = ["derive"] }

View File

@@ -2,9 +2,12 @@ use crate::asm::*;
use std::collections::HashMap;
use std::fmt;
use serde::Serialize;
#[derive(Serialize)]
pub struct Program {
pub data_memory: [u8; 16],
program_memory: [u8; 16],
pub program_memory: [u8; 16],
}
impl fmt::Display for Program {

View File

@@ -0,0 +1,7 @@
#[macro_use]
extern crate pest_derive;
pub mod generate;
pub mod asm;
pub mod parse;
pub mod simulate;

View File

@@ -5,31 +5,33 @@ use crate::generate::generate_binary;
use std::collections::HashMap;
use std::fmt;
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
use serde::Serialize;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize)]
pub struct StateRegister {
carry: bool,
zero: bool,
negative: bool
pub carry: bool,
pub zero: bool,
pub negative: bool
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize)]
pub struct OpcodeInfo {
addr: u8,
content: u8
pub addr: u8,
pub content: u8
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize)]
pub struct State {
step: usize,
clk: bool,
pc: u8,
addr_bus: u8,
data_bus: u8,
ir: u8, // instruction register
dr: u8, // data register
akku: u8,
sr: StateRegister,
opcode_info: Option<OpcodeInfo>
pub step: usize,
pub clk: bool,
pub pc: u8,
pub addr_bus: u8,
pub data_bus: u8,
pub ir: u8, // instruction register
pub dr: u8, // data register
pub akku: u8,
pub sr: StateRegister,
pub opcode_info: Option<OpcodeInfo>
}

14
hm-asm-web/Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "hm-asm-web"
version = "0.1.0"
authors = ["Henrik Böving <hargonix@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib"]
[dependencies]
hm-asm-simulator = { path = "../hm-asm-simulator", version = "0.1.0" }
pest = "2.0"
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }

20
hm-asm-web/README.md Normal file
View File

@@ -0,0 +1,20 @@
# hm-asm-web
This is a WebAssembly based frontend for `hm-asm-simulator`. It expoes
two functions to javascript.
- `simulate(code: &str, cycles: usize)`, its return value is equivalent to the one of `hm_asm_simulator::simulate::simulate`
- `assemble(code: &str)`, its return vlaue is equivalent to the one of `hm_asm_simulator::generate::generate_binary`
## Demo
In `demo/` You'll find a demo app that compiles and simulates a simple program inside of the console.
You can test it with
- `npm install`
- `npm run start`
Afterwards you can visit the demo at `localhost:8080`.
## Using it
You can use this guide https://rustwasm.github.io/docs/book/game-of-life/setup.html
to set up your own project. I'm not planning to publish to npm.org at this point.

67
hm-asm-web/demo/README.md Normal file
View File

@@ -0,0 +1,67 @@
<div align="center">
<h1><code>create-wasm-app</code></h1>
<strong>An <code>npm init</code> template for kick starting a project that uses NPM packages containing Rust-generated WebAssembly and bundles them with Webpack.</strong>
<p>
<a href="https://travis-ci.org/rustwasm/create-wasm-app"><img src="https://img.shields.io/travis/rustwasm/create-wasm-app.svg?style=flat-square" alt="Build Status" /></a>
</p>
<h3>
<a href="#usage">Usage</a>
<span> | </span>
<a href="https://discordapp.com/channels/442252698964721669/443151097398296587">Chat</a>
</h3>
<sub>Built with 🦀🕸 by <a href="https://rustwasm.github.io/">The Rust and WebAssembly Working Group</a></sub>
</div>
## About
This template is designed for depending on NPM packages that contain
Rust-generated WebAssembly and using them to create a Website.
* Want to create an NPM package with Rust and WebAssembly? [Check out
`wasm-pack-template`.](https://github.com/rustwasm/wasm-pack-template)
* Want to make a monorepo-style Website without publishing to NPM? Check out
[`rust-webpack-template`](https://github.com/rustwasm/rust-webpack-template)
and/or
[`rust-parcel-template`](https://github.com/rustwasm/rust-parcel-template).
## 🚴 Usage
```
npm init wasm-app
```
## 🔋 Batteries Included
- `.gitignore`: ignores `node_modules`
- `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you
- `README.md`: the file you are reading now!
- `index.html`: a bare bones html document that includes the webpack bundle
- `index.js`: example js file with a comment showing how to import and use a wasm pkg
- `package.json` and `package-lock.json`:
- pulls in devDependencies for using webpack:
- [`webpack`](https://www.npmjs.com/package/webpack)
- [`webpack-cli`](https://www.npmjs.com/package/webpack-cli)
- [`webpack-dev-server`](https://www.npmjs.com/package/webpack-dev-server)
- defines a `start` script to run `webpack-dev-server`
- `webpack.config.js`: configuration file for bundling your js with webpack
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally
submitted for inclusion in the work by you, as defined in the Apache-2.0
license, shall be dual licensed as above, without any additional terms or
conditions.

5
hm-asm-web/demo/bootstrap.js vendored Normal file
View File

@@ -0,0 +1,5 @@
// A dependency graph that contains any wasm must all be imported
// asynchronously. This `bootstrap.js` file does the single async import, so
// that no one else needs to worry about it again.
import("./index.js")
.catch(e => console.error("Error importing `index.js`:", e));

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello wasm-pack!</title>
</head>
<body>
<noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript>
<script src="./bootstrap.js"></script>
</body>
</html>

9
hm-asm-web/demo/index.js Normal file
View File

@@ -0,0 +1,9 @@
import * as wasm from "hm-asm-web";
console.log("Welcome to hm-asm-web");
const code = "LDA #1\nADD #3\nSTA (8)"
console.log("Compiling:\n" + code)
console.log(wasm.assemble(code));
console.log("Simulating for four clock cycles:\n" + code )
console.log(wasm.simulate(code, 4));

5998
hm-asm-web/demo/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,39 @@
{
"name": "create-wasm-app",
"version": "0.1.0",
"description": "create an app to consume rust-generated wasm packages",
"main": "index.js",
"bin": {
"create-wasm-app": ".bin/create-wasm-app.js"
},
"scripts": {
"build": "webpack --config webpack.config.js",
"start": "webpack-dev-server"
},
"repository": {
"type": "git",
"url": "git+https://github.com/rustwasm/create-wasm-app.git"
},
"keywords": [
"webassembly",
"wasm",
"rust",
"webpack"
],
"author": "Henrik Boeving",
"license": "GPlv3",
"bugs": {
"url": "https://github.com/rustwasm/create-wasm-app/issues"
},
"homepage": "https://github.com/rustwasm/create-wasm-app#readme",
"dependencies": {
"hm-asm-web": "file:../pkg"
},
"devDependencies": {
"hello-wasm-pack": "^0.1.0",
"webpack": "^4.29.3",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5",
"copy-webpack-plugin": "^5.0.0"
}
}

View File

@@ -0,0 +1,14 @@
const CopyWebpackPlugin = require("copy-webpack-plugin");
const path = require('path');
module.exports = {
entry: "./bootstrap.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bootstrap.js",
},
mode: "development",
plugins: [
new CopyWebpackPlugin(['index.html'])
],
};

1
hm-asm-web/hm-asm.js Normal file
View File

@@ -0,0 +1 @@
import { simulate, assemble } from "./pkg";

28
hm-asm-web/src/lib.rs Normal file
View File

@@ -0,0 +1,28 @@
use pest::Parser;
use wasm_bindgen::prelude::*;
use hm_asm_simulator::{
generate::generate_binary,
parse::{parse_asm, AsmParser, Rule},
};
#[wasm_bindgen]
pub fn simulate(code: &str, cycles: usize) -> JsValue {
let instructions = parse_asm(
AsmParser::parse(Rule::program, &code).unwrap_or_else(|e| panic!("{}", e)),
);
let states = hm_asm_simulator::simulate::simulate(instructions, cycles);
JsValue::from_serde(&states).unwrap()
}
#[wasm_bindgen]
pub fn assemble(code: &str) -> JsValue {
let instructions = parse_asm(
AsmParser::parse(Rule::program, &code).unwrap_or_else(|e| panic!("{}", e)),
);
let binary = generate_binary(instructions);
JsValue::from_serde(&binary).unwrap()
}