• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

A categorical programming language


Commit MetaInfo

Revisioncaae86fc44c3d23102b8225e63fc6266edaf3fbd (tree)
Time2022-09-19 02:41:02
AuthorCorbin <cds@corb...>
CommiterCorbin

Log Message

Honey can evaluate nat/256 in the browser!

Change Summary

Incremental Difference

--- a/.envrc
+++ b/.envrc
@@ -3,3 +3,4 @@ use nix
33 eval $(keychain --eval --agents ssh)
44
55 # export CAMMY_HIVE="$(pwd)/hive/"
6+export HONEY_HIVE="$(pwd)/hive.json"
--- a/honey.py
+++ b/honey.py
@@ -26,9 +26,122 @@ def home():
2626 <h2>Hive Stats</h2>
2727 <p>There are {dipperCount} dippers available.</p>
2828 <p>The heap has {heapCount} rows.</p>
29+ <form id="dipper-form">
30+ <input type="textbox" id="dipper" />
31+ <button id="go" type="submit">Go!</button>
32+ </form>
33+ <div id="log">
34+ <p>Log starts here</p>
35+ </div>
36+ <script type="text/javascript">
37+ function log(s) {{
38+ document.getElementById("log").innerHTML += s;
39+ }}
40+ function fetchJSON(url) {{
41+ return fetch(url).then((resp) => resp.json());
42+ }}
43+ function extract(expr) {{
44+ if (typeof expr === "string") {{
45+ return new Promise((resolve, reject) => resolve(expr));
46+ }} else if (typeof expr === "number") {{
47+ const url = "/extract/" + expr;
48+ return fetchJSON(url).then(extract);
49+ }} else if (Array.isArray(expr)) {{
50+ return Promise.all(expr.map(extract));
51+ }} else {{
52+ console.log("Can't extract from", expr);
53+ }}
54+ }}
55+ const prims = {{
56+ "id": x => x,
57+ "ignore": _ => null,
58+ "fst": ([x, y]) => x,
59+ "snd": ([x, y]) => y,
60+ "zero": _ => 0,
61+ "succ": n => n + 1,
62+ }};
63+ function compile(expr) {{
64+ console.log("compile", expr);
65+ if (Array.isArray(expr)) {{
66+ const l = expr.slice(1).map(compile);
67+ switch (expr[0]) {{
68+ case "comp": {{
69+ const [f, g] = l;
70+ return x => g(f(x));
71+ }}
72+ case "pair": {{
73+ const [f, g] = l;
74+ return x => [f(x), g(x)];
75+ }}
76+ case "curry": {{
77+ const [f] = l;
78+ return x => y => f([x, y]);
79+ }}
80+ case "uncurry": {{
81+ const [f] = l;
82+ return ([x, y]) => f(x)(y);
83+ }}
84+ case "pr": {{
85+ const [z, s] = l;
86+ return x => {{
87+ var rv = z(null);
88+ while (x !== 0) {{
89+ x -= 1;
90+ rv = s(rv);
91+ }}
92+ return rv;
93+ }}
94+ }}
95+ default:
96+ throw new TypeError("unknown constructor " +
97+ expr[0]);
98+ }}
99+ }} else {{
100+ return prims[expr];
101+ }}
102+ }}
103+ const textbox = document.getElementById("dipper");
104+ document.getElementById("dipper-form").addEventListener("submit", (e) => {{
105+ const url = "/dip/" + textbox.value;
106+ log("<p>Got a click! Will fetch URL " + url + "</p>");
107+ fetchJSON(url).then(({{expr, trail}}) => {{
108+ log("<p>Token is " + expr + "</p>");
109+ log("<p>Trail is " + trail + "</p>");
110+ const extracted = extract(expr);
111+ extracted.then((ex) => {{
112+ log("<p>Finished extraction, got " + ex + "</p>");
113+ const compiled = compile(ex);
114+ log("<p>Result: " + compiled(null) + "</p>");
115+ }});
116+ }});
117+ e.preventDefault();
118+ }}, false);
119+ </script>
29120 </body>
30121 """
31122
123+def substitute(context, expr):
124+ if isinstance(expr, list):
125+ return [expr[0]] + [substitute(context, sub) for sub in expr[1:]]
126+ elif isinstance(expr, int):
127+ return substitute(context, heap[expr])
128+ elif isinstance(expr, str) and expr.startswith("@"):
129+ return context[int(expr[1:])]
130+ return expr
131+
132+FUNCTORS = "comp", "pair", "curry", "uncurry", "pr"
133+
134+def maybeApplyFunctor(expr):
135+ if isinstance(expr, list) and expr[0] not in FUNCTORS:
136+ context = expr[1:]
137+ target = heap[symbols[expr[0]][0]]
138+ return substitute(context, target)
139+ return expr
140+
141+@app.route("/extract/<int:token>")
142+def extract(token):
143+ return jsonify(maybeApplyFunctor(heap[token]))
144+
32145 @app.route("/dippers")
33146 def dippers():
34147 return jsonify({name: url_for("dip", name=name) for name in symbols})
@@ -62,7 +175,7 @@ class Dip(MethodView):
62175 if name not in symbols:
63176 abort(404)
64177 index, trail = symbols[name]
65- return jsonify({"expr": resolve(index), "trail": trail})
178+ return jsonify({"expr": index, "trail": trail})
66179
67180 def put(self, name):
68181 d = request.get_json()
--- a/shell.nix
+++ b/shell.nix
@@ -44,6 +44,6 @@ in pkgs.stdenv.mkDerivation {
4444 # experimenting with hive management
4545 ranger
4646 # ???
47- openapi-generator-cli yaml2json
47+ openapi-generator-cli yaml2json python3Packages.virtualenv
4848 ];
4949 }
--- /dev/null
+++ b/update-openapi.sh
@@ -0,0 +1,4 @@
1+#!/bin/sh
2+
3+yaml2json <honey.yaml >honey.json
4+openapi-generator-cli generate -i honey.json -o honey-flask/ -g python-flask