Overview
Comment: | Repl now actually works! Code is executed and potential errors reported. |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
73f643169ec9149071835d64499bc277 |
User & Date: | robin.hansen on 2020-11-04 06:30:39 |
Other Links: | manifest | tags |
Context
2020-11-05
| ||
18:21 | Added the first five lessons. check-in: f8c89b049f user: robin.hansen tags: trunk | |
2020-11-04
| ||
06:30 | Repl now actually works! Code is executed and potential errors reported. check-in: 73f643169e user: robin.hansen tags: trunk | |
2020-11-03
| ||
06:09 | Add feature to switch between different lessons in playground check-in: 114740dc32 user: robin.hansen tags: trunk | |
Changes
Modified playground/package-lock.json from [cc2c4bf748] to [6d94a9b0de].
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 ... 955 956 957 958 959 960 961 962 963 964 965 966 967 968 .... 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 |
"@babel/helper-function-name": "^7.10.4", "@babel/template": "^7.10.4", "@babel/traverse": "^7.10.4", "@babel/types": "^7.10.4" } }, "@babel/helpers": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.1.tgz", "integrity": "sha512-9JoDSBGoWtmbay98efmT2+mySkwjzeFeAL9BuWNoVQpkPFQF8SIIFUfY5os9u8wVzglzoiPRSW7cuJmBDUt43g==", "dev": true, "requires": { "@babel/template": "^7.10.4", "@babel/traverse": "^7.12.1", "@babel/types": "^7.12.1" } }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, ................................................................................ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/preset-env": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.1.tgz", "integrity": "sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg==", "dev": true, "requires": { ................................................................................ "dev": true, "requires": { "domexception": "^1.0.1", "webidl-conversions": "^4.0.2", "xml-name-validator": "^3.0.0" } }, "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", "dev": true, "requires": { "defaults": "^1.0.3" |
| | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 .... 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 .... 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 |
"@babel/helper-function-name": "^7.10.4", "@babel/template": "^7.10.4", "@babel/traverse": "^7.10.4", "@babel/types": "^7.10.4" } }, "@babel/helpers": { "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", "dev": true, "requires": { "@babel/template": "^7.10.4", "@babel/traverse": "^7.12.5", "@babel/types": "^7.12.5" }, "dependencies": { "@babel/generator": { "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.5.tgz", "integrity": "sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A==", "dev": true, "requires": { "@babel/types": "^7.12.5", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/parser": { "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.5.tgz", "integrity": "sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ==", "dev": true }, "@babel/traverse": { "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.5.tgz", "integrity": "sha512-xa15FbQnias7z9a62LwYAA5SZZPkHIXpd42C6uW68o8uTuua96FHZy1y61Va5P/i83FAAcMpW8+A/QayntzuqA==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.11.0", "@babel/parser": "^7.12.5", "@babel/types": "^7.12.5", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.19" } }, "@babel/types": { "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.5.tgz", "integrity": "sha512-gyTcvz7JFa4V45C0Zklv//GmFOAal5fL23OWpBLqc4nZ4Yrz67s4kCNwSK1Gu0MXGTU8mRY3zJYtacLdKXlzig==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, ................................................................................ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/polyfill": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz", "integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==", "dev": true, "requires": { "core-js": "^2.6.5", "regenerator-runtime": "^0.13.4" } }, "@babel/preset-env": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.1.tgz", "integrity": "sha512-H8kxXmtPaAGT7TyBvSSkoSTUK6RHh61So05SyEbpmr0MCZrsNYn7mGMzzeYoOUCdHzww61k8XBft2TaES+xPLg==", "dev": true, "requires": { ................................................................................ "dev": true, "requires": { "domexception": "^1.0.1", "webidl-conversions": "^4.0.2", "xml-name-validator": "^3.0.0" } }, "wabt": { "version": "1.0.19", "resolved": "https://registry.npmjs.org/wabt/-/wabt-1.0.19.tgz", "integrity": "sha512-z/7XRZB8tPRW0XdE8HYbA95w2kjus5AwOHnJ5NT9PqzaNZ7z/zHnUdpNdB78TFMgWt+D/u01lg1jG6nWiFmyEw==", "dev": true }, "wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", "dev": true, "requires": { "defaults": "^1.0.3" |
Modified playground/package.json from [7c8a9cbfd9] to [8c57dc3c7c].
6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
"scripts": { "start": "parcel src/playground.html", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Robin Heggelund Hansen", "license": "MIT", "devDependencies": { "elm": "^0.19.1-3", "elm-format": "^0.8.4", "elm-hot": "^1.1.5", "node-elm-compiler": "^5.0.5", "parcel": "^1.12.4" } } |
> | > |
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
"scripts": { "start": "parcel src/playground.html", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Robin Heggelund Hansen", "license": "MIT", "devDependencies": { "@babel/polyfill": "^7.12.1", "elm": "^0.19.1-3", "elm-format": "^0.8.4", "elm-hot": "^1.1.5", "node-elm-compiler": "^5.0.5", "parcel": "^1.12.4", "wabt": "^1.0.19" } } |
Modified playground/src/Playground.elm from [027f165ed8] to [000c661098].
1 2 3 4 5 6 7 8 .. 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 .. 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 ... 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
module Playground exposing (main) import Browser import Dict exposing (Dict) import Html exposing (Html) import Html.Attributes as Attributes import Html.Events as Events import Lesson01 ................................................................................ -- MODEL type alias Model = { activeLesson : LessonContract , source : String } init : flags -> ( Model, Cmd Msg ) init _ = ( { activeLesson = Lesson01.contract , source = Lesson01.contract.content } , Cmd.none ) -- Update type Msg = EditSource String | SwitchLesson String update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of EditSource newSource -> ( { model | source = newSource } ................................................................................ } , Cmd.none ) Nothing -> ( model, Cmd.none ) -- VIEW view : Model -> Html Msg view model = Html.div [ Attributes.style "height" "100vh" ] [ Html.h1 [] [ Html.text "Playground" ] , Html.div [ Attributes.style "height" "50%" ] [ Html.textarea [ Attributes.style "width" "50vw" , Attributes.style "height" "100%" , Events.onInput EditSource , Attributes.value model.source ] [] , lessonSwitcher model ] ] lessonSwitcher : Model -> Html Msg lessonSwitcher model = Html.select ................................................................................ lessonSwitcherOption : LessonContract -> Html Msg lessonSwitcherOption contract = Html.option [ Attributes.value contract.key ] [ Html.text contract.label ] -- MAIN main : Program () Model Msg main = Browser.element { init = init , update = update , view = view , subscriptions = always Sub.none } |
| > > > > > > > > > > > > > > > > > | | | | | | | | > > > > > > | > > > > > > > > > > > > > > | |
1 2 3 4 5 6 7 8 .. 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 .. 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 ... 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
port module Playground exposing (main) import Browser import Dict exposing (Dict) import Html exposing (Html) import Html.Attributes as Attributes import Html.Events as Events import Lesson01 ................................................................................ -- MODEL type alias Model = { activeLesson : LessonContract , source : String , result : String } init : flags -> ( Model, Cmd Msg ) init _ = ( { activeLesson = Lesson01.contract , source = Lesson01.contract.content , result = "" } , Cmd.none ) -- Update type Msg = EditSource String | SwitchLesson String | Compile String | CompilationResult String update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of EditSource newSource -> ( { model | source = newSource } ................................................................................ } , Cmd.none ) Nothing -> ( model, Cmd.none ) Compile source -> ( model , compileSource source ) CompilationResult result -> ( { model | result = result } , Cmd.none ) -- VIEW view : Model -> Html Msg view model = Html.div [ Attributes.style "height" "100vh" ] [ Html.h1 [] [ Html.text "Playground" ] , Html.div [ Attributes.style "height" "100%" ] [ Html.div [ Attributes.style "height" "50%" ] [ Html.textarea [ Attributes.style "width" "50vw" , Attributes.style "height" "100%" , Events.onInput EditSource , Attributes.value model.source ] [] , Html.span [] [ Html.text model.result ] ] , Html.div [] [ lessonSwitcher model , Html.button [ Events.onClick <| Compile model.source ] [ Html.text "Run" ] ] ] ] lessonSwitcher : Model -> Html Msg lessonSwitcher model = Html.select ................................................................................ lessonSwitcherOption : LessonContract -> Html Msg lessonSwitcherOption contract = Html.option [ Attributes.value contract.key ] [ Html.text contract.label ] -- PORTS port compileSource : String -> Cmd msg port compilationResult : (String -> msg) -> Sub msg -- MAIN main : Program () Model Msg main = Browser.element { init = init , update = update , view = view , subscriptions = always <| compilationResult CompilationResult } |
Modified playground/src/playground.js from [0ab9c525d8] to [1cab96131b].
1 2 3 4 5 |
import { Elm } from './Playground.elm'; const app = Elm.Playground.init({ node: document.getElementById('elm-app') }); |
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 |
import { Elm } from './Playground.elm'; import Compiler from '../../../play/wasm_tests/compiler'; import '@babel/polyfill'; import wabtInit from 'wabt'; const app = Elm.Playground.init({ node: document.getElementById('elm-app') }); app.ports.compileSource.subscribe(source => { compileToWat(source) .then(val => { return execute(val); }) .then(val => { return app.ports.compilationResult.send(val); }) .catch(err => { return app.ports.compilationResult.send(err); }); }); function compileToWat(source) { return new Promise((resolve, reject) => { const compiler = Compiler.Elm.Main.init({}); compiler.ports.compileFinished.subscribe(([ok, output]) => { if (ok) { resolve(output); } else { reject(output); } }); compiler.ports.compileString.send(source); }); } async function execute(wat) { const wabt = await wabtInit(); const wasmModule = wabt.parseWat('tmp', wat).toBinary({}).buffer; const memory = new WebAssembly.Memory({ initial: 10 }); const imports = { host: { memory: memory } }; const program = await WebAssembly.instantiate(wasmModule, imports); const main = program.instance.exports.main; if (typeof main === 'undefined') { return "Could not find a word named 'main'"; } main(); const memView = new Uint32Array(memory.buffer); return memView[3].toString(); // First three i32 elements are stack and heap information } |