diff --git a/vweb/src/forge_editor_demo.html b/vweb/src/forge_editor_demo.html index 8e36059..03c596a 100644 --- a/vweb/src/forge_editor_demo.html +++ b/vweb/src/forge_editor_demo.html @@ -9,10 +9,20 @@
+        // Welcome! Press [run] to run this, or write your own!
+        // User manual coming soon
+        // -- ross.andrews@gmail.com
+        const str = "Hello, world!";
+
         fn main() {
+          repeat(1200) n {
+            poke(0x10000 + 1200 + n, 0x6f);
+            poke(0x10000 + n, 0);
+          }
+
           var n = 0;
-          while (n < 40 * 30) {
-            asm(72, n + 0x10000) { store }
+          while(peek(str + n)) {
+            poke(0x10000 + 41 + n, peek(str + n));
             n = n + 1;
           }
         }
diff --git a/vweb/src/forge_highlighter.js b/vweb/src/forge_highlighter.js
index 1b8bc58..fc7338b 100644
--- a/vweb/src/forge_highlighter.js
+++ b/vweb/src/forge_highlighter.js
@@ -16,7 +16,7 @@ export default {
             if (word = stream.match(/^[a-zA-Z_$][a-zA-Z0-9_$]*/)) {
                 // This is either a keyword or an identifier.
                 // All the keywords are valid names, so, check that:
-                if (word[0].match(/^fn|var|new|static|asm|return|if|while|repeat|global|const$/)) {
+                if (word[0].match(/^fn|var|new|static|asm|return|if|while|repeat|global|const|peek|poke$/)) {
                     if (word[0] === 'asm') {
                         state.asm = true
                     } // This is the start of an asm control structure
diff --git a/vweb/src/forge_simulator.jsx b/vweb/src/forge_simulator.jsx
index 584a5f7..7408bdd 100644
--- a/vweb/src/forge_simulator.jsx
+++ b/vweb/src/forge_simulator.jsx
@@ -11,6 +11,7 @@ export default function({ src: defaultSrc }) {
     const [cpu, setCpu] = useState(() => new WasmCPU()) // The actual CPU emulator
     const [errors, setErrors] = useState(null) // What's displayed on the compile errors tab
     const [status, setStatus] = useState('') // The contents of the status bar
+    const [stale, setStale] = useState(false) // Whether the editor has been changed since the last build
     // Whether the emulator should be running. Has to be a ref because the CPU setTimeout loop won't ever see changes in it otherwise
     const running = useRef(false)
 
@@ -59,6 +60,7 @@ export default function({ src: defaultSrc }) {
     // When we update the src, also update the key in localStorage
     const updateSrc = useCallback((newSrc) => {
         setSrc(newSrc)
+        setStale(true)
         window.localStorage.setItem(currentFile, newSrc)
     }, [currentFile])
 
@@ -71,6 +73,7 @@ export default function({ src: defaultSrc }) {
             setBinary(bin) // Store that
             setStatus(`Compiled ${bin.length} bytes`) // Success!
             setErrors(null) // Clear the old error messages off the tab
+            setStale(false)
             return { bin, errors: null }
         } catch (err) {
             if (err.message) { err = err.message } // How we get this differs between forge and asm
@@ -84,7 +87,7 @@ export default function({ src: defaultSrc }) {
     // Callback for the run button
     const run = useCallback(() => {
         let bin = binary
-        if (!bin) {
+        if (!bin || stale) {
             const result = build()
             if (result.errors) { return }
             else { bin = result.bin }
@@ -105,7 +108,7 @@ export default function({ src: defaultSrc }) {
             }
         }
         setTimeout(time_slice, 0)
-    }, [cpu, binary, running, build])
+    }, [cpu, binary, running, build, stale])
 
     const reset = useCallback(() => {
         running.current = false