Crude first pass at playground page

This commit is contained in:
2024-11-04 22:30:40 -08:00
parent f225d0ecbd
commit f92d287909
9 changed files with 1209 additions and 0 deletions

13
playground/src/global.d.ts vendored Normal file
View File

@@ -0,0 +1,13 @@
export {}
declare global {
interface Process {
stdout: {
write(s: string): void
},
argv: string[]
}
let files : Record<string,string>
let process : Process
let __mainExpression_0 : () => unknown
}

45
playground/src/main.ts Normal file
View File

@@ -0,0 +1,45 @@
import './style.css'
import {newtLanguage} from './monarch.ts'
import * as monaco from 'monaco-editor'
monaco.languages.setMonarchTokensProvider("newt", newtLanguage);
let container = document.getElementById('editor')!
let result = document.getElementById('result')!
const editor = monaco.editor.create(container, {
value: "module Main\n\n",
language: "newt",
theme: "vs",
automaticLayout: true,
})
let timeout : number | undefined
function run(s: string) {
console.log('run', s)
process.argv = ['','', 'src/Main.newt']
files['src/Main.newt'] = s
result.innerHTML = ''
__mainExpression_0()
}
// We'll want to collect and put info in the monaco
process.stdout.write = (s) => {
console.log('write', s)
let div = document.createElement('div')
div.className = 'log'
div.textContent = s
result.appendChild(div)
}
editor.onDidChangeModelContent((ev) => {
console.log('mc', ev)
let value = editor.getValue()
clearTimeout(timeout)
timeout = setTimeout(() => run(value), 1000)
})
console.log('REGISTER')

67
playground/src/monarch.ts Normal file
View File

@@ -0,0 +1,67 @@
import * as monaco from 'monaco-editor'
export let newtLanguage: monaco.languages.IMonarchLanguage = {
// Set defaultToken to invalid to see what you do not tokenize yet
// defaultToken: 'invalid',
keywords: [
"let",
"in",
"where",
"case",
"of",
"data",
"U",
"module",
"ptype",
"pfunc",
"module",
"infixl",
"infixr",
"infix",
],
specialOps: ["=>", "->", ":", "=", ":="],
tokenizer: {
root: [
[
/[a-z_$][\w$]*/,
{ cases: { "@keywords": "keyword", "@default": "identifier" } },
],
[/[A-Z][\w\$]*/, "type.identifier"],
[/\\|λ/, "keyword"],
{ include: "@whitespace" },
[/[{}()\[\]]/, "@brackets"],
[
/[:!#$%&*+.<=>?@\\^|~\/-]+/,
{
cases: {
"@specialOps": "keyword",
"@default": "operator",
},
},
],
[/\d+/, "number"],
// strings
[/"([^"\\]|\\.)*$/, "string.invalid"], // non-teminated string
[/"/, { token: "string.quote", bracket: "@open", next: "@string" }],
],
comment: [
[/[^-]+/, "comment"],
["-/", "comment", "@pop"],
["-", "comment"],
],
string: [
[/[^\\"]+/, "string"],
// [/@escapes/, "string.escape"],
[/\\./, "string.escape.invalid"],
[/"/, { token: "string.quote", bracket: "@close", next: "@pop" }],
],
whitespace: [
[/[ \t\r\n]+/, "white"],
["/-", "comment", "@comment"],
[/--.*$/, "comment"],
],
},
};

21
playground/src/style.css Normal file
View File

@@ -0,0 +1,21 @@
#app {
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
}
.wrapper {
display: flex;
flex-direction: row;
height: 100%;
}
.wrapper > div {
flex: 1 1;
}
#result {
overflow: auto;
font-family: 'Comic Code', monospace;
font-size: 12px;
white-space: pre;
}