@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,226 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { parse } from '../../parse';
3
+
4
+ describe('Syntax Errors - Nested Blocks', () => {
5
+ // ============================================================================
6
+ // Missing closing braces at different levels
7
+ // ============================================================================
8
+
9
+ test('missing closing brace on outer function', () => {
10
+ expect(() => parse(`
11
+ function outer() {
12
+ function inner() {
13
+ return "nested"
14
+ }
15
+ `)).toThrow();
16
+ });
17
+
18
+ test('missing closing brace on inner function', () => {
19
+ expect(() => parse(`
20
+ function outer() {
21
+ function inner() {
22
+ return "nested"
23
+ }
24
+ `)).toThrow();
25
+ });
26
+
27
+ test('missing closing brace on outer if', () => {
28
+ expect(() => parse(`
29
+ if a {
30
+ if b {
31
+ let x = "nested"
32
+ }
33
+ `)).toThrow();
34
+ });
35
+
36
+ test('missing closing brace on inner if', () => {
37
+ expect(() => parse(`
38
+ if a {
39
+ if b {
40
+ let x = "nested"
41
+ }
42
+ `)).toThrow();
43
+ });
44
+
45
+ test('missing closing brace on deeply nested block', () => {
46
+ expect(() => parse(`
47
+ {
48
+ {
49
+ {
50
+ let deep = "value"
51
+ }
52
+ }
53
+ `)).toThrow();
54
+ });
55
+
56
+ test('missing middle closing brace', () => {
57
+ expect(() => parse(`
58
+ {
59
+ {
60
+ let inner = "value"
61
+ }
62
+ `)).toThrow();
63
+ });
64
+
65
+ // ============================================================================
66
+ // Missing closing braces in mixed nesting
67
+ // ============================================================================
68
+
69
+ test('function with unclosed if inside', () => {
70
+ expect(() => parse(`
71
+ function test() {
72
+ if condition {
73
+ let x = "value"
74
+ }
75
+ `)).toThrow();
76
+ });
77
+
78
+ test('if with unclosed block inside', () => {
79
+ expect(() => parse(`
80
+ if condition {
81
+ {
82
+ let x = "value"
83
+ }
84
+ `)).toThrow();
85
+ });
86
+
87
+ test('function with unclosed nested function', () => {
88
+ expect(() => parse(`
89
+ function outer() {
90
+ function inner() {
91
+ if x {
92
+ return "deep"
93
+ }
94
+ }
95
+ `)).toThrow();
96
+ });
97
+
98
+ // ============================================================================
99
+ // Multiple unclosed braces
100
+ // ============================================================================
101
+
102
+ test('two unclosed braces', () => {
103
+ expect(() => parse(`
104
+ function test() {
105
+ if x {
106
+ let y = "value"
107
+ `)).toThrow();
108
+ });
109
+
110
+ test('three unclosed braces', () => {
111
+ expect(() => parse(`
112
+ function test() {
113
+ {
114
+ if x {
115
+ let y = "value"
116
+ `)).toThrow();
117
+ });
118
+
119
+ // ============================================================================
120
+ // Unclosed else blocks in nesting
121
+ // ============================================================================
122
+
123
+ test('unclosed else in nested if', () => {
124
+ expect(() => parse(`
125
+ function test() {
126
+ if a {
127
+ let x = "yes"
128
+ } else {
129
+ let y = "no"
130
+ }
131
+ `)).toThrow();
132
+ });
133
+
134
+ test('unclosed else-if in nested structure', () => {
135
+ expect(() => parse(`
136
+ function test() {
137
+ if a {
138
+ let x = "first"
139
+ } else if b {
140
+ let y = "second"
141
+ }
142
+ `)).toThrow();
143
+ });
144
+
145
+ // ============================================================================
146
+ // Extra closing braces
147
+ // ============================================================================
148
+
149
+ test('extra closing brace after nested blocks', () => {
150
+ expect(() => parse(`
151
+ function test() {
152
+ if x {
153
+ let y = "value"
154
+ }
155
+ }
156
+ }
157
+ `)).toThrow();
158
+ });
159
+
160
+ test('extra closing brace inside function', () => {
161
+ expect(() => parse(`
162
+ function test() {
163
+ let x = "value"
164
+ }
165
+ }
166
+ `)).toThrow();
167
+ });
168
+
169
+ // ============================================================================
170
+ // Misplaced braces
171
+ // ============================================================================
172
+
173
+ test('closing brace before opening in nested context', () => {
174
+ expect(() => parse(`
175
+ function test() {
176
+ }
177
+ if x {
178
+ let y = "value"
179
+ }
180
+ }
181
+ `)).toThrow();
182
+ });
183
+
184
+ test('opening brace without statement in nesting', () => {
185
+ expect(() => parse(`
186
+ function test() {
187
+ { {
188
+ let x = "value"
189
+ }
190
+ }
191
+ `)).toThrow(); // Missing closing brace for inner block
192
+ });
193
+
194
+ // ============================================================================
195
+ // Incomplete statements in nested blocks
196
+ // ============================================================================
197
+
198
+ test('incomplete let in nested block', () => {
199
+ expect(() => parse(`
200
+ function test() {
201
+ if x {
202
+ let y =
203
+ }
204
+ }
205
+ `)).toThrow();
206
+ });
207
+
208
+ test('incomplete const in deeply nested block', () => {
209
+ expect(() => parse(`
210
+ function outer() {
211
+ function inner() {
212
+ const x =
213
+ }
214
+ }
215
+ `)).toThrow();
216
+ });
217
+
218
+ test('incomplete function declaration in nested block', () => {
219
+ expect(() => parse(`
220
+ function outer() {
221
+ function inner(
222
+ }
223
+ }
224
+ `)).toThrow();
225
+ });
226
+ });
@@ -0,0 +1,122 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { parse } from '../../parse';
3
+
4
+ describe('Syntax Errors - Unclosed Delimiters', () => {
5
+ // ============================================================================
6
+ // Unclosed braces
7
+ // ============================================================================
8
+
9
+ test('unclosed block statement', () => {
10
+ expect(() => parse(`
11
+ {
12
+ let x = "hello"
13
+ `)).toThrow();
14
+ });
15
+
16
+ test('unclosed function body', () => {
17
+ expect(() => parse(`
18
+ function foo() {
19
+ return "hello"
20
+ `)).toThrow();
21
+ });
22
+
23
+ test('unclosed if block', () => {
24
+ expect(() => parse(`
25
+ if true {
26
+ let x = "yes"
27
+ `)).toThrow();
28
+ });
29
+
30
+ test('unclosed else block', () => {
31
+ expect(() => parse(`
32
+ if true {
33
+ let x = "yes"
34
+ } else {
35
+ let y = "no"
36
+ `)).toThrow();
37
+ });
38
+
39
+ test('nested unclosed braces', () => {
40
+ expect(() => parse(`
41
+ function outer() {
42
+ if true {
43
+ let x = "nested"
44
+ }
45
+ `)).toThrow();
46
+ });
47
+
48
+ // ============================================================================
49
+ // Unclosed parentheses
50
+ // ============================================================================
51
+
52
+ test('unclosed function call', () => {
53
+ expect(() => parse(`
54
+ foo("hello"
55
+ `)).toThrow();
56
+ });
57
+
58
+ test('unclosed function params', () => {
59
+ expect(() => parse(`
60
+ function greet(name, age
61
+ `)).toThrow();
62
+ });
63
+
64
+ test('unclosed grouped expression', () => {
65
+ expect(() => parse(`
66
+ let x = ("hello"
67
+ `)).toThrow();
68
+ });
69
+
70
+ test('nested unclosed parens in call', () => {
71
+ expect(() => parse(`
72
+ outer(inner("deep"
73
+ `)).toThrow();
74
+ });
75
+
76
+ // ============================================================================
77
+ // Unclosed strings
78
+ // ============================================================================
79
+
80
+ test('unclosed double quote string', () => {
81
+ expect(() => parse(`
82
+ let x = "hello
83
+ `)).toThrow();
84
+ });
85
+
86
+ test('unclosed single quote string', () => {
87
+ expect(() => parse(`
88
+ let x = 'hello
89
+ `)).toThrow();
90
+ });
91
+
92
+ test('unclosed string in function call', () => {
93
+ expect(() => parse(`
94
+ greet("hello)
95
+ `)).toThrow();
96
+ });
97
+
98
+ test('unclosed string in vibe expression', () => {
99
+ expect(() => parse(`
100
+ let x = vibe "what is 2+2?
101
+ `)).toThrow();
102
+ });
103
+
104
+ // ============================================================================
105
+ // Mixed unclosed delimiters
106
+ // ============================================================================
107
+
108
+ test('unclosed brace and paren', () => {
109
+ expect(() => parse(`
110
+ function test() {
111
+ foo(
112
+ }
113
+ `)).toThrow();
114
+ });
115
+
116
+ test('unclosed string inside unclosed block', () => {
117
+ expect(() => parse(`
118
+ {
119
+ let x = "hello
120
+ `)).toThrow();
121
+ });
122
+ });
@@ -0,0 +1,120 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { parse } from '../../parse';
3
+
4
+ describe('Syntax Errors - Unexpected Tokens', () => {
5
+ // ============================================================================
6
+ // Missing identifiers after keywords
7
+ // ============================================================================
8
+
9
+ test('let missing identifier', () => {
10
+ expect(() => parse(`
11
+ let = "hello"
12
+ `)).toThrow();
13
+ });
14
+
15
+ test('const missing identifier', () => {
16
+ expect(() => parse(`
17
+ const = "hello"
18
+ `)).toThrow();
19
+ });
20
+
21
+ test('function missing name', () => {
22
+ expect(() => parse(`
23
+ function() {
24
+ return "hello"
25
+ }
26
+ `)).toThrow();
27
+ });
28
+
29
+ test('function with keyword as name', () => {
30
+ expect(() => parse(`
31
+ function let() {
32
+ return "hello"
33
+ }
34
+ `)).toThrow();
35
+ });
36
+
37
+ // ============================================================================
38
+ // Keywords in wrong positions
39
+ // ============================================================================
40
+
41
+ test('return outside function at top level', () => {
42
+ // Note: This may or may not throw depending on parser design
43
+ // Testing the parser's behavior
44
+ expect(() => parse(`
45
+ return "hello"
46
+ `)).not.toThrow(); // return is valid as a statement
47
+ });
48
+
49
+ test('break at top level', () => {
50
+ // break is syntactically valid, semantics checked at runtime
51
+ expect(() => parse(`
52
+ break
53
+ `)).not.toThrow();
54
+ });
55
+
56
+ test('else without if', () => {
57
+ expect(() => parse(`
58
+ else {
59
+ let x = "no"
60
+ }
61
+ `)).toThrow();
62
+ });
63
+
64
+ // ============================================================================
65
+ // Unexpected tokens in declarations
66
+ // ============================================================================
67
+
68
+ test('let with string instead of identifier', () => {
69
+ expect(() => parse(`
70
+ let "name" = "value"
71
+ `)).toThrow();
72
+ });
73
+
74
+ test('const with number-like token instead of identifier', () => {
75
+ expect(() => parse(`
76
+ const 123 = "value"
77
+ `)).toThrow();
78
+ });
79
+
80
+ test('function param is keyword', () => {
81
+ expect(() => parse(`
82
+ function test(return) {
83
+ return "hello"
84
+ }
85
+ `)).toThrow();
86
+ });
87
+
88
+ // ============================================================================
89
+ // Unexpected tokens in expressions
90
+ // ============================================================================
91
+
92
+ test('let inside expression', () => {
93
+ expect(() => parse(`
94
+ let x = let y
95
+ `)).toThrow();
96
+ });
97
+
98
+ test('equals in wrong position', () => {
99
+ expect(() => parse(`
100
+ let x = = "hello"
101
+ `)).toThrow();
102
+ });
103
+
104
+ // ============================================================================
105
+ // Unexpected tokens in blocks
106
+ // ============================================================================
107
+
108
+ test('closing brace without opening', () => {
109
+ expect(() => parse(`
110
+ let x = "hello"
111
+ }
112
+ `)).toThrow();
113
+ });
114
+
115
+ test('closing paren without opening', () => {
116
+ expect(() => parse(`
117
+ let x = "hello")
118
+ `)).toThrow();
119
+ });
120
+ });
@@ -0,0 +1,143 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import { parse } from '../parse';
3
+ import type * as AST from '../../ast';
4
+
5
+ describe('Parser - Import Declarations', () => {
6
+ test('single import from TypeScript file', () => {
7
+ const source = `import { add } from "./math.ts"`;
8
+ const ast = parse(source);
9
+
10
+ expect(ast.body).toHaveLength(1);
11
+ const importDecl = ast.body[0] as AST.ImportDeclaration;
12
+ expect(importDecl.type).toBe('ImportDeclaration');
13
+ expect(importDecl.specifiers).toEqual([{ imported: 'add', local: 'add' }]);
14
+ expect(importDecl.source).toBe('./math.ts');
15
+ expect(importDecl.sourceType).toBe('ts');
16
+ });
17
+
18
+ test('multiple imports from TypeScript file', () => {
19
+ const source = `import { add, subtract, multiply } from "./math.ts"`;
20
+ const ast = parse(source);
21
+
22
+ const importDecl = ast.body[0] as AST.ImportDeclaration;
23
+ expect(importDecl.specifiers).toEqual([
24
+ { imported: 'add', local: 'add' },
25
+ { imported: 'subtract', local: 'subtract' },
26
+ { imported: 'multiply', local: 'multiply' },
27
+ ]);
28
+ expect(importDecl.sourceType).toBe('ts');
29
+ });
30
+
31
+ test('import from Vibe file', () => {
32
+ const source = `import { greet } from "./utils.vibe"`;
33
+ const ast = parse(source);
34
+
35
+ const importDecl = ast.body[0] as AST.ImportDeclaration;
36
+ expect(importDecl.specifiers).toEqual([{ imported: 'greet', local: 'greet' }]);
37
+ expect(importDecl.source).toBe('./utils.vibe');
38
+ expect(importDecl.sourceType).toBe('vibe');
39
+ });
40
+
41
+ test('import from JavaScript file', () => {
42
+ const source = `import { helper } from "./helper.js"`;
43
+ const ast = parse(source);
44
+
45
+ const importDecl = ast.body[0] as AST.ImportDeclaration;
46
+ expect(importDecl.sourceType).toBe('ts'); // JS files are treated as TS
47
+ });
48
+
49
+ test('multiple import statements', () => {
50
+ const source = `
51
+ import { add } from "./math.ts"
52
+ import { greet } from "./greet.vibe"
53
+ let x = add("a", "b")
54
+ `;
55
+ const ast = parse(source);
56
+
57
+ expect(ast.body).toHaveLength(3);
58
+ expect((ast.body[0] as AST.ImportDeclaration).type).toBe('ImportDeclaration');
59
+ expect((ast.body[1] as AST.ImportDeclaration).type).toBe('ImportDeclaration');
60
+ expect((ast.body[2] as AST.LetDeclaration).type).toBe('LetDeclaration');
61
+ });
62
+ });
63
+
64
+ describe('Parser - Export Declarations', () => {
65
+ test('export function', () => {
66
+ const source = `
67
+ export function greet(name: text): text {
68
+ return vibe "Hello {name}" gpt default
69
+ }
70
+ `;
71
+ const ast = parse(source);
72
+
73
+ expect(ast.body).toHaveLength(1);
74
+ const exportDecl = ast.body[0] as AST.ExportDeclaration;
75
+ expect(exportDecl.type).toBe('ExportDeclaration');
76
+ expect(exportDecl.declaration.type).toBe('FunctionDeclaration');
77
+ expect((exportDecl.declaration as AST.FunctionDeclaration).name).toBe('greet');
78
+ });
79
+
80
+ test('export let', () => {
81
+ const source = `export let counter = "0"`;
82
+ const ast = parse(source);
83
+
84
+ const exportDecl = ast.body[0] as AST.ExportDeclaration;
85
+ expect(exportDecl.type).toBe('ExportDeclaration');
86
+ expect(exportDecl.declaration.type).toBe('LetDeclaration');
87
+ expect((exportDecl.declaration as AST.LetDeclaration).name).toBe('counter');
88
+ });
89
+
90
+ test('export const', () => {
91
+ const source = `export const API_KEY = "secret123"`;
92
+ const ast = parse(source);
93
+
94
+ const exportDecl = ast.body[0] as AST.ExportDeclaration;
95
+ expect(exportDecl.type).toBe('ExportDeclaration');
96
+ expect(exportDecl.declaration.type).toBe('ConstDeclaration');
97
+ expect((exportDecl.declaration as AST.ConstDeclaration).name).toBe('API_KEY');
98
+ });
99
+
100
+ test('export model', () => {
101
+ const source = `export model gpt = { name: "gpt-4" }`;
102
+ const ast = parse(source);
103
+
104
+ const exportDecl = ast.body[0] as AST.ExportDeclaration;
105
+ expect(exportDecl.type).toBe('ExportDeclaration');
106
+ expect(exportDecl.declaration.type).toBe('ModelDeclaration');
107
+ expect((exportDecl.declaration as AST.ModelDeclaration).name).toBe('gpt');
108
+ });
109
+
110
+ test('multiple exports', () => {
111
+ const source = `
112
+ export function add(a: text, b: text): text {
113
+ return ts(a, b) { return a + b }
114
+ }
115
+ export const PI = "3.14159"
116
+ export model gpt = { name: "gpt-4" }
117
+ `;
118
+ const ast = parse(source);
119
+
120
+ expect(ast.body).toHaveLength(3);
121
+ expect((ast.body[0] as AST.ExportDeclaration).declaration.type).toBe('FunctionDeclaration');
122
+ expect((ast.body[1] as AST.ExportDeclaration).declaration.type).toBe('ConstDeclaration');
123
+ expect((ast.body[2] as AST.ExportDeclaration).declaration.type).toBe('ModelDeclaration');
124
+ });
125
+ });
126
+
127
+ describe('Parser - Import and Export Combined', () => {
128
+ test('import and export in same file', () => {
129
+ const source = `
130
+ import { helper } from "./helper.ts"
131
+
132
+ export function greet(name: text): text {
133
+ let greeting = helper(name)
134
+ return vibe "{greeting}" gpt default
135
+ }
136
+ `;
137
+ const ast = parse(source);
138
+
139
+ expect(ast.body).toHaveLength(2);
140
+ expect((ast.body[0] as AST.ImportDeclaration).type).toBe('ImportDeclaration');
141
+ expect((ast.body[1] as AST.ExportDeclaration).type).toBe('ExportDeclaration');
142
+ });
143
+ });