-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.astro
130 lines (117 loc) · 3.5 KB
/
index.astro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
---
const base = import.meta.env.BASE_URL === "/" ? "" : import.meta.env.BASE_URL;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href={ base + "/favicon.svg" } />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Rust Browser Interpreter</title>
</head>
<body>
<div id="grid">
<div>
<h1><span>Ru</span>st <span>Br</span>owser <span>I</span>nterpreter</h1>
<b><a href="https://github.com/lyonsyonii/rubri" target="_blank">See on Github</a></b>
</div>
<div id="live-edit-wrapper">
<input id="live-edit" type="checkbox" checked />
<label for="live-edit">Live Edit</label>
<input id="print-last" type="checkbox" checked />
<label for="print-last">Print last expression</label>
</div>
<textarea id="input" spellcheck="false" />
<button>RUN</button>
<div id="terminal" />
</div>
</body>
</html>
<style>
body {
height: 100vh;
font-family: 'Courier New', Courier, monospace;
margin: 0;
padding: 0;
}
#grid {
height: calc(100% - 1rem);
margin-left: 1rem;
margin-right: 1rem;
display: grid;
grid-template-rows: min-content min-content 1fr 5rem 1fr;
gap: .5rem;
}
button {
font-family: inherit;
font-weight: 700;
font-size: x-large;
}
textarea#input {
font-size: x-large;
resize: none;
}
#terminal {
white-space: pre-wrap;
}
#live-edit, #live-edit-wrapper {
user-select: none;
}
span {
text-decoration: underline;
}
</style>
<script>
import { Interpreter } from "../interpreter";
import { setupEditor } from "../editor";
import { AnsiUp } from "ansi_up";
const input = document.body.querySelector<HTMLTextAreaElement>("textarea#input")!;
const runButton = document.body.querySelector<HTMLButtonElement>("button")!;
const liveEdit = document.body.querySelector<HTMLInputElement>("#live-edit")!;
const printLast = document.body.querySelector<HTMLInputElement>("#print-last")!;
const termElement = document.getElementById("terminal")!;
const ansiUp = new AnsiUp();
input.value = "Downloading (Can take a while):";
input.placeholder = "Write your code...";
input.readOnly = true;
// Interpreter initialization
let lastInput = "";
const interpreter = new Interpreter();
// Add libraries downloaded to list
interpreter.onAssetDownloaded(lib => input.value += `\n${lib}`);
// When Interpreter has finished loading, add default code
interpreter.onLoaded(() => {
input.readOnly = false;
input.value = 'println!("Hello from WASM!");';
runButton.click();
// interpreter.run(input.value);
});
// When Interpreter is running disable the "Run" button
interpreter.onRun(() => {
runButton.disabled = true;
termElement.innerHTML = "Running...";
});
// When result is received from a running Interpreter write it to the terminal
interpreter.onResult(result => {
termElement.innerHTML = ansiUp.ansi_to_html(result.replaceAll("\n", "\r"));
runButton.disabled = false;
if (lastInput && lastInput !== input.value) {
input.dispatchEvent(new Event("input"));
}
});
setupEditor(input, runButton);
// Run the Interpreter when on "Live Edit" or the "Run" button is clicked
input.addEventListener("input", async () => {
if (!liveEdit.checked || runButton.disabled) {
return;
}
lastInput = input.value;
interpreter.run(input.value || "", printLast.checked);
});
runButton.addEventListener("click", async () => {
if (runButton.disabled) {
return;
}
interpreter.run(input.value || "", printLast.checked)
});
</script>