@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.
- package/package.json +46 -0
- package/src/ast/index.ts +375 -0
- package/src/ast.ts +2 -0
- package/src/debug/advanced-features.ts +482 -0
- package/src/debug/bun-inspector.ts +424 -0
- package/src/debug/handoff-manager.ts +283 -0
- package/src/debug/index.ts +150 -0
- package/src/debug/runner.ts +365 -0
- package/src/debug/server.ts +565 -0
- package/src/debug/stack-merger.ts +267 -0
- package/src/debug/state.ts +581 -0
- package/src/debug/test/advanced-features.test.ts +300 -0
- package/src/debug/test/e2e.test.ts +218 -0
- package/src/debug/test/handoff-manager.test.ts +256 -0
- package/src/debug/test/runner.test.ts +256 -0
- package/src/debug/test/stack-merger.test.ts +163 -0
- package/src/debug/test/state.test.ts +400 -0
- package/src/debug/test/ts-debug-integration.test.ts +374 -0
- package/src/debug/test/ts-import-tracker.test.ts +125 -0
- package/src/debug/test/ts-source-map.test.ts +169 -0
- package/src/debug/ts-import-tracker.ts +151 -0
- package/src/debug/ts-source-map.ts +171 -0
- package/src/errors/index.ts +124 -0
- package/src/index.ts +358 -0
- package/src/lexer/index.ts +348 -0
- package/src/lexer.ts +2 -0
- package/src/parser/index.ts +792 -0
- package/src/parser/parse.ts +45 -0
- package/src/parser/test/async.test.ts +248 -0
- package/src/parser/test/destructuring.test.ts +167 -0
- package/src/parser/test/do-expression.test.ts +486 -0
- package/src/parser/test/errors/do-expression.test.ts +95 -0
- package/src/parser/test/errors/error-locations.test.ts +230 -0
- package/src/parser/test/errors/invalid-expressions.test.ts +144 -0
- package/src/parser/test/errors/missing-tokens.test.ts +126 -0
- package/src/parser/test/errors/model-declaration.test.ts +185 -0
- package/src/parser/test/errors/nested-blocks.test.ts +226 -0
- package/src/parser/test/errors/unclosed-delimiters.test.ts +122 -0
- package/src/parser/test/errors/unexpected-tokens.test.ts +120 -0
- package/src/parser/test/import-export.test.ts +143 -0
- package/src/parser/test/literals.test.ts +404 -0
- package/src/parser/test/model-declaration.test.ts +161 -0
- package/src/parser/test/nested-blocks.test.ts +402 -0
- package/src/parser/test/parser.test.ts +743 -0
- package/src/parser/test/private.test.ts +136 -0
- package/src/parser/test/template-literal.test.ts +127 -0
- package/src/parser/test/tool-declaration.test.ts +302 -0
- package/src/parser/test/ts-block.test.ts +252 -0
- package/src/parser/test/type-annotations.test.ts +254 -0
- package/src/parser/visitor/helpers.ts +330 -0
- package/src/parser/visitor.ts +794 -0
- package/src/parser.ts +2 -0
- package/src/runtime/ai/cache-chunking.test.ts +69 -0
- package/src/runtime/ai/cache-chunking.ts +73 -0
- package/src/runtime/ai/client.ts +109 -0
- package/src/runtime/ai/context.ts +168 -0
- package/src/runtime/ai/formatters.ts +316 -0
- package/src/runtime/ai/index.ts +38 -0
- package/src/runtime/ai/language-ref.ts +38 -0
- package/src/runtime/ai/providers/anthropic.ts +253 -0
- package/src/runtime/ai/providers/google.ts +201 -0
- package/src/runtime/ai/providers/openai.ts +156 -0
- package/src/runtime/ai/retry.ts +100 -0
- package/src/runtime/ai/return-tools.ts +301 -0
- package/src/runtime/ai/test/client.test.ts +83 -0
- package/src/runtime/ai/test/formatters.test.ts +485 -0
- package/src/runtime/ai/test/retry.test.ts +137 -0
- package/src/runtime/ai/test/return-tools.test.ts +450 -0
- package/src/runtime/ai/test/tool-loop.test.ts +319 -0
- package/src/runtime/ai/test/tool-schema.test.ts +241 -0
- package/src/runtime/ai/tool-loop.ts +203 -0
- package/src/runtime/ai/tool-schema.ts +151 -0
- package/src/runtime/ai/types.ts +113 -0
- package/src/runtime/ai-logger.ts +255 -0
- package/src/runtime/ai-provider.ts +347 -0
- package/src/runtime/async/dependencies.ts +276 -0
- package/src/runtime/async/executor.ts +293 -0
- package/src/runtime/async/index.ts +43 -0
- package/src/runtime/async/scheduling.ts +163 -0
- package/src/runtime/async/test/dependencies.test.ts +284 -0
- package/src/runtime/async/test/executor.test.ts +388 -0
- package/src/runtime/context.ts +357 -0
- package/src/runtime/exec/ai.ts +139 -0
- package/src/runtime/exec/expressions.ts +475 -0
- package/src/runtime/exec/frames.ts +26 -0
- package/src/runtime/exec/functions.ts +305 -0
- package/src/runtime/exec/interpolation.ts +312 -0
- package/src/runtime/exec/statements.ts +604 -0
- package/src/runtime/exec/tools.ts +129 -0
- package/src/runtime/exec/typescript.ts +215 -0
- package/src/runtime/exec/variables.ts +279 -0
- package/src/runtime/index.ts +975 -0
- package/src/runtime/modules.ts +452 -0
- package/src/runtime/serialize.ts +103 -0
- package/src/runtime/state.ts +489 -0
- package/src/runtime/stdlib/core.ts +45 -0
- package/src/runtime/stdlib/directory.test.ts +156 -0
- package/src/runtime/stdlib/edit.test.ts +154 -0
- package/src/runtime/stdlib/fastEdit.test.ts +201 -0
- package/src/runtime/stdlib/glob.test.ts +106 -0
- package/src/runtime/stdlib/grep.test.ts +144 -0
- package/src/runtime/stdlib/index.ts +16 -0
- package/src/runtime/stdlib/readFile.test.ts +123 -0
- package/src/runtime/stdlib/tools/index.ts +707 -0
- package/src/runtime/stdlib/writeFile.test.ts +157 -0
- package/src/runtime/step.ts +969 -0
- package/src/runtime/test/ai-context.test.ts +1086 -0
- package/src/runtime/test/ai-result-object.test.ts +419 -0
- package/src/runtime/test/ai-tool-flow.test.ts +859 -0
- package/src/runtime/test/async-execution-order.test.ts +618 -0
- package/src/runtime/test/async-execution.test.ts +344 -0
- package/src/runtime/test/async-nested.test.ts +660 -0
- package/src/runtime/test/async-parallel-timing.test.ts +546 -0
- package/src/runtime/test/basic1.test.ts +154 -0
- package/src/runtime/test/binary-operators.test.ts +431 -0
- package/src/runtime/test/break-statement.test.ts +257 -0
- package/src/runtime/test/context-modes.test.ts +650 -0
- package/src/runtime/test/context.test.ts +466 -0
- package/src/runtime/test/core-functions.test.ts +228 -0
- package/src/runtime/test/e2e.test.ts +88 -0
- package/src/runtime/test/error-locations/error-locations.test.ts +80 -0
- package/src/runtime/test/error-locations/main-error.vibe +4 -0
- package/src/runtime/test/error-locations/main-import-error.vibe +3 -0
- package/src/runtime/test/error-locations/utils/helper.vibe +5 -0
- package/src/runtime/test/for-in.test.ts +312 -0
- package/src/runtime/test/helpers.ts +69 -0
- package/src/runtime/test/imports.test.ts +334 -0
- package/src/runtime/test/json-expressions.test.ts +232 -0
- package/src/runtime/test/literals.test.ts +372 -0
- package/src/runtime/test/logical-indexing.test.ts +478 -0
- package/src/runtime/test/member-methods.test.ts +324 -0
- package/src/runtime/test/model-config.test.ts +338 -0
- package/src/runtime/test/null-handling.test.ts +342 -0
- package/src/runtime/test/private-visibility.test.ts +332 -0
- package/src/runtime/test/runtime-state.test.ts +514 -0
- package/src/runtime/test/scoping.test.ts +370 -0
- package/src/runtime/test/string-interpolation.test.ts +354 -0
- package/src/runtime/test/template-literal.test.ts +181 -0
- package/src/runtime/test/tool-execution.test.ts +467 -0
- package/src/runtime/test/tool-schema-generation.test.ts +477 -0
- package/src/runtime/test/tostring.test.ts +210 -0
- package/src/runtime/test/ts-block.test.ts +594 -0
- package/src/runtime/test/ts-error-location.test.ts +231 -0
- package/src/runtime/test/types.test.ts +732 -0
- package/src/runtime/test/verbose-logger.test.ts +710 -0
- package/src/runtime/test/vibe-expression.test.ts +54 -0
- package/src/runtime/test/vibe-value-errors.test.ts +541 -0
- package/src/runtime/test/while.test.ts +232 -0
- package/src/runtime/tools/builtin.ts +30 -0
- package/src/runtime/tools/directory-tools.ts +70 -0
- package/src/runtime/tools/file-tools.ts +228 -0
- package/src/runtime/tools/index.ts +5 -0
- package/src/runtime/tools/registry.ts +48 -0
- package/src/runtime/tools/search-tools.ts +134 -0
- package/src/runtime/tools/security.ts +36 -0
- package/src/runtime/tools/system-tools.ts +312 -0
- package/src/runtime/tools/test/fixtures/base-types.ts +40 -0
- package/src/runtime/tools/test/fixtures/test-types.ts +132 -0
- package/src/runtime/tools/test/registry.test.ts +713 -0
- package/src/runtime/tools/test/security.test.ts +86 -0
- package/src/runtime/tools/test/system-tools.test.ts +679 -0
- package/src/runtime/tools/test/ts-schema.test.ts +357 -0
- package/src/runtime/tools/ts-schema.ts +341 -0
- package/src/runtime/tools/types.ts +89 -0
- package/src/runtime/tools/utility-tools.ts +198 -0
- package/src/runtime/ts-eval.ts +126 -0
- package/src/runtime/types.ts +797 -0
- package/src/runtime/validation.ts +160 -0
- package/src/runtime/verbose-logger.ts +459 -0
- package/src/runtime.ts +2 -0
- package/src/semantic/analyzer-context.ts +62 -0
- package/src/semantic/analyzer-validators.ts +575 -0
- package/src/semantic/analyzer-visitors.ts +534 -0
- package/src/semantic/analyzer.ts +83 -0
- package/src/semantic/index.ts +11 -0
- package/src/semantic/symbol-table.ts +58 -0
- package/src/semantic/test/async-validation.test.ts +301 -0
- package/src/semantic/test/compress-validation.test.ts +179 -0
- package/src/semantic/test/const-reassignment.test.ts +111 -0
- package/src/semantic/test/control-flow.test.ts +346 -0
- package/src/semantic/test/destructuring.test.ts +185 -0
- package/src/semantic/test/duplicate-declarations.test.ts +168 -0
- package/src/semantic/test/export-validation.test.ts +111 -0
- package/src/semantic/test/fixtures/math.ts +31 -0
- package/src/semantic/test/imports.test.ts +148 -0
- package/src/semantic/test/json-type.test.ts +68 -0
- package/src/semantic/test/literals.test.ts +127 -0
- package/src/semantic/test/model-validation.test.ts +179 -0
- package/src/semantic/test/prompt-validation.test.ts +343 -0
- package/src/semantic/test/scoping.test.ts +312 -0
- package/src/semantic/test/tool-validation.test.ts +306 -0
- package/src/semantic/test/ts-type-checking.test.ts +563 -0
- package/src/semantic/test/type-constraints.test.ts +111 -0
- package/src/semantic/test/type-inference.test.ts +87 -0
- package/src/semantic/test/type-validation.test.ts +552 -0
- package/src/semantic/test/undefined-variables.test.ts +163 -0
- package/src/semantic/ts-block-checker.ts +204 -0
- package/src/semantic/ts-signatures.ts +194 -0
- package/src/semantic/ts-types.ts +170 -0
- package/src/semantic/types.ts +58 -0
- package/tests/fixtures/conditional-logic.vibe +14 -0
- package/tests/fixtures/function-call.vibe +16 -0
- package/tests/fixtures/imports/cycle-detection/a.vibe +6 -0
- package/tests/fixtures/imports/cycle-detection/b.vibe +5 -0
- package/tests/fixtures/imports/cycle-detection/main.vibe +3 -0
- package/tests/fixtures/imports/module-isolation/main-b.vibe +8 -0
- package/tests/fixtures/imports/module-isolation/main.vibe +9 -0
- package/tests/fixtures/imports/module-isolation/moduleA.vibe +6 -0
- package/tests/fixtures/imports/module-isolation/moduleB.vibe +6 -0
- package/tests/fixtures/imports/nested-import/helper.vibe +6 -0
- package/tests/fixtures/imports/nested-import/main.vibe +3 -0
- package/tests/fixtures/imports/nested-import/utils.ts +3 -0
- package/tests/fixtures/imports/nested-isolation/file2.vibe +15 -0
- package/tests/fixtures/imports/nested-isolation/file3.vibe +10 -0
- package/tests/fixtures/imports/nested-isolation/main.vibe +21 -0
- package/tests/fixtures/imports/pure-cycle/a.vibe +5 -0
- package/tests/fixtures/imports/pure-cycle/b.vibe +5 -0
- package/tests/fixtures/imports/pure-cycle/main.vibe +3 -0
- package/tests/fixtures/imports/ts-boolean/checks.ts +14 -0
- package/tests/fixtures/imports/ts-boolean/main.vibe +10 -0
- package/tests/fixtures/imports/ts-boolean/type-mismatch.vibe +5 -0
- package/tests/fixtures/imports/ts-boolean/use-constant.vibe +18 -0
- package/tests/fixtures/imports/ts-error-handling/helpers.ts +42 -0
- package/tests/fixtures/imports/ts-error-handling/main.vibe +5 -0
- package/tests/fixtures/imports/ts-import/main.vibe +4 -0
- package/tests/fixtures/imports/ts-import/math.ts +9 -0
- package/tests/fixtures/imports/ts-variables/call-non-function.vibe +5 -0
- package/tests/fixtures/imports/ts-variables/data.ts +10 -0
- package/tests/fixtures/imports/ts-variables/import-json.vibe +5 -0
- package/tests/fixtures/imports/ts-variables/import-type-mismatch.vibe +5 -0
- package/tests/fixtures/imports/ts-variables/import-variable.vibe +5 -0
- package/tests/fixtures/imports/vibe-import/greet.vibe +5 -0
- package/tests/fixtures/imports/vibe-import/main.vibe +3 -0
- package/tests/fixtures/multiple-ai-calls.vibe +10 -0
- package/tests/fixtures/simple-greeting.vibe +6 -0
- package/tests/fixtures/template-literals.vibe +11 -0
- package/tests/integration/basic-ai/basic-ai.integration.test.ts +166 -0
- package/tests/integration/basic-ai/basic-ai.vibe +12 -0
- package/tests/integration/bug-fix/bug-fix.integration.test.ts +201 -0
- package/tests/integration/bug-fix/buggy-code.ts +22 -0
- package/tests/integration/bug-fix/fix-bug.vibe +21 -0
- package/tests/integration/compress/compress.integration.test.ts +206 -0
- package/tests/integration/destructuring/destructuring.integration.test.ts +92 -0
- package/tests/integration/hello-world-translator/hello-world-translator.integration.test.ts +61 -0
- package/tests/integration/line-annotator/context-modes.integration.test.ts +261 -0
- package/tests/integration/line-annotator/line-annotator.integration.test.ts +148 -0
- package/tests/integration/multi-feature/cumulative-sum.integration.test.ts +75 -0
- package/tests/integration/multi-feature/number-analyzer.integration.test.ts +191 -0
- package/tests/integration/multi-feature/number-analyzer.vibe +59 -0
- 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
|
+
}
|