Merge pull request #2 from catseye/develop-2019-1
Develop 2019-1
Chris Pressey authored 4 years ago
GitHub committed 4 years ago
0 | 1be0dac045fab383fe071919f1fb0174228350f7 rel_0_1_2011_1214 | |
1 | 79b1ba067b9384bff14c5154642668cbb06ee71b rel_0_1_2014_0819 |
0 | Copyright (c)2011-2019 Chris Pressey, Cat's Eye Technologies. | |
1 | All rights reserved. | |
2 | ||
3 | Redistribution and use in source and binary forms, with or without | |
4 | modification, are permitted provided that the following conditions | |
5 | are met: | |
6 | ||
7 | 1. Redistributions of source code must retain the above copyright | |
8 | notices, this list of conditions and the following disclaimer. | |
9 | 2. Redistributions in binary form must reproduce the above copyright | |
10 | notices, this list of conditions, and the following disclaimer in | |
11 | the documentation and/or other materials provided with the | |
12 | distribution. | |
13 | 3. Neither the names of the copyright holders nor the names of their | |
14 | contributors may be used to endorse or promote products derived | |
15 | from this software without specific prior written permission. | |
16 | ||
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
18 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES INCLUDING, BUT NOT | |
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
20 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
21 | COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
22 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
23 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
26 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |
27 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
28 | POSSIBILITY OF SUCH DAMAGE. |
0 | #!/bin/sh | |
1 | ||
2 | THIS=`realpath $0` | |
3 | DIR=`dirname $THIS` | |
4 | NAME=`basename $THIS` | |
5 | SRC=$DIR/../src | |
6 | if [ -x $DIR/$NAME.exe ] ; then | |
7 | exec $DIR/$NAME.exe $* | |
8 | elif command -v runhaskell 2>&1 >/dev/null ; then | |
9 | exec runhaskell -i$SRC $SRC/Main.hs $* | |
10 | elif command -v runhugs 2>&1 >/dev/null ; then | |
11 | exec runhugs -i$SRC $SRC/Main.hs $* | |
12 | else | |
13 | echo "Cannot run $NAME; neither $NAME.exe, nor runhaskell, nor runhugs found." | |
14 | exit 1 | |
15 | fi |
1 | 1 | |
2 | 2 | PROG=flobnar |
3 | 3 | |
4 | if [ x`which ghc` = x -a x`which runhugs` = x ]; then | |
5 | echo "Neither ghc nor runhugs found on search path." | |
6 | exit 1 | |
4 | if command -v ghc >/dev/null 2>&1; then | |
5 | echo "building $PROG.exe with ghc" | |
6 | (cd src && ghc --make Main.hs -o ../bin/$PROG.exe) | |
7 | else | |
8 | echo "ghc not found, not building $PROG.exe" | |
7 | 9 | fi |
8 | 10 | |
9 | mkdir -p bin | |
10 | ||
11 | if [ x`which ghc` = x -o ! x$USE_HUGS = x ]; then | |
12 | # create script to run with Hugs | |
13 | cat >bin/$PROG <<'EOF' | |
14 | #!/bin/sh | |
15 | THIS=`realpath $0` | |
16 | DIR=`dirname $THIS`/../src | |
17 | runhugs $DIR/Main.hs $* | |
18 | EOF | |
19 | chmod 755 bin/$PROG | |
11 | if command -v hastec >/dev/null 2>&1; then | |
12 | echo "building $PROG.js with hastec" | |
13 | (cd src && hastec --make HasteMain.hs -o ../demo/$PROG.js) | |
20 | 14 | else |
21 | cd src && ghc --make Main.hs -o ../bin/$PROG | |
15 | echo "hastec not found, not building $PROG.js" | |
22 | 16 | fi |
0 | function launch(config) { | |
1 | config.container.innerHTML = ` | |
2 | <textarea id="prog" rows="10" cols="80"></textarea> | |
3 | <div id="control-panel"></div> | |
4 | <div><button id="run-button">Run</button></div> | |
5 | <pre id="result"></pre> | |
6 | `; | |
7 | ||
8 | function makeSelect(container, labelText, optionsArray, fun) { | |
9 | var label = document.createElement('label'); | |
10 | label.innerHTML = labelText; | |
11 | container.appendChild(label); | |
12 | var select = document.createElement("select"); | |
13 | for (var i = 0; i < optionsArray.length; i++) { | |
14 | var op = document.createElement("option"); | |
15 | op.text = optionsArray[i].filename; | |
16 | op.value = optionsArray[i].contents; | |
17 | select.options.add(op); | |
18 | } | |
19 | select.onchange = function(e) { | |
20 | fun(optionsArray[select.selectedIndex]); | |
21 | }; | |
22 | select.selectedIndex = 0; | |
23 | label.appendChild(select); | |
24 | return select; | |
25 | }; | |
26 | ||
27 | function selectOptionByText(selectElem, text) { | |
28 | var optElem; | |
29 | for (var i = 0; optElem = selectElem.options[i]; i++) { | |
30 | if (optElem.text === text) { | |
31 | selectElem.selectedIndex = i; | |
32 | selectElem.dispatchEvent(new Event('change')); | |
33 | return; | |
34 | } | |
35 | } | |
36 | } | |
37 | ||
38 | var controlPanel = document.getElementById('control-panel'); | |
39 | var select = makeSelect(controlPanel, "example program:", examplePrograms, function(option) { | |
40 | document.getElementById('prog').value = option.contents; | |
41 | }); | |
42 | selectOptionByText(select, "factorial.flobnar"); | |
43 | } | |
44 | ||
45 | launch({ container: document.getElementById('installation') }); |
0 | <!DOCTYPE html> | |
1 | <head> | |
2 | <meta charset="utf-8"> | |
3 | <title>Flobnar</title> | |
4 | </head> | |
5 | <body> | |
6 | ||
7 | <h1>Flobnar</h1> | |
8 | ||
9 | <p>(Flobnar.hs compiled to .js by <code>hastec</code>, running in HTML5 document)</p> | |
10 | ||
11 | <div id="installation"></div> | |
12 | ||
13 | <script src="../eg/examplePrograms.jsonp.js"></script> | |
14 | <script src="flobnar-hastec-launcher.js"></script> | |
15 | <script src="flobnar.js"></script> | |
16 | </body> |
0 | examplePrograms = [ | |
1 | { | |
2 | "contents": "3\n* <\n98+@\n3/<\n-<\n1\n", | |
3 | "filename": "arithmetic.flobnar" | |
4 | }, | |
5 | { | |
6 | "contents": ">>>>>v\n^ v\n^ 4\n^<<<<@\n", | |
7 | "filename": "arrows.flobnar" | |
8 | }, | |
9 | { | |
10 | "contents": " 7v @\nv8#<\n>#9 v\n >^ \n ^ <\n", | |
11 | "filename": "bridge.flobnar" | |
12 | }, | |
13 | { | |
14 | "contents": "> v\n^\\ < \n \n:v v \\<@\n-< : 6\n1 : > *\n -| <\n 11\n", | |
15 | "filename": "factorial.flobnar" | |
16 | }, | |
17 | { | |
18 | "contents": " 3\n\n9 | @\n\n 4\n", | |
19 | "filename": "if.flobnar" | |
20 | }, | |
21 | { | |
22 | "contents": " 0\n5 p <\n 0 +@\n g <\n 0\n", | |
23 | "filename": "put-get.flobnar" | |
24 | }, | |
25 | { | |
26 | "contents": " 5\n85 #\n*p<\n40+@\n > ^\n 6\n 9\n", | |
27 | "filename": "self-mod.flobnar" | |
28 | }, | |
29 | { | |
30 | "contents": "v<\n5*@\n^<\n", | |
31 | "filename": "sharing.flobnar" | |
32 | }, | |
33 | { | |
34 | "contents": " \n v @ \n #< 17 \n \n", | |
35 | "filename": "wrapping.flobnar" | |
36 | } | |
37 | ]; |
241 | 241 | |
242 | 242 | showRun program = |
243 | 243 | case run program of |
244 | IntVal x -> "Result: " ++ (show x) | |
244 | IntVal x -> "Result: " ++ (show x) ++ "\n" |
0 | module Main where | |
1 | ||
2 | import Haste | |
3 | import Haste.DOM | |
4 | import Haste.Events | |
5 | ||
6 | import Flobnar | |
7 | ||
8 | main = withElems ["prog", "result", "run-button"] driver | |
9 | ||
10 | escapeHTML "" = "" | |
11 | escapeHTML ('<' : rest) = "<" ++ escapeHTML rest | |
12 | escapeHTML ('>' : rest) = ">" ++ escapeHTML rest | |
13 | escapeHTML ('&' : rest) = "&" ++ escapeHTML rest | |
14 | escapeHTML (c : rest) = (c : escapeHTML rest) | |
15 | ||
16 | driver [progElem, resultElem, runButtonElem] = do | |
17 | onEvent runButtonElem Click $ \_ -> execute | |
18 | where | |
19 | execute = do | |
20 | Just prog <- getValue progElem | |
21 | setProp resultElem "innerHTML" (escapeHTML $ showRun prog) |