@fraczak/k 5.1.2 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Code-derivation-tests/blowup.mjs +3 -3
- package/Code-derivation-tests/bnat.mjs +2 -2
- package/Code-derivation-tests/codec-witness-pattern.mjs +50 -0
- package/Code-derivation-tests/convergence-strategy.mjs +24 -0
- package/Code-derivation-tests/dot.mjs +12 -9
- package/Code-derivation-tests/filter-syntax.mjs +21 -0
- package/Code-derivation-tests/loop.mjs +8 -2
- package/Code-derivation-tests/nat.mjs +1 -1
- package/Code-derivation-tests/not-not.mjs +3 -3
- package/Code-derivation-tests/pattern-envelope.mjs +68 -0
- package/Code-derivation-tests/rlz.mjs +2 -2
- package/{BIG_PICTURE.md → DOCS/BIG_PICTURE.md} +103 -50
- package/DOCS/REPL.md +191 -0
- package/DOCS/book/01-introduction.md +51 -0
- package/DOCS/book/02-syntax-and-values.md +111 -0
- package/DOCS/book/03-types-as-finite-automata.md +156 -0
- package/DOCS/book/04-partial-functions-and-composition.md +146 -0
- package/DOCS/book/05-typing-filters-and-normalization.md +111 -0
- package/DOCS/book.md +54 -0
- package/README.md +204 -508
- package/TypeGraph.mjs +43 -0
- package/TypePatternGraph.mjs +251 -0
- package/Value.mjs +192 -0
- package/augmentation.mjs +198 -0
- package/codecs/BINARY_FORMAT.md +53 -0
- package/codecs/POLYMORPHIC_BINARY_FORMAT.md +303 -0
- package/codecs/README.md +215 -0
- package/codecs/example-pipeline.mjs +149 -0
- package/codecs/ieee.mjs +140 -0
- package/codecs/int.mjs +104 -0
- package/codecs/json-codec.mjs +215 -0
- package/codecs/json.mjs +40 -0
- package/codecs/k-parse.mjs +90 -0
- package/codecs/k-pattern.mjs +75 -0
- package/codecs/k-print.mjs +46 -0
- package/codecs/runtime/codec.mjs +768 -0
- package/codecs/runtime/ieee-pattern.mjs +30 -0
- package/codecs/runtime/pattern-json.mjs +96 -0
- package/codecs/runtime/prefix-codec.mjs +425 -0
- package/codecs/runtime/show-value.mjs +68 -0
- package/codecs/runtime/typeFromValue.mjs +34 -0
- package/codecs/runtime/unicode-string.mjs +220 -0
- package/codecs/show.mjs +41 -0
- package/codecs/string-codec.mjs +80 -0
- package/codecs/unit.mjs +51 -0
- package/codecs/utf16.mjs +66 -0
- package/codecs/utf8.mjs +37 -0
- package/codes.mjs +146 -44
- package/compiler.mjs +111 -0
- package/convergence.mjs +197 -0
- package/core.k +197 -0
- package/export.mjs +22 -32
- package/hash.mjs +29 -31
- package/index.mjs +41 -15
- package/k-vscode/.vscode/launch.json +14 -0
- package/k-vscode/README.md +65 -0
- package/k-vscode/language-configuration.json +42 -0
- package/k-vscode/package.json +57 -0
- package/k-vscode/snippets/k.json +92 -0
- package/k-vscode/syntaxes/k.tmLanguage.json +243 -0
- package/k.mjs +56 -54
- package/object.mjs +517 -0
- package/objects/README.md +38 -0
- package/objects/compile-lib.mjs +42 -0
- package/objects/compile.mjs +42 -0
- package/objects/decompile.mjs +32 -0
- package/package.json +18 -8
- package/parser.jison +27 -46
- package/parser.mjs +68 -100
- package/pretty.mjs +21 -40
- package/repl2.mjs +652 -0
- package/run.mjs +264 -231
- package/symbol-table.mjs +3 -17
- package/test-fingerprint.mjs +7 -7
- package/test-hash-fuzz.mjs +107 -0
- package/test-hash-normalization.mjs +134 -0
- package/test-k-object.mjs +74 -0
- package/test-repl2.mjs +95 -0
- package/test.mjs +45 -70
- package/tests.sh +10 -1
- package/typing.mjs +129 -676
- package/unification.mjs +157 -0
- package/valueIO.mjs +54 -0
- package/valueParser.jison +143 -0
- package/valueParser.mjs +713 -0
- package/Code-derivation-tests/built-in.mjs +0 -19
- package/Code-derivation-tests/vector.mjs +0 -19
- package/Filters/bug.k +0 -3
- package/Filters/composing.k +0 -15
- package/Filters/filter.k +0 -9
- package/TODO.md +0 -53
- package/TYPING.md +0 -365
- package/k-repl.cast +0 -1913
- package/k.cast +0 -618
- package/my-objects.json +0 -6
- package/patterns.mjs +0 -543
- package/repl.mjs +0 -213
- package/test-filters.mjs +0 -45
- package/typing-test.mjs +0 -40
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Code definition (union)": {
|
|
3
|
+
"prefix": "codeunion",
|
|
4
|
+
"body": ["\\$ ${1:name} = < ${2:type1} ${3:tag1}, ${4:type2} ${5:tag2} >;"],
|
|
5
|
+
"description": "Named code (type) using a tagged union"
|
|
6
|
+
},
|
|
7
|
+
"Code definition (product)": {
|
|
8
|
+
"prefix": "codeprod",
|
|
9
|
+
"body": ["\\$ ${1:name} = { ${2:type1} ${3:label1}, ${4:type2} ${5:label2} };"],
|
|
10
|
+
"description": "Named code (type) using a product (record)"
|
|
11
|
+
},
|
|
12
|
+
"Code definition (recursive union)": {
|
|
13
|
+
"prefix": "coderecunion",
|
|
14
|
+
"body": [
|
|
15
|
+
"\\$ ${1:name} = <",
|
|
16
|
+
" {} ${2:base_tag},",
|
|
17
|
+
" { ${1:name} ${3:field} } ${4:rec_tag}",
|
|
18
|
+
">;"
|
|
19
|
+
],
|
|
20
|
+
"description": "Recursive named code as a tagged union (e.g. nat, list)"
|
|
21
|
+
},
|
|
22
|
+
"Function definition": {
|
|
23
|
+
"prefix": "fn",
|
|
24
|
+
"body": ["${1:name} = ${2:expr};"],
|
|
25
|
+
"description": "Function/relation definition"
|
|
26
|
+
},
|
|
27
|
+
"Composition": {
|
|
28
|
+
"prefix": "comp",
|
|
29
|
+
"body": ["(${1:f} ${2:g})"],
|
|
30
|
+
"description": "Function composition: apply f then g"
|
|
31
|
+
},
|
|
32
|
+
"Merge": {
|
|
33
|
+
"prefix": "merge",
|
|
34
|
+
"body": ["< ${1:f}, ${2:g} >"],
|
|
35
|
+
"description": "Merge: try f first, fall back to g"
|
|
36
|
+
},
|
|
37
|
+
"Product combinator": {
|
|
38
|
+
"prefix": "prod",
|
|
39
|
+
"body": ["{ ${1:f} ${2:label1}, ${3:g} ${4:label2} }"],
|
|
40
|
+
"description": "Product combinator: apply functions in parallel, collect into a record"
|
|
41
|
+
},
|
|
42
|
+
"Filter (union)": {
|
|
43
|
+
"prefix": "filtunion",
|
|
44
|
+
"body": ["?< ${1:type1} ${2:tag1}, ${3:type2} ${4:tag2} > = ${5:X}"],
|
|
45
|
+
"description": "Filter expression constraining a union type, binding the subtype variable"
|
|
46
|
+
},
|
|
47
|
+
"Filter (product)": {
|
|
48
|
+
"prefix": "filtprod",
|
|
49
|
+
"body": ["?{ ${1:Type} ${2:field}, ${3:...} } = ${4:X}"],
|
|
50
|
+
"description": "Filter expression constraining a product type, binding the subtype variable"
|
|
51
|
+
},
|
|
52
|
+
"Product projection": {
|
|
53
|
+
"prefix": "dot",
|
|
54
|
+
"body": [".${1:field}"],
|
|
55
|
+
"description": "Product field projection: .field"
|
|
56
|
+
},
|
|
57
|
+
"Union tag projection": {
|
|
58
|
+
"prefix": "slash",
|
|
59
|
+
"body": ["/${1:tag}"],
|
|
60
|
+
"description": "Union tag projection (assert and unwrap): /tag"
|
|
61
|
+
},
|
|
62
|
+
"Variant introduction": {
|
|
63
|
+
"prefix": "vid",
|
|
64
|
+
"body": ["|${1:tag}"],
|
|
65
|
+
"description": "Variant (tagged union) introduction: |tag"
|
|
66
|
+
},
|
|
67
|
+
"Type annotation": {
|
|
68
|
+
"prefix": "typeref",
|
|
69
|
+
"body": ["\\$${1:typename}"],
|
|
70
|
+
"description": "Type annotation: pin expression output to a named code"
|
|
71
|
+
},
|
|
72
|
+
"Typed input constraint": {
|
|
73
|
+
"prefix": "typedprod",
|
|
74
|
+
"body": ["\\${ ${1:type1} ${2:field1}, ${3:type2} ${4:field2} }"],
|
|
75
|
+
"description": "Typed product input constraint: ${ type label, ... }"
|
|
76
|
+
},
|
|
77
|
+
"Identity": {
|
|
78
|
+
"prefix": "id",
|
|
79
|
+
"body": ["()"],
|
|
80
|
+
"description": "Identity function: pass value through unchanged"
|
|
81
|
+
},
|
|
82
|
+
"Empty product (unit leaf)": {
|
|
83
|
+
"prefix": "unit",
|
|
84
|
+
"body": ["{}"],
|
|
85
|
+
"description": "Empty product: the only leaf value in non-recursive definitions"
|
|
86
|
+
},
|
|
87
|
+
"Always undefined": {
|
|
88
|
+
"prefix": "undef",
|
|
89
|
+
"body": ["<>"],
|
|
90
|
+
"description": "Empty merge: always undefined (bottom)"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
|
3
|
+
"name": "k",
|
|
4
|
+
"scopeName": "source.k",
|
|
5
|
+
"patterns": [
|
|
6
|
+
{ "include": "#comment-block" },
|
|
7
|
+
{ "include": "#comment-line" },
|
|
8
|
+
{ "include": "#type-definition" },
|
|
9
|
+
{ "include": "#function-definition" },
|
|
10
|
+
{ "include": "#filter" },
|
|
11
|
+
{ "include": "#type-ref" },
|
|
12
|
+
{ "include": "#canonical-ref" },
|
|
13
|
+
{ "include": "#projection-dot" },
|
|
14
|
+
{ "include": "#projection-slash" },
|
|
15
|
+
{ "include": "#variant-intro" },
|
|
16
|
+
{ "include": "#string-double" },
|
|
17
|
+
{ "include": "#string-single" },
|
|
18
|
+
{ "include": "#dots" },
|
|
19
|
+
{ "include": "#operators" },
|
|
20
|
+
{ "include": "#brackets" }
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
|
|
24
|
+
"comment-block": {
|
|
25
|
+
"name": "comment.block.k",
|
|
26
|
+
"begin": "/\\*",
|
|
27
|
+
"end": "\\*/",
|
|
28
|
+
"beginCaptures": { "0": { "name": "punctuation.definition.comment.k" } },
|
|
29
|
+
"endCaptures": { "0": { "name": "punctuation.definition.comment.k" } }
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
"comment-line": {
|
|
33
|
+
"name": "comment.line.k",
|
|
34
|
+
"match": "(?://|--|%|#).*$"
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
"type-definition": {
|
|
38
|
+
"comment": "$ name = ... ; — defines a named code (type)",
|
|
39
|
+
"match": "(\\$)\\s*([a-zA-Z0-9_+\\-][a-zA-Z0-9_?!+\\-]*)(?=\\s*=)",
|
|
40
|
+
"captures": {
|
|
41
|
+
"1": { "name": "keyword.operator.type.k" },
|
|
42
|
+
"2": { "name": "entity.name.type.k" }
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
"function-definition": {
|
|
47
|
+
"comment": "name = ... ; — top-level function/relation definition",
|
|
48
|
+
"match": "^\\s*([a-zA-Z_][a-zA-Z0-9_?!+\\-]*)\\s*(?==)",
|
|
49
|
+
"captures": {
|
|
50
|
+
"1": { "name": "entity.name.function.k" }
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
"filter": {
|
|
55
|
+
"comment": "? introduces a filter/pattern constraint: ?<...>=X, ?{...}=X",
|
|
56
|
+
"patterns": [
|
|
57
|
+
{
|
|
58
|
+
"comment": "filter union ?< ... > = X",
|
|
59
|
+
"begin": "(\\?)\\s*(<)",
|
|
60
|
+
"end": "(>)(?:\\s*(=)\\s*([a-zA-Z0-9_?!+\\-]+))?",
|
|
61
|
+
"beginCaptures": {
|
|
62
|
+
"1": { "name": "keyword.operator.filter.k" },
|
|
63
|
+
"2": { "name": "punctuation.brackets.k" }
|
|
64
|
+
},
|
|
65
|
+
"endCaptures": {
|
|
66
|
+
"1": { "name": "punctuation.brackets.k" },
|
|
67
|
+
"2": { "name": "keyword.operator.filter.k" },
|
|
68
|
+
"3": { "name": "variable.other.pattern.k" }
|
|
69
|
+
},
|
|
70
|
+
"patterns": [
|
|
71
|
+
{ "include": "#comment-block" },
|
|
72
|
+
{ "include": "#comment-line" },
|
|
73
|
+
{ "include": "#filter" },
|
|
74
|
+
{ "include": "#pattern-variable" },
|
|
75
|
+
{ "include": "#type-ref" },
|
|
76
|
+
{ "include": "#string-double" },
|
|
77
|
+
{ "include": "#string-single" },
|
|
78
|
+
{ "include": "#dots" },
|
|
79
|
+
{ "include": "#operators" },
|
|
80
|
+
{ "include": "#brackets" }
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"comment": "filter product ?{ ... } = X",
|
|
85
|
+
"begin": "(\\?)\\s*(\\{)",
|
|
86
|
+
"end": "(\\})(?:\\s*(=)\\s*([a-zA-Z0-9_?!+\\-]+))?",
|
|
87
|
+
"beginCaptures": {
|
|
88
|
+
"1": { "name": "keyword.operator.filter.k" },
|
|
89
|
+
"2": { "name": "punctuation.brackets.k" }
|
|
90
|
+
},
|
|
91
|
+
"endCaptures": {
|
|
92
|
+
"1": { "name": "punctuation.brackets.k" },
|
|
93
|
+
"2": { "name": "keyword.operator.filter.k" },
|
|
94
|
+
"3": { "name": "variable.other.pattern.k" }
|
|
95
|
+
},
|
|
96
|
+
"patterns": [
|
|
97
|
+
{ "include": "#comment-block" },
|
|
98
|
+
{ "include": "#comment-line" },
|
|
99
|
+
{ "include": "#filter" },
|
|
100
|
+
{ "include": "#pattern-variable" },
|
|
101
|
+
{ "include": "#type-ref" },
|
|
102
|
+
{ "include": "#string-double" },
|
|
103
|
+
{ "include": "#string-single" },
|
|
104
|
+
{ "include": "#dots" },
|
|
105
|
+
{ "include": "#operators" },
|
|
106
|
+
{ "include": "#brackets" }
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
"pattern-variable": {
|
|
113
|
+
"comment": "Uppercase identifiers used as pattern variables inside filter expressions",
|
|
114
|
+
"name": "variable.other.pattern.k",
|
|
115
|
+
"match": "\\b[A-Z][a-zA-Z0-9_]*\\b"
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
"type-ref": {
|
|
119
|
+
"comment": "$name — use of a named code as a type annotation or type expression",
|
|
120
|
+
"match": "(\\$)([a-zA-Z0-9_+\\-][a-zA-Z0-9_?!+\\-]*)?",
|
|
121
|
+
"captures": {
|
|
122
|
+
"1": { "name": "keyword.operator.type.k" },
|
|
123
|
+
"2": { "name": "storage.type.k" }
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
"canonical-ref": {
|
|
128
|
+
"comment": "@base58hash — content-addressed canonical code reference",
|
|
129
|
+
"name": "variable.other.constant.k",
|
|
130
|
+
"match": "@[a-zA-Z0-9]+"
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
"projection-dot": {
|
|
134
|
+
"comment": ".label or .\"label\" — product field projection",
|
|
135
|
+
"patterns": [
|
|
136
|
+
{
|
|
137
|
+
"name": "keyword.operator.projection.k",
|
|
138
|
+
"match": "\\.(?:[a-zA-Z0-9_+\\-][a-zA-Z0-9_?!+\\-]*)"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"begin": "\\.(\")",
|
|
142
|
+
"end": "\"",
|
|
143
|
+
"beginCaptures": { "0": { "name": "keyword.operator.projection.k" } },
|
|
144
|
+
"endCaptures": { "0": { "name": "keyword.operator.projection.k" } },
|
|
145
|
+
"contentName": "string.quoted.double.k"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"begin": "\\.(\')",
|
|
149
|
+
"end": "\'",
|
|
150
|
+
"beginCaptures": { "0": { "name": "keyword.operator.projection.k" } },
|
|
151
|
+
"endCaptures": { "0": { "name": "keyword.operator.projection.k" } },
|
|
152
|
+
"contentName": "string.quoted.single.k"
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
"projection-slash": {
|
|
158
|
+
"comment": "/tag or /\"tag\" — union tag projection (assert and unwrap)",
|
|
159
|
+
"patterns": [
|
|
160
|
+
{
|
|
161
|
+
"name": "keyword.operator.projection.k",
|
|
162
|
+
"match": "/(?:[a-zA-Z0-9_+\\-][a-zA-Z0-9_?!+\\-]*)"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"begin": "/(\")",
|
|
166
|
+
"end": "\"",
|
|
167
|
+
"beginCaptures": { "0": { "name": "keyword.operator.projection.k" } },
|
|
168
|
+
"endCaptures": { "0": { "name": "keyword.operator.projection.k" } },
|
|
169
|
+
"contentName": "string.quoted.double.k"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"begin": "/(\')",
|
|
173
|
+
"end": "\'",
|
|
174
|
+
"beginCaptures": { "0": { "name": "keyword.operator.projection.k" } },
|
|
175
|
+
"endCaptures": { "0": { "name": "keyword.operator.projection.k" } },
|
|
176
|
+
"contentName": "string.quoted.single.k"
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
"variant-intro": {
|
|
182
|
+
"comment": "|tag or |\"tag\" — variant (tagged union) introduction",
|
|
183
|
+
"patterns": [
|
|
184
|
+
{
|
|
185
|
+
"name": "keyword.operator.intro.k",
|
|
186
|
+
"match": "\\|[a-zA-Z0-9_+\\-][a-zA-Z0-9_?!+\\-]*"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"begin": "\\|(\")",
|
|
190
|
+
"end": "\"",
|
|
191
|
+
"beginCaptures": { "0": { "name": "keyword.operator.intro.k" } },
|
|
192
|
+
"endCaptures": { "0": { "name": "keyword.operator.intro.k" } },
|
|
193
|
+
"contentName": "string.quoted.double.k"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"begin": "\\|(\')",
|
|
197
|
+
"end": "\'",
|
|
198
|
+
"beginCaptures": { "0": { "name": "keyword.operator.intro.k" } },
|
|
199
|
+
"endCaptures": { "0": { "name": "keyword.operator.intro.k" } },
|
|
200
|
+
"contentName": "string.quoted.single.k"
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
"string-double": {
|
|
206
|
+
"name": "string.quoted.double.k",
|
|
207
|
+
"begin": "\"",
|
|
208
|
+
"end": "\"",
|
|
209
|
+
"patterns": [
|
|
210
|
+
{ "name": "constant.character.escape.k", "match": "\\\\(?:[\"\\\\/bfnrt]|u[0-9a-fA-F]{4})" },
|
|
211
|
+
{ "name": "invalid.illegal.escape.k", "match": "\\\\." }
|
|
212
|
+
]
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
"string-single": {
|
|
216
|
+
"name": "string.quoted.single.k",
|
|
217
|
+
"begin": "'",
|
|
218
|
+
"end": "'",
|
|
219
|
+
"patterns": [
|
|
220
|
+
{ "name": "constant.character.escape.k", "match": "\\\\(?:['\\\\/bfnrt]|u[0-9a-fA-F]{4})" },
|
|
221
|
+
{ "name": "invalid.illegal.escape.k", "match": "\\\\." }
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
"dots": {
|
|
226
|
+
"comment": "... — the any/open pattern (unconstrained position)",
|
|
227
|
+
"name": "constant.language.k",
|
|
228
|
+
"match": "\\.\\.\\."
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
"operators": {
|
|
232
|
+
"comment": "= ; , : ~ — structural separators and definition operators",
|
|
233
|
+
"name": "punctuation.separator.k",
|
|
234
|
+
"match": "[=;,:]|~"
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
"brackets": {
|
|
238
|
+
"comment": "{ } ( ) < > — grouping and combinator delimiters",
|
|
239
|
+
"name": "punctuation.brackets.k",
|
|
240
|
+
"match": "[{}()<>]"
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
package/k.mjs
CHANGED
|
@@ -2,77 +2,79 @@
|
|
|
2
2
|
// !/usr/bin/node --stack-size=8000
|
|
3
3
|
|
|
4
4
|
import fs from "node:fs";
|
|
5
|
+
import { argv, stdin, exit, stdout } from "node:process";
|
|
5
6
|
import k from "./index.mjs";
|
|
7
|
+
import { decodeWire, encodeToWire } from "./codecs/runtime/prefix-codec.mjs";
|
|
8
|
+
import { decodeObject, objectToFunction, loadLibrary } from "./object.mjs";
|
|
6
9
|
|
|
7
|
-
const prog =
|
|
10
|
+
const prog = argv[1];
|
|
8
11
|
|
|
9
|
-
let kScript,
|
|
12
|
+
let kScript, inputStream;
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
function usage() {
|
|
15
|
+
console.error(`Usage: ${prog} [ --lib lib-file ]... ( k-expr | -k file ) [ input-file ]`);
|
|
16
|
+
console.error(` E.g., echo '["zebara","ela"]' | ./codecs/k-parse.mjs --input-type '$x=<{} zebara, {} ela>; $v={x 0, x 1}; $v' | ${prog} '{.1 0}'`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function compileFile(path, libraries) {
|
|
20
|
+
const buffer = fs.readFileSync(path);
|
|
21
|
+
try {
|
|
22
|
+
return objectToFunction(decodeObject(buffer));
|
|
23
|
+
} catch {
|
|
24
|
+
return k.compile(buffer.toString("utf8"), { libraries });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
({ kScript, inputStream } = ((args) => {
|
|
13
29
|
try {
|
|
14
|
-
|
|
30
|
+
const libraries = [];
|
|
31
|
+
// Parse --lib flags
|
|
32
|
+
while (args.length > 0 && args[0] === "--lib") {
|
|
33
|
+
args.shift();
|
|
34
|
+
const libPath = args.shift();
|
|
35
|
+
if (!libPath) throw new Error("--lib requires a file argument");
|
|
36
|
+
const libBuffer = fs.readFileSync(libPath);
|
|
37
|
+
libraries.push(loadLibrary(decodeObject(libBuffer)));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let kScriptStr = (function (arg) {
|
|
15
41
|
if (arg == null) {
|
|
16
|
-
throw new Error();
|
|
42
|
+
throw new Error("Missing script argument");
|
|
17
43
|
}
|
|
18
44
|
if (arg === "-k") {
|
|
19
|
-
return
|
|
45
|
+
return compileFile(args.shift(), libraries);
|
|
20
46
|
} else {
|
|
21
47
|
return arg;
|
|
22
48
|
}
|
|
23
49
|
})(args.shift());
|
|
24
|
-
kScript = k.compile(
|
|
25
|
-
|
|
26
|
-
if (arg === "-1") {
|
|
27
|
-
oneJson = true;
|
|
28
|
-
arg = args.shift();
|
|
29
|
-
}
|
|
50
|
+
let kScript = typeof kScriptStr === "function" ? kScriptStr : k.compile(kScriptStr, { libraries });
|
|
51
|
+
inputStream = (function (arg) {
|
|
30
52
|
if (arg == null) {
|
|
31
|
-
return
|
|
53
|
+
return stdin;
|
|
32
54
|
}
|
|
33
55
|
return fs.createReadStream(arg);
|
|
34
56
|
})(args.shift());
|
|
35
|
-
return { kScript,
|
|
57
|
+
return { kScript, inputStream };
|
|
36
58
|
} catch (error) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
console.error(` E.g., echo '{\"a\": 12}' | ${prog} '[(),()]'`);
|
|
41
|
-
return process.exit(-1);
|
|
59
|
+
console.error(error);
|
|
60
|
+
usage();
|
|
61
|
+
return exit(-1);
|
|
42
62
|
}
|
|
43
|
-
})(
|
|
63
|
+
})(argv.slice(2)));
|
|
44
64
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
});
|
|
55
|
-
} else {
|
|
56
|
-
let buffer = [];
|
|
57
|
-
let line = 0;
|
|
58
|
-
jsonStream.on("data", (data) => {
|
|
59
|
-
const [first, ...rest] = data.toString("utf8").split("\n");
|
|
60
|
-
buffer.push(first);
|
|
61
|
-
if (rest.length > 0) {
|
|
62
|
-
const todo = buffer.join("");
|
|
63
|
-
const last = rest.pop();
|
|
64
|
-
buffer = [last];;
|
|
65
|
-
for (const exp of [todo, ...rest]) {
|
|
66
|
-
if (!exp.match(/^[ \n\t]*(?:#.*)?$/)) {
|
|
67
|
-
try {
|
|
68
|
-
console.log(JSON.stringify(kScript(JSON.parse(exp))));
|
|
69
|
-
} catch (error) {
|
|
70
|
-
console.error(`Problem [line ${line}]: '${exp}'`);
|
|
71
|
-
console.error(error);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
line++;
|
|
75
|
-
}
|
|
65
|
+
const buffer = [];
|
|
66
|
+
inputStream.on("data", (data) => buffer.push(Buffer.isBuffer(data) ? data : Buffer.from(data)));
|
|
67
|
+
inputStream.on("end", () => {
|
|
68
|
+
try {
|
|
69
|
+
const inputBuffer = Buffer.concat(buffer);
|
|
70
|
+
const { pattern: inputPattern, value } = decodeWire(inputBuffer);
|
|
71
|
+
const result = kScript(value);
|
|
72
|
+
if (result === undefined) {
|
|
73
|
+
throw new Error("k expression evaluated to undefined; cannot encode undefined output value");
|
|
76
74
|
}
|
|
77
|
-
|
|
78
|
-
}
|
|
75
|
+
stdout.write(encodeToWire(result, result.pattern));
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error(error);
|
|
78
|
+
process.exitCode = 1;
|
|
79
|
+
}
|
|
80
|
+
});
|