• 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

Revisiónd69bf980c4d66a809825c8cbe85914b04004fad5 (tree)
Tiempo2022-08-14 13:35:28
AutorCorbin <cds@corb...>
CommiterCorbin

Log Message

Hack up a basic concept for a packed JSON hive.

Cambiar Resumen

Diferencia incremental

--- /dev/null
+++ b/json-hive.py
@@ -0,0 +1,106 @@
1+#!/usr/bin/env nix-shell
2+#! nix-shell -i python3 -p python3
3+
4+import json
5+import os
6+import sys
7+
8+class CammyParser:
9+ def __init__(self, s):
10+ self._i = 0
11+ self._s = s
12+
13+ def position(self):
14+ return self._i
15+
16+ def hasMore(self):
17+ return self._i < len(self._s)
18+
19+ def eatWhitespace(self):
20+ while self.hasMore() and self._s[self._i] in (" ", "\n"):
21+ self._i += 1
22+
23+ def canAndDoesEat(self, c):
24+ if self._s[self._i] == c:
25+ self._i += 1
26+ return True
27+ else:
28+ return False
29+
30+ def takeName(self):
31+ start = self._i
32+ while self.hasMore() and self._s[self._i] not in (")", "(", " ", "\n"):
33+ self._i += 1
34+ stop = self._i
35+ return self._s[start:stop]
36+
37+ def takeExpression(self):
38+ self.eatWhitespace()
39+ if self.canAndDoesEat('('):
40+ return self.startFunctor()
41+ else:
42+ return self.takeName()
43+
44+ def startFunctor(self):
45+ start = self._i
46+ head = self.takeName()
47+ self.eatWhitespace()
48+ args = []
49+ while not self.canAndDoesEat(')'):
50+ args.append(self.takeExpression())
51+ self.eatWhitespace()
52+ if not self.hasMore():
53+ raise ValueError("Unterminated functor starting at %d" % start)
54+ return tuple([head] + args)
55+
56+
57+def parse(s):
58+ "Parse a Cammy expression, preserving any trailing text."
59+ parser = CammyParser(s)
60+ sexp = parser.takeExpression()
61+ # Parser is now fast-forwarded to the end of the S-expression, so we can
62+ # slice from that point and get the docstring/etc.
63+ trail = s[parser.position():]
64+ return sexp, trail
65+
66+symbols = {}
67+heap = []
68+
69+strs = {}
70+tuples = {}
71+
72+def merge(sexp):
73+ if isinstance(sexp, str):
74+ if sexp not in strs:
75+ strs[sexp] = len(heap)
76+ heap.append(sexp)
77+ return strs[sexp]
78+ elif isinstance(sexp, tuple):
79+ merged = tuple([sexp[0]] + [merge(arg) for arg in sexp[1:]])
80+ if merged not in tuples:
81+ tuples[merged] = len(heap)
82+ heap.append(merged)
83+ return tuples[merged]
84+ else:
85+ raise ValueError("not sure how to merge", sexp)
86+
87+
88+hiveroot = sys.argv[-1]
89+for root, dirs, files in os.walk(hiveroot):
90+ for file in files:
91+ path = os.path.join(root, file)
92+ key = os.path.splitext(path)[0][len(hiveroot):]
93+ with open(path, "r") as handle:
94+ sexp, trail = parse(handle.read())
95+ symbols[key] = merge(sexp), trail
96+
97+# Fixup aliased symbols.
98+for i, cell in enumerate(heap):
99+ if cell in symbols:
100+ heap[i] = symbols[cell][0]
101+
102+
103+print(json.dumps({
104+ "symbols": symbols,
105+ "heap": heap,
106+}))
--- a/shell.nix
+++ b/shell.nix
@@ -26,6 +26,8 @@ in pkgs.stdenv.mkDerivation {
2626 rlwrap
2727 # working with sexps
2828 # ocamlPackages.sexp
29+ # working with JSON
30+ jq
2931 # benchmarking
3032 busybox feedgnuplot linuxPackages.perf
3133 # publishing