kumi 0.0.25 → 0.0.27

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 (223) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/CLAUDE.md +4 -0
  4. data/README.md +86 -78
  5. data/data/functions/agg/boolean.yaml +6 -2
  6. data/data/functions/agg/numeric.yaml +32 -16
  7. data/data/functions/agg/string.yaml +4 -3
  8. data/data/functions/core/arithmetic.yaml +62 -14
  9. data/data/functions/core/boolean.yaml +12 -6
  10. data/data/functions/core/comparison.yaml +25 -13
  11. data/data/functions/core/constructor.yaml +16 -8
  12. data/data/functions/core/conversion.yaml +32 -0
  13. data/data/functions/core/select.yaml +3 -1
  14. data/data/functions/core/stencil.yaml +14 -5
  15. data/data/functions/core/string.yaml +9 -4
  16. data/data/kernels/javascript/core/coercion.yaml +20 -0
  17. data/data/kernels/ruby/agg/numeric.yaml +1 -1
  18. data/data/kernels/ruby/core/coercion.yaml +20 -0
  19. data/docs/ARCHITECTURE.md +277 -0
  20. data/docs/DEVELOPMENT.md +62 -0
  21. data/docs/FUNCTIONS.md +955 -0
  22. data/docs/SYNTAX.md +8 -0
  23. data/docs/UNSAT_DETECTION.md +83 -0
  24. data/docs/VSCODE_EXTENSION.md +114 -0
  25. data/docs/functions-reference.json +1821 -0
  26. data/golden/array_element/expected/nast.txt +1 -1
  27. data/golden/array_element/expected/schema_ruby.rb +1 -1
  28. data/golden/array_index/expected/nast.txt +7 -7
  29. data/golden/array_index/expected/schema_ruby.rb +1 -1
  30. data/golden/array_operations/expected/nast.txt +2 -2
  31. data/golden/array_operations/expected/schema_ruby.rb +1 -1
  32. data/golden/array_operations/expected/snast.txt +3 -3
  33. data/golden/cascade_logic/expected/schema_ruby.rb +1 -1
  34. data/golden/cascade_logic/expected/snast.txt +2 -2
  35. data/golden/chained_fusion/expected/nast.txt +2 -2
  36. data/golden/chained_fusion/expected/schema_ruby.rb +1 -1
  37. data/golden/decimal_explicit/expected/ast.txt +38 -0
  38. data/golden/decimal_explicit/expected/input_plan.txt +3 -0
  39. data/golden/decimal_explicit/expected/lir_00_unoptimized.txt +30 -0
  40. data/golden/decimal_explicit/expected/lir_01_hoist_scalar_references.txt +30 -0
  41. data/golden/decimal_explicit/expected/lir_02_inlined.txt +44 -0
  42. data/golden/decimal_explicit/expected/lir_03_cse.txt +40 -0
  43. data/golden/decimal_explicit/expected/lir_04_1_loop_fusion.txt +40 -0
  44. data/golden/decimal_explicit/expected/lir_04_loop_invcm.txt +40 -0
  45. data/golden/decimal_explicit/expected/lir_06_const_prop.txt +40 -0
  46. data/golden/decimal_explicit/expected/nast.txt +30 -0
  47. data/golden/decimal_explicit/expected/schema_javascript.mjs +31 -0
  48. data/golden/decimal_explicit/expected/schema_ruby.rb +57 -0
  49. data/golden/decimal_explicit/expected/snast.txt +30 -0
  50. data/golden/decimal_explicit/expected.json +1 -0
  51. data/golden/decimal_explicit/input.json +5 -0
  52. data/golden/decimal_explicit/schema.kumi +14 -0
  53. data/golden/element_arrays/expected/nast.txt +2 -2
  54. data/golden/element_arrays/expected/schema_ruby.rb +1 -1
  55. data/golden/element_arrays/expected/snast.txt +1 -1
  56. data/golden/empty_and_null_inputs/expected/nast.txt +3 -3
  57. data/golden/empty_and_null_inputs/expected/schema_ruby.rb +1 -1
  58. data/golden/function_overload/expected/ast.txt +29 -0
  59. data/golden/function_overload/expected/input_plan.txt +4 -0
  60. data/golden/function_overload/expected/lir_00_unoptimized.txt +18 -0
  61. data/golden/function_overload/expected/lir_01_hoist_scalar_references.txt +18 -0
  62. data/golden/function_overload/expected/lir_02_inlined.txt +20 -0
  63. data/golden/function_overload/expected/lir_03_cse.txt +20 -0
  64. data/golden/function_overload/expected/lir_04_1_loop_fusion.txt +20 -0
  65. data/golden/function_overload/expected/lir_04_loop_invcm.txt +20 -0
  66. data/golden/function_overload/expected/lir_06_const_prop.txt +20 -0
  67. data/golden/function_overload/expected/nast.txt +22 -0
  68. data/golden/function_overload/expected/schema_javascript.mjs +12 -0
  69. data/golden/function_overload/expected/schema_ruby.rb +39 -0
  70. data/golden/function_overload/expected/snast.txt +22 -0
  71. data/golden/function_overload/input.json +8 -0
  72. data/golden/function_overload/schema.kumi +19 -0
  73. data/golden/game_of_life/expected/lir_00_unoptimized.txt +4 -4
  74. data/golden/game_of_life/expected/lir_01_hoist_scalar_references.txt +4 -4
  75. data/golden/game_of_life/expected/lir_02_inlined.txt +16 -16
  76. data/golden/game_of_life/expected/lir_03_cse.txt +20 -16
  77. data/golden/game_of_life/expected/lir_04_1_loop_fusion.txt +20 -16
  78. data/golden/game_of_life/expected/lir_04_loop_invcm.txt +20 -16
  79. data/golden/game_of_life/expected/lir_06_const_prop.txt +20 -16
  80. data/golden/game_of_life/expected/nast.txt +4 -4
  81. data/golden/game_of_life/expected/schema_javascript.mjs +4 -2
  82. data/golden/game_of_life/expected/schema_ruby.rb +5 -3
  83. data/golden/game_of_life/expected/snast.txt +10 -10
  84. data/golden/hash_keys/expected/schema_ruby.rb +1 -1
  85. data/golden/hash_value/expected/nast.txt +1 -1
  86. data/golden/hash_value/expected/schema_ruby.rb +1 -1
  87. data/golden/hash_value/expected/snast.txt +1 -1
  88. data/golden/hierarchical_complex/expected/nast.txt +3 -3
  89. data/golden/hierarchical_complex/expected/schema_ruby.rb +1 -1
  90. data/golden/hierarchical_complex/expected/snast.txt +3 -3
  91. data/golden/inline_rename_scope_leak/expected/nast.txt +3 -3
  92. data/golden/inline_rename_scope_leak/expected/schema_ruby.rb +1 -1
  93. data/golden/input_reference/expected/nast.txt +2 -2
  94. data/golden/input_reference/expected/schema_ruby.rb +1 -1
  95. data/golden/interleaved_fusion/expected/nast.txt +2 -2
  96. data/golden/interleaved_fusion/expected/schema_ruby.rb +1 -1
  97. data/golden/let_inline/expected/nast.txt +4 -4
  98. data/golden/let_inline/expected/schema_ruby.rb +1 -1
  99. data/golden/loop_fusion/expected/nast.txt +1 -1
  100. data/golden/loop_fusion/expected/schema_ruby.rb +1 -1
  101. data/golden/min_reduce_scope/expected/nast.txt +3 -3
  102. data/golden/min_reduce_scope/expected/schema_ruby.rb +1 -1
  103. data/golden/min_reduce_scope/expected/snast.txt +1 -1
  104. data/golden/mixed_dimensions/expected/nast.txt +2 -2
  105. data/golden/mixed_dimensions/expected/schema_ruby.rb +1 -1
  106. data/golden/multirank_hoisting/expected/nast.txt +7 -7
  107. data/golden/multirank_hoisting/expected/schema_ruby.rb +1 -1
  108. data/golden/nested_hash/expected/nast.txt +1 -1
  109. data/golden/nested_hash/expected/schema_ruby.rb +1 -1
  110. data/golden/reduction_broadcast/expected/nast.txt +3 -3
  111. data/golden/reduction_broadcast/expected/schema_ruby.rb +1 -1
  112. data/golden/reduction_broadcast/expected/snast.txt +1 -1
  113. data/golden/roll/expected/schema_ruby.rb +1 -1
  114. data/golden/shift/expected/schema_ruby.rb +1 -1
  115. data/golden/shift_2d/expected/schema_ruby.rb +1 -1
  116. data/golden/simple_math/expected/lir_00_unoptimized.txt +1 -1
  117. data/golden/simple_math/expected/lir_01_hoist_scalar_references.txt +1 -1
  118. data/golden/simple_math/expected/lir_02_inlined.txt +1 -1
  119. data/golden/simple_math/expected/lir_03_cse.txt +1 -1
  120. data/golden/simple_math/expected/lir_04_1_loop_fusion.txt +1 -1
  121. data/golden/simple_math/expected/lir_04_loop_invcm.txt +1 -1
  122. data/golden/simple_math/expected/lir_06_const_prop.txt +1 -1
  123. data/golden/simple_math/expected/nast.txt +5 -5
  124. data/golden/simple_math/expected/schema_ruby.rb +1 -1
  125. data/golden/simple_math/expected/snast.txt +2 -2
  126. data/golden/streaming_basics/expected/nast.txt +8 -8
  127. data/golden/streaming_basics/expected/schema_ruby.rb +1 -1
  128. data/golden/streaming_basics/expected/snast.txt +1 -1
  129. data/golden/tuples/expected/lir_00_unoptimized.txt +5 -5
  130. data/golden/tuples/expected/lir_01_hoist_scalar_references.txt +5 -5
  131. data/golden/tuples/expected/lir_02_inlined.txt +5 -5
  132. data/golden/tuples/expected/lir_03_cse.txt +5 -5
  133. data/golden/tuples/expected/lir_04_1_loop_fusion.txt +5 -5
  134. data/golden/tuples/expected/lir_04_loop_invcm.txt +5 -5
  135. data/golden/tuples/expected/lir_06_const_prop.txt +5 -5
  136. data/golden/tuples/expected/nast.txt +4 -4
  137. data/golden/tuples/expected/schema_ruby.rb +1 -1
  138. data/golden/tuples/expected/snast.txt +6 -6
  139. data/golden/tuples_and_arrays/expected/lir_00_unoptimized.txt +1 -1
  140. data/golden/tuples_and_arrays/expected/lir_01_hoist_scalar_references.txt +1 -1
  141. data/golden/tuples_and_arrays/expected/lir_02_inlined.txt +2 -2
  142. data/golden/tuples_and_arrays/expected/lir_03_cse.txt +2 -2
  143. data/golden/tuples_and_arrays/expected/lir_04_1_loop_fusion.txt +2 -2
  144. data/golden/tuples_and_arrays/expected/lir_04_loop_invcm.txt +2 -2
  145. data/golden/tuples_and_arrays/expected/lir_06_const_prop.txt +2 -2
  146. data/golden/tuples_and_arrays/expected/nast.txt +3 -3
  147. data/golden/tuples_and_arrays/expected/schema_ruby.rb +1 -1
  148. data/golden/tuples_and_arrays/expected/snast.txt +2 -2
  149. data/golden/us_tax_2024/expected/ast.txt +63 -670
  150. data/golden/us_tax_2024/expected/input_plan.txt +8 -45
  151. data/golden/us_tax_2024/expected/lir_00_unoptimized.txt +253 -863
  152. data/golden/us_tax_2024/expected/lir_01_hoist_scalar_references.txt +253 -863
  153. data/golden/us_tax_2024/expected/lir_02_inlined.txt +1215 -5139
  154. data/golden/us_tax_2024/expected/lir_03_cse.txt +587 -2460
  155. data/golden/us_tax_2024/expected/lir_04_1_loop_fusion.txt +632 -2480
  156. data/golden/us_tax_2024/expected/lir_04_loop_invcm.txt +587 -2460
  157. data/golden/us_tax_2024/expected/lir_06_const_prop.txt +587 -2460
  158. data/golden/us_tax_2024/expected/nast.txt +123 -826
  159. data/golden/us_tax_2024/expected/schema_javascript.mjs +127 -581
  160. data/golden/us_tax_2024/expected/schema_ruby.rb +135 -610
  161. data/golden/us_tax_2024/expected/snast.txt +155 -858
  162. data/golden/us_tax_2024/expected.json +120 -1
  163. data/golden/us_tax_2024/input.json +18 -9
  164. data/golden/us_tax_2024/schema.kumi +48 -178
  165. data/golden/with_constants/expected/lir_00_unoptimized.txt +1 -1
  166. data/golden/with_constants/expected/lir_01_hoist_scalar_references.txt +1 -1
  167. data/golden/with_constants/expected/lir_02_inlined.txt +1 -1
  168. data/golden/with_constants/expected/lir_03_cse.txt +1 -1
  169. data/golden/with_constants/expected/lir_04_1_loop_fusion.txt +1 -1
  170. data/golden/with_constants/expected/lir_04_loop_invcm.txt +1 -1
  171. data/golden/with_constants/expected/lir_06_const_prop.txt +1 -1
  172. data/golden/with_constants/expected/nast.txt +2 -2
  173. data/golden/with_constants/expected/schema_ruby.rb +1 -1
  174. data/golden/with_constants/expected/snast.txt +2 -2
  175. data/lib/kumi/analyzer.rb +12 -12
  176. data/lib/kumi/configuration.rb +6 -0
  177. data/lib/kumi/core/analyzer/passes/formal_constraint_propagator.rb +236 -0
  178. data/lib/kumi/core/analyzer/passes/input_collector.rb +22 -4
  179. data/lib/kumi/core/analyzer/passes/nast_dimensional_analyzer_pass.rb +64 -18
  180. data/lib/kumi/core/analyzer/passes/normalize_to_nast_pass.rb +9 -4
  181. data/lib/kumi/core/analyzer/passes/snast_pass.rb +3 -1
  182. data/lib/kumi/core/analyzer/passes/unsat_detector.rb +172 -198
  183. data/lib/kumi/core/error_reporter.rb +36 -1
  184. data/lib/kumi/core/errors.rb +33 -1
  185. data/lib/kumi/core/functions/function_spec.rb +5 -4
  186. data/lib/kumi/core/functions/loader.rb +17 -1
  187. data/lib/kumi/core/functions/overload_resolver.rb +164 -0
  188. data/lib/kumi/core/functions/type_error_reporter.rb +118 -0
  189. data/lib/kumi/core/functions/type_rules.rb +155 -35
  190. data/lib/kumi/core/input/type_matcher.rb +8 -1
  191. data/lib/kumi/core/ruby_parser/input_builder.rb +2 -2
  192. data/lib/kumi/core/types/inference.rb +29 -22
  193. data/lib/kumi/core/types/normalizer.rb +30 -45
  194. data/lib/kumi/core/types/validator.rb +17 -28
  195. data/lib/kumi/core/types/value_objects.rb +116 -0
  196. data/lib/kumi/core/types.rb +45 -37
  197. data/lib/kumi/dev/golden/reporter.rb +9 -0
  198. data/lib/kumi/dev/golden/result.rb +3 -1
  199. data/lib/kumi/dev/golden/runtime_test.rb +25 -0
  200. data/lib/kumi/dev/golden/suite.rb +4 -4
  201. data/lib/kumi/dev/golden/value_normalizer.rb +80 -0
  202. data/lib/kumi/dev/golden.rb +21 -12
  203. data/lib/kumi/doc_generator/formatters/json.rb +39 -0
  204. data/lib/kumi/doc_generator/formatters/markdown.rb +175 -0
  205. data/lib/kumi/doc_generator/loader.rb +37 -0
  206. data/lib/kumi/doc_generator/merger.rb +54 -0
  207. data/lib/kumi/doc_generator.rb +4 -0
  208. data/lib/kumi/registry_v2/loader.rb +90 -0
  209. data/lib/kumi/registry_v2.rb +18 -1
  210. data/lib/kumi/version.rb +1 -1
  211. data/vscode-extension/.gitignore +4 -0
  212. data/vscode-extension/README.md +59 -0
  213. data/vscode-extension/TESTING.md +151 -0
  214. data/vscode-extension/package.json +51 -0
  215. data/vscode-extension/src/extension.ts +295 -0
  216. data/vscode-extension/tsconfig.json +15 -0
  217. metadata +57 -7
  218. data/lib/kumi/core/analyzer/unsat_constant_evaluator.rb +0 -59
  219. data/lib/kumi/core/atom_unsat_solver.rb +0 -396
  220. data/lib/kumi/core/constraint_relationship_solver.rb +0 -641
  221. data/lib/kumi/core/types/builder.rb +0 -23
  222. data/lib/kumi/core/types/compatibility.rb +0 -96
  223. data/lib/kumi/core/types/formatter.rb +0 -26
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "kumi-language-support",
3
+ "displayName": "Kumi Language Support",
4
+ "description": "Language support for Kumi DSL with autocomplete and hover information",
5
+ "version": "0.1.0",
6
+ "publisher": "kumi",
7
+ "engines": {
8
+ "vscode": "^1.80.0"
9
+ },
10
+ "categories": [
11
+ "Programming Languages",
12
+ "Snippets"
13
+ ],
14
+ "activationEvents": [
15
+ "onLanguage:ruby",
16
+ "onLanguage:kumi"
17
+ ],
18
+ "main": "./out/extension.js",
19
+ "contributes": {
20
+ "languages": [
21
+ {
22
+ "id": "kumi",
23
+ "aliases": [
24
+ "Kumi",
25
+ "kumi"
26
+ ],
27
+ "extensions": [
28
+ ".kumi"
29
+ ],
30
+ "configuration": "./language-configuration.json"
31
+ }
32
+ ],
33
+ "grammars": [
34
+ {
35
+ "language": "kumi",
36
+ "scopeName": "source.kumi",
37
+ "path": "./syntaxes/kumi.tmLanguage.json"
38
+ }
39
+ ]
40
+ },
41
+ "scripts": {
42
+ "vscode:prepublish": "npm run compile",
43
+ "compile": "tsc -p ./",
44
+ "watch": "tsc -watch -p ./"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^20.0.0",
48
+ "@types/vscode": "^1.80.0",
49
+ "typescript": "^5.0.0"
50
+ }
51
+ }
@@ -0,0 +1,295 @@
1
+ import * as vscode from 'vscode';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+
5
+ interface FunctionDef {
6
+ id: string;
7
+ arity: number;
8
+ params: Array<{ name: string }>;
9
+ dtype: any;
10
+ kernels: Record<string, string>;
11
+ aliases: string[];
12
+ kind?: string;
13
+ }
14
+
15
+ let functionsData: Record<string, FunctionDef> = {};
16
+
17
+ export function activate(context: vscode.ExtensionContext) {
18
+ // Load functions reference JSON from kumi/docs/
19
+ const refPath = path.join(
20
+ context.extensionPath,
21
+ '..',
22
+ '..',
23
+ 'docs',
24
+ 'functions-reference.json'
25
+ );
26
+
27
+ try {
28
+ if (fs.existsSync(refPath)) {
29
+ const content = fs.readFileSync(refPath, 'utf-8');
30
+ functionsData = JSON.parse(content);
31
+ console.log('Kumi functions reference loaded');
32
+ } else {
33
+ vscode.window.showWarningMessage(
34
+ 'Kumi: functions-reference.json not found. Run "bin/kumi-doc-gen" to generate it.'
35
+ );
36
+ }
37
+ } catch (e) {
38
+ console.error('Failed to load functions reference:', e);
39
+ vscode.window.showErrorMessage(
40
+ 'Kumi: Error loading functions reference: ' + String(e)
41
+ );
42
+ }
43
+
44
+ // Register completion provider for both Ruby and Kumi files
45
+ const completionProvider = vscode.languages.registerCompletionItemProvider(
46
+ [
47
+ { language: 'ruby', scheme: 'file' },
48
+ { language: 'kumi', scheme: 'file' }
49
+ ],
50
+ new FunctionCompletionProvider(),
51
+ ':' // trigger on ':'
52
+ );
53
+
54
+ // Register hover provider for both Ruby and Kumi files
55
+ const hoverProvider = vscode.languages.registerHoverProvider(
56
+ [
57
+ { language: 'ruby', scheme: 'file' },
58
+ { language: 'kumi', scheme: 'file' }
59
+ ],
60
+ new FunctionHoverProvider()
61
+ );
62
+
63
+ context.subscriptions.push(completionProvider, hoverProvider);
64
+ }
65
+
66
+ class FunctionCompletionProvider implements vscode.CompletionItemProvider {
67
+ provideCompletionItems(
68
+ document: vscode.TextDocument,
69
+ position: vscode.Position,
70
+ token: vscode.CancellationToken,
71
+ context: vscode.CompletionContext
72
+ ): vscode.CompletionItem[] {
73
+ // Check if we're in an fn(:...) context
74
+ const lineText = document.lineAt(position).text;
75
+ const beforeCursor = lineText.substring(0, position.character);
76
+
77
+ if (!beforeCursor.match(/fn\(\s*:\s*$/)) {
78
+ return [];
79
+ }
80
+
81
+ // For Ruby files, check if we're inside a schema block
82
+ if (document.languageId === 'ruby') {
83
+ if (!this.isInSchemaBlock(document, position)) {
84
+ return [];
85
+ }
86
+ }
87
+
88
+ const completions: vscode.CompletionItem[] = [];
89
+
90
+ for (const [alias, funcDef] of Object.entries(functionsData)) {
91
+ const item = new vscode.CompletionItem(
92
+ alias,
93
+ vscode.CompletionItemKind.Function
94
+ );
95
+
96
+ item.detail = `${funcDef.id} (arity: ${funcDef.arity})`;
97
+ item.documentation = new vscode.MarkdownString(
98
+ this.getDocumentation(funcDef)
99
+ );
100
+ item.sortText = alias;
101
+
102
+ completions.push(item);
103
+ }
104
+
105
+ return completions;
106
+ }
107
+
108
+ private getDocumentation(funcDef: FunctionDef): string {
109
+ const lines: string[] = [
110
+ `**${funcDef.id}**`,
111
+ '',
112
+ `**Arity:** ${funcDef.arity}`,
113
+ ];
114
+
115
+ if (funcDef.params && funcDef.params.length > 0) {
116
+ lines.push('**Parameters:**');
117
+ funcDef.params.forEach((p) => {
118
+ lines.push(`- \`${p.name}\``);
119
+ });
120
+ }
121
+
122
+ if (funcDef.dtype) {
123
+ lines.push(`**Type:** ${this.formatType(funcDef.dtype)}`);
124
+ }
125
+
126
+ if (funcDef.kernels && Object.keys(funcDef.kernels).length > 0) {
127
+ lines.push('**Kernels:**');
128
+ Object.entries(funcDef.kernels).forEach(([target, id]) => {
129
+ lines.push(`- ${target}: \`${id}\``);
130
+ });
131
+ }
132
+
133
+ return lines.join('\n');
134
+ }
135
+
136
+ private formatType(dtype: any): string {
137
+ if (!dtype) return 'unknown';
138
+
139
+ switch (dtype.rule) {
140
+ case 'same_as':
141
+ return `same as \`${dtype.param}\``;
142
+ case 'scalar':
143
+ return dtype.kind || 'scalar';
144
+ case 'promote':
145
+ return `promoted from ${dtype.params.map((p: string) => `\`${p}\``).join(', ')}`;
146
+ case 'element_of':
147
+ return `element of \`${dtype.param}\``;
148
+ default:
149
+ return dtype.rule;
150
+ }
151
+ }
152
+
153
+ private isInSchemaBlock(document: vscode.TextDocument, position: vscode.Position): boolean {
154
+ let braceCount = 0;
155
+ let schemaFound = false;
156
+
157
+ // Search backwards from current position to find schema block
158
+ for (let i = position.line; i >= 0; i--) {
159
+ const line = document.lineAt(i).text;
160
+
161
+ // Count braces from end of line backwards
162
+ if (i === position.line) {
163
+ // Only count braces before cursor
164
+ for (let j = position.character - 1; j >= 0; j--) {
165
+ if (line[j] === '}') braceCount++;
166
+ if (line[j] === '{') braceCount--;
167
+ }
168
+ } else {
169
+ // Count all braces in the line (right to left)
170
+ for (let j = line.length - 1; j >= 0; j--) {
171
+ if (line[j] === '}') braceCount++;
172
+ if (line[j] === '{') braceCount--;
173
+ }
174
+ }
175
+
176
+ // Look for 'schema do' or 'schema {'
177
+ if (line.match(/\bschema\s+(do|{)/)) {
178
+ schemaFound = braceCount <= 0;
179
+ break;
180
+ }
181
+ }
182
+
183
+ return schemaFound;
184
+ }
185
+ }
186
+
187
+ class FunctionHoverProvider implements vscode.HoverProvider {
188
+ provideHover(
189
+ document: vscode.TextDocument,
190
+ position: vscode.Position,
191
+ token: vscode.CancellationToken
192
+ ): vscode.ProviderResult<vscode.Hover> {
193
+ const range = document.getWordRangeAtPosition(position);
194
+ if (!range) return null;
195
+
196
+ const word = document.getText(range);
197
+
198
+ // Check if we're in fn(:word, ...)
199
+ const lineText = document.lineAt(position).text;
200
+ if (!lineText.match(/fn\s*\(\s*:/)) {
201
+ return null;
202
+ }
203
+
204
+ // For Ruby files, check if we're inside a schema block
205
+ if (document.languageId === 'ruby') {
206
+ if (!this.isInSchemaBlock(document, position)) {
207
+ return null;
208
+ }
209
+ }
210
+
211
+ const funcDef = functionsData[word];
212
+ if (!funcDef) {
213
+ return null;
214
+ }
215
+
216
+ const markdown = new vscode.MarkdownString();
217
+ markdown.appendMarkdown(`### \`${funcDef.id}\`\n\n`);
218
+
219
+ if (funcDef.aliases && funcDef.aliases.length > 0) {
220
+ markdown.appendMarkdown(
221
+ `**Aliases:** ${funcDef.aliases.map((a) => `\`${a}\``).join(', ')}\n\n`
222
+ );
223
+ }
224
+
225
+ markdown.appendMarkdown(`**Arity:** ${funcDef.arity}\n\n`);
226
+
227
+ if (funcDef.dtype) {
228
+ markdown.appendMarkdown(`**Type:** ${this.formatType(funcDef.dtype)}\n\n`);
229
+ }
230
+
231
+ if (funcDef.params && funcDef.params.length > 0) {
232
+ markdown.appendMarkdown('**Parameters:**\n\n');
233
+ funcDef.params.forEach((p) => {
234
+ markdown.appendMarkdown(`- \`${p.name}\`\n`);
235
+ });
236
+ markdown.appendMarkdown('\n');
237
+ }
238
+
239
+ return new vscode.Hover(markdown);
240
+ }
241
+
242
+ private formatType(dtype: any): string {
243
+ if (!dtype) return 'unknown';
244
+
245
+ switch (dtype.rule) {
246
+ case 'same_as':
247
+ return `same as \`${dtype.param}\``;
248
+ case 'scalar':
249
+ return dtype.kind || 'scalar';
250
+ case 'promote':
251
+ return `promoted from ${dtype.params
252
+ .map((p: string) => `\`${p}\``)
253
+ .join(', ')}`;
254
+ case 'element_of':
255
+ return `element of \`${dtype.param}\``;
256
+ default:
257
+ return dtype.rule;
258
+ }
259
+ }
260
+
261
+ private isInSchemaBlock(document: vscode.TextDocument, position: vscode.Position): boolean {
262
+ let braceCount = 0;
263
+ let schemaFound = false;
264
+
265
+ // Search backwards from current position to find schema block
266
+ for (let i = position.line; i >= 0; i--) {
267
+ const line = document.lineAt(i).text;
268
+
269
+ // Count braces from end of line backwards
270
+ if (i === position.line) {
271
+ // Only count braces before cursor
272
+ for (let j = position.character - 1; j >= 0; j--) {
273
+ if (line[j] === '}') braceCount++;
274
+ if (line[j] === '{') braceCount--;
275
+ }
276
+ } else {
277
+ // Count all braces in the line (right to left)
278
+ for (let j = line.length - 1; j >= 0; j--) {
279
+ if (line[j] === '}') braceCount++;
280
+ if (line[j] === '{') braceCount--;
281
+ }
282
+ }
283
+
284
+ // Look for 'schema do' or 'schema {'
285
+ if (line.match(/\bschema\s+(do|{)/)) {
286
+ schemaFound = braceCount <= 0;
287
+ break;
288
+ }
289
+ }
290
+
291
+ return schemaFound;
292
+ }
293
+ }
294
+
295
+ export function deactivate() {}
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "target": "ES2020",
5
+ "lib": ["ES2020"],
6
+ "outDir": "./out",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true
13
+ },
14
+ "exclude": ["node_modules", ".vscode-test"]
15
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kumi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.25
4
+ version: 0.0.27
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Muta
@@ -58,6 +58,7 @@ files:
58
58
  - data/functions/core/boolean.yaml
59
59
  - data/functions/core/comparison.yaml
60
60
  - data/functions/core/constructor.yaml
61
+ - data/functions/core/conversion.yaml
61
62
  - data/functions/core/select.yaml
62
63
  - data/functions/core/stencil.yaml
63
64
  - data/functions/core/string.yaml
@@ -66,6 +67,7 @@ files:
66
67
  - data/kernels/javascript/agg/string.yaml
67
68
  - data/kernels/javascript/core/arithmetic.yaml
68
69
  - data/kernels/javascript/core/boolean.yaml
70
+ - data/kernels/javascript/core/coercion.yaml
69
71
  - data/kernels/javascript/core/comparison.yaml
70
72
  - data/kernels/javascript/core/constructor.yaml
71
73
  - data/kernels/javascript/core/select.yaml
@@ -75,14 +77,21 @@ files:
75
77
  - data/kernels/ruby/agg/string.yaml
76
78
  - data/kernels/ruby/core/arithmetic.yaml
77
79
  - data/kernels/ruby/core/boolean.yaml
80
+ - data/kernels/ruby/core/coercion.yaml
78
81
  - data/kernels/ruby/core/comparison.yaml
79
82
  - data/kernels/ruby/core/constructor.yaml
80
83
  - data/kernels/ruby/core/select.yaml
81
84
  - data/kernels/ruby/core/string.yaml
82
85
  - debug_ordering.rb
86
+ - docs/ARCHITECTURE.md
87
+ - docs/DEVELOPMENT.md
83
88
  - docs/FORM_SCHEMA.md
89
+ - docs/FUNCTIONS.md
84
90
  - docs/OUTPUT_SCHEMA.md
85
91
  - docs/SYNTAX.md
92
+ - docs/UNSAT_DETECTION.md
93
+ - docs/VSCODE_EXTENSION.md
94
+ - docs/functions-reference.json
86
95
  - examples/deep_schema_compilation_and_evaluation_benchmark.rb
87
96
  - examples/federal_tax_calculator_2024.rb
88
97
  - examples/game_of_life.rb
@@ -169,6 +178,22 @@ files:
169
178
  - golden/chained_fusion/expected/snast.txt
170
179
  - golden/chained_fusion/input.json
171
180
  - golden/chained_fusion/schema.kumi
181
+ - golden/decimal_explicit/expected.json
182
+ - golden/decimal_explicit/expected/ast.txt
183
+ - golden/decimal_explicit/expected/input_plan.txt
184
+ - golden/decimal_explicit/expected/lir_00_unoptimized.txt
185
+ - golden/decimal_explicit/expected/lir_01_hoist_scalar_references.txt
186
+ - golden/decimal_explicit/expected/lir_02_inlined.txt
187
+ - golden/decimal_explicit/expected/lir_03_cse.txt
188
+ - golden/decimal_explicit/expected/lir_04_1_loop_fusion.txt
189
+ - golden/decimal_explicit/expected/lir_04_loop_invcm.txt
190
+ - golden/decimal_explicit/expected/lir_06_const_prop.txt
191
+ - golden/decimal_explicit/expected/nast.txt
192
+ - golden/decimal_explicit/expected/schema_javascript.mjs
193
+ - golden/decimal_explicit/expected/schema_ruby.rb
194
+ - golden/decimal_explicit/expected/snast.txt
195
+ - golden/decimal_explicit/input.json
196
+ - golden/decimal_explicit/schema.kumi
172
197
  - golden/element_arrays/expected.json
173
198
  - golden/element_arrays/expected/ast.txt
174
199
  - golden/element_arrays/expected/input_plan.txt
@@ -201,6 +226,21 @@ files:
201
226
  - golden/empty_and_null_inputs/expected/snast.txt
202
227
  - golden/empty_and_null_inputs/input.json
203
228
  - golden/empty_and_null_inputs/schema.kumi
229
+ - golden/function_overload/expected/ast.txt
230
+ - golden/function_overload/expected/input_plan.txt
231
+ - golden/function_overload/expected/lir_00_unoptimized.txt
232
+ - golden/function_overload/expected/lir_01_hoist_scalar_references.txt
233
+ - golden/function_overload/expected/lir_02_inlined.txt
234
+ - golden/function_overload/expected/lir_03_cse.txt
235
+ - golden/function_overload/expected/lir_04_1_loop_fusion.txt
236
+ - golden/function_overload/expected/lir_04_loop_invcm.txt
237
+ - golden/function_overload/expected/lir_06_const_prop.txt
238
+ - golden/function_overload/expected/nast.txt
239
+ - golden/function_overload/expected/schema_javascript.mjs
240
+ - golden/function_overload/expected/schema_ruby.rb
241
+ - golden/function_overload/expected/snast.txt
242
+ - golden/function_overload/input.json
243
+ - golden/function_overload/schema.kumi
204
244
  - golden/game_of_life/expected.json
205
245
  - golden/game_of_life/expected/ast.txt
206
246
  - golden/game_of_life/expected/input_plan.txt
@@ -594,6 +634,7 @@ files:
594
634
  - lib/kumi/core/analyzer/passes/contract_checker_pass.rb
595
635
  - lib/kumi/core/analyzer/passes/declaration_validator.rb
596
636
  - lib/kumi/core/analyzer/passes/dependency_resolver.rb
637
+ - lib/kumi/core/analyzer/passes/formal_constraint_propagator.rb
597
638
  - lib/kumi/core/analyzer/passes/input_access_planner_pass.rb
598
639
  - lib/kumi/core/analyzer/passes/input_collector.rb
599
640
  - lib/kumi/core/analyzer/passes/input_form_schema_pass.rb
@@ -629,8 +670,6 @@ files:
629
670
  - lib/kumi/core/analyzer/state_serde.rb
630
671
  - lib/kumi/core/analyzer/structs/access_plan.rb
631
672
  - lib/kumi/core/analyzer/structs/input_meta.rb
632
- - lib/kumi/core/analyzer/unsat_constant_evaluator.rb
633
- - lib/kumi/core/atom_unsat_solver.rb
634
673
  - lib/kumi/core/compiler/access_builder.rb
635
674
  - lib/kumi/core/compiler/access_codegen.rb
636
675
  - lib/kumi/core/compiler/access_emit/base.rb
@@ -645,7 +684,6 @@ files:
645
684
  - lib/kumi/core/compiler/accessors/materialize_accessor.rb
646
685
  - lib/kumi/core/compiler/accessors/ravel_accessor.rb
647
686
  - lib/kumi/core/compiler/accessors/read_accessor.rb
648
- - lib/kumi/core/constraint_relationship_solver.rb
649
687
  - lib/kumi/core/domain/enum_analyzer.rb
650
688
  - lib/kumi/core/domain/range_analyzer.rb
651
689
  - lib/kumi/core/domain/validator.rb
@@ -662,6 +700,8 @@ files:
662
700
  - lib/kumi/core/export/serializer.rb
663
701
  - lib/kumi/core/functions/function_spec.rb
664
702
  - lib/kumi/core/functions/loader.rb
703
+ - lib/kumi/core/functions/overload_resolver.rb
704
+ - lib/kumi/core/functions/type_error_reporter.rb
665
705
  - lib/kumi/core/functions/type_rules.rb
666
706
  - lib/kumi/core/input/type_matcher.rb
667
707
  - lib/kumi/core/input/validator.rb
@@ -705,12 +745,10 @@ files:
705
745
  - lib/kumi/core/ruby_parser/schema_builder.rb
706
746
  - lib/kumi/core/ruby_parser/sugar.rb
707
747
  - lib/kumi/core/types.rb
708
- - lib/kumi/core/types/builder.rb
709
- - lib/kumi/core/types/compatibility.rb
710
- - lib/kumi/core/types/formatter.rb
711
748
  - lib/kumi/core/types/inference.rb
712
749
  - lib/kumi/core/types/normalizer.rb
713
750
  - lib/kumi/core/types/validator.rb
751
+ - lib/kumi/core/types/value_objects.rb
714
752
  - lib/kumi/dev.rb
715
753
  - lib/kumi/dev/codegen.rb
716
754
  - lib/kumi/dev/golden.rb
@@ -720,6 +758,7 @@ files:
720
758
  - lib/kumi/dev/golden/result.rb
721
759
  - lib/kumi/dev/golden/runtime_test.rb
722
760
  - lib/kumi/dev/golden/suite.rb
761
+ - lib/kumi/dev/golden/value_normalizer.rb
723
762
  - lib/kumi/dev/golden/verifier.rb
724
763
  - lib/kumi/dev/ir.rb
725
764
  - lib/kumi/dev/parse.rb
@@ -730,6 +769,11 @@ files:
730
769
  - lib/kumi/dev/profile_runner.rb
731
770
  - lib/kumi/dev/runner.rb
732
771
  - lib/kumi/dev/support/kumi_runner.mjs
772
+ - lib/kumi/doc_generator.rb
773
+ - lib/kumi/doc_generator/formatters/json.rb
774
+ - lib/kumi/doc_generator/formatters/markdown.rb
775
+ - lib/kumi/doc_generator/loader.rb
776
+ - lib/kumi/doc_generator/merger.rb
733
777
  - lib/kumi/errors.rb
734
778
  - lib/kumi/frontends.rb
735
779
  - lib/kumi/frontends/ruby.rb
@@ -762,6 +806,12 @@ files:
762
806
  - lib/kumi/syntax/trait_declaration.rb
763
807
  - lib/kumi/syntax/value_declaration.rb
764
808
  - lib/kumi/version.rb
809
+ - vscode-extension/.gitignore
810
+ - vscode-extension/README.md
811
+ - vscode-extension/TESTING.md
812
+ - vscode-extension/package.json
813
+ - vscode-extension/src/extension.ts
814
+ - vscode-extension/tsconfig.json
765
815
  homepage: https://github.com/amuta/kumi
766
816
  licenses:
767
817
  - MIT
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Core
5
- module Analyzer
6
- class UnsatConstantEvaluator
7
- include Syntax
8
-
9
- def initialize(definitions)
10
- @definitions = definitions
11
- @memo = {}
12
- end
13
-
14
- OPERATORS = {
15
- add: :+,
16
- subtract: :-,
17
- multiply: :*,
18
- divide: :/
19
- }.freeze
20
-
21
- def evaluate(node, visited = Set.new)
22
- return :unknown unless node
23
- return @memo[node] if @memo.key?(node)
24
- return node.value if node.is_a?(Literal)
25
-
26
- result = case node
27
- when DeclarationReference then evaluate_binding(node, visited)
28
- when CallExpression then evaluate_call_expression(node, visited)
29
- else :unknown
30
- end
31
-
32
- @memo[node] = result unless result == :unknown
33
- result
34
- end
35
-
36
- private
37
-
38
- def evaluate_binding(node, visited)
39
- return :unknown if visited.include?(node.name)
40
-
41
- visited << node.name
42
- definition = @definitions[node.name]
43
- return :unknown unless definition
44
-
45
- evaluate(definition.expression, visited)
46
- end
47
-
48
- def evaluate_call_expression(node, visited)
49
- return :unknown unless OPERATORS.key?(node.fn_name)
50
-
51
- args = node.args.map { |arg| evaluate(arg, visited) }
52
- return :unknown if args.any?(:unknown)
53
-
54
- args.reduce(OPERATORS[node.fn_name])
55
- end
56
- end
57
- end
58
- end
59
- end