jade-lang 0.1.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 (326) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +23 -0
  3. data/LICENSE +21 -0
  4. data/README.md +386 -0
  5. data/exe/jade +6 -0
  6. data/lib/jade/ast/node.rb +44 -0
  7. data/lib/jade/ast/nodes.rb +35 -0
  8. data/lib/jade/ast/pretty_printer.rb +50 -0
  9. data/lib/jade/ast.rb +723 -0
  10. data/lib/jade/calendar/runtime.rb +15 -0
  11. data/lib/jade/cli/fmt.rb +96 -0
  12. data/lib/jade/cli/lsp.rb +13 -0
  13. data/lib/jade/cli/q.rb +113 -0
  14. data/lib/jade/cli.rb +43 -0
  15. data/lib/jade/clock/runtime.rb +13 -0
  16. data/lib/jade/codegen/boundary/cache.rb +94 -0
  17. data/lib/jade/codegen/boundary/specialized/list.rb +65 -0
  18. data/lib/jade/codegen/boundary/specialized/maybe.rb +40 -0
  19. data/lib/jade/codegen/boundary/specialized/record.rb +165 -0
  20. data/lib/jade/codegen/boundary/specialized/scalar.rb +67 -0
  21. data/lib/jade/codegen/boundary/specialized.rb +106 -0
  22. data/lib/jade/codegen/boundary.rb +189 -0
  23. data/lib/jade/codegen/constructor_reference.rb +18 -0
  24. data/lib/jade/codegen/context.rb +96 -0
  25. data/lib/jade/codegen/emitter.rb +81 -0
  26. data/lib/jade/codegen/function_call.rb +367 -0
  27. data/lib/jade/codegen/function_declaration.rb +199 -0
  28. data/lib/jade/codegen/helpers.rb +103 -0
  29. data/lib/jade/codegen/implementation.rb +178 -0
  30. data/lib/jade/codegen/inline.rb +89 -0
  31. data/lib/jade/codegen/inlines.rb +326 -0
  32. data/lib/jade/codegen/method_names.rb +54 -0
  33. data/lib/jade/codegen/pattern/constructor.rb +57 -0
  34. data/lib/jade/codegen/port_decoder.rb +77 -0
  35. data/lib/jade/codegen/pretty.rb +53 -0
  36. data/lib/jade/codegen/transforms/fold_shape.rb +222 -0
  37. data/lib/jade/codegen/transforms/self_call.rb +80 -0
  38. data/lib/jade/codegen/transforms/tail_call.rb +120 -0
  39. data/lib/jade/codegen/variant_declaration.rb +41 -0
  40. data/lib/jade/codegen.rb +400 -0
  41. data/lib/jade/compiler.rb +69 -0
  42. data/lib/jade/decode.rb +320 -0
  43. data/lib/jade/diagnostics/renderer.rb +121 -0
  44. data/lib/jade/diagnostics.rb +77 -0
  45. data/lib/jade/did_you_mean.rb +16 -0
  46. data/lib/jade/entry.rb +177 -0
  47. data/lib/jade/error.rb +72 -0
  48. data/lib/jade/formatter/accesses.rb +37 -0
  49. data/lib/jade/formatter/bindings.rb +29 -0
  50. data/lib/jade/formatter/body.rb +50 -0
  51. data/lib/jade/formatter/calls.rb +51 -0
  52. data/lib/jade/formatter/case_of.rb +31 -0
  53. data/lib/jade/formatter/case_of_branch.rb +59 -0
  54. data/lib/jade/formatter/collections.rb +78 -0
  55. data/lib/jade/formatter/declarations.rb +178 -0
  56. data/lib/jade/formatter/exposing.rb +48 -0
  57. data/lib/jade/formatter/function_declaration.rb +72 -0
  58. data/lib/jade/formatter/helper.rb +122 -0
  59. data/lib/jade/formatter/if_then_else.rb +64 -0
  60. data/lib/jade/formatter/infix_application.rb +69 -0
  61. data/lib/jade/formatter/lambda.rb +50 -0
  62. data/lib/jade/formatter/leaves.rb +111 -0
  63. data/lib/jade/formatter/module_node.rb +26 -0
  64. data/lib/jade/formatter/pattern.rb +61 -0
  65. data/lib/jade/formatter/type.rb +67 -0
  66. data/lib/jade/formatter.rb +38 -0
  67. data/lib/jade/frontend/comment_attacher.rb +121 -0
  68. data/lib/jade/frontend/desugaring/placeholder.rb +39 -0
  69. data/lib/jade/frontend/desugaring/resolved.rb +63 -0
  70. data/lib/jade/frontend/desugaring.rb +217 -0
  71. data/lib/jade/frontend/fixity_fixer.rb +209 -0
  72. data/lib/jade/frontend/forward_declaration/body.rb +30 -0
  73. data/lib/jade/frontend/forward_declaration/error/bad_import.rb +19 -0
  74. data/lib/jade/frontend/forward_declaration/error/exposed_type_not_found.rb +18 -0
  75. data/lib/jade/frontend/forward_declaration/error/exposed_value_not_found.rb +18 -0
  76. data/lib/jade/frontend/forward_declaration/error/module_not_found.rb +18 -0
  77. data/lib/jade/frontend/forward_declaration/error/private_type_expansion.rb +19 -0
  78. data/lib/jade/frontend/forward_declaration/error/tuple_arity_overflow.rb +25 -0
  79. data/lib/jade/frontend/forward_declaration/error/type_not_found.rb +29 -0
  80. data/lib/jade/frontend/forward_declaration/error/type_not_lowerable.rb +16 -0
  81. data/lib/jade/frontend/forward_declaration/error/unknown_extends_interface.rb +18 -0
  82. data/lib/jade/frontend/forward_declaration/error.rb +11 -0
  83. data/lib/jade/frontend/forward_declaration/function_declaration.rb +32 -0
  84. data/lib/jade/frontend/forward_declaration/helper.rb +91 -0
  85. data/lib/jade/frontend/forward_declaration/implementation.rb +63 -0
  86. data/lib/jade/frontend/forward_declaration/implementation_function.rb +39 -0
  87. data/lib/jade/frontend/forward_declaration/import_declaration.rb +115 -0
  88. data/lib/jade/frontend/forward_declaration/interface_declaration.rb +66 -0
  89. data/lib/jade/frontend/forward_declaration/interop_import_declaration.rb +99 -0
  90. data/lib/jade/frontend/forward_declaration/module.rb +98 -0
  91. data/lib/jade/frontend/forward_declaration/struct_declaration.rb +42 -0
  92. data/lib/jade/frontend/forward_declaration/type_declaration.rb +42 -0
  93. data/lib/jade/frontend/forward_declaration.rb +71 -0
  94. data/lib/jade/frontend/pattern_analysis/exhaustiveness.rb +65 -0
  95. data/lib/jade/frontend/pattern_analysis/matrix.rb +235 -0
  96. data/lib/jade/frontend/pattern_analysis.rb +40 -0
  97. data/lib/jade/frontend/semantic_analysis/assign.rb +20 -0
  98. data/lib/jade/frontend/semantic_analysis/body.rb +33 -0
  99. data/lib/jade/frontend/semantic_analysis/case_of.rb +19 -0
  100. data/lib/jade/frontend/semantic_analysis/case_of_branch.rb +20 -0
  101. data/lib/jade/frontend/semantic_analysis/char_literal.rb +14 -0
  102. data/lib/jade/frontend/semantic_analysis/constructor_reference.rb +64 -0
  103. data/lib/jade/frontend/semantic_analysis/error/circular_extends.rb +19 -0
  104. data/lib/jade/frontend/semantic_analysis/error/constant_not_callable.rb +24 -0
  105. data/lib/jade/frontend/semantic_analysis/error/constructor_not_found.rb +34 -0
  106. data/lib/jade/frontend/semantic_analysis/error/constructor_pattern_arity_mismatch.rb +24 -0
  107. data/lib/jade/frontend/semantic_analysis/error/duplicate_field.rb +18 -0
  108. data/lib/jade/frontend/semantic_analysis/error/duplicate_function_declaration.rb +25 -0
  109. data/lib/jade/frontend/semantic_analysis/error/duplicate_record_field.rb +19 -0
  110. data/lib/jade/frontend/semantic_analysis/error/invalid_list_rest_pattern.rb +21 -0
  111. data/lib/jade/frontend/semantic_analysis/error/kwargs_on_non_constructor.rb +17 -0
  112. data/lib/jade/frontend/semantic_analysis/error/missing_exposing_clause.rb +17 -0
  113. data/lib/jade/frontend/semantic_analysis/error/missing_extends_implementation.rb +21 -0
  114. data/lib/jade/frontend/semantic_analysis/error/missing_field.rb +20 -0
  115. data/lib/jade/frontend/semantic_analysis/error/missing_implementation_function.rb +19 -0
  116. data/lib/jade/frontend/semantic_analysis/error/module_not_found.rb +22 -0
  117. data/lib/jade/frontend/semantic_analysis/error/nested_task_port.rb +19 -0
  118. data/lib/jade/frontend/semantic_analysis/error/non_task_port.rb +22 -0
  119. data/lib/jade/frontend/semantic_analysis/error/orphan_implementation.rb +20 -0
  120. data/lib/jade/frontend/semantic_analysis/error/predicate_must_return_bool.rb +22 -0
  121. data/lib/jade/frontend/semantic_analysis/error/predicate_name_not_allowed.rb +25 -0
  122. data/lib/jade/frontend/semantic_analysis/error/shadowing_error.rb +22 -0
  123. data/lib/jade/frontend/semantic_analysis/error/type_args_mismatch.rb +25 -0
  124. data/lib/jade/frontend/semantic_analysis/error/type_param_required.rb +19 -0
  125. data/lib/jade/frontend/semantic_analysis/error/unbound_type_variable.rb +22 -0
  126. data/lib/jade/frontend/semantic_analysis/error/undefined_variable.rb +29 -0
  127. data/lib/jade/frontend/semantic_analysis/error/unknown_field.rb +20 -0
  128. data/lib/jade/frontend/semantic_analysis/error/unknown_implementation_function.rb +19 -0
  129. data/lib/jade/frontend/semantic_analysis/error/unused_interface_type_param.rb +24 -0
  130. data/lib/jade/frontend/semantic_analysis/error/value_not_exposed.rb +23 -0
  131. data/lib/jade/frontend/semantic_analysis/error/variable_not_found.rb +25 -0
  132. data/lib/jade/frontend/semantic_analysis/error.rb +40 -0
  133. data/lib/jade/frontend/semantic_analysis/function_call.rb +60 -0
  134. data/lib/jade/frontend/semantic_analysis/function_declaration.rb +58 -0
  135. data/lib/jade/frontend/semantic_analysis/grouping.rb +17 -0
  136. data/lib/jade/frontend/semantic_analysis/helper.rb +152 -0
  137. data/lib/jade/frontend/semantic_analysis/if_then_else.rb +20 -0
  138. data/lib/jade/frontend/semantic_analysis/implementation.rb +143 -0
  139. data/lib/jade/frontend/semantic_analysis/implementation_function.rb +16 -0
  140. data/lib/jade/frontend/semantic_analysis/import_declaration.rb +14 -0
  141. data/lib/jade/frontend/semantic_analysis/interface_declaration.rb +45 -0
  142. data/lib/jade/frontend/semantic_analysis/interop_import_declaration.rb +69 -0
  143. data/lib/jade/frontend/semantic_analysis/keyed_call/validation.rb +109 -0
  144. data/lib/jade/frontend/semantic_analysis/keyed_call.rb +88 -0
  145. data/lib/jade/frontend/semantic_analysis/lambda.rb +23 -0
  146. data/lib/jade/frontend/semantic_analysis/list.rb +17 -0
  147. data/lib/jade/frontend/semantic_analysis/literal.rb +23 -0
  148. data/lib/jade/frontend/semantic_analysis/member_access.rb +87 -0
  149. data/lib/jade/frontend/semantic_analysis/module_node.rb +27 -0
  150. data/lib/jade/frontend/semantic_analysis/pattern_binding.rb +27 -0
  151. data/lib/jade/frontend/semantic_analysis/pattern_constructor.rb +47 -0
  152. data/lib/jade/frontend/semantic_analysis/pattern_list.rb +33 -0
  153. data/lib/jade/frontend/semantic_analysis/pattern_literal.rb +17 -0
  154. data/lib/jade/frontend/semantic_analysis/pattern_record.rb +25 -0
  155. data/lib/jade/frontend/semantic_analysis/pattern_wildcard.rb +14 -0
  156. data/lib/jade/frontend/semantic_analysis/qualified_access.rb +14 -0
  157. data/lib/jade/frontend/semantic_analysis/record_access.rb +14 -0
  158. data/lib/jade/frontend/semantic_analysis/record_field.rb +17 -0
  159. data/lib/jade/frontend/semantic_analysis/record_literal.rb +21 -0
  160. data/lib/jade/frontend/semantic_analysis/record_update.rb +21 -0
  161. data/lib/jade/frontend/semantic_analysis/struct_declaration.rb +44 -0
  162. data/lib/jade/frontend/semantic_analysis/tuple.rb +17 -0
  163. data/lib/jade/frontend/semantic_analysis/type_declaration.rb +69 -0
  164. data/lib/jade/frontend/semantic_analysis/variable_reference.rb +27 -0
  165. data/lib/jade/frontend/semantic_analysis/variant_declaration.rb +18 -0
  166. data/lib/jade/frontend/semantic_analysis.rb +161 -0
  167. data/lib/jade/frontend/type_checking/canonicalize.rb +97 -0
  168. data/lib/jade/frontend/type_checking/constraints/deriving/decodable.rb +144 -0
  169. data/lib/jade/frontend/type_checking/constraints/deriving/encodable.rb +144 -0
  170. data/lib/jade/frontend/type_checking/constraints/deriving/eq.rb +265 -0
  171. data/lib/jade/frontend/type_checking/constraints/deriving/helpers.rb +59 -0
  172. data/lib/jade/frontend/type_checking/constraints/deriving.rb +28 -0
  173. data/lib/jade/frontend/type_checking/constraints.rb +101 -0
  174. data/lib/jade/frontend/type_checking/definition.rb +71 -0
  175. data/lib/jade/frontend/type_checking/env.rb +79 -0
  176. data/lib/jade/frontend/type_checking/error/case_of_branches_type_mismatch.rb +19 -0
  177. data/lib/jade/frontend/type_checking/error/derivation_failed.rb +21 -0
  178. data/lib/jade/frontend/type_checking/error/function_body_type_mismatch.rb +23 -0
  179. data/lib/jade/frontend/type_checking/error/function_call_type_mismatch.rb +37 -0
  180. data/lib/jade/frontend/type_checking/error/if_branch_type_mismatch.rb +19 -0
  181. data/lib/jade/frontend/type_checking/error/if_branches_type_mismatch.rb +18 -0
  182. data/lib/jade/frontend/type_checking/error/if_condition_type_mismatch.rb +17 -0
  183. data/lib/jade/frontend/type_checking/error/implementation_type_mismatch.rb +20 -0
  184. data/lib/jade/frontend/type_checking/error/list_item_type_mismatch.rb +19 -0
  185. data/lib/jade/frontend/type_checking/error/missing_implementation.rb +20 -0
  186. data/lib/jade/frontend/type_checking/error/missing_patterns.rb +26 -0
  187. data/lib/jade/frontend/type_checking/error/pattern_type_mismatch.rb +13 -0
  188. data/lib/jade/frontend/type_checking/error/port_not_decodable.rb +38 -0
  189. data/lib/jade/frontend/type_checking/error/record_access_type_mismatch.rb +14 -0
  190. data/lib/jade/frontend/type_checking/error/type_mismatch.rb +23 -0
  191. data/lib/jade/frontend/type_checking/error/unresolved_constraint.rb +20 -0
  192. data/lib/jade/frontend/type_checking/error.rb +18 -0
  193. data/lib/jade/frontend/type_checking/expected.rb +23 -0
  194. data/lib/jade/frontend/type_checking/generalization.rb +17 -0
  195. data/lib/jade/frontend/type_checking/generalizer.rb +38 -0
  196. data/lib/jade/frontend/type_checking/inference/assign.rb +58 -0
  197. data/lib/jade/frontend/type_checking/inference/body.rb +45 -0
  198. data/lib/jade/frontend/type_checking/inference/case_of.rb +102 -0
  199. data/lib/jade/frontend/type_checking/inference/constructor_reference.rb +21 -0
  200. data/lib/jade/frontend/type_checking/inference/function_call.rb +132 -0
  201. data/lib/jade/frontend/type_checking/inference/function_declaration.rb +70 -0
  202. data/lib/jade/frontend/type_checking/inference/grouping.rb +18 -0
  203. data/lib/jade/frontend/type_checking/inference/helpers.rb +34 -0
  204. data/lib/jade/frontend/type_checking/inference/if_then_else.rb +46 -0
  205. data/lib/jade/frontend/type_checking/inference/implementation.rb +150 -0
  206. data/lib/jade/frontend/type_checking/inference/import_declaration.rb +19 -0
  207. data/lib/jade/frontend/type_checking/inference/interface_declaration.rb +18 -0
  208. data/lib/jade/frontend/type_checking/inference/interop_import_declaration.rb +18 -0
  209. data/lib/jade/frontend/type_checking/inference/lambda.rb +87 -0
  210. data/lib/jade/frontend/type_checking/inference/list.rb +52 -0
  211. data/lib/jade/frontend/type_checking/inference/literal.rb +24 -0
  212. data/lib/jade/frontend/type_checking/inference/module.rb +18 -0
  213. data/lib/jade/frontend/type_checking/inference/pattern.rb +135 -0
  214. data/lib/jade/frontend/type_checking/inference/qualified_access.rb +23 -0
  215. data/lib/jade/frontend/type_checking/inference/record_access.rb +35 -0
  216. data/lib/jade/frontend/type_checking/inference/record_field.rb +19 -0
  217. data/lib/jade/frontend/type_checking/inference/record_literal.rb +24 -0
  218. data/lib/jade/frontend/type_checking/inference/record_update.rb +37 -0
  219. data/lib/jade/frontend/type_checking/inference/struct_declaration.rb +18 -0
  220. data/lib/jade/frontend/type_checking/inference/type_declaration.rb +18 -0
  221. data/lib/jade/frontend/type_checking/inference/variable_reference.rb +27 -0
  222. data/lib/jade/frontend/type_checking/inference.rb +27 -0
  223. data/lib/jade/frontend/type_checking/instantiation.rb +24 -0
  224. data/lib/jade/frontend/type_checking/loader.rb +80 -0
  225. data/lib/jade/frontend/type_checking/placeholder.rb +12 -0
  226. data/lib/jade/frontend/type_checking/port_resolution.rb +123 -0
  227. data/lib/jade/frontend/type_checking/result.rb +41 -0
  228. data/lib/jade/frontend/type_checking/scheme.rb +20 -0
  229. data/lib/jade/frontend/type_checking/state.rb +52 -0
  230. data/lib/jade/frontend/type_checking/substitution.rb +93 -0
  231. data/lib/jade/frontend/type_checking/unification.rb +282 -0
  232. data/lib/jade/frontend/type_checking/var_gen.rb +33 -0
  233. data/lib/jade/frontend/type_checking.rb +129 -0
  234. data/lib/jade/frontend/unused_analysis.rb +41 -0
  235. data/lib/jade/frontend/usage_analysis/reference_index.rb +53 -0
  236. data/lib/jade/frontend/usage_analysis.rb +195 -0
  237. data/lib/jade/frontend.rb +101 -0
  238. data/lib/jade/interop/boundary.rb +68 -0
  239. data/lib/jade/interop/error.rb +84 -0
  240. data/lib/jade/interop/lowering/error.rb +32 -0
  241. data/lib/jade/interop/lowering.rb +53 -0
  242. data/lib/jade/interop/runtime.rb +24 -0
  243. data/lib/jade/interop.rb +1 -0
  244. data/lib/jade/lexer.rb +189 -0
  245. data/lib/jade/lsp/converters.rb +542 -0
  246. data/lib/jade/lsp/handlers.rb +340 -0
  247. data/lib/jade/lsp/server.rb +63 -0
  248. data/lib/jade/lsp/snippets.rb +100 -0
  249. data/lib/jade/lsp/state.rb +25 -0
  250. data/lib/jade/lsp.rb +16 -0
  251. data/lib/jade/module_loader/cache.rb +56 -0
  252. data/lib/jade/module_loader/dependency_graph.rb +23 -0
  253. data/lib/jade/module_loader/dependency_resolver.rb +48 -0
  254. data/lib/jade/module_loader/normalize.rb +34 -0
  255. data/lib/jade/module_loader/topological_sort.rb +41 -0
  256. data/lib/jade/module_loader.rb +127 -0
  257. data/lib/jade/parsing/combinators.rb +291 -0
  258. data/lib/jade/parsing/error.rb +154 -0
  259. data/lib/jade/parsing/token.rb +12 -0
  260. data/lib/jade/parsing/type.rb +92 -0
  261. data/lib/jade/parsing.rb +674 -0
  262. data/lib/jade/port.rb +1 -0
  263. data/lib/jade/registry.rb +79 -0
  264. data/lib/jade/result.rb +121 -0
  265. data/lib/jade/runtime.rb +127 -0
  266. data/lib/jade/source.rb +62 -0
  267. data/lib/jade/stdlib/basics.rb +214 -0
  268. data/lib/jade/stdlib/bytes.rb +70 -0
  269. data/lib/jade/stdlib/calendar.rb +405 -0
  270. data/lib/jade/stdlib/char.rb +27 -0
  271. data/lib/jade/stdlib/clock.rb +342 -0
  272. data/lib/jade/stdlib/compiled.rb +48 -0
  273. data/lib/jade/stdlib/decode/params.rb +154 -0
  274. data/lib/jade/stdlib/decode.rb +315 -0
  275. data/lib/jade/stdlib/dict.rb +134 -0
  276. data/lib/jade/stdlib/encode.rb +143 -0
  277. data/lib/jade/stdlib/intrinsics.rb +280 -0
  278. data/lib/jade/stdlib/list.rb +214 -0
  279. data/lib/jade/stdlib/maybe.rb +73 -0
  280. data/lib/jade/stdlib/result.rb +131 -0
  281. data/lib/jade/stdlib/set.rb +123 -0
  282. data/lib/jade/stdlib/string.rb +65 -0
  283. data/lib/jade/stdlib/task.rb +55 -0
  284. data/lib/jade/stdlib/tuple.rb +21 -0
  285. data/lib/jade/stdlib.rb +112 -0
  286. data/lib/jade/symbol/anonymous_record.rb +7 -0
  287. data/lib/jade/symbol/base.rb +15 -0
  288. data/lib/jade/symbol/constructor.rb +11 -0
  289. data/lib/jade/symbol/derived_function.rb +5 -0
  290. data/lib/jade/symbol/function.rb +15 -0
  291. data/lib/jade/symbol/function_type.rb +7 -0
  292. data/lib/jade/symbol/implementation.rb +17 -0
  293. data/lib/jade/symbol/implementation_template.rb +13 -0
  294. data/lib/jade/symbol/interface.rb +11 -0
  295. data/lib/jade/symbol/interface_function.rb +18 -0
  296. data/lib/jade/symbol/interop_function.rb +22 -0
  297. data/lib/jade/symbol/lambda.rb +7 -0
  298. data/lib/jade/symbol/parser.rb +79 -0
  299. data/lib/jade/symbol/partial_application.rb +7 -0
  300. data/lib/jade/symbol/record_type.rb +8 -0
  301. data/lib/jade/symbol/stdlib_function.rb +15 -0
  302. data/lib/jade/symbol/stdlib_implementation.rb +7 -0
  303. data/lib/jade/symbol/struct.rb +15 -0
  304. data/lib/jade/symbol/type_application.rb +8 -0
  305. data/lib/jade/symbol/type_ref.rb +11 -0
  306. data/lib/jade/symbol/union.rb +15 -0
  307. data/lib/jade/symbol/value_ref.rb +15 -0
  308. data/lib/jade/symbol/variable.rb +7 -0
  309. data/lib/jade/symbol/variant.rb +11 -0
  310. data/lib/jade/symbol.rb +162 -0
  311. data/lib/jade/task.rb +103 -0
  312. data/lib/jade/tasks/rspec.rb +266 -0
  313. data/lib/jade/tasks.rb +70 -0
  314. data/lib/jade/type/anonymous_record.rb +33 -0
  315. data/lib/jade/type/application.rb +21 -0
  316. data/lib/jade/type/base.rb +9 -0
  317. data/lib/jade/type/constraint.rb +17 -0
  318. data/lib/jade/type/constructor.rb +19 -0
  319. data/lib/jade/type/function.rb +18 -0
  320. data/lib/jade/type/partial_application.rb +17 -0
  321. data/lib/jade/type/unit.rb +15 -0
  322. data/lib/jade/type/var.rb +21 -0
  323. data/lib/jade/type.rb +259 -0
  324. data/lib/jade/version.rb +3 -0
  325. data/lib/jade.rb +55 -0
  326. metadata +387 -0
@@ -0,0 +1,69 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module InteropImportDeclaration
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::InteropImportDeclaration(functions:)
10
+
11
+ functions_with_symbols = functions.map do |fn|
12
+ entry
13
+ .lookup_value(fn.name)
14
+ .then { fn.with(symbol: it) }
15
+ end
16
+
17
+ type_errors = functions_with_symbols
18
+ .flat_map { validate_type_symbol(it.symbol, registry, entry) }
19
+
20
+ task_errors = functions_with_symbols
21
+ .flat_map { |fn| task_shape_errors(fn, entry) }
22
+
23
+ Result
24
+ .init(node.with(functions: functions_with_symbols), scope)
25
+ .add_errors(type_errors + task_errors)
26
+ end
27
+
28
+ private
29
+
30
+ def task_shape_errors(fn, entry)
31
+ unless task_type?(fn.symbol.return_type)
32
+ Error::NonTaskPort
33
+ .new(entry.name, fn.range, fn_name: fn.name)
34
+ .then { return [it] }
35
+ end
36
+
37
+ fn.symbol.return_type => Symbol::TypeApplication(args: [ok_arm, err_arm])
38
+
39
+ [ok_arm, err_arm]
40
+ .any? { contains_task?(it) }
41
+ .then { it ? [Error::NestedTaskPort.new(entry.name, fn.range, fn_name: fn.name)] : [] }
42
+ end
43
+
44
+ def task_type?(symbol)
45
+ case symbol
46
+ in Symbol::TypeApplication(constructor: Symbol::TypeRef['Task', 'Task'])
47
+ true
48
+
49
+ else
50
+ false
51
+ end
52
+ end
53
+
54
+ def contains_task?(symbol)
55
+ case symbol
56
+ in Symbol::TypeApplication(constructor: Symbol::TypeRef['Task', 'Task'])
57
+ true
58
+
59
+ in Symbol::TypeApplication(args:)
60
+ args.any? { contains_task?(it) }
61
+
62
+ else
63
+ false
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,109 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module KeyedCall
5
+ module Validation
6
+ extend self
7
+
8
+ def errors(node, fields, parent, constructor, registry, entry)
9
+ duplicate_field_errors(fields, entry) +
10
+ kwargs_callee_errors(node, parent, entry) +
11
+ field_set_errors(node, fields, parent, constructor, registry, entry)
12
+ end
13
+
14
+ def expected_field_keys(parent, constructor, registry)
15
+ case parent
16
+ in Symbol::Struct then struct_record_keys(parent, registry)
17
+ in Symbol::Union then variant_record_keys(constructor)
18
+ else []
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def duplicate_field_errors(fields, entry)
25
+ fields
26
+ .group_by(&:key)
27
+ .filter_map do |key, group|
28
+ next if group.size < 2
29
+
30
+ Error::DuplicateField.new(
31
+ entry.name,
32
+ group.last.range,
33
+ field: key,
34
+ )
35
+ end
36
+ end
37
+
38
+ def kwargs_callee_errors(node, parent, entry)
39
+ case parent
40
+ in Symbol::Struct | Symbol::Union
41
+ []
42
+ else
43
+ [Error::KwargsOnNonConstructor.new(entry.name, node.range)]
44
+ end
45
+ end
46
+
47
+ def field_set_errors(node, fields, parent, constructor, registry, entry)
48
+ parent in Symbol::Struct | Symbol::Union or return []
49
+
50
+ expected = expected_field_keys(parent, constructor, registry)
51
+ provided = fields.map(&:key)
52
+ type_name = constructor_type_name(parent, constructor)
53
+
54
+ unknown = (provided - expected).map do |key|
55
+ Error::UnknownField.new(
56
+ entry.name,
57
+ fields.find { it.key == key }.range,
58
+ type_name:,
59
+ field: key,
60
+ expected:,
61
+ )
62
+ end
63
+
64
+ (expected - provided)
65
+ .then do |missing|
66
+ if missing.empty?
67
+ []
68
+ else
69
+ Error::MissingField
70
+ .new(
71
+ entry.name,
72
+ node.range,
73
+ type_name:,
74
+ fields: missing,
75
+ )
76
+ .then { [it] }
77
+ end
78
+ end
79
+ .then { unknown + it }
80
+ end
81
+
82
+ def struct_record_keys(struct_sym, registry)
83
+ case struct_sym.record_type
84
+ in Symbol::RecordType(fields:)
85
+ fields.keys
86
+
87
+ in Symbol::TypeRef => ref
88
+ struct_record_keys(registry.lookup(ref), registry)
89
+ end
90
+ end
91
+
92
+ def variant_record_keys(constructor)
93
+ case constructor.args
94
+ in [Symbol::RecordType(fields:)] then fields.keys
95
+ else []
96
+ end
97
+ end
98
+
99
+ def constructor_type_name(parent, constructor)
100
+ case parent
101
+ in Symbol::Struct then parent.name
102
+ in Symbol::Union then constructor.name
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,88 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ # Lowers `Foo(name: x, age: y)` into a positional FunctionCall:
5
+ # - struct constructor: FunctionCall(Foo, [x, y]) ordered by struct fields
6
+ # - keyed variant: FunctionCall(V, [{a: x, b: y}]) anon record arg
7
+ module KeyedCall
8
+ extend self
9
+ extend Helper
10
+
11
+ def analyze(node, registry, scope, entry)
12
+ node => AST::KeyedCall(callee:, fields:)
13
+
14
+ callee_r = analyze_node(callee, registry, scope, entry)
15
+ callee_resolved = callee_r.node
16
+ constructor = constructor_symbol(callee_resolved, registry)
17
+ parent = constructor && registry.lookup(constructor.parent)
18
+
19
+ fields_r = analyze_in_parallel(fields, registry, scope, entry)
20
+ fields_resolved = fields_r.node
21
+
22
+ validation_errors = Validation.errors(
23
+ node, fields_resolved, parent, constructor, registry, entry,
24
+ )
25
+
26
+ lowered = lower(node, callee_resolved, fields_resolved, parent, constructor, registry)
27
+
28
+ Result[
29
+ lowered,
30
+ callee_r.errors + fields_r.errors + validation_errors,
31
+ scope,
32
+ ]
33
+ end
34
+
35
+ private
36
+
37
+ def lower(node, callee, fields, parent, constructor, registry)
38
+ case parent
39
+ in Symbol::Struct
40
+ Validation
41
+ .expected_field_keys(parent, constructor, registry)
42
+ .then { positional_struct_call(node, callee, fields, it) }
43
+
44
+ in Symbol::Union
45
+ variant_call(node, callee, fields)
46
+
47
+ else
48
+ node.with(callee:, fields:)
49
+ end
50
+ end
51
+
52
+ def positional_struct_call(node, callee, fields, struct_keys)
53
+ fields
54
+ .to_h { [it.key, it.value] }
55
+ .then { |fields_by_key| struct_keys.map { fields_by_key[it] }.compact }
56
+ .then do
57
+ AST::FunctionCall.new(
58
+ callee:,
59
+ args: it,
60
+ infix: false,
61
+ dictionaries: [],
62
+ range: node.range,
63
+ )
64
+ end
65
+ end
66
+
67
+ def variant_call(node, callee, fields)
68
+ AST::FunctionCall.new(
69
+ callee:,
70
+ args: [AST::RecordLiteral.new(fields:, range: node.range)],
71
+ infix: false,
72
+ dictionaries: [],
73
+ range: node.range,
74
+ )
75
+ end
76
+
77
+ def constructor_symbol(callee, registry)
78
+ callee in AST::ConstructorReference or return nil
79
+
80
+ case registry.lookup(callee.symbol)
81
+ in Symbol::Constructor => constructor then constructor
82
+ else nil
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,23 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module Lambda
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::Lambda(params:, body:)
10
+
11
+ params_r = analyze_in_sequence(params, registry, scope, entry)
12
+
13
+ Result
14
+ .combine(node, scope:,
15
+ params: params_r,
16
+ body: analyze_node(body, registry, params_r.scope, entry),
17
+ )
18
+ .map_node { it.with(symbol: Symbol::Lambda[params.size]) }
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module List
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::List(items:)
10
+
11
+ analyze_in_parallel(items, registry, scope, entry)
12
+ .map_node { node.with(items: it, symbol: Symbol::TypeRef['List', 'List']) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module Literal
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, _registry, scope, _entry)
9
+ node => AST::Literal(value:)
10
+
11
+ symbol = case value
12
+ in Integer then Symbol::TypeRef['Basics', 'Int']
13
+ in TrueClass | FalseClass then Symbol::TypeRef['Basics', 'Bool']
14
+ in String then Symbol::TypeRef['String', 'String']
15
+ in Float then Symbol::TypeRef['Basics', 'Float']
16
+ end
17
+
18
+ Result.init(node.with(symbol:), scope)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,87 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ # Lowers a MemberAccess chain into either a QualifiedAccess
5
+ # (when the prefix resolves to an imported module alias) or a
6
+ # RecordAccess (when it's field access on a value expression).
7
+ module MemberAccess
8
+ extend self
9
+ extend Helper
10
+
11
+ def analyze(node, registry, scope, entry)
12
+ node => AST::MemberAccess(target:)
13
+
14
+ qualified_names = collect_qualified_names(node)
15
+
16
+ if qualified_names
17
+ *path, access = qualified_names
18
+
19
+ case resolve_qualified_access(path, node, registry, entry)
20
+ in Ok(symbol)
21
+ new_node = AST::QualifiedAccess[*node.deconstruct].with(symbol:)
22
+ Result[new_node, [], scope]
23
+
24
+ in Err(error)
25
+ Result[node, [error], scope]
26
+ end
27
+
28
+ else
29
+ target_r = analyze_node(target, registry, scope, entry)
30
+ new_node = AST::RecordAccess[*node.with(target: target_r.node).deconstruct]
31
+ Result[new_node, target_r.errors, scope]
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def collect_qualified_names(node)
38
+ case node
39
+ in AST::ConstructorReference
40
+ [node.name]
41
+
42
+ in AST::MemberAccess
43
+ names = collect_qualified_names(node.target)
44
+ names ? names + [node.name.name] : nil
45
+
46
+ else
47
+ nil
48
+ end
49
+ end
50
+
51
+ def resolve_qualified_access(path, node, registry, entry)
52
+ node => AST::MemberAccess(name:, target:)
53
+
54
+ module_name = path.join('.')
55
+ import = entry
56
+ .imports
57
+ .find { it.alias == module_name }
58
+
59
+ if import.nil?
60
+ Error::ModuleNotFound
61
+ .new(entry.name, node.target.range, name: import)
62
+
63
+ else
64
+ case registry.get(import.module_name).exposed_value(name.name)
65
+ in nil
66
+ Error::ValueNotExposed
67
+ .new(entry.name, name.range, module_name:, name: name.name)
68
+
69
+ in symbol
70
+ return Ok[symbol]
71
+ end
72
+ end
73
+ .then do
74
+ Error::VariableNotFound
75
+ .new(
76
+ entry.name,
77
+ node.range,
78
+ name: [module_name, name.name].join('.'),
79
+ causes: [it],
80
+ )
81
+ end
82
+ .then { Err[it] }
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,27 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module ModuleNode
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::Module(body:, exposing:)
10
+
11
+ exposing_errors = case exposing
12
+ in AST::ExposeNone
13
+ [Error::MissingExposingClause.new(entry.name, 0..0)]
14
+ else
15
+ []
16
+ end
17
+
18
+ Result
19
+ .combine(node, scope:,
20
+ body: analyze_node(body, registry, scope, entry),
21
+ )
22
+ .add_errors(exposing_errors)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module PatternBinding
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, _registry, scope, entry)
9
+ node => AST::Pattern::Binding(name:)
10
+
11
+ predicate_errors =
12
+ if name.end_with?('?')
13
+ [Error::PredicateNameNotAllowed.new(entry.name, node.range, name:)]
14
+ else
15
+ []
16
+ end
17
+
18
+ bind_r = bind(scope, Symbol.var(name, node.range), entry)
19
+
20
+ Result
21
+ .init(node, bind_r.scope)
22
+ .add_errors(bind_r.errors + predicate_errors)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module PatternConstructor
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::Pattern::Constructor(constructor:, patterns:)
10
+
11
+ constructor_r = analyze_node(constructor, registry, scope, entry)
12
+ symbol_ref = constructor_r.node.symbol&.to_ref
13
+
14
+ if symbol_ref.nil?
15
+ return Result.combine(node, scope:, constructor: constructor_r)
16
+ end
17
+
18
+ arity_errors = arity_mismatch_errors(
19
+ registry.lookup(symbol_ref), patterns, constructor, node.range, entry,
20
+ )
21
+ patterns_r = analyze_in_sequence(patterns, registry, scope, entry)
22
+
23
+ Result
24
+ .combine(node, scope: patterns_r.scope,
25
+ constructor: constructor_r,
26
+ patterns: patterns_r,
27
+ )
28
+ .map_node { it.with(symbol: symbol_ref) }
29
+ .add_errors(arity_errors)
30
+ end
31
+
32
+ private
33
+
34
+ def arity_mismatch_errors(symbol, patterns, constructor, range, entry)
35
+ return [] if symbol.args.size == patterns.size
36
+
37
+ [Error::ConstructorPatternArityMismatch.new(
38
+ entry.name, range,
39
+ constructor:,
40
+ expected_arity: symbol.args.size,
41
+ actual_arity: patterns.size,
42
+ )]
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,33 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module PatternList
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::Pattern::List(patterns:, rest:)
10
+
11
+ patterns_r = analyze_in_sequence(patterns, registry, scope, entry)
12
+
13
+ rest_scope, rest_errors =
14
+ case rest
15
+ in AST::Pattern::Binding(name:)
16
+ bind_r = bind(patterns_r.scope, Symbol.var(name, node.range), entry)
17
+ [bind_r.scope, bind_r.errors]
18
+
19
+ in AST::Pattern::Wildcard | nil
20
+ [patterns_r.scope, []]
21
+
22
+ else
23
+ [patterns_r.scope, [Error::InvalidListRestPattern.new(entry.name, rest.range)]]
24
+ end
25
+
26
+ Result
27
+ .combine(node, scope: rest_scope, patterns: patterns_r)
28
+ .add_errors(rest_errors)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module PatternLiteral
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::Pattern::Literal(literal:)
10
+
11
+ analyze_node(literal, registry, scope, entry)
12
+ .then { Result.combine(node, scope:, literal: it) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module PatternRecord
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::Pattern::Record(fields:)
10
+
11
+ symbol = Symbol
12
+ .anonymous_record(fields.map(&:name), Symbol.var('a', nil))
13
+
14
+ patterns_r = analyze_in_sequence(fields.map(&:pattern), registry, scope, entry)
15
+
16
+ fields
17
+ .zip(patterns_r.node)
18
+ .map { |f, p| f.with(pattern: p) }
19
+ .then { node.with(fields: it, symbol:) }
20
+ .then { Result[it, patterns_r.errors, patterns_r.scope] }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module PatternWildcard
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, _registry, scope, _entry)
9
+ Result.init(node, scope)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module QualifiedAccess
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, _registry, scope, _entry)
9
+ Result.init(node, scope)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module RecordAccess
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, _registry, scope, _entry)
9
+ Result.init(node, scope)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module RecordField
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::RecordField(value:)
10
+
11
+ analyze_node(value, registry, scope, entry)
12
+ .then { Result.combine(node, scope:, value: it) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module RecordLiteral
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::RecordLiteral(fields:)
10
+
11
+ Result
12
+ .combine(node, scope:,
13
+ fields: analyze_in_parallel(fields, registry, scope, entry),
14
+ )
15
+ .map_node { it.with(symbol: Symbol.anonymous_record(fields.map(&:key))) }
16
+ .add_errors(analyze_duplicate_fields(fields, entry))
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end