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,87 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module Lambda
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, registry, state, expected)
10
+ node => AST::Lambda(body:, params:)
11
+
12
+ params_types = params.map { state.fresh }
13
+
14
+ pre_state = state
15
+ .unify_result(
16
+ Result.init(Type.function(params_types, state.fresh)),
17
+ expected.type,
18
+ &type_error(state, node)
19
+ )
20
+ .first
21
+
22
+ params_state = params
23
+ .zip(params_types)
24
+ .reduce(pre_state) do |acc, (p, t)|
25
+ case p
26
+ in AST::Pattern::Binding(name:)
27
+ pre_state.env.substitution.apply(t)
28
+ .then do |concrete_t|
29
+ acc.bind(name, Scheme.mono(concrete_t))
30
+ .then { it.with(env: it.env.pin_type(p.id, concrete_t)) }
31
+ end
32
+
33
+ in AST::Pattern::Wildcard
34
+ acc
35
+
36
+ else
37
+ pre_state.env.substitution.apply(t)
38
+ .then { Pattern.infer(p, registry, acc, Expected.check(it)) }
39
+ .first
40
+ end
41
+ end
42
+
43
+ body_state, body_result = check(
44
+ body,
45
+ registry,
46
+ params_state,
47
+ Expected.infer(params_state.fresh),
48
+ )
49
+
50
+ exhaustiveness_state = params
51
+ .zip(params_types)
52
+ .reduce(body_state) do |acc, (p, t)|
53
+ case p
54
+ in AST::Pattern::Binding | AST::Pattern::Wildcard
55
+ acc
56
+ else
57
+ concrete_t = body_state.env.substitution.apply(t)
58
+ PatternAnalysis::Exhaustiveness
59
+ .assert([p], p.range, acc.env, registry, concrete_t)
60
+ .then { acc.add_errors(it) }
61
+ end
62
+ end
63
+
64
+ Type
65
+ .function(params_types, body_result.type)
66
+ .then { Result.init(it, body_result.constraints) }
67
+ .apply(exhaustiveness_state.env.substitution)
68
+ .then { exhaustiveness_state.unify_result(it, expected.type, &type_error(exhaustiveness_state, node)) }
69
+ end
70
+
71
+ private
72
+
73
+ def type_error(state, node)
74
+ ->(e) do
75
+ Error::TypeMismatch.new(
76
+ state.env.entry_name,
77
+ node.range,
78
+ expected: e.expected,
79
+ actual: e.actual,
80
+ )
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,52 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module List
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, registry, state, expected)
10
+ node => AST::List(items:)
11
+
12
+ if items.empty?
13
+ Type.list.apply([state.fresh])
14
+ .then { Result.init(it) }
15
+ .then { return state.unify_result(it, expected.type, expected.rigid_vars) }
16
+ end
17
+
18
+ head, *rest = items
19
+ head_state, head_result = check(head, registry, state, Expected.infer(state.fresh))
20
+
21
+ items_state, items_result = rest
22
+ .each_with_index
23
+ .reduce([head_state, head_result]) do |(state_acc, result_acc), (item, i)|
24
+ new_state, result = check(item, registry, state_acc, Expected.infer(state_acc.fresh))
25
+ new_state
26
+ .unify_result(result, result_acc.type, &type_error(new_state, item, i))
27
+ .then { |st, rs| [st, rs.with(constraints: result_acc.constraints + rs.constraints)] }
28
+ end
29
+
30
+ Result
31
+ .init(Type.list.apply([items_result.type]), items_result.constraints)
32
+ .then { items_state.unify_result(it, expected.type, expected.rigid_vars) }
33
+ end
34
+
35
+ private
36
+
37
+ def type_error(state, item, index)
38
+ ->(error) do
39
+ Error::ListItemTypeMismatch.new(
40
+ state.env.entry_name,
41
+ item.range,
42
+ expected: error.expected,
43
+ actual: error.actual,
44
+ actual_index: index + 2,
45
+ )
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module Literal
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, registry, state, _)
10
+ symbol =
11
+ case node
12
+ in AST::Literal | AST::CharLiteral
13
+ node.symbol
14
+ end
15
+
16
+ type_from_symbol(symbol, registry, state.env.var_gen)
17
+ .then { [state, Result.init(*it)] }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,18 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module Module
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, registry, env, expected_type)
10
+ node => AST::Module(body:)
11
+
12
+ check(body, registry, env, expected_type)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,135 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module Pattern
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(pattern, registry, state, expected)
10
+ infer_(pattern, registry, state, expected)
11
+ .then { |s, r| [s.with(env: s.env.pin_type(pattern.id, r.type)), r] }
12
+ end
13
+
14
+ def infer_(pattern, registry, state, expected)
15
+ case pattern
16
+ in AST::Pattern::Record(fields:, symbol:)
17
+ fields_state, fields_result = fields
18
+ .reduce([state, Result.accumulator]) do |(state_acc, result_acc), field|
19
+ st, rs = Expected
20
+ .infer(state_acc.fresh)
21
+ .then { infer(field.pattern, registry, state_acc, it) }
22
+
23
+ [st, result_acc.add(rs)]
24
+ end
25
+
26
+ fields
27
+ .map(&:name)
28
+ .zip(fields_result.types)
29
+ .to_h
30
+ .then { Type.anonymous_record(it, state.fresh) }
31
+ .then { Result.init(it) }
32
+ .then do
33
+ fields_state
34
+ .unify_result(it, expected.type, &type_error(state, pattern))
35
+ end
36
+
37
+ in AST::Pattern::Literal(literal:)
38
+ new_state, literal_result = check(literal, registry, state, expected)
39
+ new_state.unify_result(literal_result, expected.type, &type_error(state, pattern))
40
+
41
+ in AST::Pattern::Wildcard
42
+ Result
43
+ .init(state.fresh)
44
+ .then { state.unify_result(it, expected.type) }
45
+
46
+ in AST::Pattern::Binding(name:)
47
+ state
48
+ .bind(name, Scheme.mono(expected.type))
49
+ .then { it.unify_result(Result.init(it.fresh), expected.type) }
50
+
51
+ in AST::Pattern::List(patterns:, rest:)
52
+ elem_type = state.fresh
53
+ list_type = Type.list.apply([elem_type])
54
+
55
+ heads_state = patterns
56
+ .reduce(state) do |acc, pat|
57
+ infer(pat, registry, acc, Expected.check(elem_type)).first
58
+ end
59
+
60
+ after_rest_state =
61
+ case rest
62
+ in AST::Pattern::Binding(name:)
63
+ generalize(heads_state.env, list_type, [])
64
+ .then { heads_state.bind(name, it) }
65
+
66
+ in AST::Pattern::Wildcard | nil
67
+ heads_state
68
+ end
69
+
70
+ Result
71
+ .init(list_type)
72
+ .then do
73
+ after_rest_state
74
+ .unify_result(
75
+ it,
76
+ expected.type,
77
+ &type_error(after_rest_state, pattern)
78
+ )
79
+ end
80
+
81
+ in AST::Pattern::Constructor(symbol:, patterns: [])
82
+ state.env.lookup(symbol.qualified_name) => { type: constructor_type }
83
+
84
+ state.unify_result(
85
+ Result.init(constructor_type),
86
+ expected.type,
87
+ &type_error(state, pattern)
88
+ )
89
+
90
+ in AST::Pattern::Constructor(symbol:, patterns:)
91
+ state.env.lookup(symbol.qualified_name) => { type: constructor_type }
92
+
93
+ patterns_state, patterns_result = constructor_type
94
+ .args
95
+ .zip(patterns)
96
+ .reduce([state, Result.accumulator]) do |(acc_state, acc_result), (inner_expected, pat)|
97
+ new_state, result = Expected
98
+ .check(inner_expected)
99
+ .then { infer(pat, registry, acc_state, it) }
100
+
101
+ [new_state, acc_result.add(result)]
102
+ end
103
+
104
+ patterns_result.types
105
+ .then { Type.function(it, expected.type) }
106
+ .then { Result.init(it) }
107
+ .then do
108
+ patterns_state
109
+ .unify_result(it, constructor_type) do |error|
110
+ Error::PatternTypeMismatch.new(
111
+ state.env.entry_name, pattern.range,
112
+ expected: error.expected.return_type,
113
+ actual: error.actual.return_type,
114
+ )
115
+ end
116
+ end
117
+ .then { |(state, result)| [state, result.map(&:return_type)] }
118
+ end
119
+ end
120
+
121
+ private
122
+
123
+ def type_error(state, pattern)
124
+ ->(error) do
125
+ Error::PatternTypeMismatch.new(
126
+ state.env.entry_name, pattern.range,
127
+ expected: error.expected, actual: error.actual,
128
+ )
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,23 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module QualifiedAccess
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, registry, state, expected)
10
+ node => AST::QualifiedAccess(symbol:)
11
+
12
+ state
13
+ .env
14
+ .lookup(symbol.qualified_name)
15
+ .then { it.attach_origin(node) }
16
+ .then { state.unify_result(it, expected.type) }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,35 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module RecordAccess
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, registry, state, expected_)
10
+ node => AST::RecordAccess(target:, name:)
11
+
12
+ record_expected = Type.anonymous_record(
13
+ { name.name => expected_.type },
14
+ state.fresh.with(name: 'a'),
15
+ )
16
+
17
+ target_state, target_result = check(target, registry, state, Expected.infer(state.fresh))
18
+ after_state, _ = target_state.unify_result(target_result, record_expected) do
19
+ Error::RecordAccessTypeMismatch.new(
20
+ state.env.entry_name,
21
+ name.range,
22
+ expected: it.expected,
23
+ actual: it.actual,
24
+ )
25
+ end
26
+
27
+ Result.init(expected_.type)
28
+ .then { it.apply(after_state.env.substitution) }
29
+ .then { [after_state, it] }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module RecordField
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, registry, env, expected_type)
10
+ node => AST::RecordField(value:)
11
+
12
+ check(value, registry, env, expected_type)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,24 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module RecordLiteral
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, registry, state, expected)
10
+ node => AST::RecordLiteral(fields:)
11
+
12
+ fields_state, fields_types, fields_constraints = fields
13
+ .reduce([state, {}, []]) do |(state_acc, types_acc, c_acc), field|
14
+ new_state, result = check(field, registry, state_acc, Expected.infer(state_acc.fresh))
15
+ [new_state, types_acc.merge(field.key => result.type), c_acc + result.constraints]
16
+ end
17
+
18
+ [fields_state, Result.init(Type.anonymous_record(fields_types, nil), fields_constraints)]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module RecordUpdate
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, registry, state, expected)
10
+ node => AST::RecordUpdate(base:, fields:)
11
+
12
+ base_state, base_result = check(base, registry, state, Expected.infer(state.fresh))
13
+
14
+ fields_state, fields_types = fields
15
+ .reduce([base_state, {}]) do |(state_acc, types_acc), field|
16
+ new_state, result = check(field, registry, state_acc, Expected.infer(state_acc.fresh))
17
+ [new_state, types_acc.merge(field.key => result.type)]
18
+ end
19
+
20
+ update_record = Type.anonymous_record(fields_types, fields_state.fresh)
21
+
22
+ after_state, result = fields_state.unify_result(base_result, update_record) do
23
+ Error::RecordAccessTypeMismatch.new(
24
+ state.env.entry_name,
25
+ node.range,
26
+ expected: it.expected,
27
+ actual: it.actual,
28
+ )
29
+ end
30
+
31
+ after_state.unify_result(result, expected.type)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,18 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module StructDeclaration
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, _, state, _)
10
+ node => AST::StructDeclaration
11
+
12
+ [state, Result.init(Type.unit)]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module TypeDeclaration
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, _, state, _)
10
+ node => AST::TypeDeclaration
11
+
12
+ [state, Result.init(Type.unit)]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Inference
5
+ module VariableReference
6
+ extend Helpers
7
+ extend self
8
+
9
+ def infer(node, registry, state, _)
10
+ node => AST::VariableReference(symbol:)
11
+
12
+ case symbol
13
+ in Symbol::Variable
14
+ symbol.name
15
+ else
16
+ symbol.qualified_name
17
+ end
18
+ .then { state.env.lookup(it) }
19
+ .then { it.attach_origin(node) }
20
+ .then { [state, it] }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,27 @@
1
+ require 'jade/frontend/type_checking/inference/helpers'
2
+
3
+ require 'jade/frontend/type_checking/inference/body'
4
+ require 'jade/frontend/type_checking/inference/case_of'
5
+ require 'jade/frontend/type_checking/inference/constructor_reference'
6
+ require 'jade/frontend/type_checking/inference/function_call'
7
+ require 'jade/frontend/type_checking/inference/function_declaration'
8
+ require 'jade/frontend/type_checking/inference/implementation'
9
+ require 'jade/frontend/type_checking/inference/grouping'
10
+ require 'jade/frontend/type_checking/inference/if_then_else'
11
+ require 'jade/frontend/type_checking/inference/import_declaration'
12
+ require 'jade/frontend/type_checking/inference/interop_import_declaration'
13
+ require 'jade/frontend/type_checking/inference/lambda'
14
+ require 'jade/frontend/type_checking/inference/list'
15
+ require 'jade/frontend/type_checking/inference/literal'
16
+ require 'jade/frontend/type_checking/inference/module'
17
+ require 'jade/frontend/type_checking/inference/pattern'
18
+ require 'jade/frontend/type_checking/inference/qualified_access'
19
+ require 'jade/frontend/type_checking/inference/record_access'
20
+ require 'jade/frontend/type_checking/inference/record_field'
21
+ require 'jade/frontend/type_checking/inference/record_literal'
22
+ require 'jade/frontend/type_checking/inference/record_update'
23
+ require 'jade/frontend/type_checking/inference/struct_declaration'
24
+ require 'jade/frontend/type_checking/inference/interface_declaration'
25
+ require 'jade/frontend/type_checking/inference/type_declaration'
26
+ require 'jade/frontend/type_checking/inference/assign'
27
+ require 'jade/frontend/type_checking/inference/variable_reference'
@@ -0,0 +1,24 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Instantiation
5
+ extend self
6
+
7
+ # Index = position in scheme.constraints. Lets attach_dictionary write
8
+ # positionally so sibling same-iface markers don't collide on one origin.
9
+ def instantiate(scheme, var_gen)
10
+ sub = scheme
11
+ .quantified.reduce(Substitution::EMPTY) do |subs, var|
12
+ subs.bind(var.id, var_gen.fresh(var.name))
13
+ end
14
+
15
+ scheme
16
+ .constraints
17
+ .each_with_index
18
+ .map { |c, i| sub.apply(c.with(index: i)) }
19
+ .then { [sub.apply(scheme.type), it] }
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,80 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ module Loader
5
+ extend self
6
+
7
+ def load(entry, registry, env: Env.empty)
8
+ env
9
+ .with(entry_name: entry.name)
10
+ .then { load_local_bindings(it, entry, registry) }
11
+ .then { load_local_definitions(it, entry, registry) }
12
+ .then { load_imports(it, entry, registry) }
13
+ end
14
+
15
+ def load_local_bindings(env, entry, registry)
16
+ entry
17
+ .defined_values
18
+ .reduce(env) do |e, (_, sym)|
19
+ case sym
20
+ in Symbol::Function
21
+ Type
22
+ .from_symbol(sym, registry, e.var_gen)
23
+ .then { Placeholder[*it] }
24
+
25
+ else
26
+ Type
27
+ .from_symbol(sym, registry, e.var_gen)
28
+ .then { Inference::Helpers.generalize(e, *it) }
29
+ end
30
+ .then { e.bind(sym.qualified_name, it) }
31
+ end
32
+ end
33
+
34
+ def load_local_definitions(env, entry, registry)
35
+ entry
36
+ .types
37
+ .reduce(env) do |e, (_, sym)|
38
+ Definition
39
+ .from_symbol(sym, registry)
40
+ .then { e.define(sym.qualified_name, it) }
41
+ end
42
+ end
43
+
44
+ def load_imports(env, entry, registry)
45
+ entry
46
+ .imports
47
+ .reduce(env) do |e, import_entry|
48
+ import_entry.qualified_symbols.reduce(e) do |acc, sym|
49
+ add_imported_symbol(acc, sym, registry)
50
+ end
51
+ end
52
+ end
53
+
54
+ def add_imported_symbol(env, sym, registry)
55
+ case sym
56
+ in Symbol::ValueRef
57
+ return env if env.bindings[sym.qualified_name]
58
+
59
+ upstream_env = registry.get(sym.module_name)&.env
60
+ return env unless upstream_env
61
+
62
+ upstream_env
63
+ .bindings[sym.qualified_name]
64
+ &.then { env.bind(sym.qualified_name, it) } || env
65
+
66
+ in Symbol::TypeRef
67
+ return env if env.lookup_def(sym.qualified_name)
68
+
69
+ Definition
70
+ .from_symbol(sym, registry)
71
+ .then { env.define(sym.qualified_name, it) }
72
+
73
+ else
74
+ env
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,12 @@
1
+ module Jade
2
+ module Frontend
3
+ module TypeChecking
4
+ Placeholder = Data.define(:type, :constraints) do
5
+ def free_vars
6
+ type.unbound_vars + constraints.flat_map(&:unbound_vars)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+