@mpeggroup/mpeg-sdl-parser 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (375) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +337 -0
  3. package/bun.lock +65 -0
  4. package/dist/index.js +11829 -0
  5. package/grammar/sdl.ebnf.grammar +399 -0
  6. package/grammar/sdl.lezer.grammar +629 -0
  7. package/index.ts +83 -0
  8. package/package.json +61 -0
  9. package/src/analyser/checks/check-array-definition.ts +90 -0
  10. package/src/analyser/checks/check-array-element-access.ts +31 -0
  11. package/src/analyser/checks/check-class-declaration.ts +417 -0
  12. package/src/analyser/checks/check-computed-array-definition.ts +44 -0
  13. package/src/analyser/checks/check-computed-elementary-type-definition.ts +45 -0
  14. package/src/analyser/checks/check-elementary-type-definition.ts +167 -0
  15. package/src/analyser/checks/check-expression-binary.ts +242 -0
  16. package/src/analyser/checks/check-expression-lengthof.ts +34 -0
  17. package/src/analyser/checks/check-expression-unary.ts +166 -0
  18. package/src/analyser/checks/check-identifier.ts +71 -0
  19. package/src/analyser/checks/check-if-statement.ts +164 -0
  20. package/src/analyser/checks/check-map-declaration.ts +180 -0
  21. package/src/analyser/checks/check-map-definition.ts +118 -0
  22. package/src/analyser/checks/check-number-literal-float.ts +28 -0
  23. package/src/analyser/checks/check-parameter-list.ts +42 -0
  24. package/src/analyser/checks/check-specification.ts +53 -0
  25. package/src/analyser/checks/check-switch-statement.ts +206 -0
  26. package/src/analyser/checks/check.ts +20 -0
  27. package/src/analyser/create-sdl-analyser.ts +85 -0
  28. package/src/analyser/node-handler/abstract-analysis-node-handler.ts +626 -0
  29. package/src/analyser/node-handler/build-symbol-table-node-handler.ts +649 -0
  30. package/src/analyser/node-handler/specific-check-node-handler.ts +46 -0
  31. package/src/analyser/node-handler/validate-scope-node-handler.ts +290 -0
  32. package/src/analyser/node-handler/validate-type-node-handler.ts +497 -0
  33. package/src/analyser/sdl-analyser.ts +119 -0
  34. package/src/analyser/symbol-table.ts +388 -0
  35. package/src/analyser/util/symbol-table-utils.ts +458 -0
  36. package/src/analyser/util/type-utils.ts +238 -0
  37. package/src/ast/build/consume/consume-abstract-node.ts +199 -0
  38. package/src/ast/build/consume/consume-ast-node.ts +400 -0
  39. package/src/ast/build/consume/consume-primitive.ts +59 -0
  40. package/src/ast/build/consume/consume-trivia.ts +96 -0
  41. package/src/ast/build/consume/consume-white-space-and-missing-errors.ts +27 -0
  42. package/src/ast/build/node/build-aggregate-output-value.ts +57 -0
  43. package/src/ast/build/node/build-aligned-modifier.ts +99 -0
  44. package/src/ast/build/node/build-array-definition.ts +131 -0
  45. package/src/ast/build/node/build-array-element-access.ts +45 -0
  46. package/src/ast/build/node/build-base64-string-literal.ts +41 -0
  47. package/src/ast/build/node/build-binary-expression.ts +113 -0
  48. package/src/ast/build/node/build-binary-literal.ts +37 -0
  49. package/src/ast/build/node/build-bit-modifier.ts +86 -0
  50. package/src/ast/build/node/build-case-clause.ts +101 -0
  51. package/src/ast/build/node/build-class-declaration.ts +124 -0
  52. package/src/ast/build/node/build-class-definition.ts +56 -0
  53. package/src/ast/build/node/build-class-id-range.ts +32 -0
  54. package/src/ast/build/node/build-class-id.ts +19 -0
  55. package/src/ast/build/node/build-class-member-access.ts +27 -0
  56. package/src/ast/build/node/build-compound-statement.ts +33 -0
  57. package/src/ast/build/node/build-computed-array-definition.ts +53 -0
  58. package/src/ast/build/node/build-computed-elementary-type-definition.ts +100 -0
  59. package/src/ast/build/node/build-decimal-literal.ts +15 -0
  60. package/src/ast/build/node/build-default-clause.ts +76 -0
  61. package/src/ast/build/node/build-do-statement.ts +71 -0
  62. package/src/ast/build/node/build-elementary-type-definition.ts +164 -0
  63. package/src/ast/build/node/build-elementary-type-output-value.ts +25 -0
  64. package/src/ast/build/node/build-elementary-type.ts +36 -0
  65. package/src/ast/build/node/build-expandable-modifier.ts +68 -0
  66. package/src/ast/build/node/build-explicit-array-dimension.ts +37 -0
  67. package/src/ast/build/node/build-expression-statement.ts +31 -0
  68. package/src/ast/build/node/build-extended-class-id-range.ts +27 -0
  69. package/src/ast/build/node/build-extends-modifier.ts +41 -0
  70. package/src/ast/build/node/build-floating-point-literal.ts +15 -0
  71. package/src/ast/build/node/build-for-statement.ts +117 -0
  72. package/src/ast/build/node/build-hexadecimal-literal.ts +38 -0
  73. package/src/ast/build/node/build-identifier.ts +8 -0
  74. package/src/ast/build/node/build-if-statement.ts +82 -0
  75. package/src/ast/build/node/build-implicit-array-dimension.ts +78 -0
  76. package/src/ast/build/node/build-integer-literal.ts +15 -0
  77. package/src/ast/build/node/build-length-attribute.ts +48 -0
  78. package/src/ast/build/node/build-lengthof-expression.ts +45 -0
  79. package/src/ast/build/node/build-map-declaration.ts +110 -0
  80. package/src/ast/build/node/build-map-definition.ts +103 -0
  81. package/src/ast/build/node/build-map-entry.ts +33 -0
  82. package/src/ast/build/node/build-missing-error.ts +10 -0
  83. package/src/ast/build/node/build-multiple-character-literal.ts +65 -0
  84. package/src/ast/build/node/build-parameter-list.ts +50 -0
  85. package/src/ast/build/node/build-parameter-value-list.ts +54 -0
  86. package/src/ast/build/node/build-parameter.ts +47 -0
  87. package/src/ast/build/node/build-partial-array-dimension.ts +55 -0
  88. package/src/ast/build/node/build-specification.ts +24 -0
  89. package/src/ast/build/node/build-string-definition.ts +106 -0
  90. package/src/ast/build/node/build-switch-statement.ts +84 -0
  91. package/src/ast/build/node/build-token.ts +26 -0
  92. package/src/ast/build/node/build-unary-expression.ts +109 -0
  93. package/src/ast/build/node/build-unexpected-error.ts +14 -0
  94. package/src/ast/build/node/build-utf-string-literal.ts +110 -0
  95. package/src/ast/build/node/build-while-statement.ts +55 -0
  96. package/src/ast/build/util/array-dimension-kind-by-token-type-id-map.ts +167 -0
  97. package/src/ast/build/util/binary-operator-kind-by-token-type-id-map.ts +152 -0
  98. package/src/ast/build/util/build-context.ts +36 -0
  99. package/src/ast/build/util/class-id-kind-by-token-type-id-map.ts +160 -0
  100. package/src/ast/build/util/expression-kind-by-token-type-id-map.ts +168 -0
  101. package/src/ast/build/util/fetch-node.ts +433 -0
  102. package/src/ast/build/util/node-kind-by-token-type-id-map.ts +202 -0
  103. package/src/ast/build/util/statement-kind-by-token-type-id-map.ts +210 -0
  104. package/src/ast/build/util/string-literal-kind-by-token-type-id-map.ts +162 -0
  105. package/src/ast/build/util/token-kind-by-token-type-id-map.ts +337 -0
  106. package/src/ast/build-ast.ts +114 -0
  107. package/src/ast/node/abstract-array-definition.ts +17 -0
  108. package/src/ast/node/abstract-array-dimension.ts +20 -0
  109. package/src/ast/node/abstract-class-id.ts +13 -0
  110. package/src/ast/node/abstract-composite-node.ts +58 -0
  111. package/src/ast/node/abstract-elementary-type-definition.ts +29 -0
  112. package/src/ast/node/abstract-expression.ts +13 -0
  113. package/src/ast/node/abstract-leaf-node.ts +10 -0
  114. package/src/ast/node/abstract-node.ts +16 -0
  115. package/src/ast/node/abstract-statement.ts +13 -0
  116. package/src/ast/node/aggregate-output-value.ts +28 -0
  117. package/src/ast/node/aligned-modifier.ts +21 -0
  118. package/src/ast/node/array-definition.ts +44 -0
  119. package/src/ast/node/array-element-access.ts +24 -0
  120. package/src/ast/node/binary-expression.ts +28 -0
  121. package/src/ast/node/bit-modifier.ts +24 -0
  122. package/src/ast/node/case-clause.ts +30 -0
  123. package/src/ast/node/class-declaration.ts +39 -0
  124. package/src/ast/node/class-definition.ts +23 -0
  125. package/src/ast/node/class-id-range.ts +17 -0
  126. package/src/ast/node/class-id.ts +14 -0
  127. package/src/ast/node/class-member-access.ts +19 -0
  128. package/src/ast/node/compound-statement.ts +19 -0
  129. package/src/ast/node/computed-array-definition.ts +26 -0
  130. package/src/ast/node/computed-elementary-type-definition.ts +34 -0
  131. package/src/ast/node/default-clause.ts +26 -0
  132. package/src/ast/node/do-statement.ts +28 -0
  133. package/src/ast/node/elementary-type-definition.ts +49 -0
  134. package/src/ast/node/elementary-type-output-value.ts +19 -0
  135. package/src/ast/node/elementary-type.ts +18 -0
  136. package/src/ast/node/enum/array-dimension-kind.ts +11 -0
  137. package/src/ast/node/enum/binary-operator-kind.ts +41 -0
  138. package/src/ast/node/enum/class-id-kind.ts +12 -0
  139. package/src/ast/node/enum/elementary-type-kind.ts +13 -0
  140. package/src/ast/node/enum/expression-kind.ts +11 -0
  141. package/src/ast/node/enum/node-kind.ts +57 -0
  142. package/src/ast/node/enum/number-literal-kind.ts +17 -0
  143. package/src/ast/node/enum/statement-kind.ts +37 -0
  144. package/src/ast/node/enum/string-literal-kind.ts +13 -0
  145. package/src/ast/node/enum/string-variable-kind.ts +25 -0
  146. package/src/ast/node/enum/token-kind.ts +87 -0
  147. package/src/ast/node/expandable-modifier.ts +21 -0
  148. package/src/ast/node/explicit-array-dimension.ts +26 -0
  149. package/src/ast/node/expression-statement.ts +23 -0
  150. package/src/ast/node/extended-class-id-range.ts +20 -0
  151. package/src/ast/node/extends-modifier.ts +21 -0
  152. package/src/ast/node/for-statement.ts +29 -0
  153. package/src/ast/node/identifier.ts +12 -0
  154. package/src/ast/node/if-statement.ts +28 -0
  155. package/src/ast/node/implicit-array-dimension.ts +34 -0
  156. package/src/ast/node/length-attribute.ts +24 -0
  157. package/src/ast/node/length-of-expression.ts +21 -0
  158. package/src/ast/node/map-declaration.ts +34 -0
  159. package/src/ast/node/map-definition.ts +27 -0
  160. package/src/ast/node/map-entry.ts +18 -0
  161. package/src/ast/node/missing-error.ts +9 -0
  162. package/src/ast/node/number-literal.ts +18 -0
  163. package/src/ast/node/parameter-list.ts +25 -0
  164. package/src/ast/node/parameter-value-list.ts +29 -0
  165. package/src/ast/node/parameter.ts +20 -0
  166. package/src/ast/node/partial-array-dimension.ts +28 -0
  167. package/src/ast/node/specification.ts +21 -0
  168. package/src/ast/node/string-definition.ts +28 -0
  169. package/src/ast/node/string-literal.ts +21 -0
  170. package/src/ast/node/switch-statement.ts +32 -0
  171. package/src/ast/node/token.ts +20 -0
  172. package/src/ast/node/trivia.ts +13 -0
  173. package/src/ast/node/unary-expression.ts +31 -0
  174. package/src/ast/node/unexpected-error.ts +12 -0
  175. package/src/ast/node/while-statement.ts +26 -0
  176. package/src/ast/util/types.ts +138 -0
  177. package/src/ast/visitor/node-handler.ts +15 -0
  178. package/src/ast/visitor/node-visitor.ts +13 -0
  179. package/src/ast/visitor/traversing-visitor.ts +69 -0
  180. package/src/completion/completion-rules.ts +447 -0
  181. package/src/completion/get-potential-syntactic-tokens.ts +54 -0
  182. package/src/completion/get-potential-token-type-ids.ts +116 -0
  183. package/src/completion/hierarchical-map.ts +43 -0
  184. package/src/completion/rules/abstract-types.ts +174 -0
  185. package/src/completion/rules/aggregate-output-value-rules.ts +48 -0
  186. package/src/completion/rules/aligned-modifier-rules.ts +45 -0
  187. package/src/completion/rules/array-definition-rules.ts +87 -0
  188. package/src/completion/rules/array-element-access-rules.ts +22 -0
  189. package/src/completion/rules/assignment-expression-rules.ts +19 -0
  190. package/src/completion/rules/binary-expression-rules.ts +23 -0
  191. package/src/completion/rules/bit-modifier-rules.ts +25 -0
  192. package/src/completion/rules/case-clause-rules.ts +39 -0
  193. package/src/completion/rules/class-declaration-rules.ts +81 -0
  194. package/src/completion/rules/class-definition-rules.ts +28 -0
  195. package/src/completion/rules/class-id-range-rules.ts +17 -0
  196. package/src/completion/rules/class-id-rules.ts +9 -0
  197. package/src/completion/rules/class-member-access-rules.ts +7 -0
  198. package/src/completion/rules/compound-statement-rules.ts +25 -0
  199. package/src/completion/rules/computed-array-definition-rules.ts +25 -0
  200. package/src/completion/rules/computed-elementary-type-rules.ts +44 -0
  201. package/src/completion/rules/default-clause-rules.ts +23 -0
  202. package/src/completion/rules/do-statement-rules.ts +38 -0
  203. package/src/completion/rules/elementary-type-definition-rules.ts +62 -0
  204. package/src/completion/rules/elementary-type-output-value-rules.ts +13 -0
  205. package/src/completion/rules/elementary-type-rules.ts +18 -0
  206. package/src/completion/rules/expandable-modifier-rules.ts +21 -0
  207. package/src/completion/rules/explicit-array-dimension-rules.ts +22 -0
  208. package/src/completion/rules/expression-statement-rules.ts +22 -0
  209. package/src/completion/rules/extended-class-id-range-rules.ts +17 -0
  210. package/src/completion/rules/extends-modifier-rules.ts +17 -0
  211. package/src/completion/rules/for-statement-rules.ts +51 -0
  212. package/src/completion/rules/if-statement-rules.ts +42 -0
  213. package/src/completion/rules/implicit-array-dimension-rules.ts +21 -0
  214. package/src/completion/rules/length-attribute-rules.ts +19 -0
  215. package/src/completion/rules/lengthof-expression-rules.ts +23 -0
  216. package/src/completion/rules/map-declaration-rules.ts +45 -0
  217. package/src/completion/rules/map-definition-rules.ts +46 -0
  218. package/src/completion/rules/map-entry-rules.ts +17 -0
  219. package/src/completion/rules/parameter-list-rules.ts +21 -0
  220. package/src/completion/rules/parameter-rules.ts +17 -0
  221. package/src/completion/rules/parameter-value-list-rules.ts +27 -0
  222. package/src/completion/rules/partial-array-dimension-rules.ts +33 -0
  223. package/src/completion/rules/specification-rules.ts +37 -0
  224. package/src/completion/rules/string-definition-rules.ts +103 -0
  225. package/src/completion/rules/switch-statement-rules.ts +50 -0
  226. package/src/completion/rules/unary-expression-rules.ts +41 -0
  227. package/src/completion/rules/utf-string-literal-rules.ts +17 -0
  228. package/src/completion/rules/while-statement-rules.ts +38 -0
  229. package/src/lezer/context-tracker.ts +45 -0
  230. package/src/lezer/create-sdl-parser.ts +88 -0
  231. package/src/lezer/create-syntax-error-from-text-and-cursor.ts +110 -0
  232. package/src/lezer/create-syntax-error-from-text-and-position.ts +36 -0
  233. package/src/lezer/parser.terms.ts +129 -0
  234. package/src/lezer/parser.ts +63 -0
  235. package/src/lezer/props/fold-node-prop-source.ts +27 -0
  236. package/src/lezer/props/primitive-node-prop-source.ts +19 -0
  237. package/src/lezer/props/style-tags-node-prop-source.ts +188 -0
  238. package/src/lezer/props/syntactic-token-node-prop-source.ts +298 -0
  239. package/src/lezer/sdl-string-input.ts +46 -0
  240. package/src/location.ts +13 -0
  241. package/src/parse-helper.ts +93 -0
  242. package/src/prettier/prettier-plugin-sdl.ts +89 -0
  243. package/src/prettier/print-abstract-array-dimension.ts +84 -0
  244. package/src/prettier/print-abstract-class-id.ts +53 -0
  245. package/src/prettier/print-abstract-expression.ts +168 -0
  246. package/src/prettier/print-abstract-node.ts +224 -0
  247. package/src/prettier/print-abstract-statement.ts +124 -0
  248. package/src/prettier/print-aggregate-output-value.ts +35 -0
  249. package/src/prettier/print-aligned-modifier.ts +50 -0
  250. package/src/prettier/print-array-definition.ts +95 -0
  251. package/src/prettier/print-array-element-access.ts +14 -0
  252. package/src/prettier/print-bit-modifier.ts +48 -0
  253. package/src/prettier/print-case-clause.ts +58 -0
  254. package/src/prettier/print-class-declaration.ts +99 -0
  255. package/src/prettier/print-class-definition.ts +44 -0
  256. package/src/prettier/print-class-member-access.ts +13 -0
  257. package/src/prettier/print-computed-array-definition.ts +33 -0
  258. package/src/prettier/print-computed-elementary-type-definition.ts +60 -0
  259. package/src/prettier/print-default-clause.ts +39 -0
  260. package/src/prettier/print-do-statement.ts +31 -0
  261. package/src/prettier/print-elementary-type-definition.ts +108 -0
  262. package/src/prettier/print-elementary-type-output-value.ts +13 -0
  263. package/src/prettier/print-elementary-type.ts +28 -0
  264. package/src/prettier/print-expandable-modifier.ts +41 -0
  265. package/src/prettier/print-extends-modifier.ts +29 -0
  266. package/src/prettier/print-for-statement.ts +64 -0
  267. package/src/prettier/print-identifier.ts +10 -0
  268. package/src/prettier/print-if-statement.ts +76 -0
  269. package/src/prettier/print-length-attribute.ts +14 -0
  270. package/src/prettier/print-map-declaration.ts +75 -0
  271. package/src/prettier/print-map-definition.ts +67 -0
  272. package/src/prettier/print-map-entry.ts +22 -0
  273. package/src/prettier/print-number-literal.ts +84 -0
  274. package/src/prettier/print-parameter-list.ts +20 -0
  275. package/src/prettier/print-parameter-value-list.ts +20 -0
  276. package/src/prettier/print-parameter.ts +34 -0
  277. package/src/prettier/print-specification.ts +51 -0
  278. package/src/prettier/print-string-definition.ts +114 -0
  279. package/src/prettier/print-string-literal.ts +57 -0
  280. package/src/prettier/print-switch-statement.ts +46 -0
  281. package/src/prettier/print-token.ts +7 -0
  282. package/src/prettier/print-unexpected-error.ts +10 -0
  283. package/src/prettier/print-while-statement.ts +26 -0
  284. package/src/prettier/util/print-utils.ts +607 -0
  285. package/src/prettier/util/types.ts +40 -0
  286. package/src/scanner-error.ts +65 -0
  287. package/src/util/location-utils.ts +16 -0
  288. package/src/util/logger.ts +165 -0
  289. package/tests/analyser/create-sdl-analyser.test.ts +54 -0
  290. package/tests/analyser/get-sdl-analyser-test-scenarios.ts +80 -0
  291. package/tests/analyser/sdl-analyser-scenarios.test.ts +67 -0
  292. package/tests/analyser/semantic-error-scenarios.test.ts +40 -0
  293. package/tests/analyser/symbol-table.test.ts +188 -0
  294. package/tests/analyser/test-cases/array_definition.txt +50 -0
  295. package/tests/analyser/test-cases/class_declaration.txt +112 -0
  296. package/tests/analyser/test-cases/class_definition.txt +60 -0
  297. package/tests/analyser/test-cases/compound_statement.txt +63 -0
  298. package/tests/analyser/test-cases/computed_array_definition.txt +12 -0
  299. package/tests/analyser/test-cases/computed_elementary_type_definition.txt +39 -0
  300. package/tests/analyser/test-cases/do_statement.txt +16 -0
  301. package/tests/analyser/test-cases/elementary_type_definition.txt +58 -0
  302. package/tests/analyser/test-cases/expression.txt +159 -0
  303. package/tests/analyser/test-cases/for_statement.txt +55 -0
  304. package/tests/analyser/test-cases/if_statement.txt +57 -0
  305. package/tests/analyser/test-cases/map_declaration.txt +89 -0
  306. package/tests/analyser/test-cases/map_definition.txt +35 -0
  307. package/tests/analyser/test-cases/number_literal.txt +31 -0
  308. package/tests/analyser/test-cases/parameter_list.txt +16 -0
  309. package/tests/analyser/test-cases/scopes.txt +239 -0
  310. package/tests/analyser/test-cases/specification.txt +28 -0
  311. package/tests/analyser/test-cases/string_definition.txt +40 -0
  312. package/tests/analyser/test-cases/switch_statement.txt +96 -0
  313. package/tests/analyser/test-cases/while_statement.txt +16 -0
  314. package/tests/analyser/util/symbol-table-utils.test.ts +65 -0
  315. package/tests/ast/__snapshots__/build-ast.test.ts.snap +38897 -0
  316. package/tests/ast/build-ast.test.ts +463 -0
  317. package/tests/ast/visitor/traversing-visitor.test.ts +36 -0
  318. package/tests/completion/get-potential-syntactic-tokens.test.ts +89 -0
  319. package/tests/completion/get-potential-token-type-ids.test.ts +76 -0
  320. package/tests/completion/test-potential-syntactic-tokens-scenario.ts +24 -0
  321. package/tests/completion/test-potential-token-type-ids-scenario.ts +33 -0
  322. package/tests/fixtures/history-recording-node-handler.ts +232 -0
  323. package/tests/lezer/create-parse-error-from-text-and-position.test.ts +129 -0
  324. package/tests/lezer/create-sdl-parser.test.ts +15 -0
  325. package/tests/lezer/sdl-parser-scenarios.test.ts +24 -0
  326. package/tests/lezer/sdl-string-input.test.ts +12 -0
  327. package/tests/lezer/syntax-error-scenarios.test.ts +114 -0
  328. package/tests/lezer/test-cases/array_definition.txt +109 -0
  329. package/tests/lezer/test-cases/class_declaration.txt +141 -0
  330. package/tests/lezer/test-cases/class_definition.txt +89 -0
  331. package/tests/lezer/test-cases/comment.txt +335 -0
  332. package/tests/lezer/test-cases/compound_statement.txt +109 -0
  333. package/tests/lezer/test-cases/computed_array_definition.txt +33 -0
  334. package/tests/lezer/test-cases/computed_elementary_type_definition.txt +59 -0
  335. package/tests/lezer/test-cases/do_statement.txt +48 -0
  336. package/tests/lezer/test-cases/elementary_type_definition.txt +158 -0
  337. package/tests/lezer/test-cases/expression.txt +1203 -0
  338. package/tests/lezer/test-cases/for_statement.txt +183 -0
  339. package/tests/lezer/test-cases/if_statement.txt +183 -0
  340. package/tests/lezer/test-cases/invalid.txt +97 -0
  341. package/tests/lezer/test-cases/map_declaration.txt +152 -0
  342. package/tests/lezer/test-cases/map_definition.txt +59 -0
  343. package/tests/lezer/test-cases/number_literal.txt +273 -0
  344. package/tests/lezer/test-cases/specification.txt +38 -0
  345. package/tests/lezer/test-cases/string_definition.txt +263 -0
  346. package/tests/lezer/test-cases/string_literal.txt +303 -0
  347. package/tests/lezer/test-cases/switch_statement.txt +407 -0
  348. package/tests/lezer/test-cases/while_statement.txt +45 -0
  349. package/tests/parse-helper.test.ts +361 -0
  350. package/tests/prettier/__snapshots__/prettier-plugin-sdl.test.ts.snap +127 -0
  351. package/tests/prettier/prettier-plugin-sdl.test.ts +58 -0
  352. package/tests/prettier/print-array.test.ts +29 -0
  353. package/tests/prettier/print-class.test.ts +15 -0
  354. package/tests/prettier/print-do.test.ts +25 -0
  355. package/tests/prettier/print-elementary-type.test.ts +62 -0
  356. package/tests/prettier/print-error.test.ts +40 -0
  357. package/tests/prettier/print-expression.test.ts +17 -0
  358. package/tests/prettier/print-for.test.ts +23 -0
  359. package/tests/prettier/print-if.test.ts +71 -0
  360. package/tests/prettier/print-number-literal.test.ts +28 -0
  361. package/tests/prettier/print-specification.test.ts +54 -0
  362. package/tests/prettier/print-string.test.ts +36 -0
  363. package/tests/prettier/print-switch.test.ts +69 -0
  364. package/tests/prettier/print-while.test.ts +23 -0
  365. package/tests/prettier/test-prettier-scenario.ts +41 -0
  366. package/tests/prettier/util/print-utils.test.ts +665 -0
  367. package/tests/prettier/util/types.test.ts +38 -0
  368. package/tests/sample-specifications/invalid.sdl +24 -0
  369. package/tests/sample-specifications/prettified-invalid.sdl +28 -0
  370. package/tests/sample-specifications/prettified-various-elements-narrow.sdl +97 -0
  371. package/tests/sample-specifications/prettified-various-elements.sdl +90 -0
  372. package/tests/sample-specifications/sample.sdl +24 -0
  373. package/tests/sample-specifications/various-elements.sdl +88 -0
  374. package/tests/util/logger.test.ts +36 -0
  375. package/tsconfig.json +29 -0
@@ -0,0 +1,65 @@
1
+ import type { Location } from "./location.ts";
2
+
3
+ /**
4
+ * Base error class.
5
+ */
6
+ export abstract class ScannerError extends Error {
7
+ protected constructor(
8
+ public errorMessage: string,
9
+ public location?: Location,
10
+ ) {
11
+ super(
12
+ errorMessage +
13
+ (location
14
+ ? ` => { row: ${location.row}, column: ${location.column}, position: ${location.position} }`
15
+ : ""),
16
+ );
17
+ }
18
+ }
19
+
20
+ /**
21
+ * Indicates an internal logic error in the scanner implementation.
22
+ */
23
+ export class InternalScannerError extends ScannerError {
24
+ constructor(errorMessage: string, location?: Location) {
25
+ super(`INTERNAL SCANNER ERROR: ${errorMessage}`, location);
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Indicates a syntactic error in the provided source.
31
+ */
32
+ export class SyntaxError extends ScannerError {
33
+ constructor(
34
+ errorMessage: string,
35
+ location?: Location,
36
+ public errorLine?: string,
37
+ public precedingLines?: string[],
38
+ ) {
39
+ super(`SYNTAX ERROR: ${errorMessage}`.trim(), location);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Indicates a semantic error in the provided AST.
45
+ */
46
+ export class SemanticError extends ScannerError {
47
+ constructor(
48
+ errorMessage: string,
49
+ location?: Location,
50
+ ) {
51
+ super(`SEMANTIC ERROR: ${errorMessage}`.trim(), location);
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Indicates a semantic warning in the provided AST.
57
+ */
58
+ export class SemanticWarning extends ScannerError {
59
+ constructor(
60
+ warningMessage: string,
61
+ location?: Location,
62
+ ) {
63
+ super(`SEMANTIC WARNING: ${warningMessage}`.trim(), location);
64
+ }
65
+ }
@@ -0,0 +1,16 @@
1
+ import { Text } from "@codemirror/state";
2
+ import type { Location } from "../location.ts";
3
+
4
+ export function getLocationFromTextPosition(
5
+ text: Text,
6
+ position: number,
7
+ ): Location {
8
+ const line = text.lineAt(position);
9
+ const row = line.number;
10
+ const column = position - line.from + 1;
11
+ return {
12
+ row,
13
+ column,
14
+ position,
15
+ };
16
+ }
@@ -0,0 +1,165 @@
1
+ declare global {
2
+ var defaultLogger: Logger | undefined;
3
+ }
4
+
5
+ type LoggerFunction = (
6
+ message: object | (() => string) | string,
7
+ ...optionalParams: unknown[]
8
+ ) => void;
9
+
10
+ export interface Logger {
11
+ trace: LoggerFunction;
12
+ debug: LoggerFunction;
13
+ info: LoggerFunction;
14
+ warn: LoggerFunction;
15
+ error: LoggerFunction;
16
+ }
17
+
18
+ const LEVEL_PADDINGS: Record<string, string> = {
19
+ TRACE: " ",
20
+ DEBUG: " ",
21
+ INFO: " ",
22
+ WARN: " ",
23
+ ERROR: " ",
24
+ };
25
+
26
+ export const debugEnabled = (() => {
27
+ // In a node-like environment, check for the environment variable.
28
+ if (typeof globalThis.process !== "undefined" && globalThis.process.env) {
29
+ return globalThis.process.env["MPEG_SDL_PARSER_DEBUG"] !== undefined;
30
+ }
31
+
32
+ // In a browser-like environment, check for the local storage item.
33
+ if (typeof localStorage !== "undefined") {
34
+ try {
35
+ return localStorage.getItem("MPEG_SDL_PARSER_DEBUG") !== null;
36
+ } catch (_e) {
37
+ // Ignore SecurityError if localStorage is disabled.
38
+ return false;
39
+ }
40
+ }
41
+ return false;
42
+ })();
43
+
44
+ let maxLoggerNameLength = 0;
45
+
46
+ const LOGGER_NAME_PADDINGS: Record<string, string> = {};
47
+
48
+ function getDefaultLogger(): Logger {
49
+ return {
50
+ trace: () => {},
51
+ debug: (message, ...optionalParams) => {
52
+ console.debug(message, ...optionalParams);
53
+ },
54
+ info: (message, ...optionalParams) => {
55
+ console.info(message, ...optionalParams);
56
+ },
57
+ warn: (message, ...optionalParams) => {
58
+ console.warn(message, ...optionalParams);
59
+ },
60
+ error: (message, ...optionalParams) => {
61
+ console.error(message, ...optionalParams);
62
+ },
63
+ };
64
+ }
65
+
66
+ function wrapDefaultLogger(
67
+ loggerName: string,
68
+ levelPadding: string,
69
+ loggerFunction: LoggerFunction,
70
+ ): LoggerFunction {
71
+ return (message, ...optionalParams) => {
72
+ if (message instanceof Function) {
73
+ loggerFunction(
74
+ `${levelPadding} [${loggerName}]${
75
+ LOGGER_NAME_PADDINGS[loggerName]
76
+ } ${message()}`,
77
+ ...optionalParams,
78
+ );
79
+ return;
80
+ }
81
+ if (message instanceof Object) {
82
+ loggerFunction(
83
+ `${levelPadding} [${loggerName}]${LOGGER_NAME_PADDINGS[loggerName]} ${
84
+ JSON.stringify(message)
85
+ }`,
86
+ ...optionalParams,
87
+ );
88
+ return;
89
+ }
90
+ loggerFunction(
91
+ `${levelPadding} [${loggerName}]${
92
+ LOGGER_NAME_PADDINGS[loggerName]
93
+ } ${message}`,
94
+ ...optionalParams,
95
+ );
96
+ };
97
+ }
98
+
99
+ /**
100
+ * Retrieves a logger instance with the specified name. If the name length exceeds the current maximum logger name length,
101
+ * it updates the padding for all existing logger names to ensure consistent formatting.
102
+ *
103
+ * @param loggerName The name of the logger to retrieve.
104
+ * @returns A logger instance with the specified name.
105
+ */
106
+ export default function getLogger(loggerName: string): Logger {
107
+ if (globalThis.defaultLogger === undefined) {
108
+ globalThis.defaultLogger = getDefaultLogger();
109
+ }
110
+
111
+ if (loggerName.length > maxLoggerNameLength) {
112
+ maxLoggerNameLength = loggerName.length;
113
+
114
+ for (const key of Object.keys(LOGGER_NAME_PADDINGS)) {
115
+ LOGGER_NAME_PADDINGS[key] = " ".repeat(maxLoggerNameLength - key.length);
116
+ }
117
+
118
+ LOGGER_NAME_PADDINGS[loggerName] = "";
119
+ } else if (LOGGER_NAME_PADDINGS[loggerName] === undefined) {
120
+ LOGGER_NAME_PADDINGS[loggerName] = " ".repeat(
121
+ maxLoggerNameLength - loggerName.length,
122
+ );
123
+ }
124
+
125
+ if (debugEnabled) {
126
+ return {
127
+ trace: wrapDefaultLogger(
128
+ loggerName,
129
+ LEVEL_PADDINGS.TRACE,
130
+ globalThis.defaultLogger.trace,
131
+ ),
132
+ debug: wrapDefaultLogger(
133
+ loggerName,
134
+ LEVEL_PADDINGS.DEBUG,
135
+ globalThis.defaultLogger.debug,
136
+ ),
137
+ info: wrapDefaultLogger(
138
+ loggerName,
139
+ LEVEL_PADDINGS.INFO,
140
+ globalThis.defaultLogger.info,
141
+ ),
142
+ warn: wrapDefaultLogger(
143
+ loggerName,
144
+ LEVEL_PADDINGS.WARN,
145
+ globalThis.defaultLogger.warn,
146
+ ),
147
+ error: wrapDefaultLogger(
148
+ loggerName,
149
+ LEVEL_PADDINGS.ERROR,
150
+ globalThis.defaultLogger.error,
151
+ ),
152
+ };
153
+ }
154
+ return {
155
+ trace: () => {},
156
+ debug: () => {},
157
+ info: () => {},
158
+ warn: () => {},
159
+ error: wrapDefaultLogger(
160
+ loggerName,
161
+ LEVEL_PADDINGS.ERROR,
162
+ globalThis.defaultLogger.error,
163
+ ),
164
+ };
165
+ }
@@ -0,0 +1,54 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import {
3
+ createLenientSdlAnalyser,
4
+ createStrictSdlAnalyser,
5
+ } from "../../src/analyser/create-sdl-analyser.ts";
6
+ import { createLenientSdlParser } from "../../src/lezer/create-sdl-parser.ts";
7
+ import { SdlStringInput } from "../../src/lezer/sdl-string-input.ts";
8
+ import { buildAst } from "../../src/ast/build-ast.ts";
9
+ import type { Specification } from "../../src/ast/node/specification.ts";
10
+
11
+ const lenientSdlParser = createLenientSdlParser();
12
+
13
+ function buildAstWithErrors() {
14
+ const sdlStringInput = new SdlStringInput(
15
+ "class A{bit transport_priority;}",
16
+ );
17
+ const parseTree = lenientSdlParser.parse(sdlStringInput);
18
+ const specification = buildAst(
19
+ parseTree,
20
+ sdlStringInput,
21
+ true,
22
+ );
23
+
24
+ return specification;
25
+ }
26
+
27
+ describe("createSdlAnalyser Tests", () => {
28
+ test("Test lenient SDL analyser creation", () => {
29
+ createLenientSdlAnalyser();
30
+ });
31
+
32
+ test("Test strict SDL analyser creation", () => {
33
+ createStrictSdlAnalyser();
34
+ });
35
+
36
+ test("Test lenient SDL analyser handles syntactic errors in parse tree", () => {
37
+ const specificationWithErrors = buildAstWithErrors();
38
+ const sdlAnalyser = createLenientSdlAnalyser();
39
+
40
+ // The lenient analyser should not throw an error
41
+ sdlAnalyser.analyse(specificationWithErrors as Specification);
42
+ });
43
+
44
+ test("Test strict SDL analyser throws on syntactic errors in parse tree", () => {
45
+ const specificationWithErrors = buildAstWithErrors();
46
+
47
+ const sdlAnalyser = createStrictSdlAnalyser();
48
+
49
+ expect(() => sdlAnalyser.analyse(specificationWithErrors as Specification))
50
+ .toThrow(
51
+ "SEMANTIC ERROR: Required identifier property is a Token node: ERROR_MISSING_TOKEN",
52
+ );
53
+ });
54
+ });
@@ -0,0 +1,80 @@
1
+ function toLineContext(file: string, index: number): string {
2
+ const endEol = file.indexOf("\n", index + 80);
3
+ const endIndex = endEol === -1 ? file.length : endEol;
4
+
5
+ return file.substring(index, endIndex).split(/\n/).map((str) => " | " + str)
6
+ .join("\n");
7
+ }
8
+
9
+ export interface TestScenario {
10
+ name: string;
11
+ text: string;
12
+ expected: string;
13
+ expectedErrors: string;
14
+ expectedWarnings: string;
15
+ }
16
+
17
+ export function getSdlAnalyserTestScenarios(file: string, fileName: string) {
18
+ const scenarioExpr =
19
+ /\s*#[ \t]*(.*)(?:\r\n|\r|\n)([^]*?)==+>([^]*?)(?:\s*$|(?:\r\n|\r|\n)+(?=#))/gy;
20
+ const testScenarios: Array<TestScenario> = [];
21
+ let lastIndex = 0;
22
+
23
+ for (;;) {
24
+ const scenarioRegexResult = scenarioExpr.exec(file);
25
+
26
+ if (!scenarioRegexResult) {
27
+ throw new Error(
28
+ `Unexpected file format in ${fileName} around\n\n${
29
+ toLineContext(file, lastIndex)
30
+ }`,
31
+ );
32
+ }
33
+
34
+ const name = scenarioRegexResult[1].trim();
35
+ const text = scenarioRegexResult[2].trim();
36
+ let rawExpected = scenarioRegexResult[3];
37
+
38
+ let expected = "";
39
+ let expectedErrors = "";
40
+ let expectedWarnings = "";
41
+
42
+ if (rawExpected.includes("errors:")) {
43
+ let expectedSplit = rawExpected.split(/errors:/);
44
+
45
+ expected = expectedSplit[0].trim();
46
+ rawExpected = expectedSplit[1] ?? "";
47
+
48
+ if (rawExpected.includes("warnings:")) {
49
+ expectedSplit = rawExpected.split(/warnings:/);
50
+ expectedErrors = (expectedSplit[0] ?? "").trim();
51
+ expectedWarnings = (expectedSplit[1] ?? "").trim();
52
+ } else {
53
+ expectedErrors = rawExpected.trim();
54
+ }
55
+ } else if (rawExpected.includes("warnings")) {
56
+ const expectedSplit = rawExpected.split(/warnings:/);
57
+
58
+ expected = expectedSplit[0].trim();
59
+ expectedWarnings = (expectedSplit[1] ?? "").trim();
60
+ } else {
61
+ expected = rawExpected.trim();
62
+ }
63
+
64
+ testScenarios.push({
65
+ name,
66
+ text,
67
+ expected,
68
+ expectedErrors,
69
+ expectedWarnings,
70
+ });
71
+
72
+ lastIndex = scenarioRegexResult.index + scenarioRegexResult[0].length;
73
+
74
+ if (lastIndex == file.length) {
75
+ break;
76
+ }
77
+ }
78
+
79
+ return testScenarios;
80
+ }
@@ -0,0 +1,67 @@
1
+ import fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { describe, expect, test } from "bun:test";
5
+ import { createStrictSdlParser } from "../../src/lezer/create-sdl-parser.ts";
6
+ import { getSdlAnalyserTestScenarios } from "./get-sdl-analyser-test-scenarios.ts";
7
+ import { createLenientSdlAnalyser } from "../../src/analyser/create-sdl-analyser.ts";
8
+ import { buildAst } from "../../src/ast/build-ast.ts";
9
+ import { SdlStringInput } from "../../src/lezer/sdl-string-input.ts";
10
+ import { getSymbolTableString } from "../../src/analyser/util/symbol-table-utils.ts";
11
+ import type { Specification } from "../../src/ast/node/specification.ts";
12
+
13
+ const sdlParser = createStrictSdlParser();
14
+ const sdlAnalyser = createLenientSdlAnalyser(undefined);
15
+ const testCaseDir = path.join(
16
+ path.dirname(fileURLToPath(import.meta.url)),
17
+ "test-cases",
18
+ );
19
+
20
+ const normalize = (s: string) => s.replace(/\r\n/g, "\n");
21
+
22
+ for (const filename of fs.readdirSync(testCaseDir)) {
23
+ if (!/\.txt$/.test(filename)) {
24
+ continue;
25
+ }
26
+
27
+ const scenarioName = /^[^\.]*/.exec(filename)?.[0] || "??";
28
+
29
+ describe(`SDL Analyser ${scenarioName} Tests`, () => {
30
+ const testCases = fs.readFileSync(path.join(testCaseDir, filename), "utf8");
31
+
32
+ for (
33
+ const testScenario of getSdlAnalyserTestScenarios(testCases, filename)
34
+ ) {
35
+ test(`Test SDL Analyser ${scenarioName} - ${testScenario.name}`, () => {
36
+ const sdlString = testScenario.text.trim();
37
+ const expectedOutput = normalize(testScenario.expected.trim());
38
+
39
+ const sdlStringInput = new SdlStringInput(sdlString);
40
+ const parseTree = sdlParser.parse(sdlStringInput);
41
+ const specification = buildAst(parseTree, sdlStringInput);
42
+ const actualAnalysisResult = sdlAnalyser.analyse(
43
+ specification as Specification,
44
+ );
45
+ const actualOutput = normalize(getSymbolTableString(
46
+ actualAnalysisResult.symbolTable,
47
+ ));
48
+
49
+ expect(actualOutput).toBe(expectedOutput);
50
+
51
+ const actualErrors = actualAnalysisResult.semanticErrors
52
+ .map((e) => e.errorMessage)
53
+ .join("\n");
54
+ const expectedErrors = normalize(testScenario.expectedErrors);
55
+
56
+ expect(actualErrors).toBe(expectedErrors);
57
+
58
+ const actualWarnings = actualAnalysisResult.semanticWarnings
59
+ .map((e) => e.errorMessage)
60
+ .join("\n");
61
+ const expectedWarnings = normalize(testScenario.expectedWarnings);
62
+
63
+ expect(actualWarnings).toBe(expectedWarnings);
64
+ });
65
+ }
66
+ });
67
+ }
@@ -0,0 +1,40 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import { Specification } from "../../src/ast/node/specification.ts";
4
+ import { createStrictSdlAnalyser } from "../../src/analyser/create-sdl-analyser.ts";
5
+ import { createStrictSdlParser } from "../../src/lezer/create-sdl-parser.ts";
6
+ import { SdlStringInput } from "../../src/lezer/sdl-string-input.ts";
7
+ import { buildAst } from "../../src/ast/build-ast.ts";
8
+
9
+ const sdlParser = createStrictSdlParser();
10
+ const sdlAnalyser = createStrictSdlAnalyser();
11
+
12
+ describe("Semantic Error Scenario Tests", () => {
13
+ test("Empty specification ok", () => {
14
+ const specification = new Specification([]);
15
+
16
+ sdlAnalyser.analyse(specification);
17
+ });
18
+
19
+ test("Duplicate global symbol", () => {
20
+ const sdlStringInput = new SdlStringInput(
21
+ "computed int a = 1; computed int a = 2;",
22
+ );
23
+ const parseTree = sdlParser.parse(sdlStringInput);
24
+ const specification = buildAst(parseTree, sdlStringInput);
25
+
26
+ expect(() => sdlAnalyser.analyse(specification as Specification)).toThrow(
27
+ "SEMANTIC ERROR: Variable: a is already declared in scope: GLOBAL => { row: 1, column: 34, position: 33 }",
28
+ );
29
+ });
30
+
31
+ test("Undefined symbol", () => {
32
+ const sdlStringInput = new SdlStringInput("class A { B b;}");
33
+ const parseTree = sdlParser.parse(sdlStringInput);
34
+ const specification = buildAst(parseTree, sdlStringInput);
35
+
36
+ expect(() => sdlAnalyser.analyse(specification as Specification)).toThrow(
37
+ "SEMANTIC ERROR: Class: B is not declared => { row: 1, column: 11, position: 10 }",
38
+ );
39
+ });
40
+ });
@@ -0,0 +1,188 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import {
3
+ AddSymbolResult,
4
+ NumericType,
5
+ ScopeKind,
6
+ type Symbol,
7
+ SymbolKind,
8
+ SymbolTable,
9
+ } from "../../src/analyser/symbol-table.ts";
10
+ import { TokenKind } from "../../src/ast/node/enum/token-kind.ts";
11
+ import { Token } from "../../src/ast/node/token.ts";
12
+ import { Identifier } from "../../src/ast/node/identifier.ts";
13
+
14
+ describe("Symbol Table Tests", () => {
15
+ const node = new Identifier(
16
+ "foo",
17
+ new Token(TokenKind.IDENTIFIER, "foo", { row: 1, column: 1, position: 0 }),
18
+ );
19
+
20
+ test("Test symbol table creation", () => {
21
+ const table = new SymbolTable();
22
+
23
+ expect(table.getCurrentScope().kind).toBe(ScopeKind.GLOBAL);
24
+ });
25
+
26
+ test("Define and lookup symbol in global scope", () => {
27
+ const table = new SymbolTable();
28
+ const symbol: Symbol = {
29
+ node,
30
+ name: "MyVariable",
31
+ kind: SymbolKind.VARIABLE,
32
+ attributes: {
33
+ isComputed: true,
34
+ isConst: true,
35
+ },
36
+ location: { row: 1, column: 1, position: 0 },
37
+ };
38
+
39
+ expect(table.addSymbol(symbol)).toBe(AddSymbolResult.SUCCESS);
40
+ expect(table.lookupVariable("MyVariable")).toBe(symbol);
41
+ });
42
+
43
+ test("Prevent duplicate symbol definition", () => {
44
+ const table = new SymbolTable();
45
+ const symbol1: Symbol = {
46
+ node,
47
+ name: "MyVariable",
48
+ kind: SymbolKind.VARIABLE,
49
+ attributes: {
50
+ isComputed: true,
51
+ isConst: true,
52
+ },
53
+ location: { row: 1, column: 1, position: 0 },
54
+ };
55
+ const symbol2: Symbol = {
56
+ node,
57
+ name: "MyVariable",
58
+ kind: SymbolKind.VARIABLE,
59
+ attributes: {
60
+ isComputed: true,
61
+ isConst: true,
62
+ },
63
+ location: { row: 1, column: 1, position: 0 },
64
+ };
65
+
66
+ expect(table.addSymbol(symbol1)).toBe(AddSymbolResult.SUCCESS);
67
+ expect(table.addSymbol(symbol2)).toBe(AddSymbolResult.DUPLICATE);
68
+ expect(table.lookupVariable("MyVariable")).toBe(symbol1);
69
+ });
70
+
71
+ test("Prevent conflicting member definition", () => {
72
+ const table = new SymbolTable();
73
+
74
+ const symbol1: Symbol = {
75
+ node,
76
+ name: "MyVariable",
77
+ kind: SymbolKind.VARIABLE,
78
+ attributes: {
79
+ numericType: NumericType.INTEGER,
80
+ isConst: true,
81
+ },
82
+ location: { row: 1, column: 1, position: 0 },
83
+ };
84
+ const symbol2: Symbol = {
85
+ node,
86
+ name: "MyVariable",
87
+ kind: SymbolKind.VARIABLE,
88
+ attributes: {
89
+ numericType: NumericType.FLOATING_POINT,
90
+ isConst: true,
91
+ },
92
+ location: { row: 1, column: 1, position: 0 },
93
+ };
94
+
95
+ table.enterClassScope("A");
96
+ table.enterBlockScope("COMPOUND");
97
+ expect(table.addSymbol(symbol1)).toBe(AddSymbolResult.SUCCESS);
98
+ table.exitScope();
99
+ table.enterBlockScope("COMPOUND");
100
+ expect(table.addSymbol(symbol2)).toBe(AddSymbolResult.MEMBER_CONFLICT);
101
+ table.exitScope();
102
+ });
103
+
104
+ test("Enter and exit scope", () => {
105
+ const table = new SymbolTable();
106
+
107
+ table.enterBlockScope("inner");
108
+
109
+ expect(table.getCurrentScope().kind).toBe(ScopeKind.BLOCK);
110
+ expect(table.getCurrentScope().name).toBe("inner");
111
+
112
+ table.exitScope();
113
+
114
+ expect(table.getCurrentScope().kind).toBe(ScopeKind.GLOBAL);
115
+ });
116
+
117
+ test("Lookup traverses parent scopes", () => {
118
+ const table = new SymbolTable();
119
+ const globalSymbol: Symbol = {
120
+ node,
121
+ name: "globalVar",
122
+ kind: SymbolKind.VARIABLE,
123
+ attributes: {},
124
+ location: { row: 1, column: 1, position: 0 },
125
+ };
126
+
127
+ table.addSymbol(globalSymbol);
128
+
129
+ table.enterBlockScope("inner");
130
+
131
+ const innerSymbol: Symbol = {
132
+ node,
133
+ name: "innerVar",
134
+ kind: SymbolKind.VARIABLE,
135
+ attributes: {},
136
+ location: { row: 1, column: 1, position: 0 },
137
+ };
138
+
139
+ table.addSymbol(innerSymbol);
140
+
141
+ expect(table.lookupVariable("globalVar")).toBe(globalSymbol);
142
+ expect(table.lookupVariable("innerVar")).toBe(innerSymbol);
143
+ });
144
+
145
+ test("lookupClass returns only CLASS symbols", () => {
146
+ const table = new SymbolTable();
147
+
148
+ table.addSymbol({
149
+ node,
150
+ name: "MyClass",
151
+ kind: SymbolKind.CLASS,
152
+ attributes: {},
153
+ location: { row: 1, column: 1, position: 0 },
154
+ });
155
+ table.addSymbol({
156
+ node,
157
+ name: "MyMap",
158
+ kind: SymbolKind.MAP,
159
+ attributes: {},
160
+ location: { row: 1, column: 1, position: 0 },
161
+ });
162
+
163
+ expect(table.lookupClass("MyClass")).toBeDefined();
164
+ expect(table.lookupClass("MyMap")).toBeUndefined();
165
+ });
166
+
167
+ test("lookupMap returns only MAP symbols", () => {
168
+ const table = new SymbolTable();
169
+
170
+ table.addSymbol({
171
+ node,
172
+ name: "MyClass",
173
+ kind: SymbolKind.CLASS,
174
+ attributes: {},
175
+ location: { row: 1, column: 1, position: 0 },
176
+ });
177
+ table.addSymbol({
178
+ node,
179
+ name: "MyMap",
180
+ kind: SymbolKind.MAP,
181
+ attributes: {},
182
+ location: { row: 1, column: 1, position: 0 },
183
+ });
184
+
185
+ expect(table.lookupMap("MyMap")).toBeDefined();
186
+ expect(table.lookupMap("MyClass")).toBeUndefined();
187
+ });
188
+ });