Fix deafult session Id, edit register values
This commit is contained in:
@@ -355,7 +355,7 @@ fn write_instructions_enum() {
|
||||
|
||||
write!(
|
||||
&mut writer,
|
||||
"#[derive(PartialEq, Debug)]\n\
|
||||
"#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]\n\
|
||||
pub enum InstructionOp {{\n\
|
||||
"
|
||||
)
|
||||
|
||||
@@ -210,7 +210,7 @@ impl FromStr for Comment {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Instruction {
|
||||
pub instruction: InstructionOp,
|
||||
pub operands: Vec<Operand>,
|
||||
|
||||
@@ -156,7 +156,7 @@ pub struct IC {
|
||||
pub state: ICState,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Program {
|
||||
pub instructions: Vec<grammar::Instruction>,
|
||||
pub labels: HashMap<String, u32>,
|
||||
@@ -169,12 +169,14 @@ impl Default for Program {
|
||||
}
|
||||
|
||||
impl Program {
|
||||
|
||||
pub fn new() -> Self {
|
||||
Program {
|
||||
instructions: Vec::new(),
|
||||
labels: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_from_code(code: &str) -> Result<Self, ICError> {
|
||||
let parse_tree = grammar::parse(&code)?;
|
||||
let mut labels_set = HashSet::new();
|
||||
@@ -209,6 +211,7 @@ impl Program {
|
||||
labels,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_line(&self, line: u32) -> Result<&grammar::Instruction, ICError> {
|
||||
self.instructions
|
||||
.get(line as usize)
|
||||
@@ -217,6 +220,7 @@ impl Program {
|
||||
}
|
||||
|
||||
impl IC {
|
||||
|
||||
pub fn new(id: u16, device: u16) -> Self {
|
||||
IC {
|
||||
device,
|
||||
@@ -319,7 +323,7 @@ impl IC {
|
||||
self.registers[17] = self.ip as f64 + 1.0;
|
||||
}
|
||||
|
||||
fn push(&mut self, val: f64) -> Result<f64, ICError> {
|
||||
pub fn push(&mut self, val: f64) -> Result<f64, ICError> {
|
||||
let sp = (self.registers[16]) as i32;
|
||||
if sp < 0 {
|
||||
Err(ICError::StackUnderflow)
|
||||
@@ -333,7 +337,7 @@ impl IC {
|
||||
}
|
||||
}
|
||||
|
||||
fn pop(&mut self) -> Result<f64, ICError> {
|
||||
pub fn pop(&mut self) -> Result<f64, ICError> {
|
||||
let sp = (self.registers[16]) as i32;
|
||||
if sp < 0 {
|
||||
Err(ICError::StackUnderflow)
|
||||
@@ -346,7 +350,7 @@ impl IC {
|
||||
}
|
||||
}
|
||||
|
||||
fn poke(&mut self, address: f64, val: f64) -> Result<f64, ICError> {
|
||||
pub fn poke(&mut self, address: f64, val: f64) -> Result<f64, ICError> {
|
||||
let sp = address as i32;
|
||||
if sp < 0 || sp >= 512 {
|
||||
Err(ICError::StackIndexOutOfRange(address))
|
||||
@@ -357,7 +361,7 @@ impl IC {
|
||||
}
|
||||
}
|
||||
|
||||
fn peek(&self) -> Result<f64, ICError> {
|
||||
pub fn peek(&self) -> Result<f64, ICError> {
|
||||
let sp = (self.registers[16]) as i32;
|
||||
if sp < 0 {
|
||||
Err(ICError::StackUnderflow)
|
||||
@@ -369,7 +373,7 @@ impl IC {
|
||||
}
|
||||
}
|
||||
|
||||
fn peek_addr(&self, addr: f64) -> Result<f64, ICError> {
|
||||
pub fn peek_addr(&self, addr: f64) -> Result<f64, ICError> {
|
||||
let sp = (addr) as i32;
|
||||
if sp < 0 {
|
||||
Err(ICError::StackUnderflow)
|
||||
|
||||
@@ -205,8 +205,7 @@ impl DeviceRef {
|
||||
|
||||
#[wasm_bindgen(getter, js_name = "state")]
|
||||
pub fn ic_state(&self) -> Option<String> {
|
||||
self
|
||||
.device
|
||||
self.device
|
||||
.borrow()
|
||||
.ic
|
||||
.as_ref()
|
||||
@@ -221,6 +220,26 @@ impl DeviceRef {
|
||||
.map(|state| state.to_string())
|
||||
}
|
||||
|
||||
#[wasm_bindgen(getter, js_name = "program")]
|
||||
pub fn ic_program(&self) -> JsValue {
|
||||
serde_wasm_bindgen::to_value(
|
||||
&self
|
||||
.device
|
||||
.borrow()
|
||||
.ic
|
||||
.as_ref()
|
||||
.map(|ic| {
|
||||
self.vm
|
||||
.borrow()
|
||||
.ics
|
||||
.get(ic)
|
||||
.map(|ic| ic.borrow().program.clone())
|
||||
})
|
||||
.flatten(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "step")]
|
||||
pub fn step_ic(&self) -> Result<bool, JsError> {
|
||||
let id = self.device.borrow().id;
|
||||
@@ -244,6 +263,40 @@ impl DeviceRef {
|
||||
let id = self.device.borrow().id;
|
||||
Ok(self.vm.borrow().set_code(id, code)?)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "setRegister")]
|
||||
pub fn ic_set_register(&self, index: u32, val: f64) -> Result<f64, JsError> {
|
||||
let ic_id = *self
|
||||
.device
|
||||
.borrow()
|
||||
.ic
|
||||
.as_ref()
|
||||
.ok_or(ic10emu::VMError::NoIC(self.device.borrow().id))?;
|
||||
let vm_borrow = self.vm.borrow();
|
||||
let ic = vm_borrow
|
||||
.ics
|
||||
.get(&ic_id)
|
||||
.ok_or(ic10emu::VMError::NoIC(self.device.borrow().id))?;
|
||||
let result = ic.borrow_mut().set_register(0, index, val)?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "setStack")]
|
||||
pub fn ic_set_stack(&mut self, address: f64, val: f64) -> Result<f64, JsError> {
|
||||
let ic_id = *self
|
||||
.device
|
||||
.borrow()
|
||||
.ic
|
||||
.as_ref()
|
||||
.ok_or(ic10emu::VMError::NoIC(self.device.borrow().id))?;
|
||||
let vm_borrow = self.vm.borrow();
|
||||
let ic = vm_borrow
|
||||
.ics
|
||||
.get(&ic_id)
|
||||
.ok_or(ic10emu::VMError::NoIC(self.device.borrow().id))?;
|
||||
let result = ic.borrow_mut().poke(address, val)?;
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
|
||||
@@ -43,6 +43,7 @@ class IC10Editor {
|
||||
customScrollbar: false,
|
||||
firstLineNumber: 0,
|
||||
printMarginColumn: 52,
|
||||
placeholder: "Your code goes here ...",
|
||||
});
|
||||
|
||||
this.sessions = {};
|
||||
@@ -80,16 +81,17 @@ class IC10Editor {
|
||||
if (marker) {
|
||||
self.sessions[id].removeMarker(marker);
|
||||
self.active_line_markers[id] = null;
|
||||
|
||||
}
|
||||
self.active_line_markers[id] = self.sessions[id].addMarker(new Range(active_line, 0, active_line, 1), "vm_ic_active_line", "fullLine", true);
|
||||
if (self.active_session == id) {
|
||||
// editor.resize(true);
|
||||
self.aceEditor.scrollToLine(active_line, true, true)
|
||||
const session = self.sessions[id];
|
||||
if (session) {
|
||||
self.active_line_markers[id] = session.addMarker(new Range(active_line, 0, active_line, 1), "vm_ic_active_line", "fullLine", true);
|
||||
if (self.active_session == id) {
|
||||
// editor.resize(true);
|
||||
self.aceEditor.scrollToLine(active_line, true, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
@@ -105,8 +107,20 @@ class IC10Editor {
|
||||
if (this.sessions.hasOwnProperty(session_id)) {
|
||||
return false;
|
||||
}
|
||||
this.sessions[session_id] = ace.createEditSession("", this.mode);
|
||||
this.bindSession(session_id, this.sessions[session_id]);
|
||||
const session = ace.createEditSession("", this.mode);
|
||||
session.setOptions({
|
||||
enableBasicAutocompletion: true,
|
||||
enableLiveAutocompletion: true,
|
||||
enableSnippets: true,
|
||||
theme: "ace/theme/one_dark",
|
||||
fontSize: "16px",
|
||||
customScrollbar: false,
|
||||
firstLineNumber: 0,
|
||||
printMarginColumn: 52,
|
||||
placeholder: "Your code goes here ...",
|
||||
})
|
||||
this.sessions[session_id] = session;
|
||||
this.bindSession(session_id, session);
|
||||
}
|
||||
|
||||
setupLsp(lsp_worker) {
|
||||
|
||||
@@ -24,7 +24,9 @@ docReady(() => {
|
||||
|
||||
App.vm = new VirtualMachine();
|
||||
|
||||
App.editor = new IC10Editor();
|
||||
const init_session_id = App.vm.devices[0];
|
||||
|
||||
App.editor = new IC10Editor(init_session_id);
|
||||
|
||||
setupLspWorker().then((worker) => {
|
||||
App.editor.setupLsp(worker);
|
||||
|
||||
@@ -21,6 +21,10 @@ class VirtualMachine {
|
||||
|
||||
}
|
||||
|
||||
get devices () {
|
||||
return this.ic10vm.devices;
|
||||
}
|
||||
|
||||
updateCode() {
|
||||
const progs = window.App.session.programs;
|
||||
for (const id of Object.keys(progs)) {
|
||||
@@ -28,7 +32,11 @@ class VirtualMachine {
|
||||
const prog = progs[id];
|
||||
if (ic && prog) {
|
||||
console.time(`CompileProgram_${id}`);
|
||||
this.ics[id].setCode(progs[id]);
|
||||
try {
|
||||
this.ics[id].setCode(progs[id]);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
console.timeEnd(`CompileProgram_${id}`);
|
||||
}
|
||||
}
|
||||
@@ -72,14 +80,23 @@ class VirtualMachine {
|
||||
window.App.session.setActiveLine(window.App.session.activeSession, ic.ip);
|
||||
this.ui.update(ic);
|
||||
}
|
||||
|
||||
setRegister(index, val) {
|
||||
const ic = this.ics[window.App.session.activeSession];
|
||||
try {
|
||||
ic.setRegister(index, val);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class VirtualMachineUI {
|
||||
constructor(vm) {
|
||||
this.vm = vm
|
||||
this.state = new VMStateUI();
|
||||
this.registers = new VMRegistersUI();
|
||||
this.state = new VMStateUI(this);
|
||||
this.registers = new VMRegistersUI(this);
|
||||
this.buildStackDisplay();
|
||||
|
||||
const self = this;
|
||||
@@ -109,7 +126,8 @@ class VirtualMachineUI {
|
||||
}
|
||||
|
||||
class VMStateUI {
|
||||
constructor() {
|
||||
constructor(ui) {
|
||||
this.ui = ui;
|
||||
const stateDom = document.getElementById("vmActiveICState");
|
||||
|
||||
this.tbl = document.createElement("table");
|
||||
@@ -143,7 +161,8 @@ class VMStateUI {
|
||||
}
|
||||
|
||||
class VMRegistersUI {
|
||||
constructor() {
|
||||
constructor(ui) {
|
||||
this.ui = ui;
|
||||
const regDom = document.getElementById("vmActiveRegisters");
|
||||
this.tbl = document.createElement("div");
|
||||
this.tbl.classList.add("d-flex", "flex-wrap", "justify-content-start", "align-items-start", "align-self-center");
|
||||
@@ -161,18 +180,12 @@ class VMRegistersUI {
|
||||
const input = document.createElement("input");
|
||||
input.type = "text"
|
||||
input.value = 0;
|
||||
// input.size = 3;
|
||||
// input.style.width = 40;
|
||||
input.dataset.index = i;
|
||||
cell.appendChild(input);
|
||||
const aliasesLabel = document.createElement("span");
|
||||
aliasesLabel.classList.add("input-group-text")
|
||||
aliasesLabel.innerText = "\xa0";
|
||||
cell.appendChild(aliasesLabel);
|
||||
if (i == 16 ) {
|
||||
aliasesLabel.innerText = "sp";
|
||||
} else if (i == 17) {
|
||||
aliasesLabel.innerText = "ra";
|
||||
}
|
||||
this.regCels.push({
|
||||
cell,
|
||||
nameLabel,
|
||||
@@ -182,18 +195,69 @@ class VMRegistersUI {
|
||||
container.appendChild(cell);
|
||||
this.tbl.appendChild(container);
|
||||
}
|
||||
this.regCels.forEach(cell => {
|
||||
cell.input.addEventListener('change', this.onCellUpdate);
|
||||
});
|
||||
this.default_aliases = { "sp": 16, "ra": 17 }
|
||||
this.ic_aliases = {}
|
||||
regDom.appendChild(this.tbl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
onCellUpdate(e) {
|
||||
let index;
|
||||
let val;
|
||||
try {
|
||||
index = parseInt(e.target.dataset.index);
|
||||
val = parseFloat(e.target.value);
|
||||
} catch (e) {
|
||||
// reset the edit
|
||||
console.log(e);
|
||||
VM.update();
|
||||
return;
|
||||
}
|
||||
VM.setRegister(index, val);
|
||||
}
|
||||
|
||||
update(ic) {
|
||||
const self = this;
|
||||
if (ic) {
|
||||
const registers = ic.registers;
|
||||
if (registers) {
|
||||
console.log(registers)
|
||||
for (var i = 0; i < registers.length; i++) {
|
||||
this.regCels[i].input.value = registers[i];
|
||||
}
|
||||
}
|
||||
const aliases = ic.aliases;
|
||||
if (aliases) {
|
||||
this.ic_aliases = {}
|
||||
aliases.keys().forEach(alias => {
|
||||
const target = aliases.get(alias);
|
||||
if (target.RegisterSpec && target.RegisterSpec.indirection == 0) {
|
||||
const index = target.RegisterSpec.target;
|
||||
this.ic_aliases[alias] = index;
|
||||
}
|
||||
})
|
||||
}
|
||||
console.log(aliases);
|
||||
}
|
||||
this.updateAliases();
|
||||
}
|
||||
|
||||
updateAliases () {
|
||||
const aliases = Object.assign({}, this.default_aliases, this.ic_aliases);
|
||||
const labels = {}
|
||||
for (const [alias, target] of Object.entries(aliases)) {
|
||||
if (labels.hasOwnProperty(target)) {
|
||||
labels[target].push(alias)
|
||||
} else {
|
||||
labels[target] = [alias]
|
||||
}
|
||||
}
|
||||
|
||||
for(const [index, label] of Object.entries(labels)) {
|
||||
this.regCels[index].aliasesLabel.innerText = label.join(", ")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,4 +438,5 @@ code {
|
||||
|
||||
.vm_reg_cel input {
|
||||
width: 6rem;
|
||||
background-color: var(--bs-body-bg);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user