aontu 0.60.0 → 0.62.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/README.md +3 -3
- package/dist/agentsmd.d.ts +1 -0
- package/dist/agentsmd.js +7 -1
- package/dist/agentsmd.js.map +1 -1
- package/dist/allow.d.ts +23 -0
- package/dist/allow.js +230 -0
- package/dist/allow.js.map +1 -0
- package/dist/aontu.d.ts +4 -2
- package/dist/aontu.js +4 -2
- package/dist/aontu.js.map +1 -1
- package/dist/cli.d.ts +10 -1
- package/dist/cli.js +1000 -47
- package/dist/cli.js.map +1 -1
- package/dist/format.d.ts +1 -0
- package/dist/format.js +154 -12
- package/dist/format.js.map +1 -1
- package/dist/helpdoc.d.ts +16 -0
- package/dist/helpdoc.js +59 -0
- package/dist/helpdoc.js.map +1 -0
- package/dist/hints.js +15 -2
- package/dist/hints.js.map +1 -1
- package/dist/lang.js +93 -40
- package/dist/lang.js.map +1 -1
- package/dist/lower.d.ts +3 -0
- package/dist/lower.js +3 -0
- package/dist/lower.js.map +1 -1
- package/dist/lsp.d.ts +1 -1
- package/dist/lsp.js +1 -1
- package/dist/lsp.js.map +1 -1
- package/dist/relation.d.ts +2 -0
- package/dist/relation.js +7 -1
- package/dist/relation.js.map +1 -1
- package/dist/render.js +26 -21
- package/dist/render.js.map +1 -1
- package/dist/sigdecl.js +1 -1
- package/dist/sigdecl.js.map +1 -1
- package/dist/std.js +112 -69
- package/dist/std.js.map +1 -1
- package/dist/template.d.ts +2 -1
- package/dist/template.js +51 -15
- package/dist/template.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/val/AggFuncVal.js +2 -2
- package/dist/val/AggFuncVal.js.map +1 -1
- package/dist/val/CmpFuncVal.d.ts +20 -0
- package/dist/val/CmpFuncVal.js +245 -0
- package/dist/val/CmpFuncVal.js.map +1 -0
- package/dist/val/EachFuncVal.d.ts +1 -2
- package/dist/val/EachFuncVal.js +15 -29
- package/dist/val/EachFuncVal.js.map +1 -1
- package/dist/val/FormFuncVal.js.map +1 -1
- package/dist/val/LowerFuncVal.js +17 -1
- package/dist/val/LowerFuncVal.js.map +1 -1
- package/dist/val/NamerFuncVal.d.ts +12 -0
- package/dist/val/NamerFuncVal.js +176 -0
- package/dist/val/NamerFuncVal.js.map +1 -0
- package/dist/val/NilVal.js +29 -3
- package/dist/val/NilVal.js.map +1 -1
- package/dist/val/NomFuncVal.d.ts +12 -0
- package/dist/val/NomFuncVal.js +187 -0
- package/dist/val/NomFuncVal.js.map +1 -0
- package/dist/val/PackFuncVal.js +3 -3
- package/dist/val/PackFuncVal.js.map +1 -1
- package/dist/val/RefVal.js +1 -1
- package/dist/val/TranslateFuncVal.d.ts +12 -0
- package/dist/val/TranslateFuncVal.js +101 -0
- package/dist/val/TranslateFuncVal.js.map +1 -0
- package/dist/val/UpperFuncVal.js +17 -1
- package/dist/val/UpperFuncVal.js.map +1 -1
- package/dist/val/caserange.d.ts +3 -0
- package/dist/val/caserange.js +110 -0
- package/dist/val/caserange.js.map +1 -0
- package/dist/vet.d.ts +12 -0
- package/dist/vet.js +209 -1
- package/dist/vet.js.map +1 -1
- package/grammar/aontu.abnf +1 -1
- package/grammar/aontu.gbnf +1 -1
- package/grammar/aontu.lark +1 -1
- package/grammar/aontu.tmLanguage.json +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +8 -0
- package/skill/init/check.sh +28 -0
- package/skill/init/data.aon +12 -0
- package/skill/init/model.aon +19 -0
- package/skill/tasks.md +151 -0
- package/src/agentsmd.ts +13 -2
- package/src/allow.ts +316 -0
- package/src/aontu.ts +10 -1
- package/src/cli.ts +1131 -53
- package/src/format.ts +191 -14
- package/src/helpdoc.ts +77 -0
- package/src/hints.ts +16 -2
- package/src/lang.ts +98 -42
- package/src/lower.ts +3 -3
- package/src/lsp.ts +1 -1
- package/src/relation.ts +21 -1
- package/src/render.ts +26 -21
- package/src/sigdecl.ts +1 -1
- package/src/std.ts +112 -69
- package/src/template.ts +55 -15
- package/src/val/AggFuncVal.ts +2 -2
- package/src/val/CmpFuncVal.ts +411 -0
- package/src/val/EachFuncVal.ts +49 -50
- package/src/val/LowerFuncVal.ts +18 -1
- package/src/val/NilVal.ts +29 -3
- package/src/val/NomFuncVal.ts +287 -0
- package/src/val/PackFuncVal.ts +3 -3
- package/src/val/RefVal.ts +1 -1
- package/src/val/TranslateFuncVal.ts +182 -0
- package/src/val/UpperFuncVal.ts +18 -1
- package/src/val/caserange.ts +115 -0
- package/src/vet.ts +287 -1
- package/src/val/FormFuncVal.ts +0 -119
package/src/std.ts
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
/* Copyright (c) 2025 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
|
-
// THE
|
|
4
|
-
// docs/capability-review/g4-identity-relations.md): `@"
|
|
5
|
-
// served from the engine itself — no filesystem, no package
|
|
6
|
-
// — so a document may use it under every include capability
|
|
7
|
-
// `none`, and the hermeticity posture is not widened by a source
|
|
8
|
-
// never leaves the process.
|
|
3
|
+
// THE LANGUAGE-SUPPLIED MODELS (G4 phase 4,
|
|
4
|
+
// docs/capability-review/g4-identity-relations.md): `@"aontu:system"`
|
|
5
|
+
// is served from the engine itself — no filesystem, no package
|
|
6
|
+
// resolution — so a document may use it under every include capability
|
|
7
|
+
// except `none`, and the hermeticity posture is not widened by a source
|
|
8
|
+
// that never leaves the process.
|
|
9
|
+
//
|
|
10
|
+
// EVERY name here carries the `aontu:` prefix (ADR-028): a
|
|
11
|
+
// language-supplied schema is spelled one way, and the scheme is what
|
|
12
|
+
// makes it unshadowable. There is no second, bare-name spelling.
|
|
9
13
|
//
|
|
10
14
|
// The TEXT is the shared artifact: go/std.go carries the same bytes,
|
|
11
|
-
// and test/spec/
|
|
15
|
+
// and test/spec/aontu-system.tsv pins its canon and its canon-hash in
|
|
12
16
|
// both engines, so the two copies cannot drift without a red suite.
|
|
13
17
|
// It carries no backtick for that reason: one string literal per port,
|
|
14
18
|
// and Go's raw string has no escape.
|
|
15
19
|
|
|
16
|
-
const STD_SYSTEM = `#
|
|
20
|
+
const STD_SYSTEM = `# aontu:system --- the SYSTEM VOCABULARY (G4 phase 4). Ports, components
|
|
17
21
|
# and relations need no syntax: they are schemas. Everything here is
|
|
18
22
|
# ordinary unification --- conjunction, spreads, marks, defaults ---
|
|
19
23
|
# so the vocabulary costs the language nothing, and an author who wants
|
|
@@ -24,31 +28,57 @@ const STD_SYSTEM = `# std/system --- the SYSTEM VOCABULARY (G4 phase 4). Ports,
|
|
|
24
28
|
# identity and version makes "v1 and v2 describe the same entity"
|
|
25
29
|
# inexpressible.
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
aontu: System: {
|
|
29
32
|
# One end of a connection.
|
|
30
|
-
Port: type({
|
|
31
|
-
direction: *in | out | inout
|
|
32
|
-
protocol?: string
|
|
33
|
-
})
|
|
33
|
+
Port: type({ direction:*in | out | inout protocol?:string })
|
|
34
34
|
|
|
35
35
|
# A node with ports. Where a Component sits in the tree is what it
|
|
36
36
|
# is a component OF -- containment is the document's own structure
|
|
37
37
|
# and needs no mark of its own.
|
|
38
|
-
Component: type({
|
|
39
|
-
ports?: {&: $.std.Port}
|
|
40
|
-
})
|
|
38
|
+
Component: type({ ports?:{ &: $.aontu.System.Port } })
|
|
41
39
|
|
|
42
40
|
# A component that is a service. Written out rather than as
|
|
43
|
-
# $.
|
|
41
|
+
# $.aontu.System.Component & {kind: service}: a reference from one member of
|
|
44
42
|
# this file to another does not survive being INCLUDED into a
|
|
45
43
|
# document (the marks the include carries make the referring member
|
|
46
44
|
# unusable), so the vocabulary states each schema on its own.
|
|
47
|
-
Service: type({
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
Service: type({ kind:service ports?:{ &: $.aontu.System.Port } })
|
|
46
|
+
|
|
47
|
+
# A semantic version (semver.org 2.0.0) as an ORDERED TUPLE: major,
|
|
48
|
+
# minor, patch, pre-release. A list and not a dotted string, because a
|
|
49
|
+
# version is COMPARED and the comparison runs component by component
|
|
50
|
+
# from the left: "1.10.0" sorts below "1.9.0" as text. A list and not
|
|
51
|
+
# a map, because a map has no order of its own to compare along.
|
|
52
|
+
#
|
|
53
|
+
# THE TAIL DEFAULTS, so [1] is [1 0 0 ""] and [1 2] is [1 2 0 ""].
|
|
54
|
+
# A major-only version is the common case and should cost one token.
|
|
55
|
+
#
|
|
56
|
+
# LEADING ZEROES ARE IMPOSSIBLE HERE rather than merely forbidden:
|
|
57
|
+
# the numeric parts are integers, and 01 is not a distinct integer
|
|
58
|
+
# literal. The spec's "MUST NOT contain leading zeroes" needs no rule.
|
|
59
|
+
#
|
|
60
|
+
# THE PRE-RELEASE CHECK IS PARTIAL, and deliberately says so. The
|
|
61
|
+
# spec's grammar is dot-separated identifiers, each non-empty, each
|
|
62
|
+
# [0-9A-Za-z-], numeric ones without leading zeroes -- which as a
|
|
63
|
+
# regex is a quantified group containing a quantifier, and re()
|
|
64
|
+
# refuses that shape outright (constraint_pattern) because it
|
|
65
|
+
# backtracks exponentially. So the alphabet is checked and the
|
|
66
|
+
# STRUCTURE is not: "beta_1" is refused, "alpha..1" and "01" are not.
|
|
67
|
+
# Carrying the pre-release as a LIST of identifiers would check it in
|
|
68
|
+
# full, one identifier per element, and is the change to make if that
|
|
69
|
+
# matters more than [1 0 0 ""] does.
|
|
70
|
+
#
|
|
71
|
+
# BUILD METADATA IS NOT CARRIED. The spec has it, and the spec also
|
|
72
|
+
# says it MUST be ignored when determining precedence -- so a type
|
|
73
|
+
# whose purpose is comparison is the wrong place for it.
|
|
74
|
+
Semver: type(
|
|
75
|
+
[
|
|
76
|
+
integer & min(0)
|
|
77
|
+
*0 | (integer & min(0))
|
|
78
|
+
*0 | (integer & min(0))
|
|
79
|
+
*"" | (string & re("^[0-9A-Za-z.-]+$"))
|
|
80
|
+
] & length(4)
|
|
81
|
+
)
|
|
52
82
|
# (The Relation schema that used to sit here is retired with the
|
|
53
83
|
# relations: magic key, RELATIONS.0.md P2: a relation is declared
|
|
54
84
|
# by the graph atoms at its field -- rel(t) & acyclic() &
|
|
@@ -57,17 +87,17 @@ std: {
|
|
|
57
87
|
`
|
|
58
88
|
|
|
59
89
|
|
|
60
|
-
const STD_VIEW = `#
|
|
90
|
+
const STD_VIEW = `# aontu:view --- the FIGURE VOCABULARY (VIEWS.0.md, "6. The view
|
|
61
91
|
# document"). A view document declares its figures as data, and a
|
|
62
92
|
# declaration is just a map: this is the schema for one, so a typo is
|
|
63
93
|
# refused where every other mistake in an aontu document is refused --
|
|
64
94
|
# at evaluation, by unification -- rather than by the verb that reads
|
|
65
95
|
# it afterwards.
|
|
66
96
|
#
|
|
67
|
-
# @"
|
|
97
|
+
# @"aontu:view"
|
|
68
98
|
# @"./system.aon"
|
|
69
99
|
#
|
|
70
|
-
# views: {&: $.
|
|
100
|
+
# views: {&: $.aontu.View.Figure} & {
|
|
71
101
|
# arch: {kind: matrix, order: partition, out: "docs/arch.dsm.txt"}
|
|
72
102
|
# }
|
|
73
103
|
#
|
|
@@ -81,8 +111,7 @@ const STD_VIEW = `# std/view --- the FIGURE VOCABULARY (VIEWS.0.md, "6. The view
|
|
|
81
111
|
# canon-hash. This file carries no backtick: it is one string literal
|
|
82
112
|
# per port, and Go raw strings have no escape.
|
|
83
113
|
|
|
84
|
-
|
|
85
|
-
|
|
114
|
+
aontu: View: {
|
|
86
115
|
# One declared figure. The kind says what to draw and out says where
|
|
87
116
|
# it belongs; everything else narrows the drawing, and each option
|
|
88
117
|
# belongs to the kinds that read it.
|
|
@@ -186,6 +215,7 @@ const STD_CODE = String.raw`# aontu:code --- THE OUTPUT VOCABULARY. An aontu tra
|
|
|
186
215
|
k: "prim"
|
|
187
216
|
prim: "string" | "int" | "bigint" | "float" | "decimal" | "bool" | "null" | "any"
|
|
188
217
|
})
|
|
218
|
+
|
|
189
219
|
%ref = close({ k:"ref" name:%name unit?:string })
|
|
190
220
|
%leaf = %prim | %ref | %text
|
|
191
221
|
|
|
@@ -208,6 +238,7 @@ const STD_CODE = String.raw`# aontu:code --- THE OUTPUT VOCABULARY. An aontu tra
|
|
|
208
238
|
})
|
|
209
239
|
|
|
210
240
|
%member = close({ name:%name value?:string | number doc?:%doc x?:{} })
|
|
241
|
+
|
|
211
242
|
%param = close({
|
|
212
243
|
name: %name
|
|
213
244
|
type: %type
|
|
@@ -221,12 +252,14 @@ const STD_CODE = String.raw`# aontu:code --- THE OUTPUT VOCABULARY. An aontu tra
|
|
|
221
252
|
%inline = string & re("^[^\n\r]*$") | %ref
|
|
222
253
|
%line = close({ k:"line" at:*0 | integer & min(0) & max(64) of:[&: %inline] })
|
|
223
254
|
%blank = close({ k:"blank" n:*1 | integer & min(1) & max(16) })
|
|
255
|
+
|
|
224
256
|
%raw = close({
|
|
225
257
|
k: "raw"
|
|
226
258
|
at: *0 | integer & min(0) & max(64)
|
|
227
259
|
text: string
|
|
228
260
|
reindent: *true | boolean
|
|
229
261
|
})
|
|
262
|
+
|
|
230
263
|
%piece = %line | %blank | %raw | string & re("^[^\n\r]*$")
|
|
231
264
|
%frag = close({ k:"frag" of:[&: %piece] })
|
|
232
265
|
%body = %frag | close({ k:"abstract" })
|
|
@@ -241,7 +274,9 @@ const STD_CODE = String.raw`# aontu:code --- THE OUTPUT VOCABULARY. An aontu tra
|
|
|
241
274
|
check?: [&: %check]
|
|
242
275
|
x?: {}
|
|
243
276
|
})
|
|
277
|
+
|
|
244
278
|
%enum = close({ k:"enum" name:%name doc?:%doc members:[&: %member] x?:{} })
|
|
279
|
+
|
|
245
280
|
%alias = close({
|
|
246
281
|
k: "alias"
|
|
247
282
|
name: %name
|
|
@@ -250,6 +285,7 @@ const STD_CODE = String.raw`# aontu:code --- THE OUTPUT VOCABULARY. An aontu tra
|
|
|
250
285
|
check?: [&: %check]
|
|
251
286
|
x?: {}
|
|
252
287
|
})
|
|
288
|
+
|
|
253
289
|
%const = close({
|
|
254
290
|
k: "const"
|
|
255
291
|
name: %name
|
|
@@ -258,6 +294,7 @@ const STD_CODE = String.raw`# aontu:code --- THE OUTPUT VOCABULARY. An aontu tra
|
|
|
258
294
|
value: string | number | boolean | null
|
|
259
295
|
x?: {}
|
|
260
296
|
})
|
|
297
|
+
|
|
261
298
|
%func = close({
|
|
262
299
|
k: "func"
|
|
263
300
|
name: %name
|
|
@@ -290,7 +327,7 @@ const STD_CODE = String.raw`# aontu:code --- THE OUTPUT VOCABULARY. An aontu tra
|
|
|
290
327
|
|
|
291
328
|
%source = close({ path?:string hash?:string & re("^aon1-[A-Za-z0-9_-]+$") })
|
|
292
329
|
|
|
293
|
-
|
|
330
|
+
aontu: Code: close({ source?:%source units:[&: %unit] })
|
|
294
331
|
`
|
|
295
332
|
|
|
296
333
|
|
|
@@ -364,7 +401,7 @@ const STD_PROFILE = String.raw`# aontu:profile --- THE PROFILE VOCABULARY. A pro
|
|
|
364
401
|
banner?: string
|
|
365
402
|
})
|
|
366
403
|
|
|
367
|
-
|
|
404
|
+
aontu: Profile: %profile
|
|
368
405
|
`
|
|
369
406
|
|
|
370
407
|
|
|
@@ -381,7 +418,7 @@ const STD_LANG_TEXT = String.raw`# aontu:lang/text --- THE TEXT PROFILE. The pro
|
|
|
381
418
|
|
|
382
419
|
@"aontu:profile"
|
|
383
420
|
|
|
384
|
-
|
|
421
|
+
aontu: Profile: { lang:"text" indent:{ unit:" " width:2 } }
|
|
385
422
|
`
|
|
386
423
|
|
|
387
424
|
// THE TYPESCRIPT PROFILE (docs/design/RENDER.0.md D5, P5): the data the
|
|
@@ -402,7 +439,7 @@ const STD_LANG_TYPESCRIPT = String.raw`# aontu:lang/typescript --- THE TYPESCRIP
|
|
|
402
439
|
|
|
403
440
|
@"aontu:profile"
|
|
404
441
|
|
|
405
|
-
|
|
442
|
+
aontu: Profile: {
|
|
406
443
|
lang: "typescript"
|
|
407
444
|
lowering: "typescript"
|
|
408
445
|
indent: { unit:" " width:2 }
|
|
@@ -410,13 +447,15 @@ profile: {
|
|
|
410
447
|
comment: block: { open:"/*" prefix:" * " close:" */" }
|
|
411
448
|
comment: doc: { open:"/**" prefix:" * " close:" */" }
|
|
412
449
|
str: quote: "\""
|
|
413
|
-
str: escape:
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
450
|
+
str: escape: {
|
|
451
|
+
"8": "\\b"
|
|
452
|
+
"9": "\\t"
|
|
453
|
+
"10": "\\n"
|
|
454
|
+
"12": "\\f"
|
|
455
|
+
"13": "\\r"
|
|
456
|
+
"34": "\\\""
|
|
457
|
+
"92": "\\\\"
|
|
458
|
+
}
|
|
420
459
|
ident: {
|
|
421
460
|
chars: "ascii-word"
|
|
422
461
|
reserved: [
|
|
@@ -477,14 +516,16 @@ profile: {
|
|
|
477
516
|
case: alias: "pascal"
|
|
478
517
|
acronyms: []
|
|
479
518
|
}
|
|
480
|
-
types: prim:
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
519
|
+
types: prim: {
|
|
520
|
+
string: "string"
|
|
521
|
+
int: "number"
|
|
522
|
+
bigint: "bigint"
|
|
523
|
+
float: "number"
|
|
524
|
+
decimal: "string"
|
|
525
|
+
bool: "boolean"
|
|
526
|
+
null: "null"
|
|
527
|
+
any: "unknown"
|
|
528
|
+
}
|
|
488
529
|
types: list: { close:"[]" childPrec:2 }
|
|
489
530
|
types: map: { open:"Record<" close:">" }
|
|
490
531
|
types: opt: { close:" | null" prec:1 childPrec:2 }
|
|
@@ -512,21 +553,23 @@ const STD_LANG_GO = String.raw`# aontu:lang/go --- THE GO PROFILE. The data a un
|
|
|
512
553
|
|
|
513
554
|
@"aontu:profile"
|
|
514
555
|
|
|
515
|
-
|
|
556
|
+
aontu: Profile: {
|
|
516
557
|
lang: "go"
|
|
517
558
|
lowering: "go"
|
|
518
559
|
indent: { unit:"\t" width:1 }
|
|
519
560
|
comment: { line:prefix:"// " block:{ open:"/*" close:"*/" } doc:prefix:"// " }
|
|
520
561
|
str: quote: "\""
|
|
521
|
-
str: escape:
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
562
|
+
str: escape: {
|
|
563
|
+
"7": "\\a"
|
|
564
|
+
"8": "\\b"
|
|
565
|
+
"9": "\\t"
|
|
566
|
+
"10": "\\n"
|
|
567
|
+
"11": "\\v"
|
|
568
|
+
"12": "\\f"
|
|
569
|
+
"13": "\\r"
|
|
570
|
+
"34": "\\\""
|
|
571
|
+
"92": "\\\\"
|
|
572
|
+
}
|
|
530
573
|
ident: {
|
|
531
574
|
chars: "ascii-word"
|
|
532
575
|
reserved: [
|
|
@@ -605,14 +648,16 @@ profile: {
|
|
|
605
648
|
"XSS"
|
|
606
649
|
]
|
|
607
650
|
}
|
|
608
|
-
types: prim:
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
651
|
+
types: prim: {
|
|
652
|
+
string: "string"
|
|
653
|
+
int: "int64"
|
|
654
|
+
bigint: "string"
|
|
655
|
+
float: "float64"
|
|
656
|
+
decimal: "string"
|
|
657
|
+
bool: "bool"
|
|
658
|
+
null: "any"
|
|
659
|
+
any: "any"
|
|
660
|
+
}
|
|
616
661
|
types: list: open: "[]"
|
|
617
662
|
types: map: open: "map["
|
|
618
663
|
types: opt: open: "*"
|
|
@@ -621,10 +666,8 @@ profile: {
|
|
|
621
666
|
`
|
|
622
667
|
|
|
623
668
|
export const STD_SOURCES: Record<string, string> = {
|
|
624
|
-
'
|
|
625
|
-
'
|
|
626
|
-
'std/view': STD_VIEW,
|
|
627
|
-
'std/view.aon': STD_VIEW,
|
|
669
|
+
'aontu:system': STD_SYSTEM,
|
|
670
|
+
'aontu:view': STD_VIEW,
|
|
628
671
|
'aontu:code': STD_CODE,
|
|
629
672
|
'aontu:lang/go': STD_LANG_GO,
|
|
630
673
|
'aontu:lang/text': STD_LANG_TEXT,
|
package/src/template.ts
CHANGED
|
@@ -24,12 +24,22 @@
|
|
|
24
24
|
// comment, and derives for a language this table has never seen: the
|
|
25
25
|
// caller passes the token.
|
|
26
26
|
//
|
|
27
|
-
// A MARKER IS RECOGNISED AFTER LEADING WHITESPACE AND
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
// indented two spaces in the
|
|
31
|
-
//
|
|
32
|
-
// the
|
|
27
|
+
// A MARKER IS RECOGNISED AFTER LEADING WHITESPACE, AND THE INDENTATION
|
|
28
|
+
// THE RESUGARING WRITES IS THE AONTU'S (D2, amended 2026-09-07). An
|
|
29
|
+
// output line is verbatim -- a line indented two spaces in the template
|
|
30
|
+
// is indented two spaces in the generated file (D7) -- and that is the
|
|
31
|
+
// half a reader of the TARGET needs. The other half is the document:
|
|
32
|
+
// the marker lines carry a tree, and a tree nobody can see the shape of
|
|
33
|
+
// is the one thing this surface took away. So the marker stands at the
|
|
34
|
+
// left margin and the aontu is indented AFTER it, which `aontu fmt`
|
|
35
|
+
// (FMT.0.md M-BM-'3.14) is what writes.
|
|
36
|
+
//
|
|
37
|
+
// Reading is unchanged and stays generous: a marker after leading
|
|
38
|
+
// whitespace is a marker, and its own indentation still counts toward
|
|
39
|
+
// the aontu it carries, so a template written the other way desugars to
|
|
40
|
+
// the same document. What changes is the spelling the round trip
|
|
41
|
+
// answers, and `template --check` names the difference as the drift it
|
|
42
|
+
// is.
|
|
33
43
|
//
|
|
34
44
|
// THE SUGAR IS THE FIXPOINT OF THE TWO TRANSFORMS (D6), and that is
|
|
35
45
|
// the whole of the resugaring's safety. A canonical line that looks
|
|
@@ -128,13 +138,19 @@ function indentOf(line: string): number {
|
|
|
128
138
|
}
|
|
129
139
|
|
|
130
140
|
|
|
131
|
-
// The line without its
|
|
132
|
-
function
|
|
141
|
+
// The line without its trailing spaces and tabs.
|
|
142
|
+
function trimEnd(line: string): string {
|
|
133
143
|
let end = line.length
|
|
134
144
|
while (0 < end && (' ' === line[end - 1] || '\t' === line[end - 1])) {
|
|
135
145
|
end--
|
|
136
146
|
}
|
|
137
|
-
return line.slice(
|
|
147
|
+
return line.slice(0, end)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
// The line without its indentation or its trailing spaces and tabs.
|
|
152
|
+
function trimLine(line: string): string {
|
|
153
|
+
return trimEnd(line).slice(indentOf(line))
|
|
138
154
|
}
|
|
139
155
|
|
|
140
156
|
|
|
@@ -159,12 +175,15 @@ function readLine(line: string, marker: string): Line {
|
|
|
159
175
|
// The block form's closer is part of the marker, not of the aontu.
|
|
160
176
|
// A block marker line that never closes is not a marker line: the
|
|
161
177
|
// language's own parser would not read it as a comment either.
|
|
178
|
+
// Only the TRAILING space goes: what stands between the opener and
|
|
179
|
+
// the aontu is the aontu's indentation, exactly as it is for a line
|
|
180
|
+
// marker, and the one-space rule below takes the marker's own.
|
|
162
181
|
if (isBlock(marker)) {
|
|
163
182
|
const end = body.lastIndexOf(BLOCK_CLOSE)
|
|
164
183
|
if (end < 0) {
|
|
165
184
|
return { marker: false, indent: '', text: line }
|
|
166
185
|
}
|
|
167
|
-
body =
|
|
186
|
+
body = trimEnd(body.slice(0, end))
|
|
168
187
|
}
|
|
169
188
|
// ONE SPACE AFTER THE MARKER IS THE MARKER'S, so `//- x: 1` carries
|
|
170
189
|
// `x: 1` and the resugaring writes the space back. A marker written
|
|
@@ -273,19 +292,40 @@ function resugarTemplate(src: string, marker?: string): string {
|
|
|
273
292
|
if (undefined !== target && desugarTemplate(target, mark) === trimLine(line)) {
|
|
274
293
|
return target
|
|
275
294
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
295
|
+
// THE MARKER STANDS AT THE LEFT MARGIN and the line's indentation
|
|
296
|
+
// is written after it, so the aontu's own shape is on the page.
|
|
297
|
+
// The one space is the marker's, which the reading takes back.
|
|
298
|
+
const text = trimEnd(line)
|
|
279
299
|
const close = isBlock(mark) ? ' ' + BLOCK_CLOSE : ''
|
|
280
|
-
return '' === text ?
|
|
300
|
+
return '' === text ? mark + close : mark + ' ' + text + close
|
|
281
301
|
})
|
|
282
302
|
return out.join('\n') + (tail ? '\n' : '')
|
|
283
|
-
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
// WHICH LINES OF THE DESUGARED DOCUMENT ARE THE TARGET'S. The
|
|
307
|
+
// desugaring is line for line, so this is one flag per line of what
|
|
308
|
+
// `desugarTemplate` returns: true where the template's line was not a
|
|
309
|
+
// marker, and so where the document's line is one quoted line of the
|
|
310
|
+
// generated file.
|
|
311
|
+
//
|
|
312
|
+
// `aontu fmt` reads it (FMT.0.md M-BM-'3.14) to hold those lines on lines of
|
|
313
|
+
// their own. A body element is a string like any other, and the packing
|
|
314
|
+
// budget would put three of them on one line -- which is aontu where
|
|
315
|
+
// three lines of output were, and a generator that writes them as one.
|
|
316
|
+
function templateOutputs(src: string, marker: string): boolean[] {
|
|
317
|
+
const lines = src.split('\n')
|
|
318
|
+
if (1 < lines.length && '' === lines[lines.length - 1]) {
|
|
319
|
+
lines.pop()
|
|
320
|
+
}
|
|
321
|
+
return lines.map((line) => !readLine(line, marker).marker)
|
|
322
|
+
} /* node:coverage ignore next 9 */
|
|
284
323
|
|
|
285
324
|
|
|
286
325
|
export {
|
|
287
326
|
desugarTemplate,
|
|
288
327
|
resugarTemplate,
|
|
328
|
+
templateOutputs,
|
|
289
329
|
markerFor,
|
|
290
330
|
DEFAULT_MARKER,
|
|
291
331
|
}
|
package/src/val/AggFuncVal.ts
CHANGED
|
@@ -204,8 +204,8 @@ function unpref(v: any): any {
|
|
|
204
204
|
//
|
|
205
205
|
// total: sum(pick($.lines, amountCents))
|
|
206
206
|
//
|
|
207
|
-
// IT IS NOT `each` WITH A CLEVER TEMPLATE. `each(d, t)` MEETS each
|
|
208
|
-
// child with `t`, and a meet cannot select: `each($.lines, _.amount)`
|
|
207
|
+
// IT IS NOT `each` WITH A CLEVER TEMPLATE. `each(d, _ & t)` MEETS each
|
|
208
|
+
// child with `t`, and a meet cannot select: `each($.lines, _ & _.amount)`
|
|
209
209
|
// asks for a child that is simultaneously the whole record and one of
|
|
210
210
|
// its fields, which is why every spelling of it answers `no_path`.
|
|
211
211
|
// Selection is a different operation and gets its own verb.
|