Create a state machine with Alpine

master
Araozu 2024-05-19 21:47:31 -05:00
parent 063a9e1c06
commit 525e4f5197
1 changed files with 34 additions and 20 deletions

View File

@ -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.
// @ts-ignore function alpineNext(data: AlpineState) {
const Alpine: any = window.Alpine; const len = data.inst.length;
const ip = data.ip;
data.ip += 1;
function f(obj: AlpineState) { const instructionArr = data.inst[ip]!;
obj.line += 1; switch (instructionArr[0]) {
case "line": {
data.line = Number(instructionArr[1]);
break;
}
} }
Alpine.data("editor", () => ({ if (data.ip >= len) {
line: 0, console.log("done");
stdout: "", data.done = true;
next() { return;
f(this); }
}, }
reset() { // @ts-ignore
this.line = 0; window.alpineNext = alpineNext;
this.stdout = "";
},
}));
});
</script> </script>