@vibe-lang/runtime 0.2.5

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.
Files changed (250) hide show
  1. package/package.json +46 -0
  2. package/src/ast/index.ts +375 -0
  3. package/src/ast.ts +2 -0
  4. package/src/debug/advanced-features.ts +482 -0
  5. package/src/debug/bun-inspector.ts +424 -0
  6. package/src/debug/handoff-manager.ts +283 -0
  7. package/src/debug/index.ts +150 -0
  8. package/src/debug/runner.ts +365 -0
  9. package/src/debug/server.ts +565 -0
  10. package/src/debug/stack-merger.ts +267 -0
  11. package/src/debug/state.ts +581 -0
  12. package/src/debug/test/advanced-features.test.ts +300 -0
  13. package/src/debug/test/e2e.test.ts +218 -0
  14. package/src/debug/test/handoff-manager.test.ts +256 -0
  15. package/src/debug/test/runner.test.ts +256 -0
  16. package/src/debug/test/stack-merger.test.ts +163 -0
  17. package/src/debug/test/state.test.ts +400 -0
  18. package/src/debug/test/ts-debug-integration.test.ts +374 -0
  19. package/src/debug/test/ts-import-tracker.test.ts +125 -0
  20. package/src/debug/test/ts-source-map.test.ts +169 -0
  21. package/src/debug/ts-import-tracker.ts +151 -0
  22. package/src/debug/ts-source-map.ts +171 -0
  23. package/src/errors/index.ts +124 -0
  24. package/src/index.ts +358 -0
  25. package/src/lexer/index.ts +348 -0
  26. package/src/lexer.ts +2 -0
  27. package/src/parser/index.ts +792 -0
  28. package/src/parser/parse.ts +45 -0
  29. package/src/parser/test/async.test.ts +248 -0
  30. package/src/parser/test/destructuring.test.ts +167 -0
  31. package/src/parser/test/do-expression.test.ts +486 -0
  32. package/src/parser/test/errors/do-expression.test.ts +95 -0
  33. package/src/parser/test/errors/error-locations.test.ts +230 -0
  34. package/src/parser/test/errors/invalid-expressions.test.ts +144 -0
  35. package/src/parser/test/errors/missing-tokens.test.ts +126 -0
  36. package/src/parser/test/errors/model-declaration.test.ts +185 -0
  37. package/src/parser/test/errors/nested-blocks.test.ts +226 -0
  38. package/src/parser/test/errors/unclosed-delimiters.test.ts +122 -0
  39. package/src/parser/test/errors/unexpected-tokens.test.ts +120 -0
  40. package/src/parser/test/import-export.test.ts +143 -0
  41. package/src/parser/test/literals.test.ts +404 -0
  42. package/src/parser/test/model-declaration.test.ts +161 -0
  43. package/src/parser/test/nested-blocks.test.ts +402 -0
  44. package/src/parser/test/parser.test.ts +743 -0
  45. package/src/parser/test/private.test.ts +136 -0
  46. package/src/parser/test/template-literal.test.ts +127 -0
  47. package/src/parser/test/tool-declaration.test.ts +302 -0
  48. package/src/parser/test/ts-block.test.ts +252 -0
  49. package/src/parser/test/type-annotations.test.ts +254 -0
  50. package/src/parser/visitor/helpers.ts +330 -0
  51. package/src/parser/visitor.ts +794 -0
  52. package/src/parser.ts +2 -0
  53. package/src/runtime/ai/cache-chunking.test.ts +69 -0
  54. package/src/runtime/ai/cache-chunking.ts +73 -0
  55. package/src/runtime/ai/client.ts +109 -0
  56. package/src/runtime/ai/context.ts +168 -0
  57. package/src/runtime/ai/formatters.ts +316 -0
  58. package/src/runtime/ai/index.ts +38 -0
  59. package/src/runtime/ai/language-ref.ts +38 -0
  60. package/src/runtime/ai/providers/anthropic.ts +253 -0
  61. package/src/runtime/ai/providers/google.ts +201 -0
  62. package/src/runtime/ai/providers/openai.ts +156 -0
  63. package/src/runtime/ai/retry.ts +100 -0
  64. package/src/runtime/ai/return-tools.ts +301 -0
  65. package/src/runtime/ai/test/client.test.ts +83 -0
  66. package/src/runtime/ai/test/formatters.test.ts +485 -0
  67. package/src/runtime/ai/test/retry.test.ts +137 -0
  68. package/src/runtime/ai/test/return-tools.test.ts +450 -0
  69. package/src/runtime/ai/test/tool-loop.test.ts +319 -0
  70. package/src/runtime/ai/test/tool-schema.test.ts +241 -0
  71. package/src/runtime/ai/tool-loop.ts +203 -0
  72. package/src/runtime/ai/tool-schema.ts +151 -0
  73. package/src/runtime/ai/types.ts +113 -0
  74. package/src/runtime/ai-logger.ts +255 -0
  75. package/src/runtime/ai-provider.ts +347 -0
  76. package/src/runtime/async/dependencies.ts +276 -0
  77. package/src/runtime/async/executor.ts +293 -0
  78. package/src/runtime/async/index.ts +43 -0
  79. package/src/runtime/async/scheduling.ts +163 -0
  80. package/src/runtime/async/test/dependencies.test.ts +284 -0
  81. package/src/runtime/async/test/executor.test.ts +388 -0
  82. package/src/runtime/context.ts +357 -0
  83. package/src/runtime/exec/ai.ts +139 -0
  84. package/src/runtime/exec/expressions.ts +475 -0
  85. package/src/runtime/exec/frames.ts +26 -0
  86. package/src/runtime/exec/functions.ts +305 -0
  87. package/src/runtime/exec/interpolation.ts +312 -0
  88. package/src/runtime/exec/statements.ts +604 -0
  89. package/src/runtime/exec/tools.ts +129 -0
  90. package/src/runtime/exec/typescript.ts +215 -0
  91. package/src/runtime/exec/variables.ts +279 -0
  92. package/src/runtime/index.ts +975 -0
  93. package/src/runtime/modules.ts +452 -0
  94. package/src/runtime/serialize.ts +103 -0
  95. package/src/runtime/state.ts +489 -0
  96. package/src/runtime/stdlib/core.ts +45 -0
  97. package/src/runtime/stdlib/directory.test.ts +156 -0
  98. package/src/runtime/stdlib/edit.test.ts +154 -0
  99. package/src/runtime/stdlib/fastEdit.test.ts +201 -0
  100. package/src/runtime/stdlib/glob.test.ts +106 -0
  101. package/src/runtime/stdlib/grep.test.ts +144 -0
  102. package/src/runtime/stdlib/index.ts +16 -0
  103. package/src/runtime/stdlib/readFile.test.ts +123 -0
  104. package/src/runtime/stdlib/tools/index.ts +707 -0
  105. package/src/runtime/stdlib/writeFile.test.ts +157 -0
  106. package/src/runtime/step.ts +969 -0
  107. package/src/runtime/test/ai-context.test.ts +1086 -0
  108. package/src/runtime/test/ai-result-object.test.ts +419 -0
  109. package/src/runtime/test/ai-tool-flow.test.ts +859 -0
  110. package/src/runtime/test/async-execution-order.test.ts +618 -0
  111. package/src/runtime/test/async-execution.test.ts +344 -0
  112. package/src/runtime/test/async-nested.test.ts +660 -0
  113. package/src/runtime/test/async-parallel-timing.test.ts +546 -0
  114. package/src/runtime/test/basic1.test.ts +154 -0
  115. package/src/runtime/test/binary-operators.test.ts +431 -0
  116. package/src/runtime/test/break-statement.test.ts +257 -0
  117. package/src/runtime/test/context-modes.test.ts +650 -0
  118. package/src/runtime/test/context.test.ts +466 -0
  119. package/src/runtime/test/core-functions.test.ts +228 -0
  120. package/src/runtime/test/e2e.test.ts +88 -0
  121. package/src/runtime/test/error-locations/error-locations.test.ts +80 -0
  122. package/src/runtime/test/error-locations/main-error.vibe +4 -0
  123. package/src/runtime/test/error-locations/main-import-error.vibe +3 -0
  124. package/src/runtime/test/error-locations/utils/helper.vibe +5 -0
  125. package/src/runtime/test/for-in.test.ts +312 -0
  126. package/src/runtime/test/helpers.ts +69 -0
  127. package/src/runtime/test/imports.test.ts +334 -0
  128. package/src/runtime/test/json-expressions.test.ts +232 -0
  129. package/src/runtime/test/literals.test.ts +372 -0
  130. package/src/runtime/test/logical-indexing.test.ts +478 -0
  131. package/src/runtime/test/member-methods.test.ts +324 -0
  132. package/src/runtime/test/model-config.test.ts +338 -0
  133. package/src/runtime/test/null-handling.test.ts +342 -0
  134. package/src/runtime/test/private-visibility.test.ts +332 -0
  135. package/src/runtime/test/runtime-state.test.ts +514 -0
  136. package/src/runtime/test/scoping.test.ts +370 -0
  137. package/src/runtime/test/string-interpolation.test.ts +354 -0
  138. package/src/runtime/test/template-literal.test.ts +181 -0
  139. package/src/runtime/test/tool-execution.test.ts +467 -0
  140. package/src/runtime/test/tool-schema-generation.test.ts +477 -0
  141. package/src/runtime/test/tostring.test.ts +210 -0
  142. package/src/runtime/test/ts-block.test.ts +594 -0
  143. package/src/runtime/test/ts-error-location.test.ts +231 -0
  144. package/src/runtime/test/types.test.ts +732 -0
  145. package/src/runtime/test/verbose-logger.test.ts +710 -0
  146. package/src/runtime/test/vibe-expression.test.ts +54 -0
  147. package/src/runtime/test/vibe-value-errors.test.ts +541 -0
  148. package/src/runtime/test/while.test.ts +232 -0
  149. package/src/runtime/tools/builtin.ts +30 -0
  150. package/src/runtime/tools/directory-tools.ts +70 -0
  151. package/src/runtime/tools/file-tools.ts +228 -0
  152. package/src/runtime/tools/index.ts +5 -0
  153. package/src/runtime/tools/registry.ts +48 -0
  154. package/src/runtime/tools/search-tools.ts +134 -0
  155. package/src/runtime/tools/security.ts +36 -0
  156. package/src/runtime/tools/system-tools.ts +312 -0
  157. package/src/runtime/tools/test/fixtures/base-types.ts +40 -0
  158. package/src/runtime/tools/test/fixtures/test-types.ts +132 -0
  159. package/src/runtime/tools/test/registry.test.ts +713 -0
  160. package/src/runtime/tools/test/security.test.ts +86 -0
  161. package/src/runtime/tools/test/system-tools.test.ts +679 -0
  162. package/src/runtime/tools/test/ts-schema.test.ts +357 -0
  163. package/src/runtime/tools/ts-schema.ts +341 -0
  164. package/src/runtime/tools/types.ts +89 -0
  165. package/src/runtime/tools/utility-tools.ts +198 -0
  166. package/src/runtime/ts-eval.ts +126 -0
  167. package/src/runtime/types.ts +797 -0
  168. package/src/runtime/validation.ts +160 -0
  169. package/src/runtime/verbose-logger.ts +459 -0
  170. package/src/runtime.ts +2 -0
  171. package/src/semantic/analyzer-context.ts +62 -0
  172. package/src/semantic/analyzer-validators.ts +575 -0
  173. package/src/semantic/analyzer-visitors.ts +534 -0
  174. package/src/semantic/analyzer.ts +83 -0
  175. package/src/semantic/index.ts +11 -0
  176. package/src/semantic/symbol-table.ts +58 -0
  177. package/src/semantic/test/async-validation.test.ts +301 -0
  178. package/src/semantic/test/compress-validation.test.ts +179 -0
  179. package/src/semantic/test/const-reassignment.test.ts +111 -0
  180. package/src/semantic/test/control-flow.test.ts +346 -0
  181. package/src/semantic/test/destructuring.test.ts +185 -0
  182. package/src/semantic/test/duplicate-declarations.test.ts +168 -0
  183. package/src/semantic/test/export-validation.test.ts +111 -0
  184. package/src/semantic/test/fixtures/math.ts +31 -0
  185. package/src/semantic/test/imports.test.ts +148 -0
  186. package/src/semantic/test/json-type.test.ts +68 -0
  187. package/src/semantic/test/literals.test.ts +127 -0
  188. package/src/semantic/test/model-validation.test.ts +179 -0
  189. package/src/semantic/test/prompt-validation.test.ts +343 -0
  190. package/src/semantic/test/scoping.test.ts +312 -0
  191. package/src/semantic/test/tool-validation.test.ts +306 -0
  192. package/src/semantic/test/ts-type-checking.test.ts +563 -0
  193. package/src/semantic/test/type-constraints.test.ts +111 -0
  194. package/src/semantic/test/type-inference.test.ts +87 -0
  195. package/src/semantic/test/type-validation.test.ts +552 -0
  196. package/src/semantic/test/undefined-variables.test.ts +163 -0
  197. package/src/semantic/ts-block-checker.ts +204 -0
  198. package/src/semantic/ts-signatures.ts +194 -0
  199. package/src/semantic/ts-types.ts +170 -0
  200. package/src/semantic/types.ts +58 -0
  201. package/tests/fixtures/conditional-logic.vibe +14 -0
  202. package/tests/fixtures/function-call.vibe +16 -0
  203. package/tests/fixtures/imports/cycle-detection/a.vibe +6 -0
  204. package/tests/fixtures/imports/cycle-detection/b.vibe +5 -0
  205. package/tests/fixtures/imports/cycle-detection/main.vibe +3 -0
  206. package/tests/fixtures/imports/module-isolation/main-b.vibe +8 -0
  207. package/tests/fixtures/imports/module-isolation/main.vibe +9 -0
  208. package/tests/fixtures/imports/module-isolation/moduleA.vibe +6 -0
  209. package/tests/fixtures/imports/module-isolation/moduleB.vibe +6 -0
  210. package/tests/fixtures/imports/nested-import/helper.vibe +6 -0
  211. package/tests/fixtures/imports/nested-import/main.vibe +3 -0
  212. package/tests/fixtures/imports/nested-import/utils.ts +3 -0
  213. package/tests/fixtures/imports/nested-isolation/file2.vibe +15 -0
  214. package/tests/fixtures/imports/nested-isolation/file3.vibe +10 -0
  215. package/tests/fixtures/imports/nested-isolation/main.vibe +21 -0
  216. package/tests/fixtures/imports/pure-cycle/a.vibe +5 -0
  217. package/tests/fixtures/imports/pure-cycle/b.vibe +5 -0
  218. package/tests/fixtures/imports/pure-cycle/main.vibe +3 -0
  219. package/tests/fixtures/imports/ts-boolean/checks.ts +14 -0
  220. package/tests/fixtures/imports/ts-boolean/main.vibe +10 -0
  221. package/tests/fixtures/imports/ts-boolean/type-mismatch.vibe +5 -0
  222. package/tests/fixtures/imports/ts-boolean/use-constant.vibe +18 -0
  223. package/tests/fixtures/imports/ts-error-handling/helpers.ts +42 -0
  224. package/tests/fixtures/imports/ts-error-handling/main.vibe +5 -0
  225. package/tests/fixtures/imports/ts-import/main.vibe +4 -0
  226. package/tests/fixtures/imports/ts-import/math.ts +9 -0
  227. package/tests/fixtures/imports/ts-variables/call-non-function.vibe +5 -0
  228. package/tests/fixtures/imports/ts-variables/data.ts +10 -0
  229. package/tests/fixtures/imports/ts-variables/import-json.vibe +5 -0
  230. package/tests/fixtures/imports/ts-variables/import-type-mismatch.vibe +5 -0
  231. package/tests/fixtures/imports/ts-variables/import-variable.vibe +5 -0
  232. package/tests/fixtures/imports/vibe-import/greet.vibe +5 -0
  233. package/tests/fixtures/imports/vibe-import/main.vibe +3 -0
  234. package/tests/fixtures/multiple-ai-calls.vibe +10 -0
  235. package/tests/fixtures/simple-greeting.vibe +6 -0
  236. package/tests/fixtures/template-literals.vibe +11 -0
  237. package/tests/integration/basic-ai/basic-ai.integration.test.ts +166 -0
  238. package/tests/integration/basic-ai/basic-ai.vibe +12 -0
  239. package/tests/integration/bug-fix/bug-fix.integration.test.ts +201 -0
  240. package/tests/integration/bug-fix/buggy-code.ts +22 -0
  241. package/tests/integration/bug-fix/fix-bug.vibe +21 -0
  242. package/tests/integration/compress/compress.integration.test.ts +206 -0
  243. package/tests/integration/destructuring/destructuring.integration.test.ts +92 -0
  244. package/tests/integration/hello-world-translator/hello-world-translator.integration.test.ts +61 -0
  245. package/tests/integration/line-annotator/context-modes.integration.test.ts +261 -0
  246. package/tests/integration/line-annotator/line-annotator.integration.test.ts +148 -0
  247. package/tests/integration/multi-feature/cumulative-sum.integration.test.ts +75 -0
  248. package/tests/integration/multi-feature/number-analyzer.integration.test.ts +191 -0
  249. package/tests/integration/multi-feature/number-analyzer.vibe +59 -0
  250. package/tests/integration/tool-calls/tool-calls.integration.test.ts +93 -0
@@ -0,0 +1,330 @@
1
+ // Visitor helper functions
2
+
3
+ import type { IToken, CstNode } from 'chevrotain';
4
+ import type { SourceLocation } from '../../errors';
5
+ import type * as AST from '../../ast';
6
+
7
+ // Current file being parsed (set before parsing, used in tokenLocation)
8
+ let currentFile: string | undefined;
9
+
10
+ /**
11
+ * Set the current file path for location tracking.
12
+ * Call this before parsing a file.
13
+ */
14
+ export function setCurrentFile(file: string | undefined): void {
15
+ currentFile = file;
16
+ }
17
+
18
+ /**
19
+ * Get location from a token.
20
+ */
21
+ export function tokenLocation(token: IToken): SourceLocation {
22
+ return {
23
+ line: token.startLine ?? 1,
24
+ column: token.startColumn ?? 1,
25
+ file: currentFile,
26
+ };
27
+ }
28
+
29
+ // Placeholders for escaped braces (will be converted back after interpolation)
30
+ export const ESCAPED_LBRACE = '\x00ESC_LBRACE\x00';
31
+ export const ESCAPED_RBRACE = '\x00ESC_RBRACE\x00';
32
+ export const ESCAPED_BANG_LBRACE = '\x00ESC_BANG_LBRACE\x00';
33
+
34
+ /**
35
+ * Convert escape placeholders back to literal characters.
36
+ * Called after interpolation is complete.
37
+ */
38
+ export function unescapeBraces(str: string): string {
39
+ return str
40
+ .replace(new RegExp(ESCAPED_LBRACE, 'g'), '{')
41
+ .replace(new RegExp(ESCAPED_RBRACE, 'g'), '}')
42
+ .replace(new RegExp(ESCAPED_BANG_LBRACE, 'g'), '!{');
43
+ }
44
+
45
+ /**
46
+ * Extract string value from a string literal token.
47
+ * Escaped braces (\{, \}, \!{) are converted to placeholders for interpolation.
48
+ */
49
+ export function parseStringLiteral(token: IToken): string {
50
+ const raw = token.image;
51
+ // Remove quotes, handle brace escapes with placeholders, then general escapes
52
+ return raw.slice(1, -1)
53
+ .replace(/\\!\{/g, ESCAPED_BANG_LBRACE) // \!{ -> placeholder (must be before \{)
54
+ .replace(/\\\{/g, ESCAPED_LBRACE) // \{ -> placeholder
55
+ .replace(/\\\}/g, ESCAPED_RBRACE) // \} -> placeholder
56
+ .replace(/\\(.)/g, '$1'); // Other escapes: \n -> n, \\ -> \, etc.
57
+ }
58
+
59
+ /**
60
+ * Extract string value from a template literal token.
61
+ * Escaped braces (\{, \}, \!{) are converted to placeholders for interpolation.
62
+ */
63
+ export function parseTemplateLiteral(token: IToken): string {
64
+ const raw = token.image;
65
+ // Remove backticks, handle brace escapes with placeholders, then general escapes
66
+ return raw.slice(1, -1)
67
+ .replace(/\\!\{/g, ESCAPED_BANG_LBRACE) // \!{ -> placeholder (must be before \{)
68
+ .replace(/\\\{/g, ESCAPED_LBRACE) // \{ -> placeholder
69
+ .replace(/\\\}/g, ESCAPED_RBRACE) // \} -> placeholder
70
+ .replace(/\\(.)/g, '$1'); // Other escapes: \n -> n, \\ -> \, etc.
71
+ }
72
+
73
+ /**
74
+ * Parse TsBlock token: ts(param1, param2) { body }
75
+ */
76
+ export function parseTsBlock(token: IToken): { params: string[]; body: string } {
77
+ const raw = token.image;
78
+
79
+ // Find the opening paren
80
+ const parenStart = raw.indexOf('(');
81
+ const parenEnd = raw.indexOf(')');
82
+
83
+ // Extract params string and split by comma
84
+ const paramsStr = raw.slice(parenStart + 1, parenEnd).trim();
85
+ const params = paramsStr
86
+ ? paramsStr.split(',').map((p) => p.trim())
87
+ : [];
88
+
89
+ // Find the body (between first { and last })
90
+ const braceStart = raw.indexOf('{', parenEnd);
91
+ const braceEnd = raw.lastIndexOf('}');
92
+ const body = raw.slice(braceStart + 1, braceEnd);
93
+
94
+ return { params, body };
95
+ }
96
+
97
+ /**
98
+ * Get the first token from a CST node (for position checking).
99
+ */
100
+ export function getFirstToken(node: CstNode): IToken | undefined {
101
+ // Recursively find the first token in the CST
102
+ for (const key of Object.keys(node.children ?? {})) {
103
+ const child = (node.children as Record<string, (CstNode | IToken)[]>)[key];
104
+ if (child && child.length > 0) {
105
+ const first = child[0];
106
+ if ('image' in first) {
107
+ // It's a token
108
+ return first as IToken;
109
+ } else if ('children' in first) {
110
+ // It's a CstNode, recurse
111
+ const token = getFirstToken(first as CstNode);
112
+ if (token) return token;
113
+ }
114
+ }
115
+ }
116
+ return undefined;
117
+ }
118
+
119
+ /**
120
+ * Build a left-associative binary expression chain from operands and a single operator type.
121
+ * Used for 'and' and 'or' expressions where all operators are the same.
122
+ */
123
+ export function buildBinaryChain(
124
+ operands: AST.Expression[],
125
+ operator: AST.BinaryOperator,
126
+ count: number
127
+ ): AST.Expression {
128
+ let left = operands[0];
129
+ for (let i = 0; i < count; i++) {
130
+ left = {
131
+ type: 'BinaryExpression',
132
+ operator,
133
+ left,
134
+ right: operands[i + 1],
135
+ location: left.location,
136
+ };
137
+ }
138
+ return left;
139
+ }
140
+
141
+ /**
142
+ * Build a left-associative binary expression chain from operands and mixed operators.
143
+ * Operators are sorted by position to maintain correct order.
144
+ * Used for additive (+, -) and multiplicative (*, /, %) expressions.
145
+ */
146
+ export function buildMixedBinaryChain(
147
+ operands: AST.Expression[],
148
+ operators: IToken[]
149
+ ): AST.Expression {
150
+ if (operators.length === 0) {
151
+ return operands[0];
152
+ }
153
+
154
+ const sorted = [...operators].sort((a, b) => a.startOffset - b.startOffset);
155
+ let left = operands[0];
156
+
157
+ for (let i = 0; i < sorted.length; i++) {
158
+ left = {
159
+ type: 'BinaryExpression',
160
+ operator: sorted[i].image as AST.BinaryOperator,
161
+ left,
162
+ right: operands[i + 1],
163
+ location: left.location,
164
+ };
165
+ }
166
+
167
+ return left;
168
+ }
169
+
170
+ /**
171
+ * Build a single binary expression (for comparison operators where only one is allowed).
172
+ */
173
+ export function buildSingleBinary(
174
+ left: AST.Expression,
175
+ right: AST.Expression,
176
+ operator: IToken
177
+ ): AST.BinaryExpression {
178
+ return {
179
+ type: 'BinaryExpression',
180
+ operator: operator.image as AST.BinaryOperator,
181
+ left,
182
+ right,
183
+ location: left.location,
184
+ };
185
+ }
186
+
187
+ // ============================================================================
188
+ // Literal node builders
189
+ // ============================================================================
190
+
191
+ export function makeStringLiteral(token: IToken): AST.StringLiteral {
192
+ return {
193
+ type: 'StringLiteral',
194
+ value: parseStringLiteral(token),
195
+ location: tokenLocation(token),
196
+ };
197
+ }
198
+
199
+ export function makeTemplateLiteral(token: IToken): AST.TemplateLiteral {
200
+ return {
201
+ type: 'TemplateLiteral',
202
+ value: parseTemplateLiteral(token),
203
+ location: tokenLocation(token),
204
+ };
205
+ }
206
+
207
+ export function makeNumberLiteral(token: IToken): AST.NumberLiteral {
208
+ return {
209
+ type: 'NumberLiteral',
210
+ value: parseFloat(token.image),
211
+ location: tokenLocation(token),
212
+ };
213
+ }
214
+
215
+ export function makeBooleanLiteral(token: IToken, value: boolean): AST.BooleanLiteral {
216
+ return {
217
+ type: 'BooleanLiteral',
218
+ value,
219
+ location: tokenLocation(token),
220
+ };
221
+ }
222
+
223
+ export function makeNullLiteral(token: IToken): AST.NullLiteral {
224
+ return {
225
+ type: 'NullLiteral',
226
+ location: tokenLocation(token),
227
+ };
228
+ }
229
+
230
+ export function makeIdentifier(token: IToken): AST.Identifier {
231
+ return {
232
+ type: 'Identifier',
233
+ name: token.image,
234
+ location: tokenLocation(token),
235
+ };
236
+ }
237
+
238
+ export function makeTsBlock(token: IToken): AST.TsBlock {
239
+ const { params, body } = parseTsBlock(token);
240
+ return {
241
+ type: 'TsBlock',
242
+ params,
243
+ body,
244
+ location: tokenLocation(token),
245
+ };
246
+ }
247
+
248
+ // ============================================================================
249
+ // Expression node builders
250
+ // ============================================================================
251
+
252
+ export function makeCallExpression(
253
+ callee: AST.Expression,
254
+ args: AST.Expression[]
255
+ ): AST.CallExpression {
256
+ return {
257
+ type: 'CallExpression',
258
+ callee,
259
+ arguments: args,
260
+ location: callee.location,
261
+ };
262
+ }
263
+
264
+ export function makeIndexExpression(
265
+ object: AST.Expression,
266
+ index: AST.Expression
267
+ ): AST.IndexExpression {
268
+ return {
269
+ type: 'IndexExpression',
270
+ object,
271
+ index,
272
+ location: object.location,
273
+ };
274
+ }
275
+
276
+ export function makeSliceExpression(
277
+ object: AST.Expression,
278
+ start: AST.Expression | null,
279
+ end: AST.Expression | null
280
+ ): AST.SliceExpression {
281
+ return {
282
+ type: 'SliceExpression',
283
+ object,
284
+ start,
285
+ end,
286
+ location: object.location,
287
+ };
288
+ }
289
+
290
+ export function makeMemberExpression(
291
+ object: AST.Expression,
292
+ property: string
293
+ ): AST.MemberExpression {
294
+ return {
295
+ type: 'MemberExpression',
296
+ object,
297
+ property,
298
+ location: object.location,
299
+ };
300
+ }
301
+
302
+ export function makeVibeExpression(
303
+ token: IToken,
304
+ prompt: AST.Expression,
305
+ model: AST.Expression | null,
306
+ context: AST.ContextSpecifier | null,
307
+ operationType: AST.AIOperationType = 'vibe'
308
+ ): AST.VibeExpression {
309
+ return {
310
+ type: 'VibeExpression',
311
+ operationType,
312
+ prompt,
313
+ model,
314
+ context,
315
+ location: tokenLocation(token),
316
+ };
317
+ }
318
+
319
+ export function makeContextSpecifier(
320
+ token: IToken,
321
+ kind: 'default' | 'local' | 'variable',
322
+ variable?: string
323
+ ): AST.ContextSpecifier {
324
+ return {
325
+ type: 'ContextSpecifier',
326
+ kind,
327
+ variable,
328
+ location: tokenLocation(token),
329
+ } as AST.ContextSpecifier;
330
+ }