├── languages ├── brainfuck │ ├── tests │ │ ├── cat.txt │ │ ├── helloworld-subzero.txt │ │ ├── cellsize.txt │ │ ├── helloworld.txt │ │ └── index.test.ts │ ├── engine.ts │ ├── index.ts │ ├── README.md │ ├── renderer.tsx │ └── common.ts ├── deadfish │ ├── tests │ │ ├── 288.txt │ │ ├── zero1.txt │ │ ├── zero2.txt │ │ ├── helloworld.txt │ │ └── index.test.ts │ ├── engine.ts │ ├── index.ts │ ├── README.md │ ├── renderer.tsx │ ├── constants.ts │ └── runtime.ts ├── befunge93 │ ├── tests │ │ ├── samples │ │ │ ├── cat.txt │ │ │ ├── quine3.txt │ │ │ ├── factorial.txt │ │ │ ├── quine1.txt │ │ │ ├── helloworld.txt │ │ │ ├── dna.txt │ │ │ ├── quine2.txt │ │ │ └── prime-sieve.txt │ │ └── index.test.ts │ ├── engine.ts │ ├── index.ts │ ├── input-stream.ts │ ├── constants.ts │ ├── README.md │ └── renderer.tsx ├── chef │ ├── engine.ts │ ├── index.ts │ ├── renderer │ │ ├── utils.tsx │ │ ├── index.tsx │ │ ├── ingredients-pane.tsx │ │ ├── kitchen-display.tsx │ │ └── bowl-dish-columns.tsx │ ├── parser │ │ ├── constants.ts │ │ └── regex.ts │ ├── tests │ │ ├── samples │ │ │ ├── hello-world-souffle.txt │ │ │ ├── fibonacci-fromage.txt │ │ │ └── hello-world-cake.txt │ │ └── index.test.ts │ ├── runtime │ │ └── input-stream.ts │ ├── README.md │ └── constants.ts ├── shakespeare │ ├── engine.ts │ ├── index.ts │ ├── renderer │ │ ├── character-row.tsx │ │ ├── topbar.tsx │ │ └── index.tsx │ ├── parser │ │ ├── generate-cst-types.ts │ │ ├── index.ts │ │ └── constants.ts │ ├── tests │ │ ├── index.test.ts │ │ ├── reverse.txt │ │ ├── primes.txt │ │ └── helloworld.txt │ ├── input-stream.ts │ ├── README.md │ └── common.ts ├── engine-utils.ts ├── test-utils.ts ├── ui-utils.tsx ├── worker-constants.ts ├── worker-errors.ts ├── types.ts └── setup-worker.ts ├── .eslintrc.json ├── public ├── favicon.ico └── vercel.svg ├── ui ├── assets │ ├── logo.png │ ├── guide-info-btn.png │ ├── guide-breakpoints.png │ ├── guide-exec-controls.png │ └── guide-syntax-check.png ├── providers │ ├── index.tsx │ ├── features-guide-provider.tsx │ ├── dark-mode-provider.tsx │ └── error-boundary-provider.tsx ├── code-editor │ ├── use-editor-lang-config.ts │ ├── use-code-validator.ts │ ├── monaco-utils.ts │ ├── use-editor-breakpoints.ts │ ├── themes │ │ ├── dark.json │ │ └── light.json │ └── index.tsx ├── input-editor.tsx ├── renderer-wrapper.tsx ├── MainLayout.tsx ├── output-viewer.tsx ├── header.tsx ├── custom-icons.tsx ├── execution-controls.tsx ├── features-guide.tsx └── Mainframe.tsx ├── next.config.js ├── scripts ├── new-lang-template │ ├── engine.ts │ ├── renderer.tsx │ ├── index.ts │ ├── common.ts │ ├── runtime.ts │ ├── ide-page.tsx │ └── README.md └── add-new-language.js ├── worker-pack ├── webpack.prod.js ├── webpack.dev.js ├── tsconfig.json └── webpack.common.js ├── next-env.d.ts ├── pages ├── languages.json ├── ide │ ├── chef.tsx │ ├── deadfish.tsx │ ├── befunge93.tsx │ ├── brainfuck.tsx │ └── shakespeare.tsx ├── _app.tsx └── index.tsx ├── styles ├── editor.css ├── globals.css └── mosaic.scss ├── tsconfig.json ├── .gitignore ├── jest.config.js ├── LICENSE ├── package.json └── README.md /languages/brainfuck/tests/cat.txt: -------------------------------------------------------------------------------- 1 | ,[.,] -------------------------------------------------------------------------------- /languages/deadfish/tests/288.txt: -------------------------------------------------------------------------------- 1 | diissisdo -------------------------------------------------------------------------------- /languages/deadfish/tests/zero1.txt: -------------------------------------------------------------------------------- 1 | iissso -------------------------------------------------------------------------------- /languages/befunge93/tests/samples/cat.txt: -------------------------------------------------------------------------------- 1 | ~:1+!#@_, -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /languages/befunge93/tests/samples/quine3.txt: -------------------------------------------------------------------------------- 1 | <@,+2*48_,#! #:<,_$#-:#*8#4<8" -------------------------------------------------------------------------------- /languages/deadfish/tests/zero2.txt: -------------------------------------------------------------------------------- 1 | iissisdddddddddddddddddddddddddddddddddo -------------------------------------------------------------------------------- /languages/befunge93/tests/samples/factorial.txt: -------------------------------------------------------------------------------- 1 | &>:1-:v v *_$.@ 2 | ^ _$>\:^ -------------------------------------------------------------------------------- /languages/befunge93/tests/samples/quine1.txt: -------------------------------------------------------------------------------- 1 | 01->1# +# :# 0# g# ,# :# 5# 8# *# 4# +# -# _@ -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilaymaj/esolang-park/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /ui/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilaymaj/esolang-park/HEAD/ui/assets/logo.png -------------------------------------------------------------------------------- /languages/befunge93/tests/samples/helloworld.txt: -------------------------------------------------------------------------------- 1 | "!dlroW ,olleH">:v 2 | |,< 3 | @ -------------------------------------------------------------------------------- /ui/assets/guide-info-btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilaymaj/esolang-park/HEAD/ui/assets/guide-info-btn.png -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | module.exports = { 3 | reactStrictMode: true, 4 | }; 5 | -------------------------------------------------------------------------------- /ui/assets/guide-breakpoints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilaymaj/esolang-park/HEAD/ui/assets/guide-breakpoints.png -------------------------------------------------------------------------------- /ui/assets/guide-exec-controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilaymaj/esolang-park/HEAD/ui/assets/guide-exec-controls.png -------------------------------------------------------------------------------- /ui/assets/guide-syntax-check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nilaymaj/esolang-park/HEAD/ui/assets/guide-syntax-check.png -------------------------------------------------------------------------------- /languages/befunge93/tests/samples/dna.txt: -------------------------------------------------------------------------------- 1 | 7^DN>vA 2 | v_#v? v 3 | 7^<"""" 4 | 3 ACGT 5 | 90!"""" 6 | 4*:>>>v 7 | +8^-1,< 8 | > ,+,@) -------------------------------------------------------------------------------- /languages/befunge93/tests/samples/quine2.txt: -------------------------------------------------------------------------------- 1 | 0 v 2 | "<@_ #! #: #,<*2-1*92,*84,*25,+*92*4*55.0 -------------------------------------------------------------------------------- /languages/chef/engine.ts: -------------------------------------------------------------------------------- 1 | import { setupWorker } from "../setup-worker"; 2 | import ChefRuntime from "./runtime"; 3 | 4 | setupWorker(new ChefRuntime()); 5 | -------------------------------------------------------------------------------- /languages/shakespeare/engine.ts: -------------------------------------------------------------------------------- 1 | import { setupWorker } from "../setup-worker"; 2 | import XYZLanguageEngine from "./runtime"; 3 | 4 | setupWorker(new XYZLanguageEngine()); 5 | -------------------------------------------------------------------------------- /languages/deadfish/engine.ts: -------------------------------------------------------------------------------- 1 | import { setupWorker } from "../setup-worker"; 2 | import DeadfishLanguageEngine from "./runtime"; 3 | 4 | setupWorker(new DeadfishLanguageEngine()); 5 | -------------------------------------------------------------------------------- /languages/befunge93/engine.ts: -------------------------------------------------------------------------------- 1 | import { setupWorker } from "../setup-worker"; 2 | import Befunge93LanguageEngine from "./runtime"; 3 | 4 | setupWorker(new Befunge93LanguageEngine()); 5 | -------------------------------------------------------------------------------- /languages/brainfuck/engine.ts: -------------------------------------------------------------------------------- 1 | import { setupWorker } from "../setup-worker"; 2 | import BrainfuckLanguageEngine from "./runtime"; 3 | 4 | setupWorker(new BrainfuckLanguageEngine()); 5 | -------------------------------------------------------------------------------- /languages/brainfuck/tests/helloworld-subzero.txt: -------------------------------------------------------------------------------- 1 | >++++++++[-<+++++++++>]<.>>+>-[+]++>++>+++[>[->+++<<+++>]<<]>-----.>-> 2 | +++..+++.>-.<<+[>[+>+]>>]<--------------.>>.+++.------.--------.>+.>+. -------------------------------------------------------------------------------- /scripts/new-lang-template/engine.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { setupWorker } from "../setup-worker"; 3 | import XYZLanguageEngine from "./runtime"; 4 | 5 | setupWorker(new XYZLanguageEngine()); 6 | -------------------------------------------------------------------------------- /worker-pack/webpack.prod.js: -------------------------------------------------------------------------------- 1 | const { merge } = require("webpack-merge"); 2 | const common = require("./webpack.common.js"); 3 | 4 | module.exports = merge(common, { 5 | mode: "production", 6 | }); 7 | -------------------------------------------------------------------------------- /languages/befunge93/tests/samples/prime-sieve.txt: -------------------------------------------------------------------------------- 1 | 2>:3g" "-!v\ g30 < 2 | |!`"$":+1_:.:03p>03g+:"$"`| 3 | @ ^ p3\" ":< 4 | 2 234567890123456789012345678901234567890123456789012345678901234567890123456789 -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /worker-pack/webpack.dev.js: -------------------------------------------------------------------------------- 1 | const { merge } = require("webpack-merge"); 2 | const common = require("./webpack.common.js"); 3 | 4 | module.exports = merge(common, { 5 | mode: "development", 6 | devtool: "inline-source-map", 7 | }); 8 | -------------------------------------------------------------------------------- /languages/deadfish/tests/helloworld.txt: -------------------------------------------------------------------------------- 1 | iisiiiisiiiiiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiooiiio 2 | dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddo 3 | dddddddddddddddddddddsddoddddddddoiiioddddddoddddddddo -------------------------------------------------------------------------------- /scripts/new-lang-template/renderer.tsx: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { RendererProps } from "../types"; 3 | import { RS } from "./common"; 4 | 5 | export const Renderer = ({ state }: RendererProps) => { 6 | return state == null ? null :

state.value

; 7 | }; 8 | -------------------------------------------------------------------------------- /languages/shakespeare/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "./renderer"; 2 | import { LanguageProvider } from "../types"; 3 | import { RS, sampleProgram, editorTokensProvider } from "./common"; 4 | 5 | const provider: LanguageProvider = { 6 | Renderer, 7 | sampleProgram, 8 | editorTokensProvider, 9 | }; 10 | 11 | export default provider; 12 | -------------------------------------------------------------------------------- /languages/brainfuck/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "./renderer"; 2 | import { LanguageProvider } from "../types"; 3 | import { BFRS, sampleProgram, editorTokensProvider } from "./common"; 4 | 5 | const provider: LanguageProvider = { 6 | Renderer, 7 | sampleProgram, 8 | editorTokensProvider, 9 | }; 10 | 11 | export default provider; 12 | -------------------------------------------------------------------------------- /languages/deadfish/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "./renderer"; 2 | import { LanguageProvider } from "../types"; 3 | import { DFRS, sampleProgram, editorTokensProvider } from "./constants"; 4 | 5 | const provider: LanguageProvider = { 6 | Renderer, 7 | sampleProgram, 8 | editorTokensProvider, 9 | }; 10 | 11 | export default provider; 12 | -------------------------------------------------------------------------------- /languages/befunge93/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "./renderer"; 2 | import { LanguageProvider } from "../types"; 3 | import { Bfg93RS, sampleProgram, editorTokensProvider } from "./constants"; 4 | 5 | const provider: LanguageProvider = { 6 | Renderer, 7 | sampleProgram, 8 | editorTokensProvider, 9 | }; 10 | 11 | export default provider; 12 | -------------------------------------------------------------------------------- /scripts/new-lang-template/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { Renderer } from "./renderer"; 3 | import { LanguageProvider } from "../types"; 4 | import { RS, sampleProgram, editorTokensProvider } from "./common"; 5 | 6 | const provider: LanguageProvider = { 7 | Renderer, 8 | sampleProgram, 9 | editorTokensProvider, 10 | }; 11 | 12 | export default provider; 13 | -------------------------------------------------------------------------------- /languages/chef/index.ts: -------------------------------------------------------------------------------- 1 | import { Renderer } from "./renderer"; 2 | import { LanguageProvider } from "../types"; 3 | import { ChefRS } from "./types"; 4 | import { sampleProgram, editorTokensProvider } from "./constants"; 5 | 6 | const provider: LanguageProvider = { 7 | Renderer, 8 | sampleProgram, 9 | editorTokensProvider, 10 | }; 11 | 12 | export default provider; 13 | -------------------------------------------------------------------------------- /pages/languages.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "display": "Befunge-93", 4 | "id": "befunge93" 5 | }, 6 | { 7 | "display": "Brainfuck", 8 | "id": "brainfuck" 9 | }, 10 | { 11 | "display": "Chef", 12 | "id": "chef" 13 | }, 14 | { 15 | "display": "Deadfish", 16 | "id": "deadfish" 17 | }, 18 | { 19 | "display": "Shakespeare", 20 | "id": "shakespeare" 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /styles/editor.css: -------------------------------------------------------------------------------- 1 | .code-highlight { 2 | background-color: #ffff0055; 3 | } 4 | 5 | .breakpoint-glyph { 6 | box-sizing: border-box; 7 | padding: 6%; /* Make the dot smaller in size */ 8 | margin-top: 2px; /* Fix dot appearing slightly above baseline */ 9 | border-radius: 50%; 10 | background-clip: content-box; 11 | } 12 | 13 | .breakpoint-glyph.solid { 14 | background-color: #ff5555 !important; 15 | } 16 | 17 | .breakpoint-glyph.hint { 18 | background-color: #ff555555; 19 | } 20 | -------------------------------------------------------------------------------- /worker-pack/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "outDir": "./dist/", 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "sourceMap": true, 16 | "incremental": true, 17 | "noImplicitAny": true 18 | }, 19 | } -------------------------------------------------------------------------------- /languages/chef/renderer/utils.tsx: -------------------------------------------------------------------------------- 1 | import { Icon } from "@blueprintjs/core"; 2 | import { Colors } from "@blueprintjs/core"; 3 | 4 | /** Common border color for dark and light, using transparency */ 5 | export const BorderColor = Colors.GRAY3 + "55"; 6 | 7 | /** Map from item type to corresponding icon */ 8 | export const ItemTypeIcons: { [k: string]: React.ReactNode } = { 9 | dry: , 10 | liquid: , 11 | unknown: , 12 | }; 13 | -------------------------------------------------------------------------------- /languages/deadfish/README.md: -------------------------------------------------------------------------------- 1 | # Deadfish 2 | 3 | Deadfish is a dead-simple esolang created by Jonathan Todd Skinner. Four straightforward commands, no conditionals, 4 | no loops. It was the second language to be added to Esolang Park simply because I was feeling a bit lazy. The 5 | [esolangs wiki page](https://esolangs.org/wiki/Deadfish) is the only resource used for this implementation. 6 | 7 | In all honesty, Esolang Park does not do Deadfish justice. Deadfish is designed for writing highly interactive 8 | programs, but due to the lack of support for interactive input a lot of Deadfish's power is taken away. 9 | -------------------------------------------------------------------------------- /languages/deadfish/renderer.tsx: -------------------------------------------------------------------------------- 1 | import { RendererProps } from "../types"; 2 | import { DFRS } from "./constants"; 3 | 4 | const styles = { 5 | container: { 6 | width: "100%", 7 | height: "100%", 8 | display: "flex", 9 | alignItems: "center", 10 | justifyContent: "center", 11 | }, 12 | text: { 13 | fontSize: "4em", 14 | }, 15 | }; 16 | 17 | export const Renderer = ({ state }: RendererProps) => { 18 | const value = state == null ? 0 : state.value; 19 | return ( 20 |
21 |

{value}

22 |
23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /pages/ide/chef.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { NextPage } from "next"; 3 | import Head from "next/head"; 4 | import { Mainframe } from "../../ui/Mainframe"; 5 | import LangProvider from "../../languages/chef"; 6 | const LANG_ID = "chef"; 7 | const LANG_NAME = "Chef"; 8 | 9 | const IDE: NextPage = () => { 10 | return ( 11 | <> 12 | 13 | {LANG_NAME} | Esolang Park 14 | 15 | 20 | 21 | ); 22 | }; 23 | 24 | export default IDE; 25 | -------------------------------------------------------------------------------- /scripts/new-lang-template/common.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { MonacoTokensProvider } from "../types"; 3 | 4 | /** Type of props passed to renderer */ 5 | export type RS = { 6 | value: number; 7 | }; 8 | 9 | /** Sample program */ 10 | export const sampleProgram = `Program line 1 11 | Program line 2 12 | Program line 3`; 13 | 14 | /** Syntax highlighting */ 15 | export const editorTokensProvider: MonacoTokensProvider = { 16 | tokenizer: { 17 | root: [ 18 | [/i/, "variable"], 19 | [/d/, "keyword"], 20 | [/s/, "constant"], 21 | [/o/, "operator"], 22 | ], 23 | }, 24 | defaultToken: "comment", 25 | }; 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true 17 | }, 18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 19 | "exclude": ["node_modules", "scripts/*/*.ts", "scripts/*/*.tsx"] 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | 36 | # typescript 37 | *.tsbuildinfo 38 | 39 | # bundled worker scripts 40 | public/workers 41 | -------------------------------------------------------------------------------- /pages/ide/deadfish.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { NextPage } from "next"; 3 | import Head from "next/head"; 4 | import { Mainframe } from "../../ui/Mainframe"; 5 | import LangProvider from "../../languages/deadfish"; 6 | const LANG_ID = "deadfish"; 7 | const LANG_NAME = "Deadfish"; 8 | 9 | const IDE: NextPage = () => { 10 | return ( 11 | <> 12 | 13 | {LANG_NAME} | Esolang Park 14 | 15 | 20 | 21 | ); 22 | }; 23 | 24 | export default IDE; 25 | -------------------------------------------------------------------------------- /pages/ide/befunge93.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { NextPage } from "next"; 3 | import Head from "next/head"; 4 | import { Mainframe } from "../../ui/Mainframe"; 5 | import LangProvider from "../../languages/befunge93"; 6 | const LANG_ID = "befunge93"; 7 | const LANG_NAME = "Befunge-93"; 8 | 9 | const IDE: NextPage = () => { 10 | return ( 11 | <> 12 | 13 | {LANG_NAME} | Esolang Park 14 | 15 | 20 | 21 | ); 22 | }; 23 | 24 | export default IDE; 25 | -------------------------------------------------------------------------------- /pages/ide/brainfuck.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { NextPage } from "next"; 3 | import Head from "next/head"; 4 | import { Mainframe } from "../../ui/Mainframe"; 5 | import LangProvider from "../../languages/brainfuck"; 6 | const LANG_ID = "brainfuck"; 7 | const LANG_NAME = "Brainfuck"; 8 | 9 | const IDE: NextPage = () => { 10 | return ( 11 | <> 12 | 13 | {LANG_NAME} | Esolang Park 14 | 15 | 20 | 21 | ); 22 | }; 23 | 24 | export default IDE; 25 | -------------------------------------------------------------------------------- /scripts/new-lang-template/runtime.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { LanguageEngine, StepExecutionResult } from "../types"; 3 | import { RS } from "./common"; 4 | 5 | export default class XYZLanguageEngine implements LanguageEngine { 6 | resetState() { 7 | // TODO: Unimplemented 8 | } 9 | 10 | validateCode(code: string) { 11 | // TODO: Unimplemented 12 | } 13 | 14 | prepare(code: string, input: string) { 15 | // TODO: Unimplemented 16 | } 17 | 18 | executeStep(): StepExecutionResult { 19 | // TODO: Unimplemented 20 | return { rendererState: { value: 0 }, nextStepLocation: { startLine: 0 } }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /pages/ide/shakespeare.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { NextPage } from "next"; 3 | import Head from "next/head"; 4 | import { Mainframe } from "../../ui/Mainframe"; 5 | import LangProvider from "../../languages/shakespeare"; 6 | const LANG_ID = "shakespeare"; 7 | const LANG_NAME = "Shakespeare"; 8 | 9 | const IDE: NextPage = () => { 10 | return ( 11 | <> 12 | 13 | {LANG_NAME} | Esolang Park 14 | 15 | 20 | 21 | ); 22 | }; 23 | 24 | export default IDE; 25 | -------------------------------------------------------------------------------- /languages/brainfuck/tests/cellsize.txt: -------------------------------------------------------------------------------- 1 | Calculate the value 256 and test if it's zero 2 | If the interpreter errors on overflow this is where it'll happen 3 | ++++++++[>++++++++<-]>[<++++>-] 4 | +<[>-< 5 | Not zero so multiply by 256 again to get 65536 6 | [>++++<-]>[<++++++++>-]<[>++++++++<-] 7 | +>[> 8 | # Print "32" 9 | ++++++++++[>+++++<-]>+.-.[-]< 10 | <[-]<->] <[>> 11 | # Print "16" 12 | +++++++[>+++++++<-]>.+++++.[-]< 13 | <<-]] >[> 14 | # Print "8" 15 | ++++++++[>+++++++<-]>.[-]< 16 | <-]< 17 | # Print " bit cells" 18 | +++++++++++[>+++>+++++++++>+++++++++>+<<<<-]>-.>-.+++++++.+++++++++++.<. 19 | >>.++.+++++++..<-.>>- -------------------------------------------------------------------------------- /scripts/new-lang-template/ide-page.tsx: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import React from "react"; 3 | import { NextPage } from "next"; 4 | import Head from "next/head"; 5 | import { Mainframe } from "../../ui/Mainframe"; 6 | import LangProvider from "../../languages/$LANG_ID"; 7 | const LANG_ID = "$LANG_ID"; 8 | const LANG_NAME = "$LANG_NAME"; 9 | 10 | const IDE: NextPage = () => { 11 | return ( 12 | <> 13 | 14 | {LANG_NAME} | Esolang Park 15 | 16 | 21 | 22 | ); 23 | }; 24 | 25 | export default IDE; 26 | -------------------------------------------------------------------------------- /languages/shakespeare/renderer/character-row.tsx: -------------------------------------------------------------------------------- 1 | import { Box } from "../../ui-utils"; 2 | import { CharacterValue } from "../common"; 3 | 4 | type Props = { 5 | name: string; 6 | value: CharacterValue; 7 | }; 8 | 9 | export const CharacterRow = (props: Props) => { 10 | const { name, value } = props; 11 | 12 | return ( 13 |
14 |
15 | {name}:{" "} 16 |
{value.value}
17 | {value.stack.map((v, i) => ( 18 | {v} 19 | ))} 20 |
21 |
22 |
23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /ui/providers/index.tsx: -------------------------------------------------------------------------------- 1 | import { DarkModeProvider } from "./dark-mode-provider"; 2 | import { ErrorBoundaryProvider } from "./error-boundary-provider"; 3 | import { FeaturesGuideProvider } from "./features-guide-provider"; 4 | 5 | type Props = { 6 | omitFeatureGuide?: boolean; 7 | children: React.ReactNode; 8 | }; 9 | 10 | export const Providers = (props: Props) => { 11 | return ( 12 | 13 | 14 | {props.omitFeatureGuide ? ( 15 | props.children 16 | ) : ( 17 | {props.children} 18 | )} 19 | 20 | 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /languages/shakespeare/parser/generate-cst-types.ts: -------------------------------------------------------------------------------- 1 | import { writeFileSync } from "fs"; 2 | import { resolve } from "path"; 3 | import { generateCstDts } from "chevrotain"; 4 | import { ShakespeareParser } from "./parser"; 5 | 6 | /** 7 | * This script generates CST types for the Shakespeare parser. 8 | * To run: `yarn ts-node $(pwd)/generate-cst-types.ts` in this directory. 9 | * 10 | * The `$(pwd)` makes the path absolute. Due to some reason, relative paths with ts-node 11 | * aren't working on my side. 12 | */ 13 | 14 | const productions = new ShakespeareParser().getGAstProductions(); 15 | const dtsString = generateCstDts(productions); 16 | 17 | const dtsPath = resolve(__dirname, "./cst.d.ts"); 18 | writeFileSync(dtsPath, dtsString); 19 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | const nextJest = require("next/jest"); 2 | 3 | const createJestConfig = nextJest({ 4 | // Provide the path to your Next.js app to load next.config.js and .env files in your test environment 5 | dir: "./", 6 | }); 7 | 8 | // Add any custom config to be passed to Jest 9 | const customJestConfig = { 10 | // setupFilesAfterEnv: ["/jest.setup.js"], 11 | // if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work 12 | // moduleDirectories: ["node_modules", "/"], 13 | testEnvironment: "jest-environment-node", 14 | }; 15 | 16 | // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async 17 | module.exports = createJestConfig(customJestConfig); 18 | -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | @import "@blueprintjs/core/lib/css/blueprint.css"; 2 | @import "@blueprintjs/icons/lib/css/blueprint-icons.css"; 3 | @import "react-mosaic-component/react-mosaic-component.css"; 4 | 5 | html, 6 | body, 7 | #__next { 8 | padding: 0; 9 | margin: 0; 10 | width: 100%; 11 | height: 100vh; 12 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 13 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 14 | } 15 | 16 | a { 17 | color: inherit; 18 | text-decoration: none; 19 | } 20 | 21 | * { 22 | box-sizing: border-box; 23 | } 24 | 25 | .esolang-notes-hint { 26 | transition: all 0.1s; 27 | transform-origin: 100% 50%; 28 | } 29 | 30 | .esolang-notes-hint.hide { 31 | transform: scaleX(0); 32 | } 33 | -------------------------------------------------------------------------------- /ui/code-editor/use-editor-lang-config.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useMonaco } from "@monaco-editor/react"; 3 | import { MonacoTokensProvider } from "../../languages/types"; 4 | 5 | type ConfigParams = { 6 | languageId: string; 7 | tokensProvider?: MonacoTokensProvider; 8 | }; 9 | 10 | /** Add custom language and relevant providers to Monaco */ 11 | export const useEditorLanguageConfig = (params: ConfigParams) => { 12 | const monaco = useMonaco(); 13 | 14 | React.useEffect(() => { 15 | if (!monaco) return; 16 | 17 | // Register language 18 | monaco.languages.register({ id: params.languageId }); 19 | 20 | // If provided, register token provider for language 21 | if (params.tokensProvider) { 22 | monaco.languages.setMonarchTokensProvider( 23 | params.languageId, 24 | params.tokensProvider 25 | ); 26 | } 27 | }, [monaco]); 28 | }; 29 | -------------------------------------------------------------------------------- /worker-pack/webpack.common.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs"); 3 | 4 | const langNames = fs.readdirSync("languages").filter((name) => { 5 | const stats = fs.statSync(`./languages/${name}`); 6 | return stats.isDirectory(); 7 | }); 8 | 9 | const entryPoints = {}; 10 | for (const lang of langNames) { 11 | entryPoints[lang] = `./languages/${lang}/engine.ts`; 12 | } 13 | 14 | module.exports = { 15 | entry: entryPoints, 16 | output: { 17 | path: path.resolve(__dirname, "../public/workers"), 18 | filename: "[name].js", 19 | }, 20 | resolve: { extensions: [".ts", ".js"] }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.tsx?$/, 25 | loader: "ts-loader", 26 | exclude: /node_modules/, 27 | options: { 28 | configFile: path.resolve(__dirname, "tsconfig.json"), 29 | }, 30 | }, 31 | ], 32 | }, 33 | }; 34 | -------------------------------------------------------------------------------- /languages/engine-utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * For given ASCII code, returns character that is safe to insert into code. 3 | * 4 | * This is useful for self-modifying programs that may insert non-printable characters into 5 | * the source code at runtime. Characters like `\n`, `\r` and `Tab` distort the grid visually 6 | * in the code editor. This function replaces such characters with safely printable alts. Other 7 | * control characters will be safely rendered by the code editor. 8 | * 9 | * @param asciiVal ASCII value to get safe character for 10 | * @returns Character safe to print without distorting code 11 | */ 12 | export const toSafePrintableChar = (asciiVal: number): string => { 13 | // "\n" -> "⤶" 14 | if (asciiVal === 10) return "\u21b5"; 15 | // "\r" -> "␍" 16 | else if (asciiVal === 13) return "\u240d"; 17 | // Tab -> "⇆" 18 | else if (asciiVal === 9) return "\u21c6"; 19 | else return String.fromCharCode(asciiVal); 20 | }; 21 | -------------------------------------------------------------------------------- /languages/chef/parser/constants.ts: -------------------------------------------------------------------------------- 1 | import { ChefArithmeticOp } from "../types"; 2 | 3 | /** Ingredient measures considered as dry */ 4 | export const DryMeasures = ["g", "kg", "pinch", "pinches"]; 5 | 6 | /** Ingredient measures considered as liquid */ 7 | export const LiquidMeasures = ["ml", "l", "dash", "dashes"]; 8 | 9 | /** Ingredient measures that may be dry or liquid */ 10 | export const UnknownMeasures = [ 11 | "cup", 12 | "cups", 13 | "teaspoon", 14 | "teaspoons", 15 | "tablespoon", 16 | "tablespoons", 17 | ]; 18 | 19 | /** Types of measures - irrelevant to execution */ 20 | export const MeasureTypes = ["heaped", "level"]; 21 | 22 | /** A map from arithmetic instruction verbs to op codes */ 23 | export const ArithmeticCodes: { [k: string]: ChefArithmeticOp["code"] } = { 24 | Add: "ADD", 25 | Remove: "SUBTRACT", 26 | Combine: "MULTIPLY", 27 | Divide: "DIVIDE", 28 | }; 29 | 30 | /** Placeholder value for loop jump addresses */ 31 | export const JumpAddressPlaceholder = -1; 32 | -------------------------------------------------------------------------------- /languages/chef/tests/samples/hello-world-souffle.txt: -------------------------------------------------------------------------------- 1 | Hello World Souffle. 2 | 3 | ==== Source: David Morgan-Mar, https://www.dangermouse.net/esoteric/chef_hello.html ==== 4 | This recipe prints the immortal words "Hello world!", in a basically brute force way. It also makes a lot of food for one person. 5 | 6 | Ingredients. 7 | 72 g haricot beans 8 | 101 eggs 9 | 108 g lard 10 | 111 cups oil 11 | 32 zucchinis 12 | 119 ml water 13 | 114 g red salmon 14 | 100 g dijon mustard 15 | 33 potatoes 16 | 17 | Method. 18 | Put potatoes into the mixing bowl. Put dijon mustard into the mixing bowl. Put lard into the mixing bowl. Put red salmon into the mixing bowl. Put oil into the mixing bowl. Put water into the mixing bowl. Put zucchinis into the mixing bowl. Put oil into the mixing bowl. Put lard into the mixing bowl. Put lard into the mixing bowl. Put eggs into the mixing bowl. Put haricot beans into the mixing bowl. Liquefy contents of the mixing bowl. Pour contents of the mixing bowl into the baking dish. 19 | 20 | Serves 1. -------------------------------------------------------------------------------- /languages/shakespeare/tests/index.test.ts: -------------------------------------------------------------------------------- 1 | import { executeProgram, readTestProgram } from "../../test-utils"; 2 | import Engine from "../runtime"; 3 | 4 | describe("Test programs", () => { 5 | test("Hello World", async () => { 6 | const code = readTestProgram(__dirname, "helloworld"); 7 | const result = await executeProgram(new Engine(), code); 8 | expect(result.output).toBe("Hello World!\n"); 9 | }); 10 | 11 | test("Prime Numbers", async () => { 12 | const code = readTestProgram(__dirname, "primes"); 13 | const result = await executeProgram(new Engine(), code, "15"); 14 | expect(result.output).toBe(">2 3 5 7 11 13 "); 15 | }); 16 | 17 | test("Reverse cat", async () => { 18 | const code = readTestProgram(__dirname, "reverse"); 19 | const input = "abcd efgh\nijkl mnop\n"; 20 | const expectedOutput = input.split("").reverse().join(""); 21 | const result = await executeProgram(new Engine(), code, input); 22 | expect(result.output).toBe(expectedOutput); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /scripts/new-lang-template/README.md: -------------------------------------------------------------------------------- 1 | # $LANG_NAME 2 | 3 | Add a short summary about the language, including link(s) to the language specification and sample programs. 4 | 5 | ## Notes for the user 6 | 7 | - Add details and quirks (if any) about the Esolang Park implementation of this esolang. 8 | - These are details that the user may want to know while executing or debugging programs on the editor. 9 | 10 | ## Implementation details 11 | 12 | - Add notes that a contributor may want to read while looking at the source code of the language provider. 13 | - This includes any third-party libraries you've used, something you've done for performance, or just the 14 | main decisions you took while implementing the language provider. 15 | - If the source code is simple enough, you can simply omit this section. 16 | 17 | ## Possible improvements 18 | 19 | - Add any bugs or suboptimalities in the language provider that a contributor can work on. 20 | - (this section doesn't mean you can add a half-baked interpreter and leave, though.) 21 | -------------------------------------------------------------------------------- /languages/chef/tests/index.test.ts: -------------------------------------------------------------------------------- 1 | import { executeProgram, readTestProgram } from "../../test-utils"; 2 | import ChefRuntime from "../runtime"; 3 | 4 | /** Absolute path to directory of sample programs */ 5 | const DIRNAME = __dirname + "/samples"; 6 | 7 | describe("Test programs", () => { 8 | test("Hello World Souffle", async () => { 9 | const code = readTestProgram(DIRNAME, "hello-world-souffle"); 10 | const result = await executeProgram(new ChefRuntime(), code); 11 | expect(result.output).toBe("Hello world!"); 12 | }); 13 | 14 | test("Fibonacci Du Fromage", async () => { 15 | const code = readTestProgram(DIRNAME, "fibonacci-fromage"); 16 | const result = await executeProgram(new ChefRuntime(), code, "10"); 17 | expect(result.output).toBe(" 1 1 2 3 5 8 13 21 34 55"); 18 | }); 19 | 20 | test("Hello World Cake with Chocolate Sauce", async () => { 21 | const code = readTestProgram(DIRNAME, "hello-world-cake"); 22 | const result = await executeProgram(new ChefRuntime(), code); 23 | expect(result.output).toBe("Hello world!"); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "../styles/globals.css"; 3 | import "../styles/editor.css"; 4 | import "../styles/mosaic.scss"; 5 | import "@blueprintjs/core/lib/css/blueprint.css"; 6 | import "@blueprintjs/icons/lib/css/blueprint-icons.css"; 7 | import "react-mosaic-component/react-mosaic-component.css"; 8 | import type { AppProps } from "next/app"; 9 | import { Providers } from "../ui/providers"; 10 | import { NextPage } from "next"; 11 | 12 | /** Type for pages that use a custom layout */ 13 | export type NextPageWithLayout = NextPage & { 14 | getLayout?: (page: React.ReactNode) => React.ReactNode; 15 | }; 16 | 17 | /** AppProps type but extended for custom layouts */ 18 | type AppPropsWithLayout = AppProps & { 19 | Component: NextPageWithLayout; 20 | }; 21 | 22 | function MyApp({ Component, pageProps }: AppPropsWithLayout) { 23 | // Use the layout defined at the page level, if available 24 | const getLayout = 25 | Component.getLayout ?? ((page) => {page}); 26 | return getLayout(); 27 | } 28 | 29 | export default MyApp; 30 | -------------------------------------------------------------------------------- /languages/deadfish/constants.ts: -------------------------------------------------------------------------------- 1 | import { MonacoTokensProvider } from "../types"; 2 | 3 | export type DFRS = { 4 | value: number; 5 | }; 6 | 7 | export enum DF_OP { 8 | INCR = "i", 9 | DECR = "d", 10 | SQ = "s", 11 | OUT = "o", 12 | } 13 | 14 | /** A single element of the program's AST */ 15 | export type DFAstStep = { 16 | instr: DF_OP; 17 | location: { line: number; char: number }; 18 | }; 19 | 20 | /** Sample program printing "Hello world" */ 21 | export const sampleProgram = [ 22 | "iisiiiisiiiiiiiio", 23 | "iiiiiiiiiiiiiiiiiiiiiiiiiiiiio", 24 | "iiiiiiioo", 25 | "iiio", 26 | "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddo", 27 | "dddddddddddddddddddddsddo", 28 | "ddddddddo", 29 | "iiio", 30 | "ddddddo", 31 | "ddddddddo", 32 | ].join("\n"); 33 | 34 | /** Tokens provider */ 35 | export const editorTokensProvider: MonacoTokensProvider = { 36 | tokenizer: { 37 | root: [ 38 | [/i/, "identifier"], 39 | [/d/, "variable"], 40 | [/s/, "meta"], 41 | [/o/, "tag"], 42 | ], 43 | }, 44 | defaultToken: "comment", 45 | }; 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Nilay Majorwar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /languages/shakespeare/tests/reverse.txt: -------------------------------------------------------------------------------- 1 | Outputting Input Reversedly. 2 | 3 | Othello, a stacky man. 4 | Lady Macbeth, who pushes him around till he pops. 5 | 6 | 7 | Act I: The one and only. 8 | 9 | Scene I: In the beginning, there was nothing. 10 | 11 | [Enter Othello and Lady Macbeth] 12 | 13 | Othello: 14 | You are nothing! 15 | 16 | Scene II: Pushing to the very end. 17 | 18 | Lady Macbeth: 19 | Open your mind! Remember yourself. 20 | 21 | Othello: 22 | You are as hard as the sum of yourself and a stone wall. Am I as 23 | horrid as a flirt-gill? 24 | 25 | Lady Macbeth: 26 | If not, let us return to scene II. Recall your imminent death! 27 | 28 | Othello: 29 | You are as small as the difference between yourself and a hair! 30 | 31 | Scene III: Once you pop, you can't stop! 32 | 33 | Lady Macbeth: 34 | Recall your unhappy childhood. Speak your mind! 35 | 36 | Othello: 37 | You are as vile as the sum of yourself and a toad! Are you better 38 | than nothing? 39 | 40 | Lady Macbeth: 41 | If so, let us return to scene III. 42 | 43 | Scene IV: The end. 44 | 45 | [Exeunt] 46 | -------------------------------------------------------------------------------- /languages/brainfuck/README.md: -------------------------------------------------------------------------------- 1 | # Brainfuck 2 | 3 | Brainfuck is perhaps the most popular esoteric programming language, created by Urban Müller in 1993. 4 | It is Turing-complete and has 8 instructions which operate on a linear array of cells storing integer values. 5 | The [esolangs wiki page](https://esolangs.org/wiki/Brainfuck) contains the language specification and some 6 | sample programs. 7 | 8 | ## Notes for the user 9 | 10 | - The cell array is semi-infinite. There is no cell to the left of the initial cell, and trying to go left 11 | anyway will result in a runtime error. The right side of the cell array is unbounded. 12 | - Cell size is 8 bits, and allows values in the range `[0, 255]`. Values loop over to the other side on reaching the bounds. 13 | - The usual ASCII value `10` is designated for newlines. 14 | - The value `0` is returned in input (`,`) operations on reaching `EOF`. 15 | 16 | ## Possible improvements 17 | 18 | - The renderer currently uses Blueprint's `Card` component. This leads to performance issues when the stack grows large. 19 | Usage of this component should be replaced by a simple custom component to drastically improve performance. Look at the 20 | `SimpleTag` component used in the Shakespeare renderer for an example. 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esolang-park", 3 | "private": true, 4 | "scripts": { 5 | "dev": "next dev", 6 | "start": "next start", 7 | "lint": "next lint", 8 | "test": "jest", 9 | "build": "yarn run build:worker && next build", 10 | "dev:worker": "webpack -c worker-pack/webpack.dev.js --watch", 11 | "build:worker": "webpack -c worker-pack/webpack.prod.js", 12 | "add-new-language": "node scripts/add-new-language.js" 13 | }, 14 | "dependencies": { 15 | "@blueprintjs/core": "^4.0.0-beta.12", 16 | "@monaco-editor/react": "^4.3.1", 17 | "chevrotain": "^10.0.0", 18 | "monaco-editor": "^0.30.1", 19 | "next": "12.0.7", 20 | "react": "17.0.2", 21 | "react-dom": "17.0.2", 22 | "react-mosaic-component": "^5.0.0", 23 | "sass": "^1.49.7" 24 | }, 25 | "devDependencies": { 26 | "@types/jest": "^27.4.0", 27 | "@types/node": "16.11.11", 28 | "@types/react": "17.0.37", 29 | "eslint": "8.4.0", 30 | "eslint-config-next": "12.0.7", 31 | "jest": "^27.4.7", 32 | "peggy": "^1.2.0", 33 | "ts-loader": "^9.2.6", 34 | "ts-node": "^10.5.0", 35 | "typescript": "4.5.2", 36 | "webpack": "^5.65.0", 37 | "webpack-cli": "^4.9.1", 38 | "webpack-merge": "^5.8.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /languages/chef/tests/samples/fibonacci-fromage.txt: -------------------------------------------------------------------------------- 1 | Fibonacci Du Fromage. 2 | 3 | ==== Source: https://github.com/joostrijneveld/Chef-Interpreter/blob/master/ChefInterpreter/FibonacciDuFromage ==== 4 | An improvement on the Fibonacci with Caramel Sauce recipe. Much less for the sweettooths, much more correct. 5 | 6 | Ingredients. 7 | 5 g numbers 8 | 1 g cheese 9 | 10 | Method. 11 | Take numbers from refrigerator. 12 | Put cheese into mixing bowl. 13 | Put cheese into mixing bowl. 14 | Put numbers into 2nd mixing bowl. 15 | Remove cheese from 2nd mixing bowl. 16 | Remove cheese from 2nd mixing bowl. 17 | Fold numbers into 2nd mixing bowl. 18 | Put numbers into 2nd mixing bowl. 19 | Calculate the numbers. 20 | Serve with salt and pepper. 21 | Ponder the numbers until calculated. 22 | Add cheese to 2nd mixing bowl. 23 | Add cheese to 2nd mixing bowl. 24 | Fold numbers into 2nd mixing bowl. 25 | Move the numbers. 26 | Fold cheese into mixing bowl. 27 | Put cheese into 2nd mixing bowl. 28 | Transfer the numbers until moved. 29 | Pour contents of the 2nd mixing bowl into the baking dish. 30 | 31 | Serves 1. 32 | 33 | salt and pepper. 34 | 35 | Ingredients. 36 | 1 g salt 37 | 1 g pepper 38 | 39 | Method. 40 | Fold salt into mixing bowl. 41 | Fold pepper into mixing bowl. 42 | Clean mixing bowl. 43 | Put salt into mixing bowl. 44 | Add pepper. -------------------------------------------------------------------------------- /ui/providers/features-guide-provider.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { FeaturesGuide } from "../features-guide"; 3 | 4 | /** Local storage key that stores boolean for whether guide has been closed by user */ 5 | const GUIDE_CLOSED_KEY = "guide-closed"; 6 | 7 | const FeaturesGuideContext = React.createContext<{ 8 | show: () => void; 9 | }>({ show: () => {} }); 10 | 11 | /** Context provider for showing the features guide dialog */ 12 | export const FeaturesGuideProvider = (props: { children: React.ReactNode }) => { 13 | const [isOpen, setIsOpen] = React.useState(false); 14 | 15 | React.useEffect(() => { 16 | const hasClosedGuide = window.localStorage.getItem(GUIDE_CLOSED_KEY); 17 | if (hasClosedGuide == null) setIsOpen(true); 18 | }); 19 | 20 | return ( 21 | setIsOpen(true) }}> 22 | {props.children} 23 | {isOpen && ( 24 | { 27 | window.localStorage.setItem(GUIDE_CLOSED_KEY, "true"); 28 | setIsOpen(false); 29 | }} 30 | /> 31 | )} 32 | 33 | ); 34 | }; 35 | 36 | /** Utility hook to show the features guide */ 37 | export const useFeaturesGuide = () => React.useContext(FeaturesGuideContext); 38 | -------------------------------------------------------------------------------- /languages/chef/runtime/input-stream.ts: -------------------------------------------------------------------------------- 1 | import { RuntimeError } from "../../worker-errors"; 2 | 3 | /** 4 | * A barebones input stream implementation for consuming integers from a string. 5 | */ 6 | export default class InputStream { 7 | private _text: string; 8 | 9 | /** Create a new input stream loaded with the given input */ 10 | constructor(text: string) { 11 | this._text = text; 12 | } 13 | 14 | /** Remove leading whitespace from the current input stream */ 15 | private exhaustLeadingWhitespace(): void { 16 | const firstChar = this._text.trim()[0]; 17 | const posn = this._text.search(firstChar); 18 | this._text = this._text.slice(posn); 19 | } 20 | 21 | /** Parse input stream for an integer */ 22 | getNumber(): number { 23 | this.exhaustLeadingWhitespace(); 24 | // The extra whitespace differentiates whether string is empty or all numbers. 25 | if (this._text === "") throw new RuntimeError("Unexpected end of input"); 26 | let posn = this._text.search(/[^0-9]/); 27 | if (posn === 0) 28 | throw new RuntimeError(`Unexpected input character: '${this._text[0]}'`); 29 | if (posn === -1) posn = this._text.length; 30 | // Consume and parse numeric part 31 | const numStr = this._text.slice(0, posn); 32 | this._text = this._text.slice(posn); 33 | return parseInt(numStr, 10); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /languages/shakespeare/renderer/topbar.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Text } from "@blueprintjs/core"; 3 | import { Box } from "../../ui-utils"; 4 | 5 | const styles = { 6 | charChip: { 7 | margin: "0 5px", 8 | }, 9 | questionText: { 10 | marginLeft: 30, 11 | marginRight: 10, 12 | }, 13 | }; 14 | 15 | type Props = { 16 | charactersOnStage: string[]; 17 | currSpeaker: string | null; 18 | questionState: boolean | null; 19 | }; 20 | 21 | export const TopBar = (props: Props) => { 22 | const { charactersOnStage, currSpeaker, questionState } = props; 23 | 24 | const characterChips = 25 | charactersOnStage.length === 0 ? ( 26 | The stage is empty 27 | ) : ( 28 | charactersOnStage.map((character) => ( 29 | 33 | {character} 34 | 35 | )) 36 | ); 37 | 38 | return ( 39 |
40 | {characterChips} 41 | {questionState != null && ( 42 | <> 43 | 44 | Answer to question: 45 | 46 | 47 | {questionState ? "yes" : "no"} 48 | 49 | 50 | )} 51 |
52 | ); 53 | }; 54 | -------------------------------------------------------------------------------- /ui/input-editor.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { TextArea } from "@blueprintjs/core"; 3 | 4 | // Interface for interacting with the editor 5 | export interface InputEditorRef { 6 | /** 7 | * Get the current text content of the editor. 8 | */ 9 | getValue: () => string; 10 | } 11 | 12 | /** 13 | * A very simple text editor for user input 14 | */ 15 | const InputEditorComponent = ( 16 | props: { readOnly?: boolean }, 17 | ref: React.Ref 18 | ) => { 19 | const textareaRef = React.useRef(null); 20 | 21 | React.useImperativeHandle( 22 | ref, 23 | () => ({ 24 | getValue: () => textareaRef.current!.value, 25 | }), 26 | [] 27 | ); 28 | 29 | return ( 30 |
31 |