Instead of passing a flag through the parser and tokenizer for telling the input source if we need further input or not, we steal a trick from Lua: In the REPL, we just continue to read lines and append them to the input, until the input was loaded with no "unexpected EOF" error. After all, when we didn't expect an EOF is exactly the scenario, when we need more input. Doing things this way simplifies a bunch of places and lets us remove the ugly source_reader and iterative_runner concepts. To allow the REPL to see the error that happened during loading required some smaller refactorings, but those were honestly for the better anyway. I also decided to get rid of the token_source concept, the parser now gets the tokenizer directly. This also made things a bit simpler, also I want to soon-ish implement string interpolation, and for that the parser needs to do more with the tokenizer than just reading the next token. One last thing: This also cleans up the web playground and makes the playground and REPL share a bunch of code. Nice!
95 lines
2.5 KiB
HTML
95 lines
2.5 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>apfl Playground</title>
|
|
<style type="text/css">
|
|
.apfl_playground {
|
|
--bg: #E0E0E0;
|
|
--fg: #101010;
|
|
--err: #FF0086;
|
|
--prompt-bg: #ececec;
|
|
--prompt-placeholder: #555;
|
|
}
|
|
|
|
@media screen and (prefers-color-scheme: dark) {
|
|
html {
|
|
background: #000;
|
|
}
|
|
|
|
.apfl_playground {
|
|
--bg: #101010;
|
|
--fg: #E0E0E0;
|
|
--err: #EC3308;
|
|
--prompt-bg: #333;
|
|
--prompt-placeholder: #ccc;
|
|
}
|
|
}
|
|
|
|
html {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.apfl_playground {
|
|
background: var(--bg);
|
|
color: var(--fg);
|
|
padding: 0;
|
|
border-radius: 4px;
|
|
font-family: monospace;
|
|
font-size: 1em;
|
|
overflow: hidden;
|
|
box-shadow: 2px 2px 4px rgba(0, 0, 0, 30%), 0 0 2px rgba(0,0,0,30%);
|
|
}
|
|
.apfl_playground .error {
|
|
color: var(--err);
|
|
}
|
|
.apfl_playground_output {
|
|
margin: 0;
|
|
padding: 4px 10px 0;
|
|
min-height: 50px;
|
|
max-height: 80vh;
|
|
overflow-y: auto;
|
|
}
|
|
.apfl_playground form {
|
|
display: flex;
|
|
padding: 2px 10px 4px;
|
|
background: var(--prompt-bg);
|
|
margin-top: 2px;
|
|
}
|
|
.apfl_playground_input {
|
|
flex-grow: 1;
|
|
background: transparent;
|
|
border: 0;
|
|
font-family: monospace;
|
|
padding: 0;
|
|
margin: 0;
|
|
font-size: 1em;
|
|
color: inherit;
|
|
}
|
|
.apfl_playground_input::placeholder {
|
|
font-style: italic;
|
|
color: var(--prompt-placeholder);
|
|
}
|
|
.apfl_playground_prompt {
|
|
padding-right: 1ch;
|
|
}
|
|
</style>
|
|
<script type="text/javascript" src="playground.js"></script>
|
|
<script type="text/javascript" src="web_playground.js"></script>
|
|
<script>
|
|
async function playground_init() {
|
|
let Playground = await apfl_playground();
|
|
playground_container.innerHTML = "";
|
|
|
|
(new Playground()).interactive(playground_container);
|
|
}
|
|
</script>
|
|
</head>
|
|
<body onload="playground_init()">
|
|
<div id="playground_container">
|
|
<span>Loading playground....</span>
|
|
</div>
|
|
</body>
|
|
</html>
|