Create a state machine with Alpine
This commit is contained in:
parent
063a9e1c06
commit
525e4f5197
@ -99,7 +99,15 @@ function highlightCode(lines: Array<string>): string {
|
|||||||
const codeHtml = highlightCode(trimAndDedent(code));
|
const codeHtml = highlightCode(trimAndDedent(code));
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="bg-black text-white rounded" x-data="editor">
|
<div class="bg-black text-white rounded"
|
||||||
|
x-data={`{
|
||||||
|
line: 0,
|
||||||
|
stdout: "",
|
||||||
|
ip: 0,
|
||||||
|
inst: [["line", 5]],
|
||||||
|
done: false,
|
||||||
|
}`}
|
||||||
|
>
|
||||||
<span class="inline-block bg-[var(--code-theme-bg-acolor)] px-2 rounded-tl rounded-tr font-mono text-sm">thp code</span>
|
<span class="inline-block bg-[var(--code-theme-bg-acolor)] px-2 rounded-tl rounded-tr font-mono text-sm">thp code</span>
|
||||||
<pre class="language-thp" style="margin: 0; border-top-left-radius: 0;" data-disabled><code set:html={codeHtml}></code></pre>
|
<pre class="language-thp" style="margin: 0; border-top-left-radius: 0;" data-disabled><code set:html={codeHtml}></code></pre>
|
||||||
<div class="grid grid-cols-2 font-mono text-sm">
|
<div class="grid grid-cols-2 font-mono text-sm">
|
||||||
@ -117,36 +125,42 @@ const codeHtml = highlightCode(trimAndDedent(code));
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-t border-white p-1">
|
<div class="border-t border-white p-1">
|
||||||
<button class="font-mono px-1 rounded bg-pink-950" @click="next()">
|
<button class="font-mono px-1 rounded bg-pink-950" @click="alpineNext($data)" :disabled="done && 'true'">
|
||||||
Step
|
Step
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
type Instruction = "line" ;
|
||||||
type AlpineState = {
|
type AlpineState = {
|
||||||
line: number,
|
line: number,
|
||||||
stdout: string,
|
stdout: string,
|
||||||
|
ip: number,
|
||||||
|
inst: Array<[Instruction, number]>
|
||||||
|
done: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener("alpine:init", () => {
|
/// Executes the instruction following the state of the machine.
|
||||||
|
function alpineNext(data: AlpineState) {
|
||||||
|
const len = data.inst.length;
|
||||||
|
const ip = data.ip;
|
||||||
|
data.ip += 1;
|
||||||
|
|
||||||
|
const instructionArr = data.inst[ip]!;
|
||||||
|
switch (instructionArr[0]) {
|
||||||
|
case "line": {
|
||||||
|
data.line = Number(instructionArr[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.ip >= len) {
|
||||||
|
console.log("done");
|
||||||
|
data.done = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const Alpine: any = window.Alpine;
|
window.alpineNext = alpineNext;
|
||||||
|
|
||||||
function f(obj: AlpineState) {
|
|
||||||
obj.line += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Alpine.data("editor", () => ({
|
|
||||||
line: 0,
|
|
||||||
stdout: "",
|
|
||||||
next() {
|
|
||||||
f(this);
|
|
||||||
},
|
|
||||||
reset() {
|
|
||||||
this.line = 0;
|
|
||||||
this.stdout = "";
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user