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,98 @@
1
+ module Jade
2
+ module Frontend
3
+ module ForwardDeclaration
4
+ module Module
5
+ extend self
6
+ extend Helper
7
+
8
+ def shallow(node, registry, entry)
9
+ node => AST::Module(body:)
10
+
11
+ shallow_declare_node(body, registry, entry)
12
+ end
13
+
14
+ def deep(node, entry, registry)
15
+ node => AST::Module(exposing:, body:)
16
+
17
+ case exposing
18
+ in AST::ExposeList(items:)
19
+ items
20
+ .reduce(Result[entry, []]) do |acc, exposed|
21
+ case exposed
22
+ in AST::ExposeValue(name:, range:)
23
+ lookup_and_expose_value(acc.entry, name, range)
24
+
25
+ in AST::ExposeType(name:, range:)
26
+ lookup_and_expose_type(acc.entry, name, range)
27
+
28
+ in AST::ExposeTypeExpand(name:, range:)
29
+ lookup_and_expose_type_with_variants(acc.entry, name, range)
30
+ end
31
+ .add_errors(acc.errors)
32
+ end
33
+
34
+ in AST::ExposeAll
35
+ entry
36
+ .values
37
+ .merge(entry.types)
38
+ .reduce(entry) { |acc, (name, sym)| acc.expose(sym.to_ref) }
39
+ .then { Result[it, []] }
40
+
41
+ in AST::ExposeNone
42
+ Result[entry, []]
43
+ end
44
+ .then { deep_declare_node(body, it.entry, registry).add_errors(it.errors) }
45
+ end
46
+
47
+ private
48
+
49
+ def lookup_and_expose_type(entry, name, span)
50
+ symbol = entry.lookup_type(name)
51
+
52
+ if symbol
53
+ return entry
54
+ .expose(symbol.to_ref)
55
+ .then { Result[it, []] }
56
+ end
57
+
58
+ Result[
59
+ entry,
60
+ [Error::ExposedTypeNotFound.new(entry.name, span, name:)],
61
+ ]
62
+ end
63
+
64
+ def lookup_and_expose_type_with_variants(entry, name, span)
65
+ symbol = entry.lookup_type(name)
66
+
67
+ unless symbol
68
+ return Result[
69
+ entry,
70
+ [Error::ExposedTypeNotFound.new(entry.name, span, name:)],
71
+ ]
72
+ end
73
+
74
+ symbol
75
+ .constructor_refs
76
+ .reduce(entry) { |acc, ctor| acc.expose(ctor.to_ref) }
77
+ .expose(symbol.to_ref)
78
+ .then { Result[it, []] }
79
+ end
80
+
81
+ def lookup_and_expose_value(entry, name, span)
82
+ symbol = entry.lookup_value(name)
83
+
84
+ if symbol
85
+ return entry
86
+ .expose(symbol.to_ref)
87
+ .then { Result[it, []] }
88
+ end
89
+
90
+ Result[
91
+ entry,
92
+ [Error::ExposedValueNotFound.new(entry.name, span, name:)],
93
+ ]
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,42 @@
1
+ module Jade
2
+ module Frontend
3
+ module ForwardDeclaration
4
+ module StructDeclaration
5
+ extend self
6
+ extend Helper
7
+
8
+ def shallow(node, registry, entry)
9
+ node => AST::StructDeclaration(name:, type_params:)
10
+
11
+ type_params
12
+ .map { Symbol.var(it.name, it.range) }
13
+ .then { Symbol.predeclared_struct(name, it, node.range) }
14
+ .then { entry.define(it) }
15
+ .then { Result[it, []] }
16
+ end
17
+
18
+ def deep(node, entry, _)
19
+ node => AST::StructDeclaration(name:, record_type:)
20
+
21
+ symbol = entry.lookup_type(name)
22
+
23
+ figure_out_type(entry, record_type)
24
+ .map do |record_type_symbol|
25
+ constructor_fn_symbol = Symbol.constructor(
26
+ name,
27
+ record_type_symbol.fields.values,
28
+ symbol.to_ref,
29
+ nil,
30
+ )
31
+
32
+ record_type_symbol
33
+ .then { symbol.with(record_type: it) }
34
+ .then { entry.define(it) }
35
+ .then { it.define(constructor_fn_symbol) }
36
+ end
37
+ .then { to_declaration_result(entry, it) }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,42 @@
1
+ module Jade
2
+ module Frontend
3
+ module ForwardDeclaration
4
+ module TypeDeclaration
5
+ extend self
6
+ extend Helper
7
+
8
+ def shallow(node, registry, entry)
9
+ node => AST::TypeDeclaration(name:, type_params:, variants:)
10
+
11
+ predeclared_variants = variants
12
+ .map { |var| Symbol.predeclared_constructor(var.name, var.range) }
13
+
14
+ type_params.map { Symbol.var(it.name, it.range) }
15
+ .then { Symbol.union(name, it, predeclared_variants, node.range) }
16
+ .then { entry.define(it) }
17
+ .then { Result[it, []] }
18
+ end
19
+
20
+ def deep(node, entry, _)
21
+ node => AST::TypeDeclaration(name:, variants:)
22
+
23
+ symbol = entry.lookup_type(name)
24
+
25
+ variants
26
+ .map do |var|
27
+ var.args.map { figure_out_type(entry, it) }
28
+ .then { Results.sequence(it) }
29
+ .map { Symbol.constructor(var.name, it, symbol.to_ref, var.range) }
30
+ end
31
+ .then { Results.sequence(it) }
32
+ .map do |variant_symbols|
33
+ variant_symbols
34
+ .reduce(entry) { |acc_entry, sym| acc_entry.define(sym) }
35
+ .then { it.define(symbol.with(variants: variant_symbols.map(&:to_ref))) }
36
+ end
37
+ .then { to_declaration_result(entry, it) }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,71 @@
1
+ require 'jade/frontend/forward_declaration/helper'
2
+ require 'jade/frontend/forward_declaration/error'
3
+
4
+ require 'jade/interop/lowering'
5
+
6
+ require 'jade/frontend/forward_declaration/body'
7
+ require 'jade/frontend/forward_declaration/function_declaration'
8
+ require 'jade/frontend/forward_declaration/implementation'
9
+ require 'jade/frontend/forward_declaration/implementation_function'
10
+ require 'jade/frontend/forward_declaration/import_declaration'
11
+ require 'jade/frontend/forward_declaration/interop_import_declaration'
12
+ require 'jade/frontend/forward_declaration/module'
13
+ require 'jade/frontend/forward_declaration/struct_declaration'
14
+ require 'jade/frontend/forward_declaration/type_declaration'
15
+ require 'jade/frontend/forward_declaration/interface_declaration'
16
+
17
+ module Jade
18
+ module Frontend
19
+ module ForwardDeclaration
20
+ extend self
21
+
22
+ Result = Data.define(:entry, :errors) do
23
+ def add_errors(new_errors)
24
+ with(errors: errors + new_errors)
25
+ end
26
+
27
+ def to_result
28
+ errors.empty? ? Ok[entry] : Err[errors]
29
+ end
30
+ end
31
+
32
+ def declare(node, registry, entry)
33
+ shallow_declare_node(node, registry, entry)
34
+ .then { deep_declare_node(node, it.entry, registry).add_errors(it.errors) }
35
+ .to_result
36
+ end
37
+
38
+ def declare_entry(entry, registry)
39
+ declare(entry.ast, registry, entry)
40
+ end
41
+
42
+ def shallow_declare_node(node, registry, entry)
43
+ resolver(node, entry)
44
+ &.shallow(node, registry, entry) || Result[entry, []]
45
+ end
46
+
47
+ def deep_declare_node(node, entry, registry)
48
+ resolver(node, entry)
49
+ &.deep(node, entry, registry) || Result[entry, []]
50
+ end
51
+
52
+ private
53
+
54
+ def resolver(node, entry)
55
+ case node
56
+ in AST::Body then Body
57
+ in AST::FunctionDeclaration then FunctionDeclaration
58
+ in AST::Implementation then Implementation
59
+ in AST::ImportDeclaration then ImportDeclaration
60
+ in AST::InteropImportDeclaration then InteropImportDeclaration
61
+ in AST::Module then Module
62
+ in AST::StructDeclaration then StructDeclaration
63
+ in AST::TypeDeclaration then TypeDeclaration
64
+ in AST::InterfaceDeclaration then InterfaceDeclaration
65
+ else
66
+ nil
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,65 @@
1
+ module Jade
2
+ module Frontend
3
+ module PatternAnalysis
4
+ module Exhaustiveness
5
+ extend self
6
+
7
+ def assert(patterns, range, env, registry, expected)
8
+ Matrix[
9
+ patterns.map { [node_to_matrix_pattern(it)] },
10
+ [expected],
11
+ ]
12
+ .missing_patterns(env)
13
+ .then { to_errors(it, range, env) }
14
+ end
15
+
16
+ private
17
+
18
+ def to_errors(matrix, range, env)
19
+ return [] if matrix.empty?
20
+
21
+ TypeChecking::Error::MissingPatterns
22
+ .new(env.entry_name, range, missing_patterns: matrix.rows)
23
+ .then { [it] }
24
+ end
25
+
26
+ def node_to_matrix_pattern(pattern_node)
27
+ case pattern_node
28
+ in AST::Pattern::Record(fields:)
29
+ Record[
30
+ fields
31
+ .map(&:name)
32
+ .zip(fields.map(&:pattern))
33
+ .to_h
34
+ .transform_values { node_to_matrix_pattern(it) },
35
+ ]
36
+
37
+ in AST::Pattern::Constructor(constructor:, patterns:)
38
+ Constructor[
39
+ constructor.symbol.qualified_name,
40
+ patterns.map { node_to_matrix_pattern(it) },
41
+ ]
42
+
43
+ in AST::Pattern::List(patterns:, rest:)
44
+ # Rewrite [x, y | xs] / [x, y] into nested Cons/Nil constructors
45
+ tail = rest ? Wildcard[] : Constructor['List.Nil', []]
46
+ patterns
47
+ .map { node_to_matrix_pattern(it) }
48
+ .reverse
49
+ .reduce(tail) { |acc, head| Constructor['List.Cons', [head, acc]] }
50
+
51
+ in AST::Pattern::Binding | AST::Pattern::Wildcard
52
+ Wildcard[]
53
+
54
+ in AST::Pattern::Literal(literal: { value:, symbol: })
55
+ Literal[
56
+ value,
57
+ symbol.qualified_name,
58
+ ]
59
+
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,235 @@
1
+ module Jade
2
+ module Frontend
3
+ module PatternAnalysis
4
+ Matrix = Data.define(:rows, :types) do
5
+ def self.wildcard(types)
6
+ types
7
+ .map { Wildcard[] }
8
+ .then { [it] }
9
+ .then { Matrix[it, types] }
10
+ end
11
+
12
+ def self.empty(types = [])
13
+ self.new([], types)
14
+ end
15
+
16
+ def map
17
+ rows
18
+ .map { yield it }
19
+ .then { with(rows: it) }
20
+ end
21
+
22
+ def include?(row)
23
+ rows.include?(row)
24
+ end
25
+
26
+ def size
27
+ rows.size
28
+ end
29
+
30
+ def empty?
31
+ rows.empty?
32
+ end
33
+
34
+ def any?
35
+ rows.any?
36
+ end
37
+
38
+ def concat(other)
39
+ with(rows: rows + other.rows)
40
+ end
41
+
42
+ def missing_patterns(env, seen_recursive_types = ::Set.new)
43
+ if types.empty?
44
+ return rows.empty? ? Matrix[[[]], types] : Matrix.empty
45
+ end
46
+
47
+ type = types.first
48
+
49
+ return Matrix.empty if never?(type)
50
+ return Matrix.wildcard(types) if rows.empty?
51
+
52
+ if infinite?(type) || type_var?(type) || seen_recursive_types.include?(type)
53
+ matrix = default
54
+ .missing_patterns(env, seen_recursive_types)
55
+
56
+ matrix
57
+ .map { [Wildcard[]] + it }
58
+
59
+ elsif expandable?(type, env)
60
+ expand(env).missing_patterns(env, seen_recursive_types)
61
+
62
+ else
63
+ new_seen = seen_recursive_types | ::Set[type]
64
+ constructors_of(type, env)
65
+ .reduce(Matrix.empty.with(types:)) do |acc, constructor|
66
+ missing = specialize(constructor)
67
+ .missing_patterns(env, new_seen)
68
+
69
+ missing
70
+ .map do |row|
71
+ new_args = row.take(constructor.args.size)
72
+ tail = row.drop(constructor.args.size)
73
+
74
+ [Constructor[constructor.name, new_args]] + tail
75
+ end
76
+ .then { acc.concat(it) }
77
+ end
78
+ end
79
+ end
80
+
81
+ protected
82
+
83
+ def expandable?(type, env)
84
+ case type
85
+ in Type::AnonymousRecord
86
+ true
87
+
88
+ in Type::Application(constructor:)
89
+ env.lookup_def(constructor.name).is_a?(TypeChecking::StructDef)
90
+
91
+ else
92
+ false
93
+ end
94
+ end
95
+
96
+ def expand(env)
97
+ type_fields =
98
+ case types.first
99
+ in Type::AnonymousRecord(fields:)
100
+ fields
101
+
102
+ in Type::Application(constructor:)
103
+ env.lookup_def(constructor.name).body.fields
104
+ end
105
+
106
+ map do |row|
107
+ case row.first
108
+ in Record(fields:)
109
+ type_fields
110
+ .map do |(k, v)|
111
+ fields[k] || Wildcard[]
112
+ end + row.drop(1)
113
+
114
+ in Wildcard
115
+ type_fields.map { Wildcard[] } + row.drop(1)
116
+ end
117
+ end
118
+ .with(types: type_fields.values + types.drop(1))
119
+ end
120
+
121
+ def constructors_of(type, env)
122
+ case type
123
+ in Type::Application(constructor: Type::Constructor(name: 'Basics.Bool'))
124
+ [
125
+ TypeChecking::ConstructorDef['Basics.True', 'Basics.Bool', []],
126
+ TypeChecking::ConstructorDef['Basics.False', 'Basics.Bool', []],
127
+ ]
128
+ in Type::Application(constructor: Type::Constructor(name: /^Tuple\.Tuple([2-4])$/ => name))
129
+ n = name[-1].to_i
130
+ [TypeChecking::Definition.constructor(name, name, Array.new(n) { env.fresh })]
131
+
132
+ in Type::Application(constructor: Type::Constructor(name: 'List.List'), args: [elem_type])
133
+ [
134
+ TypeChecking::ConstructorDef['List.Nil', 'List.List', []],
135
+ TypeChecking::ConstructorDef['List.Cons', 'List.List', [elem_type, type]],
136
+ ]
137
+
138
+ else
139
+ type_def = env.lookup_def(type.constructor.name)
140
+
141
+ # Type the user can't destructure from here (transitively reached
142
+ # through an imported struct field, or opaque intrinsic) —
143
+ # any pattern they can write is trivially exhaustive.
144
+ return [] if type_def.nil? || type_def.opaque?
145
+
146
+ type_def
147
+ .constructors
148
+ .map do |con|
149
+ con
150
+ .args
151
+ .map do |arg|
152
+ if type_var?(arg)
153
+ type_def
154
+ .type_params
155
+ .find_index { arg.name == it.name }
156
+ .then { type.args.at(it) }
157
+
158
+ else
159
+ arg
160
+ end
161
+ end
162
+ .then { con.with(args: it) }
163
+ end
164
+ end
165
+ end
166
+
167
+ def specialize(constructor)
168
+ rows
169
+ .filter_map do |cols|
170
+ case cols.first
171
+ in Literal(value:)
172
+ next [] + cols.drop(1) if value == false && "Basics.False" == constructor.name
173
+ next [] + cols.drop(1) if value == true && "Basics.True" == constructor.name
174
+
175
+ in Constructor(constructor: cons_name, args:)
176
+ args + cols.drop(1) if cons_name == constructor.name
177
+
178
+ in Wildcard
179
+ constructor.args.map { Wildcard[] } + cols.drop(1)
180
+
181
+ end
182
+ end
183
+ .then { with(rows: it) }
184
+ .then { it.with(types: constructor.args) }
185
+ end
186
+
187
+ def default
188
+ rows
189
+ .select { it.first.wildcard? }
190
+ .map { it.drop(1) }
191
+ .then { with(rows: it) }
192
+ .with(types: types.drop(1))
193
+ end
194
+
195
+ def add(columns)
196
+ with(rows: rows.concat(columns))
197
+ end
198
+
199
+ private
200
+
201
+ def never?(type)
202
+ case type
203
+ in Type::Application(constructor: Type::Constructor(name: 'Basics.Never'))
204
+ true
205
+ else
206
+ false
207
+ end
208
+ end
209
+
210
+ def type_var?(type)
211
+ type.is_a?(Type::Var)
212
+ end
213
+
214
+ def infinite?(type)
215
+ case type
216
+ in Type::Function
217
+ true
218
+
219
+ in Type::Application(constructor:)
220
+ case constructor
221
+ in Type::Constructor(name: 'Basics.Int') then true
222
+ in Type::Constructor(name: 'Basics.Float') then true
223
+ in Type::Constructor(name: 'String.String') then true
224
+ else
225
+ false
226
+ end
227
+
228
+ else
229
+ false
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,40 @@
1
+ require 'jade/frontend/pattern_analysis/matrix'
2
+ require 'jade/frontend/pattern_analysis/exhaustiveness'
3
+
4
+ module Jade
5
+ module Frontend
6
+ module PatternAnalysis
7
+ Wildcard = Data.define do
8
+ def wildcard?; true; end
9
+ def to_s; '_'; end
10
+ end
11
+
12
+ Literal = Data.define(:value, :type) do
13
+ def wildcard?; false; end
14
+ def to_s; value.inspect; end
15
+ end
16
+
17
+ Constructor = Data.define(:constructor, :args) do
18
+ def wildcard?; false; end
19
+
20
+ def to_s
21
+ if constructor.start_with?('Tuple.')
22
+ "(#{args.map(&:to_s).join(', ')})"
23
+ else
24
+ name = constructor.split('.').last
25
+ args.empty? ? name : "#{name}(#{args.map(&:to_s).join(', ')})"
26
+ end
27
+ end
28
+ end
29
+
30
+ Record = Data.define(:fields) do
31
+ def wildcard?; false; end
32
+
33
+ def to_s
34
+ fields_str = fields.map { |k, v| "#{k}: #{v}" }.join(', ')
35
+ "{ #{fields_str} }"
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module Assign
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::Assign(pattern:, expression:)
10
+
11
+ ptn_r = analyze_node(pattern, registry, scope, entry)
12
+ Result.combine(node, scope: ptn_r.scope,
13
+ pattern: ptn_r,
14
+ expression: analyze_node(expression, registry, scope, entry),
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module Body
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::Body(expressions:)
10
+
11
+ duplicate_errors = expressions
12
+ .select { it.is_a?(AST::FunctionDeclaration) }
13
+ .group_by(&:name)
14
+ .filter_map do |name, decls|
15
+ next nil if decls.size < 2
16
+
17
+ first, *rest = decls
18
+ Error::DuplicateFunctionDeclaration.new(
19
+ entry.name,
20
+ first.range,
21
+ name,
22
+ duplicate_spans: rest.map(&:range),
23
+ )
24
+ end
25
+
26
+ analyze_in_sequence(expressions, registry, scope, entry)
27
+ .add_errors(duplicate_errors)
28
+ .map_node { node.with(expressions: it) }
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module CaseOf
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::CaseOf(expression:, branches:)
10
+
11
+ Result.combine(node, scope:,
12
+ expression: analyze_node(expression, registry, scope, entry),
13
+ branches: analyze_in_parallel(branches, registry, scope, entry),
14
+ )
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ module Jade
2
+ module Frontend
3
+ module SemanticAnalysis
4
+ module CaseOfBranch
5
+ extend self
6
+ extend Helper
7
+
8
+ def analyze(node, registry, scope, entry)
9
+ node => AST::CaseOfBranch(pattern:, body:)
10
+
11
+ ptn_r = analyze_node(pattern, registry, scope, entry)
12
+ Result.combine(node, scope:,
13
+ pattern: ptn_r,
14
+ body: analyze_node(body, registry, ptn_r.scope, entry),
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end