Part of a snippet emulator

This commit is contained in:
2023-01-26 15:14:37 -06:00
parent b3c533b0c6
commit 87daef0fdc
6 changed files with 201 additions and 2 deletions
+41
View File
@@ -0,0 +1,41 @@
body {
display: grid;
grid-template-columns: 1fr auto 1fr;
grid-template-rows: 2em auto;
background: #777777;
}
.react-root {
grid-area: 2 / 2 / 3 / 3;
}
.snippetEmulator {
display: grid;
grid-template-rows: 10em 1em 1em 2em;
grid-template-columns: 20em;
background: #333333;
font-family: monospace;
padding: 0.5em;
}
.snippetEmulator textarea { grid-area: 1 / 1 / 2 / 2 }
.snippetEmulator .src { grid-area: 1 / 1 / 2 / 2 }
.snippetEmulator .message { grid-area: 2 / 1 / 3 / 2 }
.snippetEmulator .buttons { grid-area: 3 / 1 / 4 / 2 }
.snippetEmulator .stacks { grid-area: 4 / 1 / 5 / 2 }
.snippetEmulator textarea {
background: #0f0f0f;
color: #dddddd;
min-height: 10em;
border: none;
resize: vertical;
padding: 0;
border: none;
}
.snippetEmulator textarea:focus { outline: none; }
.snippetEmulator .buttons a {
margin-right: 0.5em;
cursor: pointer;
}
.snippetEmulator .step, .snippetEmulator .run { color: lightgreen }
.snippetEmulator .reset { color: lightcoral }
.snippetEmulator .build, .snippetEmulator .edit { color: dodgerblue }
+69
View File
@@ -0,0 +1,69 @@
import './snippet_emulator.css'
import React, {useState, useCallback, useEffect} from 'react'
import { WasmCPU, assemble_snippet, source_map } from '../pkg/vweb.js'
export default function({ snippet }) {
const [editing, setEditing] = useState(false) // Whether we're editing the snippet or running it
const [src, setSrc] = useState(snippet) // The source code currently set
const [message, setMessage] = useState('') // A status / error message
const onChangeSrc = useCallback((e) => setSrc(e.target.value), []) // Callback for the textarea
const [binary, setBinary] = useState(null) // The assembled binary
const [sourceMap, setSourceMap] = useState({}) // A map from byte address to line number
// A callback to build the binary from source
const rebuild = useCallback((code) => {
try {
const bin = assemble_snippet(code)
const sm = source_map(code)
setBinary(bin)
setSourceMap(sm)
setMessage(`Assembled ${bin.length} bytes`)
console.log(sm.Ok)
return true
} catch(e) {
setMessage(e.message)
}
}, [])
// On load, build the stuff
useEffect(() => { rebuild(snippet) }, [snippet])
if (editing) {
return (
<div className='snippetEmulator'>
<textarea value={src} onChange={onChangeSrc}></textarea>
<div className='message'>{message}</div>
<div className='buttons'>
<a className='build' onClick={() => { rebuild(src) && setEditing(false) }}>[Build]</a>
</div>
</div>
)
} else {
return (
<div className='snippetEmulator'>
<SourceDisplay src={src}/>
<div className='message'>{message}</div>
<div className='buttons'>
<a className='step'>[Step]</a>
<a className='step'>[Run]</a>
<a className='reset'>[Reset]</a>
<a className='edit' onClick={() => { setEditing(true); setMessage('') }}>[Edit]</a>
</div>
</div>
)
}
}
function SourceDisplay({ src }) {
const lines = src.split('\n')
const lineDivs = lines.map((line, i) => {
return (<div key={`line_${i}`}>{line || <>&nbsp;</>}</div>)
})
return (
<div className='src'>{lineDivs}</div>
)
}
function StackDisplay({ data, call }) {
}