Skip to content

Commit

Permalink
Add hex highlighting and switch tabs on cross reference click
Browse files Browse the repository at this point in the history
  • Loading branch information
cayb0rg committed Feb 4, 2024
1 parent e65efd6 commit 539903a
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 144 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ js-sys = "0.3.61"
monaco = { git = "https://github.com/SWIM-ucf/rust-monaco", rev = "c9586e4af77131a15daf53e91e1ad5161a5265e8", features = ["yew-components"] }
wasm-bindgen = "0.2.83"
wasm-bindgen-futures = "0.4.33"
web-sys = {version = "0.3.60", features = ["CssStyleDeclaration", "Event", "HtmlCollection", "HtmlElement", "HtmlInputElement", "HtmlObjectElement", "SvgElement", "CanvasRenderingContext2d", "Document", "HtmlCanvasElement", "EventTarget", "InputEvent"]}
web-sys = {version = "0.3.60", features = ["CssStyleDeclaration", "Event", "HtmlCollection", "HtmlElement", "HtmlInputElement", "HtmlObjectElement", "SvgElement", "CanvasRenderingContext2d", "Document", "HtmlCanvasElement", "EventTarget", "InputEvent", "ScrollLogicalPosition", "ScrollIntoViewOptions"]}
yew = {version = "0.20.0", features = ["csr"] }
yew-hooks = "0.2.0"
yew-agent = "0.3.0"
Expand Down
30 changes: 19 additions & 11 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use monaco::{
IMarkdownString, MarkerSeverity,
}
};
use swim::{parser::parser_assembler_main::parser, ui::{console::component::TabState, swim_editor::component::EditorTabState}};
use swim::{parser::parser_assembler_main::parser, ui::{console::component::ConsoleTabState, swim_editor::component::EditorTabState}};
use swim::parser::parser_structs_and_enums::ProgramInfo;
use std::rc::Rc;
use swim::agent::EmulationCoreAgent;
Expand Down Expand Up @@ -65,7 +65,7 @@ fn app(props: &AppProps) -> Html {

// Store the currently executed line in code editor and hex editor
let editor_curr_line = use_state_eq(|| 0.0);
let memory_curr_line = use_state_eq(|| 0.0);
let memory_curr_instr = use_state_eq(|| 0);

// Output strings for the console and memory viewers.
let parser_text_output = use_state_eq(String::new);
Expand All @@ -84,7 +84,7 @@ fn app(props: &AppProps) -> Html {
let memory_text_model = use_state_eq(|| TextModel::create(&memory_text_output, Some("ini"), None).unwrap());

// Store the currently selected tabs in windows
let console_active_tab = use_state_eq(TabState::default);
let console_active_tab = use_state_eq(ConsoleTabState::default);
let editor_active_tab = use_state_eq(EditorTabState::default);

// Since we want the Datapath to be independent from all the
Expand All @@ -111,6 +111,7 @@ fn app(props: &AppProps) -> Html {
let text_model = text_model.clone();
// let memory_text_model = Rc::clone(&memory_text_model);
let memory_text_model = memory_text_model.clone();
let memory_curr_instr = memory_curr_instr.clone();
// let last_memory_text_model = Rc::clone(&last_memory_text_model);
let last_memory_text_model = last_memory_text_model.clone();
let datapath = Rc::clone(&datapath);
Expand All @@ -124,7 +125,7 @@ fn app(props: &AppProps) -> Html {
let binary_ref = Rc::clone(&binary_ref);

use_callback(
move |_, (text_model, editor_curr_line)| {
move |_, (text_model, editor_curr_line, memory_curr_instr)| {
let mut datapath = datapath.borrow_mut();
let text_model = text_model.clone();
let memory_text_model = memory_text_model.clone();
Expand Down Expand Up @@ -179,6 +180,7 @@ fn app(props: &AppProps) -> Html {
parser_text_output.set(format!("This program failed to load into the datapath. Message returned by datapath: {msg}"));
}
}
memory_curr_instr.set(datapath.registers.pc);
// log!(datapath.memory.to_string());
text_model.set_value(&program_info.updated_monaco_string); // Expands pseudo-instructions to their hardware counterpart.
let hexdump = &datapath.memory.generate_formatted_hex();
Expand All @@ -189,7 +191,7 @@ fn app(props: &AppProps) -> Html {

trigger.force_update();
},
(text_model, editor_curr_line),
(text_model, editor_curr_line, memory_curr_instr),
)
};

Expand All @@ -206,6 +208,7 @@ fn app(props: &AppProps) -> Html {
// let text_model = Rc::clone(&text_model);
let text_model = text_model.clone();
let editor_curr_line = editor_curr_line.clone();
let memory_curr_instr = memory_curr_instr.clone();

// Hex editor
// let memory_text_model = Rc::clone(&memory_text_model);
Expand All @@ -215,7 +218,7 @@ fn app(props: &AppProps) -> Html {
let trigger = use_force_update();

use_callback(
move |_, editor_curr_line| {
move |_, (editor_curr_line, memory_curr_instr)| {
let mut datapath = datapath.borrow_mut();
let text_model = text_model.clone();
// let memory_text_model = Rc::clone(&memory_text_model);
Expand All @@ -231,6 +234,7 @@ fn app(props: &AppProps) -> Html {
let list_of_line_numbers = programinfo.address_to_line_number;
let index = datapath.registers.pc as usize / 4;
editor_curr_line.set(*list_of_line_numbers.get(index).unwrap_or(&0) as f64 + 1.0); // add one to account for the editor's line numbers
memory_curr_instr.set(datapath.registers.pc);

// Execute instruction
datapath.execute_instruction();
Expand All @@ -243,7 +247,7 @@ fn app(props: &AppProps) -> Html {

trigger.force_update();
},
editor_curr_line,
(editor_curr_line, memory_curr_instr),
)
};

Expand All @@ -261,9 +265,10 @@ fn app(props: &AppProps) -> Html {
let memory_text_model = memory_text_model.clone();
// let last_memory_text_model = Rc::clone(&last_memory_text_model);
let last_memory_text_model = last_memory_text_model.clone();
let memory_curr_instr = memory_curr_instr.clone();

use_callback(
move |_, editor_curr_line| {
move |_, (editor_curr_line, memory_curr_instr)| {
let mut datapath = datapath.borrow_mut();

// let memory_text_model = Rc::clone(&memory_text_model);
Expand All @@ -278,6 +283,7 @@ fn app(props: &AppProps) -> Html {
let list_of_line_numbers = programinfo.address_to_line_number;
let index = datapath.registers.pc as usize / 4;
editor_curr_line.set(*list_of_line_numbers.get(index).unwrap_or(&0) as f64 + 1.0);
memory_curr_instr.set(datapath.registers.pc);
datapath.execute_stage();
} else {
datapath.execute_stage();
Expand All @@ -290,7 +296,7 @@ fn app(props: &AppProps) -> Html {
last_memory_text_model.set_value(hexdump);
trigger.force_update();
},
editor_curr_line,
(editor_curr_line, memory_curr_instr),
)
};

Expand Down Expand Up @@ -420,13 +426,15 @@ fn app(props: &AppProps) -> Html {
let memory_text_model = memory_text_model.clone();
// let last_memory_text_model = Rc::clone(&last_memory_text_model);
let last_memory_text_model = last_memory_text_model.clone();
let memory_curr_instr = memory_curr_instr.clone();

use_callback(
move |_, editor_curr_line| {
let mut datapath = datapath.borrow_mut();

// Set highlighted line to 0
editor_curr_line.set(0.0);
memory_curr_instr.set(datapath.registers.pc);

parser_text_output.set("".to_string());
datapath.reset();
Expand Down Expand Up @@ -580,11 +588,11 @@ fn app(props: &AppProps) -> Html {

// Editor
<div class="code">
<SwimEditor text_model={text_model} lines_content={lines_content} program_info={program_info_ref.borrow().clone()} binary={binary_ref.borrow().clone()} memory_curr_line={memory_curr_line.clone()} editor_curr_line={editor_curr_line.clone()} active_tab={editor_active_tab.clone()} pc={(*datapath.borrow()).clone().registers.pc}/>
<SwimEditor text_model={text_model} lines_content={lines_content} program_info={program_info_ref.borrow().clone()} binary={binary_ref.borrow().clone()} memory_curr_instr={memory_curr_instr.clone()} editor_curr_line={editor_curr_line.clone()} editor_active_tab={editor_active_tab.clone()} console_active_tab={console_active_tab.clone()} pc={(*datapath.borrow()).clone().registers.pc}/>
</div>

// Console
<Console parsermsg={(*parser_text_output).clone()} datapath={(*datapath.borrow()).clone()} memory_text_model={memory_text_model} memory_curr_line={memory_curr_line.clone()} active_tab={console_active_tab.clone()}/>
<Console parsermsg={(*parser_text_output).clone()} datapath={(*datapath.borrow()).clone()} memory_text_model={memory_text_model} memory_curr_instr={memory_curr_instr.clone()} active_tab={console_active_tab.clone()}/>
</div>

// Right column
Expand Down
116 changes: 79 additions & 37 deletions src/ui/assembled_view/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,25 @@ use std::cell::RefCell;
use std::rc::Rc;

// use monaco::api::TextModel;
use web_sys::HtmlInputElement;
use web_sys::{HtmlElement, HtmlInputElement};
use yew::{Properties, Html};
use yew::prelude::*;
use wasm_bindgen::JsCast;
use log::debug;
use crate::parser::parser_structs_and_enums::ProgramInfo;
use crate::ui::console::component::ConsoleTabState;
use crate::ui::swim_editor::component::EditorTabState;


#[derive(PartialEq, Properties)]
pub struct TextSegmentProps {
pub program_info: ProgramInfo,
pub lines_content: Rc<RefCell<Vec<String>>>,
pub memory_curr_line: UseStateHandle<f64>,
pub memory_curr_instr: UseStateHandle<u64>,
pub editor_curr_line: UseStateHandle<f64>,
pub pc: u64,
pub active_tab: UseStateHandle<EditorTabState>,
pub editor_active_tab: UseStateHandle<EditorTabState>,
pub console_active_tab: UseStateHandle<ConsoleTabState>
}
#[derive(PartialEq, Properties)]
pub struct DataSegmentProps {
Expand All @@ -31,9 +33,21 @@ pub struct DataSegmentProps {
pub fn TextSegment(props: &TextSegmentProps) -> Html {
let program_info = &props.program_info;
let lines_content = props.lines_content.borrow_mut().clone();
let memory_curr_line = &props.memory_curr_line;
let memory_curr_instr = &props.memory_curr_instr;
let editor_curr_line = &props.editor_curr_line;
let active_tab = &props.active_tab;
let editor_active_tab = &props.editor_active_tab;
let console_active_tab = &props.console_active_tab;
let executed_ref = use_node_ref();

{
// Always scroll to the executed row on re-render
let executed_row = executed_ref.cast::<HtmlElement>();
if let Some(executed_row) = executed_row {
let mut options = web_sys::ScrollIntoViewOptions::new();
options.block(web_sys::ScrollLogicalPosition::Center);
executed_row.scroll_into_view_with_scroll_into_view_options(&options);
}
}

let on_check = Callback::from(move |args: (MouseEvent, i64)| {
let (e, address) = args;
Expand All @@ -47,20 +61,22 @@ pub fn TextSegment(props: &TextSegmentProps) -> Html {
});

let on_address_click = {
let memory_curr_line = memory_curr_line.clone();
use_callback(move |args: (MouseEvent, i64), memory_curr_line| {
let memory_curr_instr = memory_curr_instr.clone();
let console_active_tab = console_active_tab.clone();
use_callback(move |args: (MouseEvent, i64), memory_curr_instr| {
let (_e, address) = args;
memory_curr_line.set((address / 4) as f64);
}, memory_curr_line)
memory_curr_instr.set(address as u64);
console_active_tab.set(ConsoleTabState::HexEditor);
}, memory_curr_instr)
};

let on_assembled_click = {
let editor_curr_line = editor_curr_line.clone();
let active_tab = active_tab.clone();
let editor_active_tab = editor_active_tab.clone();
use_callback(move |args: (MouseEvent, usize), _| {
let (_e, line_number) = args;
editor_curr_line.set(line_number as f64);
active_tab.set(EditorTabState::Editor);
editor_active_tab.set(EditorTabState::Editor);
}, ())
};

Expand All @@ -82,36 +98,62 @@ pub fn TextSegment(props: &TextSegmentProps) -> Html {
let on_check = Callback::clone(&on_check);
let on_address_click = Callback::clone(&on_address_click);
let on_assembled_click = Callback::clone(&on_assembled_click);
let executed_ref = executed_ref.clone();
address += 4;

let line_number = instruction.line_number.clone();

let mut conditional_class = "";
if props.pc as i64 == address {
conditional_class = "executing";
conditional_class = "executedLine";
html!{
<tr ref={executed_ref} key={index} class={classes!("row", conditional_class)}>
<td class={classes!("bkpt")}>
<input type="checkbox" onclick={move |e: MouseEvent| {on_check.emit((e, address))}}/>
<div class="circle"></div>
</td>
<td class="address" title={format!("Go to address {:08x}", address)} onclick={move |e: MouseEvent| {on_address_click.emit((e, address))}}>
{format!("0x{:08x}", address as u64)}
</td>
<td>
{format!("0b{:032b}", instruction.binary)}
</td>
<td>
{format!("0x{:08x}", instruction.binary)}
</td>
<td class="assembled-string" title="Go to line" onclick={move |e: MouseEvent| {on_assembled_click.emit((e, line_number))}}>
{recreated_string}
</td>
<td>
{format!("{}: {:?}", line_number, lines_content.get(line_number).unwrap_or(&String::from("")))}
</td>
</tr>
}
}

let line_number = instruction.line_number.clone();
html!{

<tr key={index} class={classes!("row", conditional_class)}>
<td class={classes!("bkpt")}>
<input type="checkbox" onclick={move |e: MouseEvent| {on_check.emit((e, address))}}/>
<div class="circle"></div>
</td>
<td class="address" title={format!("Go to address {:08x}", address)} onclick={move |e: MouseEvent| {on_address_click.emit((e, address))}}>
{format!("0x{:08x}", address as u64)}
</td>
<td>
{format!("0b{:032b}", instruction.binary)}
</td>
<td>
{format!("0x{:08x}", instruction.binary)}
</td>
<td class="assembled-string" title="Go to line" onclick={move |e: MouseEvent| {on_assembled_click.emit((e, line_number))}}>
{recreated_string}
</td>
<td>
{format!("{}: {:?}", line_number, lines_content.get(line_number).unwrap_or(&String::from("")))}
</td>
</tr>
else {
html!{
<tr key={index} class={classes!("row", conditional_class)}>
<td class={classes!("bkpt")}>
<input type="checkbox" onclick={move |e: MouseEvent| {on_check.emit((e, address))}}/>
<div class="circle"></div>
</td>
<td class="address" title={format!("Go to address {:08x}", address)} onclick={move |e: MouseEvent| {on_address_click.emit((e, address))}}>
{format!("0x{:08x}", address as u64)}
</td>
<td>
{format!("0b{:032b}", instruction.binary)}
</td>
<td>
{format!("0x{:08x}", instruction.binary)}
</td>
<td class="assembled-string" title="Go to line" onclick={move |e: MouseEvent| {on_assembled_click.emit((e, line_number))}}>
{recreated_string}
</td>
<td>
{format!("{}: {:?}", line_number, lines_content.get(line_number).unwrap_or(&String::from("")))}
</td>
</tr>
}
}
}).collect::<Html>()
}
Expand Down
Loading

0 comments on commit 539903a

Please sign in to comment.