capdag 1.426.27 → 1.439.69

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/machine.pegjs CHANGED
@@ -1,57 +1,152 @@
1
1
  // Machine notation grammar for Peggy.
2
2
  //
3
- // This grammar mirrors the Rust pest grammar in machine.pest exactly.
4
- // All actions return location() for LSP position tracking.
3
+ // This grammar reads the same language as the reference's pest grammar
4
+ // (capdag-rs/src/machine/machine.pest). Every part of a statement carries
5
+ // where it stands in the text, for editor support.
5
6
  //
6
7
  // Two equally valid statement forms:
7
8
  //
8
9
  // Bracketed (one or more statements per line, any layout):
9
- // [extract cap:in="media:ext=pdf";extract;out="media:txt;textable"]
10
+ // [extract cap:in="media:document;ext=pdf";extract;out="media:enc=utf-8;ext=txt"]
10
11
  // [doc -> extract -> text]
11
12
  //
12
13
  // Line-based (one statement per line, no brackets):
13
- // extract cap:in="media:ext=pdf";extract;out="media:txt;textable"
14
+ // extract cap:in="media:document;ext=pdf";extract;out="media:enc=utf-8;ext=txt"
14
15
  // doc -> extract -> text
15
16
  // (thumbnail, model_spec) -> describe -> description
16
17
  //
17
18
  // Both forms can be freely mixed in the same program.
19
+ //
20
+ // A wiring is one invocation: what it is given, the step, what is taken.
21
+ // (path, benchmark=bench) -> compare -> result a named member
22
+ // (prices, window=20, statistic="mean") -> rolling -> s constants: any JSON value
23
+ // () -> now -> stamp a source given nothing
24
+ // report -> publish -> () a sink
25
+ // obs -> regress -> (fit, residuals=res) several outputs
26
+ // ref -> fetch{retry=3} -> series a step policy
18
27
 
19
28
  program = _ stmts:stmt* _ { return stmts; }
20
29
 
21
- stmt = "[" _ inner:inner _ "]" _ { return inner; }
30
+ // A bracketed statement stands where its brackets do.
31
+ stmt = b:bracketed _ { return b; }
22
32
  / inner:inner _ { return inner; }
23
33
 
24
- inner = wiring / header
34
+ bracketed = "[" _ inner:inner _ "]" { return { ...inner, location: location() }; }
35
+
36
+ // A wiring is tried first: it is the only form with an arrow, and its first
37
+ // token may be a group. The two headers both start with an alias and are told
38
+ // apart by what follows it.
39
+ inner = wiring / machine_header / header
25
40
 
26
41
  // Header: alias followed by a cap URN starting with "cap:".
27
42
  header = a:alias_loc __ c:cap_urn_loc {
28
43
  return { type: 'header', alias: a.value, capUrn: c.value, location: location(), aliasLocation: a.location, capUrnLocation: c.location };
29
44
  }
30
45
 
31
- // Wiring: source -> cap -> target
46
+ // Machine header: an alias for another machine, usable in step position. The
47
+ // reference is an opaque string the host resolves; it is kept as written
48
+ // (`referenceText`), and read as the JSON string it is by the syntax layer.
49
+ machine_header = a:alias_loc __ machine_kw _ r:string_loc {
50
+ return { type: 'machine_header', alias: a.value, referenceText: r.value, location: location(), aliasLocation: a.location, referenceLocation: r.location };
51
+ }
52
+
53
+ machine_kw = "machine" !alias_continue
54
+
55
+ // Wiring: sources -> step -> targets
32
56
  //
33
- // The cap position is a plain alias. There is no LOOP marker: per-item map
34
- // (`is_loop`) is a derived cardinality property, never authored syntax.
35
- wiring = s:source_loc _ arrow _ c:alias_loc _ arrow _ t:alias_loc {
36
- return { type: 'wiring', sources: s.values, capAlias: c.value, target: t.value, location: location(), sourceLocations: s.locations, capAliasLocation: c.location, targetLocation: t.location };
57
+ // There is no per-item marker and no gather marker: both are derived from
58
+ // cardinality, never authored syntax.
59
+ wiring = s:sources _ a1:arrow_loc _ c:step _ a2:arrow_loc _ t:targets {
60
+ return {
61
+ type: 'wiring',
62
+ sources: s.members,
63
+ sourcesLocation: s.location,
64
+ step: c.alias.value,
65
+ stepLocation: c.alias.location,
66
+ policy: c.policy,
67
+ policyLocation: c.policyLocation,
68
+ arrowLocations: [a1, a2],
69
+ targets: t.targets,
70
+ targetsLocation: t.location,
71
+ location: location(),
72
+ };
73
+ }
74
+
75
+ sources = g:source_group { return g; }
76
+ / a:alias_loc { return { members: [{ name: null, nameLocation: null, node: a.value, location: a.location, valueLocation: a.location }], location: a.location }; }
77
+
78
+ source_group = "(" _ ms:(first:member rest:(_ "," _ m:member { return m; })* { return [first, ...rest]; })? _ ")" {
79
+ return { members: ms || [], location: location() };
80
+ }
81
+
82
+ // A member names an arg, or does not. Named is tried first: it is the longer
83
+ // form, and an unnamed member is exactly a node alias. A member stands where
84
+ // all of it does; its name and its value each where they do.
85
+ member = named_member
86
+ / c:constant_loc { return { name: null, nameLocation: null, constantText: c.value, location: c.location, valueLocation: c.location }; }
87
+ / a:alias_loc { return { name: null, nameLocation: null, node: a.value, location: a.location, valueLocation: a.location }; }
88
+
89
+ named_member = n:alias_loc _ "=" _ v:(c:constant_loc { return { constantText: c.value, valueLocation: c.location }; }
90
+ / a:alias_loc { return { node: a.value, valueLocation: a.location }; }) {
91
+ return { name: n.value, nameLocation: n.location, ...v, location: location() };
37
92
  }
38
93
 
39
- source_loc = group_loc / single_alias_loc
94
+ // A step is a header alias or a registered cap alias, with an optional policy.
95
+ step = a:alias_loc _ p:policy_loc? {
96
+ return { alias: a, policy: p ? p.entries : [], policyLocation: p ? p.location : null };
97
+ }
40
98
 
41
- single_alias_loc = a:alias_loc { return { values: [a.value], locations: [a.location] }; }
99
+ policy_loc = "{" _ es:(first:policy_entry rest:(_ "," _ e:policy_entry { return e; })* { return [first, ...rest]; })? _ "}" {
100
+ return { entries: es || [], location: location() };
101
+ }
42
102
 
43
- group_loc = "(" _ first:alias_loc rest:("," _ a:alias_loc { return a; })+ _ ")" {
44
- return { values: [first.value, ...rest.map(r => r.value)], locations: [first.location, ...rest.map(r => r.location)] };
103
+ policy_entry = k:alias_loc _ "=" _ v:policy_value {
104
+ return { key: k.value, keyLocation: k.location, value: v.value, isNumber: v.isNumber, valueLocation: v.location };
45
105
  }
46
106
 
47
- arrow = "-"+ ">"
107
+ policy_value = n:$number { return { value: n, isNumber: true, location: location() }; }
108
+ / a:alias { return { value: a, isNumber: false, location: location() }; }
109
+
110
+ targets = g:target_group { return g; }
111
+ / a:alias_loc { return { targets: [{ name: null, nameLocation: null, node: a.value, location: a.location, valueLocation: a.location }], location: a.location }; }
112
+
113
+ target_group = "(" _ ts:(first:target rest:(_ "," _ t:target { return t; })* { return [first, ...rest]; })? _ ")" {
114
+ return { targets: ts || [], location: location() };
115
+ }
116
+
117
+ // A target stands where all of it does; its name and its node each where they do.
118
+ target = n:alias_loc _ "=" _ a:alias_loc { return { name: n.value, nameLocation: n.location, node: a.value, location: location(), valueLocation: a.location }; }
119
+ / a:alias_loc { return { name: null, nameLocation: null, node: a.value, location: a.location, valueLocation: a.location }; }
120
+
121
+ arrow_loc = "-"+ ">" { return location(); }
48
122
 
49
123
  // Alias with location tracking
50
124
  alias_loc = a:alias { return { value: a, location: location() }; }
51
125
 
52
126
  // Alias: starts with alpha or underscore, continues with alphanumeric, underscore, or hyphen.
53
127
  // This is atomic — no whitespace skipping inside.
54
- alias = $( [a-zA-Z_] [a-zA-Z0-9_-]* )
128
+ alias = $( [a-zA-Z_] alias_continue* )
129
+ alias_continue = [a-zA-Z0-9_-]
130
+
131
+ // A constant is a JSON value. `true`, `false` and `null` are constants, never
132
+ // node names; a bare word that is none of them is an alias. The text is kept
133
+ // as written; the syntax layer reads it as the value it writes.
134
+ constant_loc = c:$constant { return { value: c, location: location() }; }
135
+ constant = object / array / string / number / boolean / null
136
+ boolean = ("true" / "false") !alias_continue
137
+ null = "null" !alias_continue
138
+ object = "{" _ (pair (_ "," _ pair)*)? _ "}"
139
+ pair = string _ ":" _ constant
140
+ array = "[" _ (constant (_ "," _ constant)*)? _ "]"
141
+ number = "-"? ("0" / [1-9] [0-9]*) ("." [0-9]+)? ([eE] [+-]? [0-9]+)? !alias_continue
142
+
143
+ // A JSON string: any character but an unescaped quote, backslash or control
144
+ // character, with JSON's escapes.
145
+ string_loc = s:$string { return { value: s, location: location() }; }
146
+ string = '"' string_char* '"'
147
+ string_char = [^"\\\u0000-\u001F]
148
+ / "\\" ["\\/bfnrt]
149
+ / "\\u" [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F]
55
150
 
56
151
  // Cap URN with location tracking
57
152
  cap_urn_loc = c:cap_urn { return { value: c, location: location() }; }
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "author": "Bahram Joharshamshiri",
3
3
  "dependencies": {
4
- "lungo-ts": "1.106.540",
4
+ "lungo-ts": "1.108.38",
5
5
  "peggy": "^5.1.0",
6
- "tagged-urn": "^1.129.4"
6
+ "tagged-urn": "^1.137.33"
7
7
  },
8
8
  "description": "JavaScript implementation of Cap URN (Capability Uniform Resource Names) with strict validation and matching",
9
9
  "engines": {
@@ -47,8 +47,8 @@
47
47
  "build:parser": "npx peggy --format es -o machine-parser.js machine.pegjs",
48
48
  "build:browser": "npm run build:parser && node build-browser.js",
49
49
  "pretest": "npm run build:parser",
50
- "test": "node capdag.test.js"
50
+ "test": "node capdag.test.js && node machine.test.js"
51
51
  },
52
52
  "type": "module",
53
- "version": "1.426.27"
53
+ "version": "1.439.69"
54
54
  }