From aa2f31d072f68b37e21ead655bc7a8c7e9837328 Mon Sep 17 00:00:00 2001 From: Haydn Ewers <27211+haydn@users.noreply.github.com> Date: Tue, 25 Jun 2019 11:42:49 +1000 Subject: [PATCH] Add basic playground --- ulm-js/AST.ts | 4 +- ulm-js/compile.test.ts | 10 +- ulm-js/parse.test.ts | 34 +- ulm-js/parse.ts | 12 +- ulm-js/toLatex.test.ts | 14 +- ulm-js/toLatex.ts | 2 +- ulm-playground/.gitignore | 22 + ulm-playground/now.json | 12 + ulm-playground/package.json | 38 +- ulm-playground/public/favicon.ico | Bin 0 -> 3870 bytes ulm-playground/public/index.html | 42 + ulm-playground/public/manifest.json | 15 + ulm-playground/src/App.css | 33 + ulm-playground/src/App.test.tsx | 9 + ulm-playground/src/App.tsx | 115 + ulm-playground/src/index.css | 13 + ulm-playground/src/index.tsx | 12 + ulm-playground/src/react-app-env.d.ts | 1 + ulm-playground/src/serviceWorker.ts | 143 + ulm-playground/tsconfig.json | 25 + yarn.lock | 10165 +++++++++++++++++++++++- 21 files changed, 10651 insertions(+), 70 deletions(-) create mode 100644 ulm-playground/now.json create mode 100644 ulm-playground/public/favicon.ico create mode 100644 ulm-playground/public/index.html create mode 100644 ulm-playground/public/manifest.json create mode 100644 ulm-playground/src/App.css create mode 100644 ulm-playground/src/App.test.tsx create mode 100644 ulm-playground/src/App.tsx create mode 100644 ulm-playground/src/index.css create mode 100644 ulm-playground/src/index.tsx create mode 100644 ulm-playground/src/react-app-env.d.ts create mode 100644 ulm-playground/src/serviceWorker.ts create mode 100644 ulm-playground/tsconfig.json diff --git a/ulm-js/AST.ts b/ulm-js/AST.ts index a71d6ff..d347b8f 100644 --- a/ulm-js/AST.ts +++ b/ulm-js/AST.ts @@ -24,9 +24,9 @@ type NumericOperation = | NumericAdditionOperation | NumericMultiplicationOperation; -type NaturalNumber = bigint; +type NaturalNumber = number; -type IntegerNumber = bigint; +type IntegerNumber = number; interface RationalNumber { type: "RationalNumber"; diff --git a/ulm-js/compile.test.ts b/ulm-js/compile.test.ts index 3c8c83c..fff1765 100644 --- a/ulm-js/compile.test.ts +++ b/ulm-js/compile.test.ts @@ -12,17 +12,17 @@ assert.deepEqual( operands: [ { type: "RationalNumber", - numerator: BigInt(12312), - denominator: BigInt(1) + numerator: 12312, + denominator: 1 }, { type: "RationalNumber", - numerator: BigInt(33), - denominator: BigInt(100) + numerator: 33, + denominator: 100 } ] }, - { type: "RationalNumber", numerator: BigInt(1), denominator: BigInt(4) } + { type: "RationalNumber", numerator: 1, denominator: 4 } ] } ] diff --git a/ulm-js/parse.test.ts b/ulm-js/parse.test.ts index d6f60f0..e7c0285 100644 --- a/ulm-js/parse.test.ts +++ b/ulm-js/parse.test.ts @@ -224,29 +224,29 @@ assert.deepEqual(parse(tokens), [ operands: [ { type: "RationalNumber", - numerator: BigInt(12312), - denominator: BigInt(1) + numerator: 12312, + denominator: 1 }, { type: "RationalNumber", - numerator: BigInt(33), - denominator: BigInt(100) + numerator: 33, + denominator: 100 } ] }, - { type: "RationalNumber", numerator: BigInt(1), denominator: BigInt(4) } + { type: "RationalNumber", numerator: 1, denominator: 4 } ] }, - { type: "RationalNumber", numerator: BigInt(33), denominator: BigInt(100) }, - { type: "RationalNumber", numerator: BigInt(1), denominator: BigInt(3) }, - { type: "RationalNumber", numerator: BigInt(-2), denominator: BigInt(1) }, - { type: "RationalNumber", numerator: BigInt(23), denominator: BigInt(5) }, - { type: "RationalNumber", numerator: BigInt(558), denominator: BigInt(100) }, - { type: "RationalNumber", numerator: BigInt(13), denominator: BigInt(1) }, - { type: "RationalNumber", numerator: BigInt(3), denominator: BigInt(1) }, - { type: "RationalNumber", numerator: BigInt(0), denominator: BigInt(1) }, - { type: "RationalNumber", numerator: BigInt(-34), denominator: BigInt(1) }, - { type: "RationalNumber", numerator: BigInt(2), denominator: BigInt(1) }, - { type: "RationalNumber", numerator: BigInt(33), denominator: BigInt(1) }, - { type: "RationalNumber", numerator: BigInt(1), denominator: BigInt(1) } + { type: "RationalNumber", numerator: 33, denominator: 100 }, + { type: "RationalNumber", numerator: 1, denominator: 3 }, + { type: "RationalNumber", numerator: -2, denominator: 1 }, + { type: "RationalNumber", numerator: 23, denominator: 5 }, + { type: "RationalNumber", numerator: 558, denominator: 100 }, + { type: "RationalNumber", numerator: 13, denominator: 1 }, + { type: "RationalNumber", numerator: 3, denominator: 1 }, + { type: "RationalNumber", numerator: 0, denominator: 1 }, + { type: "RationalNumber", numerator: -34, denominator: 1 }, + { type: "RationalNumber", numerator: 2, denominator: 1 }, + { type: "RationalNumber", numerator: 33, denominator: 1 }, + { type: "RationalNumber", numerator: 1, denominator: 1 } ]); diff --git a/ulm-js/parse.ts b/ulm-js/parse.ts index 04b5e12..5467fab 100644 --- a/ulm-js/parse.ts +++ b/ulm-js/parse.ts @@ -56,15 +56,15 @@ const parse = (tokens: Token[]): AST => { let numerator, denominator; if (value.includes(".")) { const [n, d] = value.split("."); - numerator = BigInt(n + d); - denominator = BigInt(10 ** d.length); + numerator = Number(n + d); + denominator = 10 ** d.length; } else if (value.includes("/")) { const [n, d] = value.split("/"); - numerator = BigInt(n); - denominator = BigInt(d); + numerator = Number(n); + denominator = Number(d); } else { - numerator = BigInt(value); - denominator = BigInt(1); + numerator = Number(value); + denominator = 1; } index += 1; diff --git a/ulm-js/toLatex.test.ts b/ulm-js/toLatex.test.ts index 8eb95db..5aca8f9 100644 --- a/ulm-js/toLatex.test.ts +++ b/ulm-js/toLatex.test.ts @@ -11,23 +11,23 @@ assert.equal( operands: [ { type: "RationalNumber", - numerator: BigInt(12312), - denominator: BigInt(1) + numerator: 12312, + denominator: 1 }, { type: "RationalNumber", - numerator: BigInt(33), - denominator: BigInt(100) + numerator: 33, + denominator: 100 } ] }, - { type: "RationalNumber", numerator: BigInt(1), denominator: BigInt(4) } + { type: "RationalNumber", numerator: 1, denominator: 4 } ] }, { type: "RationalNumber", - numerator: BigInt(10), - denominator: BigInt(1) + numerator: 10, + denominator: 1 } ]), "12312 + \\frac{33}{100} = \\frac{1}{4}\\\\[16pt]10" diff --git a/ulm-js/toLatex.ts b/ulm-js/toLatex.ts index 677b942..2058400 100644 --- a/ulm-js/toLatex.ts +++ b/ulm-js/toLatex.ts @@ -22,7 +22,7 @@ const expressionToLatex = (expression: Expression): string => { )}`; } if (expression.type === "RationalNumber") { - return expression.denominator === BigInt(1) + return expression.denominator === 1 ? expression.numerator.toString() : `\\frac{${expression.numerator}}{${expression.denominator}}`; } diff --git a/ulm-playground/.gitignore b/ulm-playground/.gitignore index 07e6e47..4d29575 100644 --- a/ulm-playground/.gitignore +++ b/ulm-playground/.gitignore @@ -1 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies /node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/ulm-playground/now.json b/ulm-playground/now.json new file mode 100644 index 0000000..2dee0ed --- /dev/null +++ b/ulm-playground/now.json @@ -0,0 +1,12 @@ +{ + "version": 2, + "name": "ulm-playground", + "scope": "haydn", + "builds": [ + { + "src": "package.json", + "use": "@now/static-build", + "config": { "distDir": "build" } + } + ] +} diff --git a/ulm-playground/package.json b/ulm-playground/package.json index 75b6e62..204af95 100644 --- a/ulm-playground/package.json +++ b/ulm-playground/package.json @@ -1,5 +1,41 @@ { "name": "ulm-playground", "version": "0.0.0", - "license": "MIT" + "license": "MIT", + "dependencies": { + "@types/jest": "24.0.15", + "@types/node": "12.0.10", + "@types/react": "16.8.22", + "@types/react-dom": "16.8.4", + "katex": "^0.10.2", + "react": "^16.8.6", + "react-dom": "^16.8.6", + "react-scripts": "3.0.1", + "typescript": "3.5.2" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject", + "now-build": "react-scripts build" + }, + "eslintConfig": { + "extends": "react-app" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "@types/katex": "^0.10.1" + } } diff --git a/ulm-playground/public/favicon.ico b/ulm-playground/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a11777cc471a4344702741ab1c8a588998b1311a GIT binary patch literal 3870 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 ZtMWJ#1p_C + + + + + + + + + + ULM Playground + + + + +
+ + + diff --git a/ulm-playground/public/manifest.json b/ulm-playground/public/manifest.json new file mode 100644 index 0000000..1f2f141 --- /dev/null +++ b/ulm-playground/public/manifest.json @@ -0,0 +1,15 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/ulm-playground/src/App.css b/ulm-playground/src/App.css new file mode 100644 index 0000000..b41d297 --- /dev/null +++ b/ulm-playground/src/App.css @@ -0,0 +1,33 @@ +.App { + text-align: center; +} + +.App-logo { + animation: App-logo-spin infinite 20s linear; + height: 40vmin; + pointer-events: none; +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/ulm-playground/src/App.test.tsx b/ulm-playground/src/App.test.tsx new file mode 100644 index 0000000..a754b20 --- /dev/null +++ b/ulm-playground/src/App.test.tsx @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/ulm-playground/src/App.tsx b/ulm-playground/src/App.tsx new file mode 100644 index 0000000..a4a9092 --- /dev/null +++ b/ulm-playground/src/App.tsx @@ -0,0 +1,115 @@ +import React, { useState } from "react"; +import katex from "katex"; +import "./App.css"; + +import { compile, toLatex } from "ulm-js"; + +const useCompiler = ( + initialCode: string +): [string, object, string, (newCode: string) => void] => { + const render = (newCode: string): [object, string] => { + let newAst, newHtml; + + try { + newAst = compile(newCode); + newHtml = katex.renderToString(toLatex(newAst), { + throwOnError: false + }); + } catch (error) { + newAst = { error }; + newHtml = ""; + } + + return [newAst, newHtml]; + }; + + const [initialAst, initialHtml] = render(initialCode); + + const [code, setCode] = useState(initialCode); + const [ast, setAst] = useState(initialAst); + const [html, setHtml] = useState(initialHtml); + + return [ + code, + ast, + html, + (newCode: string): void => { + const [newAst, newHtml] = render(newCode); + setCode(newCode); + setAst(newAst); + setHtml(newHtml); + } + ]; +}; + +const App: React.FC = () => { + const [code, ast, html, update] = useCompiler( + "NumericEqualRelation(\n NumericAdditionOperation(\n NumericAdditionOperation(0.1, 0.3),\n 0.2\n ),\n 3/5\n)" + ); + return ( +
+

ULM Playground

+

Code

+
+