cobolx-2 1.2.3

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 (284) hide show
  1. package/.github/pull_request_template.md +9 -0
  2. package/.github/workflows/ci.yml +18 -0
  3. package/.vscode/launch.json +19 -0
  4. package/.vscode/tasks.json +14 -0
  5. package/CHANGELOG.md +16 -0
  6. package/CONTRIBUTING.md +23 -0
  7. package/CargoX.lock +2 -0
  8. package/LICENSE +21 -0
  9. package/README.md +164 -0
  10. package/api-demo/CargoX.lock +1 -0
  11. package/api-demo/README.md +3 -0
  12. package/api-demo/benchmarks/arith.cbx +6 -0
  13. package/api-demo/cobolx.toml +6 -0
  14. package/api-demo/docs-output/index.html +1 -0
  15. package/api-demo/generated/LEGACYDEMO.cbx +5 -0
  16. package/api-demo/generated/client-types.ts +2 -0
  17. package/api-demo/generated/deploy.json +12 -0
  18. package/api-demo/generated/flowchart.mmd +4 -0
  19. package/api-demo/migrations/20260411215238_init.sql +1 -0
  20. package/api-demo/src/main.cbx +5 -0
  21. package/api-demo/tests/smoke.cbx +6 -0
  22. package/benchmarks/arithmetic.cbx +6 -0
  23. package/cargox/package.json +11 -0
  24. package/cargox/src/index.d.ts +4 -0
  25. package/cargox/src/index.js +5 -0
  26. package/cargox/src/index.js.map +1 -0
  27. package/cargox/src/index.ts +4 -0
  28. package/cargox/src/lockfile/index.d.ts +1 -0
  29. package/cargox/src/lockfile/index.js +9 -0
  30. package/cargox/src/lockfile/index.js.map +1 -0
  31. package/cargox/src/lockfile/index.ts +9 -0
  32. package/cargox/src/manifest.d.ts +10 -0
  33. package/cargox/src/manifest.js +49 -0
  34. package/cargox/src/manifest.js.map +1 -0
  35. package/cargox/src/manifest.ts +58 -0
  36. package/cargox/src/registry/index.d.ts +4 -0
  37. package/cargox/src/registry/index.js +13 -0
  38. package/cargox/src/registry/index.js.map +1 -0
  39. package/cargox/src/registry/index.ts +13 -0
  40. package/cargox/src/resolver/index.d.ts +5 -0
  41. package/cargox/src/resolver/index.js +4 -0
  42. package/cargox/src/resolver/index.js.map +1 -0
  43. package/cargox/src/resolver/index.ts +8 -0
  44. package/cargox/tsconfig.json +7 -0
  45. package/cli/cobolx-cli/package.json +23 -0
  46. package/cli/cobolx-cli/src/commands/add.ts +18 -0
  47. package/cli/cobolx-cli/src/commands/bench.ts +47 -0
  48. package/cli/cobolx-cli/src/commands/build.ts +74 -0
  49. package/cli/cobolx-cli/src/commands/check.ts +24 -0
  50. package/cli/cobolx-cli/src/commands/debug.ts +15 -0
  51. package/cli/cobolx-cli/src/commands/debug_rewind.ts +16 -0
  52. package/cli/cobolx-cli/src/commands/deploy.ts +18 -0
  53. package/cli/cobolx-cli/src/commands/dev.ts +24 -0
  54. package/cli/cobolx-cli/src/commands/doc.ts +19 -0
  55. package/cli/cobolx-cli/src/commands/fmt.ts +14 -0
  56. package/cli/cobolx-cli/src/commands/fuzz.ts +24 -0
  57. package/cli/cobolx-cli/src/commands/generate.ts +38 -0
  58. package/cli/cobolx-cli/src/commands/install.ts +25 -0
  59. package/cli/cobolx-cli/src/commands/legacy.ts +17 -0
  60. package/cli/cobolx-cli/src/commands/lint.ts +17 -0
  61. package/cli/cobolx-cli/src/commands/migrate.ts +27 -0
  62. package/cli/cobolx-cli/src/commands/new.ts +20 -0
  63. package/cli/cobolx-cli/src/commands/profile.ts +8 -0
  64. package/cli/cobolx-cli/src/commands/publish.ts +16 -0
  65. package/cli/cobolx-cli/src/commands/repl.ts +30 -0
  66. package/cli/cobolx-cli/src/commands/run.ts +22 -0
  67. package/cli/cobolx-cli/src/commands/task.ts +27 -0
  68. package/cli/cobolx-cli/src/commands/test.ts +44 -0
  69. package/cli/cobolx-cli/src/commands/update.ts +30 -0
  70. package/cli/cobolx-cli/src/commands/visualize.ts +25 -0
  71. package/cli/cobolx-cli/src/index.ts +101 -0
  72. package/cli/cobolx-cli/src/project.ts +74 -0
  73. package/cli/cobolx-cli/tsconfig.json +7 -0
  74. package/cobolx.toml +7 -0
  75. package/compiler/package.json +14 -0
  76. package/compiler/src/ast/types.d.ts +87 -0
  77. package/compiler/src/ast/types.js +2 -0
  78. package/compiler/src/ast/types.js.map +1 -0
  79. package/compiler/src/ast/types.ts +329 -0
  80. package/compiler/src/backend/custom.d.ts +8 -0
  81. package/compiler/src/backend/custom.js +12 -0
  82. package/compiler/src/backend/custom.js.map +1 -0
  83. package/compiler/src/backend/custom.ts +21 -0
  84. package/compiler/src/borrow_checker/checker.d.ts +3 -0
  85. package/compiler/src/borrow_checker/checker.js +82 -0
  86. package/compiler/src/borrow_checker/checker.js.map +1 -0
  87. package/compiler/src/borrow_checker/checker.ts +100 -0
  88. package/compiler/src/codegen/javascript.d.ts +2 -0
  89. package/compiler/src/codegen/javascript.js +89 -0
  90. package/compiler/src/codegen/javascript.js.map +1 -0
  91. package/compiler/src/codegen/javascript.ts +175 -0
  92. package/compiler/src/const_eval/evaluator.ts +58 -0
  93. package/compiler/src/diagnostics.d.ts +11 -0
  94. package/compiler/src/diagnostics.js +14 -0
  95. package/compiler/src/diagnostics.js.map +1 -0
  96. package/compiler/src/diagnostics.ts +20 -0
  97. package/compiler/src/hir/lower.d.ts +7 -0
  98. package/compiler/src/hir/lower.js +44 -0
  99. package/compiler/src/hir/lower.js.map +1 -0
  100. package/compiler/src/hir/lower.ts +60 -0
  101. package/compiler/src/hir/types.d.ts +21 -0
  102. package/compiler/src/hir/types.js +2 -0
  103. package/compiler/src/hir/types.js.map +1 -0
  104. package/compiler/src/hir/types.ts +26 -0
  105. package/compiler/src/index.d.ts +22 -0
  106. package/compiler/src/index.js +84 -0
  107. package/compiler/src/index.js.map +1 -0
  108. package/compiler/src/index.ts +122 -0
  109. package/compiler/src/lexer/lexer.d.ts +21 -0
  110. package/compiler/src/lexer/lexer.js +207 -0
  111. package/compiler/src/lexer/lexer.js.map +1 -0
  112. package/compiler/src/lexer/lexer.ts +274 -0
  113. package/compiler/src/lexer/tokens.d.ts +8 -0
  114. package/compiler/src/lexer/tokens.js +18 -0
  115. package/compiler/src/lexer/tokens.js.map +1 -0
  116. package/compiler/src/lexer/tokens.ts +126 -0
  117. package/compiler/src/macros/expand.ts +75 -0
  118. package/compiler/src/main.ts +4 -0
  119. package/compiler/src/mir/lower.d.ts +3 -0
  120. package/compiler/src/mir/lower.js +10 -0
  121. package/compiler/src/mir/lower.js.map +1 -0
  122. package/compiler/src/mir/lower.ts +12 -0
  123. package/compiler/src/mir/types.d.ts +13 -0
  124. package/compiler/src/mir/types.js +2 -0
  125. package/compiler/src/mir/types.js.map +1 -0
  126. package/compiler/src/mir/types.ts +16 -0
  127. package/compiler/src/optimizer/constantFold.d.ts +2 -0
  128. package/compiler/src/optimizer/constantFold.js +61 -0
  129. package/compiler/src/optimizer/constantFold.js.map +1 -0
  130. package/compiler/src/optimizer/constantFold.ts +109 -0
  131. package/compiler/src/parser/parser.d.ts +33 -0
  132. package/compiler/src/parser/parser.js +323 -0
  133. package/compiler/src/parser/parser.js.map +1 -0
  134. package/compiler/src/parser/parser.ts +710 -0
  135. package/compiler/src/plugins/api.ts +8 -0
  136. package/compiler/src/plugins/loader.ts +21 -0
  137. package/compiler/src/semantic/analyzer.d.ts +12 -0
  138. package/compiler/src/semantic/analyzer.js +144 -0
  139. package/compiler/src/semantic/analyzer.js.map +1 -0
  140. package/compiler/src/semantic/analyzer.ts +277 -0
  141. package/compiler/src/type_system/checker.d.ts +7 -0
  142. package/compiler/src/type_system/checker.js +84 -0
  143. package/compiler/src/type_system/checker.js.map +1 -0
  144. package/compiler/src/type_system/checker.ts +108 -0
  145. package/compiler/tsconfig.json +7 -0
  146. package/debugger/package.json +11 -0
  147. package/debugger/src/index.d.ts +1 -0
  148. package/debugger/src/index.js +9 -0
  149. package/debugger/src/index.js.map +1 -0
  150. package/debugger/src/index.ts +9 -0
  151. package/debugger/tsconfig.json +7 -0
  152. package/docs/CHANGELOG.md +11 -0
  153. package/docs/CONTRIBUTING.md +15 -0
  154. package/docs/LICENSE +21 -0
  155. package/docs/architecture.md +29 -0
  156. package/docs/cli.md +58 -0
  157. package/docs/language-spec.md +49 -0
  158. package/docs/packages.md +19 -0
  159. package/docs/platform-systems.md +31 -0
  160. package/docs/release-validation.md +22 -0
  161. package/docs/runtime.md +10 -0
  162. package/docs/tooling.md +17 -0
  163. package/docs/vscode-extension.md +40 -0
  164. package/enterprise-demo/CargoX.lock +2 -0
  165. package/enterprise-demo/README.md +3 -0
  166. package/enterprise-demo/benchmarks/arith.cbx +6 -0
  167. package/enterprise-demo/cobolx.toml +7 -0
  168. package/enterprise-demo/src/main.cbx +5 -0
  169. package/enterprise-demo/tests/smoke.cbx +6 -0
  170. package/examples/README.md +20 -0
  171. package/examples/actors-and-flags.md +8 -0
  172. package/examples/api-server/README.md +9 -0
  173. package/examples/api-server/cobolx.toml +6 -0
  174. package/examples/api-server/src/main.cbx +8 -0
  175. package/examples/debug-replay.md +7 -0
  176. package/examples/debugging-demo/README.md +3 -0
  177. package/examples/debugging-demo/cobolx.toml +6 -0
  178. package/examples/debugging-demo/src/main.cbx +7 -0
  179. package/examples/distributed-service.md +12 -0
  180. package/examples/distributed-system/README.md +3 -0
  181. package/examples/distributed-system/cobolx.toml +6 -0
  182. package/examples/distributed-system/generated/deploy.json +12 -0
  183. package/examples/distributed-system/src/main.cbx +6 -0
  184. package/examples/event-driven.md +5 -0
  185. package/examples/event-system/README.md +3 -0
  186. package/examples/event-system/cobolx.toml +6 -0
  187. package/examples/event-system/src/main.cbx +11 -0
  188. package/examples/functions.cbx +10 -0
  189. package/examples/functions.mjs +12 -0
  190. package/examples/hello.cbx +5 -0
  191. package/examples/hello.mjs +7 -0
  192. package/examples/legacy-sample.cob +5 -0
  193. package/examples/parallel-processing/README.md +3 -0
  194. package/examples/parallel-processing/cobolx.toml +6 -0
  195. package/examples/parallel-processing/src/main.cbx +6 -0
  196. package/examples/parallel-processing.md +8 -0
  197. package/examples/platform-features.cbx +32 -0
  198. package/examples/platform-features.mjs +35 -0
  199. package/examples/service.cbx +10 -0
  200. package/examples/workflow-engine/README.md +3 -0
  201. package/examples/workflow-engine/cobolx.toml +6 -0
  202. package/examples/workflow-engine/generated/flowchart.mmd +8 -0
  203. package/examples/workflow-engine/src/main.cbx +13 -0
  204. package/examples/workflow-engine.md +5 -0
  205. package/formatter/package.json +14 -0
  206. package/formatter/src/index.d.ts +1 -0
  207. package/formatter/src/index.js +59 -0
  208. package/formatter/src/index.js.map +1 -0
  209. package/formatter/src/index.ts +103 -0
  210. package/formatter/tsconfig.json +7 -0
  211. package/generated/LEGACYDEMO.cbx +5 -0
  212. package/install.ps1 +4 -0
  213. package/install.sh +5 -0
  214. package/linter/package.json +14 -0
  215. package/linter/src/index.d.ts +2 -0
  216. package/linter/src/index.js +18 -0
  217. package/linter/src/index.js.map +1 -0
  218. package/linter/src/index.ts +19 -0
  219. package/linter/tsconfig.json +7 -0
  220. package/lsp/server/package.json +16 -0
  221. package/lsp/server/src/index.ts +168 -0
  222. package/lsp/server/tsconfig.json +7 -0
  223. package/package.json +30 -0
  224. package/profiler/package.json +11 -0
  225. package/profiler/src/index.d.ts +5 -0
  226. package/profiler/src/index.js +11 -0
  227. package/profiler/src/index.js.map +1 -0
  228. package/profiler/src/index.ts +11 -0
  229. package/profiler/tsconfig.json +7 -0
  230. package/release.json +10 -0
  231. package/runtime/package.json +14 -0
  232. package/runtime/src/actors/index.ts +27 -0
  233. package/runtime/src/async/futures.ts +11 -0
  234. package/runtime/src/code_as_data/index.ts +5 -0
  235. package/runtime/src/config/index.ts +17 -0
  236. package/runtime/src/distributed/index.ts +13 -0
  237. package/runtime/src/events/index.ts +21 -0
  238. package/runtime/src/feature_flags/index.ts +9 -0
  239. package/runtime/src/gc_or_arc/index.ts +1 -0
  240. package/runtime/src/healing/index.ts +26 -0
  241. package/runtime/src/index.ts +20 -0
  242. package/runtime/src/intents/index.ts +9 -0
  243. package/runtime/src/iterators/index.ts +23 -0
  244. package/runtime/src/memory/arc.ts +22 -0
  245. package/runtime/src/observability/index.ts +23 -0
  246. package/runtime/src/repl/context.ts +7 -0
  247. package/runtime/src/scheduler/taskScheduler.ts +11 -0
  248. package/runtime/src/security/capabilities.ts +15 -0
  249. package/runtime/src/security/secrets.ts +13 -0
  250. package/runtime/src/state/versioned.ts +31 -0
  251. package/runtime/src/std_hooks/audit.ts +23 -0
  252. package/runtime/src/time_travel/index.ts +54 -0
  253. package/runtime/src/workflows/index.ts +35 -0
  254. package/runtime/tsconfig.json +7 -0
  255. package/sample-payroll/README.md +3 -0
  256. package/sample-payroll/cobolx.toml +3 -0
  257. package/sample-payroll/src/main.cbx +5 -0
  258. package/stdlib/business/index.js +15 -0
  259. package/stdlib/core/README.md +8 -0
  260. package/stdlib/core/runtime.js +191 -0
  261. package/stdlib/crypto/index.js +5 -0
  262. package/stdlib/datetime/index.js +3 -0
  263. package/stdlib/fs/index.js +9 -0
  264. package/stdlib/http/index.js +7 -0
  265. package/stdlib/io/index.js +1 -0
  266. package/stdlib/json/index.js +7 -0
  267. package/stdlib/net/index.js +4 -0
  268. package/tests/macros.cbx +10 -0
  269. package/tests/pattern_match.cbx +16 -0
  270. package/tests/smoke.cbx +7 -0
  271. package/tests/validate-release.mjs +54 -0
  272. package/tsconfig.base.json +24 -0
  273. package/vscode-extension/LICENSE +21 -0
  274. package/vscode-extension/README.md +47 -0
  275. package/vscode-extension/cobolx-1.2.0.vsix +0 -0
  276. package/vscode-extension/icon.png +0 -0
  277. package/vscode-extension/icon.svg +15 -0
  278. package/vscode-extension/language-configuration.json +17 -0
  279. package/vscode-extension/package.json +148 -0
  280. package/vscode-extension/snippets/cobolx.code-snippets +49 -0
  281. package/vscode-extension/src/extension.ts +283 -0
  282. package/vscode-extension/syntaxes/cobolx.tmLanguage.json +75 -0
  283. package/vscode-extension/tests/test.cbl +3 -0
  284. package/vscode-extension/tsconfig.json +7 -0
@@ -0,0 +1,8 @@
1
+ import type { Diagnostic } from "../diagnostics.js";
2
+ import type { ProgramNode } from "../ast/types.js";
3
+
4
+ export interface CompilerPlugin {
5
+ name: string;
6
+ transformProgram?(program: ProgramNode): ProgramNode | Promise<ProgramNode>;
7
+ lintProgram?(program: ProgramNode): Diagnostic[] | Promise<Diagnostic[]>;
8
+ }
@@ -0,0 +1,21 @@
1
+ import path from "node:path";
2
+ import { createRequire } from "node:module";
3
+ import type { Diagnostic } from "../diagnostics.js";
4
+ import type { ProgramNode } from "../ast/types.js";
5
+ import type { CompilerPlugin } from "./api.js";
6
+
7
+ export function applyCompilerPlugins(program: ProgramNode, baseDir: string): { program: ProgramNode; diagnostics: Diagnostic[] } {
8
+ let current = program;
9
+ const diagnostics: Diagnostic[] = [];
10
+ const require = createRequire(import.meta.url);
11
+
12
+ for (const pluginRef of program.plugins) {
13
+ const pluginPath = path.isAbsolute(pluginRef.pluginPath) ? pluginRef.pluginPath : path.resolve(baseDir, pluginRef.pluginPath);
14
+ const module = require(pluginPath);
15
+ const plugin = (module.default ?? module.plugin) as CompilerPlugin;
16
+ if (plugin.transformProgram) current = plugin.transformProgram(current) as ProgramNode;
17
+ if (plugin.lintProgram) diagnostics.push(...(plugin.lintProgram(current) as Diagnostic[]));
18
+ }
19
+
20
+ return { program: current, diagnostics };
21
+ }
@@ -0,0 +1,12 @@
1
+ import type { ProgramNode } from "../ast/types.js";
2
+ import type { Diagnostic } from "../diagnostics.js";
3
+ export declare class SemanticAnalyzer {
4
+ analyze(program: ProgramNode): Diagnostic[];
5
+ private analyzeStatements;
6
+ private analyzeIfStatement;
7
+ private analyzeExpression;
8
+ private analyzeIdentifier;
9
+ private analyzeCallExpression;
10
+ private isStdlibSymbol;
11
+ private isStdlibCall;
12
+ }
@@ -0,0 +1,144 @@
1
+ class Scope {
2
+ parent;
3
+ values = new Set();
4
+ constructor(parent) {
5
+ this.parent = parent;
6
+ }
7
+ declare(name) {
8
+ this.values.add(name);
9
+ }
10
+ has(name) {
11
+ if (this.values.has(name)) {
12
+ return true;
13
+ }
14
+ return this.parent?.has(name) ?? false;
15
+ }
16
+ }
17
+ export class SemanticAnalyzer {
18
+ analyze(program) {
19
+ const diagnostics = [];
20
+ const functions = new Map();
21
+ for (const fn of program.functions) {
22
+ if (functions.has(fn.name)) {
23
+ diagnostics.push({
24
+ message: `Function '${fn.name}' is already declared`,
25
+ range: fn.range,
26
+ severity: "error"
27
+ });
28
+ }
29
+ else {
30
+ functions.set(fn.name, { params: fn.params, declaration: fn });
31
+ }
32
+ }
33
+ for (const fn of program.functions) {
34
+ const scope = new Scope();
35
+ for (const param of fn.params) {
36
+ scope.declare(param);
37
+ }
38
+ this.analyzeStatements(fn.body, scope, functions, diagnostics, true);
39
+ }
40
+ this.analyzeStatements(program.body, new Scope(), functions, diagnostics, false);
41
+ return diagnostics;
42
+ }
43
+ analyzeStatements(statements, scope, functions, diagnostics, insideFunction) {
44
+ for (const statement of statements) {
45
+ switch (statement.kind) {
46
+ case "SetStatement":
47
+ this.analyzeExpression(statement.expression, scope, functions, diagnostics);
48
+ scope.declare(statement.name);
49
+ break;
50
+ case "DisplayStatement":
51
+ this.analyzeExpression(statement.expression, scope, functions, diagnostics);
52
+ break;
53
+ case "InputStatement":
54
+ if (statement.prompt) {
55
+ this.analyzeExpression(statement.prompt, scope, functions, diagnostics);
56
+ }
57
+ scope.declare(statement.name);
58
+ break;
59
+ case "IfStatement":
60
+ this.analyzeIfStatement(statement, scope, functions, diagnostics, insideFunction);
61
+ break;
62
+ case "ReturnStatement":
63
+ if (!insideFunction) {
64
+ diagnostics.push({
65
+ message: "RETURN can only be used inside a FUNCTION",
66
+ range: statement.range,
67
+ severity: "error"
68
+ });
69
+ }
70
+ this.analyzeExpression(statement.expression, scope, functions, diagnostics);
71
+ break;
72
+ case "ExpressionStatement":
73
+ this.analyzeExpression(statement.expression, scope, functions, diagnostics);
74
+ break;
75
+ }
76
+ }
77
+ }
78
+ analyzeIfStatement(statement, scope, functions, diagnostics, insideFunction) {
79
+ this.analyzeExpression(statement.condition, scope, functions, diagnostics);
80
+ this.analyzeStatements(statement.thenBranch, new Scope(scope), functions, diagnostics, insideFunction);
81
+ this.analyzeStatements(statement.elseBranch, new Scope(scope), functions, diagnostics, insideFunction);
82
+ }
83
+ analyzeExpression(expression, scope, functions, diagnostics) {
84
+ switch (expression.kind) {
85
+ case "Identifier":
86
+ this.analyzeIdentifier(expression, scope, diagnostics);
87
+ break;
88
+ case "BinaryExpression":
89
+ this.analyzeExpression(expression.left, scope, functions, diagnostics);
90
+ this.analyzeExpression(expression.right, scope, functions, diagnostics);
91
+ break;
92
+ case "UnaryExpression":
93
+ this.analyzeExpression(expression.operand, scope, functions, diagnostics);
94
+ break;
95
+ case "CallExpression":
96
+ this.analyzeCallExpression(expression, scope, functions, diagnostics);
97
+ break;
98
+ case "NumberLiteral":
99
+ case "StringLiteral":
100
+ case "BooleanLiteral":
101
+ break;
102
+ }
103
+ }
104
+ analyzeIdentifier(expression, scope, diagnostics) {
105
+ if (!scope.has(expression.name) && !this.isStdlibSymbol(expression.name)) {
106
+ diagnostics.push({
107
+ message: `Variable '${expression.name}' is not defined`,
108
+ range: expression.range,
109
+ severity: "error"
110
+ });
111
+ }
112
+ }
113
+ analyzeCallExpression(expression, scope, functions, diagnostics) {
114
+ for (const arg of expression.args) {
115
+ this.analyzeExpression(arg, scope, functions, diagnostics);
116
+ }
117
+ if (this.isStdlibCall(expression.callee)) {
118
+ return;
119
+ }
120
+ const fn = functions.get(expression.callee);
121
+ if (!fn) {
122
+ diagnostics.push({
123
+ message: `Function '${expression.callee}' is not defined`,
124
+ range: expression.range,
125
+ severity: "error"
126
+ });
127
+ return;
128
+ }
129
+ if (fn.params.length !== expression.args.length) {
130
+ diagnostics.push({
131
+ message: `Function '${expression.callee}' expects ${fn.params.length} argument(s) but received ${expression.args.length}`,
132
+ range: expression.range,
133
+ severity: "error"
134
+ });
135
+ }
136
+ }
137
+ isStdlibSymbol(name) {
138
+ return name === "math" || name === "strings";
139
+ }
140
+ isStdlibCall(name) {
141
+ return name === "display" || name === "input";
142
+ }
143
+ }
144
+ //# sourceMappingURL=analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,277 @@
1
+ import type {
2
+ CallExpressionNode,
3
+ ExpressionNode,
4
+ FunctionDeclarationNode,
5
+ FunctionSignatureNode,
6
+ IdentifierNode,
7
+ MatchStatementNode,
8
+ ProgramNode,
9
+ StatementNode
10
+ } from "../ast/types.js";
11
+ import type { Diagnostic } from "../diagnostics.js";
12
+
13
+ interface FunctionInfo {
14
+ params: string[];
15
+ declaration: FunctionDeclarationNode;
16
+ }
17
+
18
+ class Scope {
19
+ private readonly values = new Set<string>();
20
+
21
+ constructor(private readonly parent?: Scope) {}
22
+
23
+ declare(name: string): void {
24
+ this.values.add(name);
25
+ }
26
+
27
+ has(name: string): boolean {
28
+ if (this.values.has(name)) return true;
29
+ return this.parent?.has(name) ?? false;
30
+ }
31
+ }
32
+
33
+ export class SemanticAnalyzer {
34
+ analyze(program: ProgramNode): Diagnostic[] {
35
+ const diagnostics: Diagnostic[] = [];
36
+ const functions = new Map<string, FunctionInfo>();
37
+ const traits = new Map(program.traits.map((trait) => [trait.name, trait]));
38
+ const macros = new Set<string>();
39
+
40
+ for (const value of [...program.consts.map((item) => item.name), ...program.enums.map((item) => item.name), ...program.modules.map((item) => item.name)]) {
41
+ if (functions.has(value)) {
42
+ diagnostics.push({ message: `Duplicate top-level symbol '${value}'`, range: program.range, severity: "error" });
43
+ }
44
+ }
45
+
46
+ for (const fn of program.functions) {
47
+ const name = fn.signature.name;
48
+ if (functions.has(name)) diagnostics.push({ message: `Function '${name}' is already declared`, range: fn.range, severity: "error" });
49
+ else functions.set(name, { params: fn.signature.params.map((param) => param.name), declaration: fn });
50
+ this.validateLifetimeSignature(fn.signature, diagnostics);
51
+ }
52
+
53
+ for (const macro of program.macros) {
54
+ if (macros.has(macro.name)) diagnostics.push({ message: `Macro '${macro.name}' is already declared`, range: macro.range, severity: "error" });
55
+ macros.add(macro.name);
56
+ if (!functions.has(macro.name)) {
57
+ functions.set(macro.name, { params: macro.params, declaration: { kind: "FunctionDeclaration", signature: { kind: "FunctionSignature", name: macro.name, genericParams: [], params: macro.params.map((param) => ({ name: param })), range: macro.range }, body: macro.body, range: macro.range } });
58
+ }
59
+ }
60
+
61
+ for (const implNode of program.impls) {
62
+ if (!implNode.traitName) continue;
63
+ const trait = traits.get(implNode.traitName);
64
+ if (!trait) {
65
+ diagnostics.push({ message: `Trait '${implNode.traitName}' is not defined`, range: implNode.range, severity: "error" });
66
+ continue;
67
+ }
68
+ const implemented = new Set(implNode.methods.map((method) => method.signature.name));
69
+ for (const traitMethod of trait.methods) {
70
+ if (!implemented.has(traitMethod.signature.name)) {
71
+ diagnostics.push({
72
+ message: `Impl for '${implNode.targetType}' is missing trait method '${traitMethod.signature.name}'`,
73
+ range: implNode.range,
74
+ severity: "error"
75
+ });
76
+ }
77
+ }
78
+ }
79
+
80
+ for (const fn of program.functions) {
81
+ const scope = new Scope();
82
+ for (const constant of program.consts) scope.declare(constant.name);
83
+ for (const param of fn.signature.params) scope.declare(param.name);
84
+ this.analyzeStatements(fn.body, scope, functions, macros, diagnostics, true);
85
+ }
86
+
87
+ const rootScope = new Scope();
88
+ for (const constant of program.consts) rootScope.declare(constant.name);
89
+ for (const importDecl of program.imports) rootScope.declare(importDecl.alias ?? importDecl.importedName);
90
+ this.analyzeStatements(program.body, rootScope, functions, macros, diagnostics, false);
91
+ return diagnostics;
92
+ }
93
+
94
+ private validateLifetimeSignature(signature: FunctionSignatureNode, diagnostics: Diagnostic[]): void {
95
+ if (!signature.returnLifetime) return;
96
+ const knownLifetimes = new Set(signature.params.map((param) => param.lifetime).filter(Boolean));
97
+ const declaredLifetimes = new Set(signature.genericParams.map((param) => param.lifetime).filter(Boolean));
98
+ if (!knownLifetimes.has(signature.returnLifetime) && !declaredLifetimes.has(signature.returnLifetime)) {
99
+ diagnostics.push({
100
+ message: `Unknown lifetime '${signature.returnLifetime}' in return type of '${signature.name}'`,
101
+ range: signature.range,
102
+ severity: "error"
103
+ });
104
+ }
105
+ }
106
+
107
+ private analyzeStatements(
108
+ statements: StatementNode[],
109
+ scope: Scope,
110
+ functions: Map<string, FunctionInfo>,
111
+ macros: Set<string>,
112
+ diagnostics: Diagnostic[],
113
+ insideFunction: boolean
114
+ ): void {
115
+ for (const statement of statements) {
116
+ switch (statement.kind) {
117
+ case "LetStatement":
118
+ this.analyzeExpression(statement.expression, scope, functions, macros, diagnostics);
119
+ scope.declare(statement.binding.name);
120
+ break;
121
+ case "SetStatement":
122
+ this.analyzeExpression(statement.expression, scope, functions, macros, diagnostics);
123
+ scope.declare(statement.name);
124
+ break;
125
+ case "DisplayStatement":
126
+ case "AssertStatement":
127
+ case "SpawnStatement":
128
+ case "ExpressionStatement":
129
+ this.analyzeExpression(statement.expression, scope, functions, macros, diagnostics);
130
+ break;
131
+ case "InputStatement":
132
+ if (statement.prompt) this.analyzeExpression(statement.prompt, scope, functions, macros, diagnostics);
133
+ scope.declare(statement.name);
134
+ break;
135
+ case "IfStatement":
136
+ this.analyzeExpression(statement.condition, scope, functions, macros, diagnostics);
137
+ this.analyzeStatements(statement.thenBranch, new Scope(scope), functions, macros, diagnostics, insideFunction);
138
+ this.analyzeStatements(statement.elseBranch, new Scope(scope), functions, macros, diagnostics, insideFunction);
139
+ break;
140
+ case "MatchStatement":
141
+ this.analyzeMatchStatement(statement, scope, functions, macros, diagnostics, insideFunction);
142
+ break;
143
+ case "ReturnStatement":
144
+ if (!insideFunction) diagnostics.push({ message: "RETURN can only be used inside a FUNCTION", range: statement.range, severity: "error" });
145
+ this.analyzeExpression(statement.expression, scope, functions, macros, diagnostics);
146
+ break;
147
+ case "UnsafeBlock":
148
+ case "BlockStatement":
149
+ this.analyzeStatements(statement.body, new Scope(scope), functions, macros, diagnostics, insideFunction);
150
+ break;
151
+ }
152
+ }
153
+ }
154
+
155
+ private analyzeMatchStatement(
156
+ statement: MatchStatementNode,
157
+ scope: Scope,
158
+ functions: Map<string, FunctionInfo>,
159
+ macros: Set<string>,
160
+ diagnostics: Diagnostic[],
161
+ insideFunction: boolean
162
+ ): void {
163
+ this.analyzeExpression(statement.expression, scope, functions, macros, diagnostics);
164
+ const variantPatterns = new Set<string>();
165
+ for (const arm of statement.arms) {
166
+ if (arm.pattern.kind === "VariantPattern") variantPatterns.add(arm.pattern.variantName);
167
+ const armScope = new Scope(scope);
168
+ if (arm.pattern.kind === "IdentifierPattern") armScope.declare(arm.pattern.name);
169
+ if (arm.pattern.kind === "VariantPattern") for (const binding of arm.pattern.bindings) armScope.declare(binding);
170
+ this.analyzeStatements(arm.body, armScope, functions, macros, diagnostics, insideFunction);
171
+ }
172
+ if (statement.arms.length === 0) diagnostics.push({ message: "MATCH must contain at least one arm", range: statement.range, severity: "error" });
173
+ const hasWildcard = statement.arms.some((arm) => arm.pattern.kind === "WildcardPattern" || arm.pattern.kind === "IdentifierPattern");
174
+ if (!hasWildcard && variantPatterns.size < 2) {
175
+ diagnostics.push({ message: "MATCH should include exhaustive patterns or a wildcard arm", range: statement.range, severity: "warning" });
176
+ }
177
+ }
178
+
179
+ private analyzeExpression(
180
+ expression: ExpressionNode,
181
+ scope: Scope,
182
+ functions: Map<string, FunctionInfo>,
183
+ macros: Set<string>,
184
+ diagnostics: Diagnostic[]
185
+ ): void {
186
+ switch (expression.kind) {
187
+ case "Identifier":
188
+ this.analyzeIdentifier(expression, scope, diagnostics);
189
+ break;
190
+ case "BinaryExpression":
191
+ this.analyzeExpression(expression.left, scope, functions, macros, diagnostics);
192
+ this.analyzeExpression(expression.right, scope, functions, macros, diagnostics);
193
+ break;
194
+ case "UnaryExpression":
195
+ this.analyzeExpression(expression.operand, scope, functions, macros, diagnostics);
196
+ break;
197
+ case "TryExpression":
198
+ this.analyzeExpression(expression.expression, scope, functions, macros, diagnostics);
199
+ break;
200
+ case "CallExpression":
201
+ this.analyzeCallExpression(expression, scope, functions, macros, diagnostics);
202
+ break;
203
+ case "MacroInvocation":
204
+ if (!macros.has(expression.name)) diagnostics.push({ message: `Macro '${expression.name}' is not defined`, range: expression.range, severity: "error" });
205
+ for (const arg of expression.args) this.analyzeExpression(arg, scope, functions, macros, diagnostics);
206
+ break;
207
+ case "MemberExpression":
208
+ this.analyzeExpression(expression.object, scope, functions, macros, diagnostics);
209
+ break;
210
+ case "EnumConstructorExpression":
211
+ for (const field of expression.fields) this.analyzeExpression(field, scope, functions, macros, diagnostics);
212
+ break;
213
+ case "ArrayLiteral":
214
+ for (const item of expression.items) this.analyzeExpression(item, scope, functions, macros, diagnostics);
215
+ break;
216
+ case "NumberLiteral":
217
+ case "StringLiteral":
218
+ case "BooleanLiteral":
219
+ break;
220
+ }
221
+ }
222
+
223
+ private analyzeIdentifier(expression: IdentifierNode, scope: Scope, diagnostics: Diagnostic[]): void {
224
+ if (!scope.has(expression.name) && !this.isBuiltinSymbol(expression.name)) {
225
+ diagnostics.push({ message: `Variable '${expression.name}' is not defined`, range: expression.range, severity: "error" });
226
+ }
227
+ }
228
+
229
+ private analyzeCallExpression(
230
+ expression: CallExpressionNode,
231
+ scope: Scope,
232
+ functions: Map<string, FunctionInfo>,
233
+ macros: Set<string>,
234
+ diagnostics: Diagnostic[]
235
+ ): void {
236
+ if (expression.callee.kind !== "Identifier") this.analyzeExpression(expression.callee, scope, functions, macros, diagnostics);
237
+ for (const arg of expression.args) this.analyzeExpression(arg, scope, functions, macros, diagnostics);
238
+
239
+ if (expression.callee.kind !== "Identifier") return;
240
+ const callee = expression.callee.name;
241
+ if (this.isBuiltinCall(callee)) return;
242
+ const fn = functions.get(callee);
243
+ if (!fn) {
244
+ diagnostics.push({ message: `Function '${callee}' is not defined`, range: expression.range, severity: "error" });
245
+ return;
246
+ }
247
+ if (fn.params.length !== expression.args.length) {
248
+ diagnostics.push({
249
+ message: `Function '${callee}' expects ${fn.params.length} argument(s) but received ${expression.args.length}`,
250
+ range: expression.range,
251
+ severity: "error"
252
+ });
253
+ }
254
+ }
255
+
256
+ private isBuiltinSymbol(name: string): boolean {
257
+ return ["math", "strings", "iter", "Result", "Option"].includes(name);
258
+ }
259
+
260
+ private isBuiltinCall(name: string): boolean {
261
+ return [
262
+ "display",
263
+ "input",
264
+ "OK",
265
+ "ERR",
266
+ "SOME",
267
+ "NONE",
268
+ "spawn",
269
+ "channel",
270
+ "iter",
271
+ "collect",
272
+ "map",
273
+ "filter",
274
+ "reduce"
275
+ ].includes(name);
276
+ }
277
+ }
@@ -0,0 +1,7 @@
1
+ import type { ProgramNode } from "../ast/types.js";
2
+ import type { Diagnostic } from "../diagnostics.js";
3
+ import type { CobolxType } from "../hir/types.js";
4
+ export declare function inferProgramTypes(program: ProgramNode): {
5
+ symbolTypes: Record<string, CobolxType>;
6
+ diagnostics: Diagnostic[];
7
+ };
@@ -0,0 +1,84 @@
1
+ function lookup(scope, name) {
2
+ return scope.values.get(name) ?? (scope.parent ? lookup(scope.parent, name) : undefined);
3
+ }
4
+ function inferExpression(expression, scope, diagnostics) {
5
+ switch (expression.kind) {
6
+ case "NumberLiteral":
7
+ return "number";
8
+ case "StringLiteral":
9
+ return "string";
10
+ case "BooleanLiteral":
11
+ return "boolean";
12
+ case "Identifier":
13
+ return lookup(scope, expression.name) ?? "unknown";
14
+ case "UnaryExpression":
15
+ return inferExpression(expression.operand, scope, diagnostics);
16
+ case "CallExpression":
17
+ for (const arg of expression.args) {
18
+ inferExpression(arg, scope, diagnostics);
19
+ }
20
+ return "unknown";
21
+ case "BinaryExpression":
22
+ return inferBinaryExpression(expression, scope, diagnostics);
23
+ }
24
+ }
25
+ function inferBinaryExpression(expression, scope, diagnostics) {
26
+ const left = inferExpression(expression.left, scope, diagnostics);
27
+ const right = inferExpression(expression.right, scope, diagnostics);
28
+ if (["+", "-", "*", "/"].includes(expression.operator)) {
29
+ if (left !== "number" || right !== "number") {
30
+ diagnostics.push({
31
+ message: `Arithmetic operator '${expression.operator}' expects number operands`,
32
+ severity: "warning",
33
+ range: expression.range
34
+ });
35
+ }
36
+ return "number";
37
+ }
38
+ if (["==", "!=", "<", "<=", ">", ">="].includes(expression.operator)) {
39
+ return "boolean";
40
+ }
41
+ return "unknown";
42
+ }
43
+ export function inferProgramTypes(program) {
44
+ const diagnostics = [];
45
+ const scope = { values: new Map() };
46
+ const visitStatements = (statements, localScope) => {
47
+ for (const statement of statements) {
48
+ switch (statement.kind) {
49
+ case "SetStatement":
50
+ localScope.values.set(statement.name, inferExpression(statement.expression, localScope, diagnostics));
51
+ break;
52
+ case "InputStatement":
53
+ localScope.values.set(statement.name, "string");
54
+ if (statement.prompt) {
55
+ inferExpression(statement.prompt, localScope, diagnostics);
56
+ }
57
+ break;
58
+ case "DisplayStatement":
59
+ case "ExpressionStatement":
60
+ case "ReturnStatement":
61
+ inferExpression(statement.expression, localScope, diagnostics);
62
+ break;
63
+ case "IfStatement":
64
+ inferExpression(statement.condition, localScope, diagnostics);
65
+ visitStatements(statement.thenBranch, { values: new Map(localScope.values), parent: localScope.parent });
66
+ visitStatements(statement.elseBranch, { values: new Map(localScope.values), parent: localScope.parent });
67
+ break;
68
+ }
69
+ }
70
+ };
71
+ for (const fn of program.functions) {
72
+ const fnScope = { values: new Map(), parent: scope };
73
+ for (const param of fn.params) {
74
+ fnScope.values.set(param, "unknown");
75
+ }
76
+ visitStatements(fn.body, fnScope);
77
+ }
78
+ visitStatements(program.body, scope);
79
+ return {
80
+ symbolTypes: Object.fromEntries(scope.values.entries()),
81
+ diagnostics
82
+ };
83
+ }
84
+ //# sourceMappingURL=checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checker.js","sourceRoot":"","sources":["checker.ts"],"names":[],"mappings":"AAcA,SAAS,MAAM,CAAC,KAAY,EAAE,IAAY;IACxC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,eAAe,CAAC,UAA0B,EAAE,KAAY,EAAE,WAAyB;IAC1F,QAAQ,UAAU,CAAC,IAAI,EAAE,CAAC;QACxB,KAAK,eAAe;YAClB,OAAO,QAAQ,CAAC;QAClB,KAAK,eAAe;YAClB,OAAO,QAAQ,CAAC;QAClB,KAAK,gBAAgB;YACnB,OAAO,SAAS,CAAC;QACnB,KAAK,YAAY;YACf,OAAO,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QACrD,KAAK,iBAAiB;YACpB,OAAO,eAAe,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;QACjE,KAAK,gBAAgB;YACnB,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;gBAClC,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;YAC3C,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,KAAK,kBAAkB;YACrB,OAAO,qBAAqB,CAAC,UAAU,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACjE,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,UAAgC,EAAE,KAAY,EAAE,WAAyB;IACtG,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,eAAe,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACpE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,IAAI,IAAI,KAAK,QAAQ,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5C,WAAW,CAAC,IAAI,CAAC;gBACf,OAAO,EAAE,wBAAwB,UAAU,CAAC,QAAQ,2BAA2B;gBAC/E,QAAQ,EAAE,SAAS;gBACnB,KAAK,EAAE,UAAU,CAAC,KAAK;aACxB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAoB;IACpD,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,MAAM,KAAK,GAAU,EAAE,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;IAE3C,MAAM,eAAe,GAAG,CAAC,UAA2B,EAAE,UAAiB,EAAQ,EAAE;QAC/E,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;gBACvB,KAAK,cAAc;oBACjB,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;oBACtG,MAAM;gBACR,KAAK,gBAAgB;oBACnB,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;oBAChD,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;wBACrB,eAAe,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;oBAC7D,CAAC;oBACD,MAAM;gBACR,KAAK,kBAAkB,CAAC;gBACxB,KAAK,qBAAqB,CAAC;gBAC3B,KAAK,iBAAiB;oBACpB,eAAe,CAAC,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;oBAC/D,MAAM;gBACR,KAAK,aAAa;oBAChB,eAAe,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;oBAC9D,eAAe,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;oBACzG,eAAe,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;oBACzG,MAAM;YACV,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACnC,MAAM,OAAO,GAAU,EAAE,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAC5D,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;YAC9B,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACvC,CAAC;QACD,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO;QACL,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACvD,WAAW;KACZ,CAAC;AACJ,CAAC"}