jade-lang 0.8.0 → 0.10.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 (152) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +439 -2
  3. data/docs/interop.md +18 -1
  4. data/docs/stdlib.md +3 -1
  5. data/docs/syntax.md +96 -0
  6. data/lib/jade/api.rb +9 -0
  7. data/lib/jade/ast.rb +37 -1
  8. data/lib/jade/cli/eject.rb +132 -0
  9. data/lib/jade/cli.rb +2 -0
  10. data/lib/jade/codegen/boundary/specialized/list.rb +11 -7
  11. data/lib/jade/codegen/boundary/specialized/maybe.rb +2 -2
  12. data/lib/jade/codegen/boundary/specialized/record.rb +19 -4
  13. data/lib/jade/codegen/boundary/specialized/scalar.rb +2 -2
  14. data/lib/jade/codegen/boundary/specialized.rb +13 -5
  15. data/lib/jade/codegen/boundary.rb +12 -2
  16. data/lib/jade/codegen/context.rb +17 -0
  17. data/lib/jade/codegen/error.rb +1 -0
  18. data/lib/jade/codegen/function_call.rb +23 -7
  19. data/lib/jade/codegen/function_declaration.rb +25 -13
  20. data/lib/jade/codegen/helpers.rb +27 -4
  21. data/lib/jade/codegen/implementation.rb +2 -2
  22. data/lib/jade/codegen/inline.rb +1 -1
  23. data/lib/jade/codegen/inlines.rb +6 -1
  24. data/lib/jade/codegen/names.rb +31 -0
  25. data/lib/jade/codegen/pattern/constructor.rb +2 -2
  26. data/lib/jade/codegen/transforms/fold_shape.rb +1 -1
  27. data/lib/jade/codegen.rb +76 -15
  28. data/lib/jade/compiler.rb +2 -0
  29. data/lib/jade/entry.rb +1 -1
  30. data/lib/jade/error.rb +5 -0
  31. data/lib/jade/extensions.rb +70 -0
  32. data/lib/jade/formatter/calls.rb +68 -11
  33. data/lib/jade/formatter/collections.rb +4 -4
  34. data/lib/jade/formatter/declarations.rb +13 -15
  35. data/lib/jade/formatter/helper.rb +20 -0
  36. data/lib/jade/formatter/infix_application.rb +19 -4
  37. data/lib/jade/formatter/lambda.rb +24 -12
  38. data/lib/jade/formatter/pattern.rb +3 -0
  39. data/lib/jade/frontend/desugaring/placeholder.rb +40 -17
  40. data/lib/jade/frontend/desugaring.rb +29 -9
  41. data/lib/jade/frontend/fixity_fixer.rb +6 -4
  42. data/lib/jade/frontend/forward_declaration/error/alias_expansion.rb +23 -0
  43. data/lib/jade/frontend/forward_declaration/error/duplicate_constructor_name.rb +45 -0
  44. data/lib/jade/frontend/forward_declaration/error/duplicate_type_name.rb +42 -0
  45. data/lib/jade/frontend/forward_declaration/error.rb +3 -0
  46. data/lib/jade/frontend/forward_declaration/helper.rb +58 -0
  47. data/lib/jade/frontend/forward_declaration/import_declaration.rb +4 -0
  48. data/lib/jade/frontend/forward_declaration/interface_declaration.rb +6 -0
  49. data/lib/jade/frontend/forward_declaration/module.rb +4 -0
  50. data/lib/jade/frontend/forward_declaration/struct_declaration.rb +10 -1
  51. data/lib/jade/frontend/forward_declaration/type_alias_declaration.rb +37 -0
  52. data/lib/jade/frontend/forward_declaration/type_declaration.rb +10 -1
  53. data/lib/jade/frontend/forward_declaration.rb +2 -0
  54. data/lib/jade/frontend/pattern_analysis/exhaustiveness.rb +47 -43
  55. data/lib/jade/frontend/pattern_analysis/matrix.rb +28 -219
  56. data/lib/jade/frontend/pattern_analysis/pattern.rb +132 -0
  57. data/lib/jade/frontend/pattern_analysis/redundancy.rb +24 -0
  58. data/lib/jade/frontend/pattern_analysis/signature.rb +220 -0
  59. data/lib/jade/frontend/pattern_analysis/usefulness.rb +72 -0
  60. data/lib/jade/frontend/pattern_analysis/witnesses.rb +73 -0
  61. data/lib/jade/frontend/pattern_analysis.rb +5 -38
  62. data/lib/jade/frontend/semantic_analysis/body.rb +29 -1
  63. data/lib/jade/frontend/semantic_analysis/error/duplicate_implementation.rb +39 -0
  64. data/lib/jade/frontend/semantic_analysis/error/implementation_on_alias.rb +24 -0
  65. data/lib/jade/frontend/semantic_analysis/error/no_base_case.rb +45 -0
  66. data/lib/jade/frontend/semantic_analysis/error/placeholder_not_allowed.rb +15 -3
  67. data/lib/jade/frontend/semantic_analysis/error/recursive_type_alias.rb +24 -0
  68. data/lib/jade/frontend/semantic_analysis/error.rb +4 -0
  69. data/lib/jade/frontend/semantic_analysis/helper.rb +41 -0
  70. data/lib/jade/frontend/semantic_analysis/implementation.rb +13 -10
  71. data/lib/jade/frontend/semantic_analysis/inhabitedness.rb +90 -0
  72. data/lib/jade/frontend/semantic_analysis/interop_import_declaration.rb +28 -16
  73. data/lib/jade/frontend/semantic_analysis/keyed_call.rb +21 -5
  74. data/lib/jade/frontend/semantic_analysis/pattern_range.rb +16 -0
  75. data/lib/jade/frontend/semantic_analysis/struct_declaration.rb +1 -0
  76. data/lib/jade/frontend/semantic_analysis/type_alias_declaration/cycle_detection.rb +95 -0
  77. data/lib/jade/frontend/semantic_analysis/type_alias_declaration.rb +48 -0
  78. data/lib/jade/frontend/semantic_analysis/type_declaration.rb +1 -0
  79. data/lib/jade/frontend/semantic_analysis.rb +5 -0
  80. data/lib/jade/frontend/type_checking/canonicalize.rb +1 -0
  81. data/lib/jade/frontend/type_checking/cascade.rb +90 -0
  82. data/lib/jade/frontend/type_checking/constraints/deriving/encodable.rb +10 -0
  83. data/lib/jade/frontend/type_checking/constraints/deriving.rb +5 -4
  84. data/lib/jade/frontend/type_checking/constraints.rb +18 -3
  85. data/lib/jade/frontend/type_checking/error/display.rb +49 -0
  86. data/lib/jade/frontend/type_checking/error/division_by_zero.rb +31 -0
  87. data/lib/jade/frontend/type_checking/error/empty_range_pattern.rb +25 -0
  88. data/lib/jade/frontend/type_checking/error/function_body_type_mismatch.rb +4 -3
  89. data/lib/jade/frontend/type_checking/error/function_call_type_mismatch.rb +108 -5
  90. data/lib/jade/frontend/type_checking/error/if_branch_type_mismatch.rb +1 -1
  91. data/lib/jade/frontend/type_checking/error/if_branches_type_mismatch.rb +1 -1
  92. data/lib/jade/frontend/type_checking/error/if_condition_type_mismatch.rb +1 -1
  93. data/lib/jade/frontend/type_checking/error/implementation_type_mismatch.rb +1 -1
  94. data/lib/jade/frontend/type_checking/error/list_item_type_mismatch.rb +1 -1
  95. data/lib/jade/frontend/type_checking/error/missing_patterns.rb +20 -4
  96. data/lib/jade/frontend/type_checking/error/pattern_type_mismatch.rb +7 -1
  97. data/lib/jade/frontend/type_checking/error/range_pattern_type.rb +29 -0
  98. data/lib/jade/frontend/type_checking/error/record_access_type_mismatch.rb +2 -2
  99. data/lib/jade/frontend/type_checking/error/recursive_derivation.rb +25 -0
  100. data/lib/jade/frontend/type_checking/error/type_mismatch.rb +10 -2
  101. data/lib/jade/frontend/type_checking/error/unreachable_branch.rb +22 -0
  102. data/lib/jade/frontend/type_checking/error.rb +6 -0
  103. data/lib/jade/frontend/type_checking/inference/assign.rb +1 -1
  104. data/lib/jade/frontend/type_checking/inference/case_of.rb +21 -4
  105. data/lib/jade/frontend/type_checking/inference/division.rb +50 -0
  106. data/lib/jade/frontend/type_checking/inference/function_call.rb +47 -2
  107. data/lib/jade/frontend/type_checking/inference/lambda.rb +1 -1
  108. data/lib/jade/frontend/type_checking/inference/pattern.rb +35 -0
  109. data/lib/jade/frontend/type_checking/inference/type_alias_declaration.rb +18 -0
  110. data/lib/jade/frontend/type_checking/inference.rb +2 -0
  111. data/lib/jade/frontend/type_checking/loader.rb +11 -0
  112. data/lib/jade/frontend/type_checking/port_resolution.rb +26 -8
  113. data/lib/jade/frontend/type_checking/substitution.rb +2 -2
  114. data/lib/jade/frontend/type_checking.rb +3 -1
  115. data/lib/jade/frontend/usage_analysis.rb +5 -1
  116. data/lib/jade/interop/boundary.rb +64 -24
  117. data/lib/jade/interop/error.rb +35 -7
  118. data/lib/jade/interop/lowering.rb +8 -2
  119. data/lib/jade/lsp/converters.rb +83 -2
  120. data/lib/jade/lsp/handlers.rb +122 -25
  121. data/lib/jade/lsp/snippets.rb +12 -0
  122. data/lib/jade/lsp/state.rb +11 -4
  123. data/lib/jade/module_loader/build.rb +36 -0
  124. data/lib/jade/module_loader.rb +1 -0
  125. data/lib/jade/parsing/combinators.rb +78 -2
  126. data/lib/jade/parsing/error.rb +43 -6
  127. data/lib/jade/parsing/type.rb +5 -3
  128. data/lib/jade/parsing.rb +140 -26
  129. data/lib/jade/runtime.rb +32 -13
  130. data/lib/jade/source.rb +6 -2
  131. data/lib/jade/stdlib/basics.rb +22 -3
  132. data/lib/jade/stdlib/char.rb +2 -0
  133. data/lib/jade/stdlib/clock.rb +6 -2
  134. data/lib/jade/stdlib/decimal.rb +51 -14
  135. data/lib/jade/stdlib/intrinsics.rb +59 -6
  136. data/lib/jade/stdlib/list.rb +37 -1
  137. data/lib/jade/stdlib/number.rb +47 -0
  138. data/lib/jade/stdlib/range.rb +211 -0
  139. data/lib/jade/stdlib.rb +11 -4
  140. data/lib/jade/symbol/alias.rb +11 -0
  141. data/lib/jade/symbol/parser.rb +1 -1
  142. data/lib/jade/symbol.rb +13 -1
  143. data/lib/jade/task.rb +74 -56
  144. data/lib/jade/type/anonymous_record.rb +11 -2
  145. data/lib/jade/type/application.rb +11 -2
  146. data/lib/jade/type/base.rb +26 -0
  147. data/lib/jade/type/function.rb +11 -2
  148. data/lib/jade/type.rb +36 -10
  149. data/lib/jade/version.rb +1 -1
  150. data/lib/jade.rb +1 -0
  151. metadata +35 -3
  152. data/lib/jade/frontend/type_checking/constraints/deriving/assignable.rb +0 -170
@@ -1,170 +0,0 @@
1
- module Jade
2
- module Frontend
3
- module TypeChecking
4
- module Constraints
5
- module Deriving
6
- # jade-sql's interface, derived here rather than there: the
7
- # deriving framework is not extensible, and this stays inert
8
- # without jade-sql, since nothing else names the interface.
9
- module Assignable
10
- extend self
11
- include Helpers
12
-
13
- INTERFACE = 'Sql.Assignable'
14
- ASSIGNMENT = 'Sql.Assignment'
15
- ASSIGNMENT_FIELDS = %w[col value_sql params].freeze
16
-
17
- def supports?(interface) = interface == INTERFACE
18
-
19
- def derive(constraint, registry, entry_name, &lookup)
20
- return failed(constraint, entry_name) unless assignment_matches?(registry)
21
-
22
- case constraint.type
23
- in Type::Application(constructor: Type::Constructor(name:), args:)
24
- Symbol
25
- .type_ref_from_qualified_name(name)
26
- .then { registry.lookup(it) }
27
- .then { derive_for(constraint, it, args, registry, lookup, entry_name) }
28
-
29
- else
30
- failed(constraint, entry_name)
31
- end
32
- end
33
-
34
- private
35
-
36
- # The interface is matched by name, so some other module called
37
- # `Sql` would otherwise be derived against as though it were
38
- # jade-sql — building its Assignment with the wrong arity, and
39
- # failing at runtime rather than here.
40
- def assignment_matches?(registry)
41
- Symbol
42
- .type_ref_from_qualified_name(ASSIGNMENT)
43
- .then { registry.lookup(it) }
44
- .then do
45
- it in Symbol::Struct(record_type: { fields: }) and
46
- fields.keys.map(&:to_s) == ASSIGNMENT_FIELDS
47
- end
48
- end
49
-
50
- def derive_for(constraint, symbol, args, registry, lookup, entry_name)
51
- case symbol
52
- in Symbol::Union if args.empty? && single_payload?(symbol, registry)
53
- derive_union(constraint, symbol, registry, lookup, entry_name)
54
-
55
- in Symbol::Struct
56
- derive_struct(constraint, symbol, args, registry, lookup, entry_name)
57
-
58
- else
59
- failed(constraint, entry_name)
60
- end
61
- end
62
-
63
- # One column per variant, so each variant carries exactly the
64
- # value that column is set to.
65
- def single_payload?(union_sym, registry)
66
- variants(union_sym, registry)
67
- .then { it.any? && it.all? { it.args.size == 1 } }
68
- end
69
-
70
- def derive_union(constraint, union_sym, registry, lookup, entry_name)
71
- vs = variants(union_sym, registry)
72
-
73
- vs
74
- .map { encodable_dep(it, registry) }
75
- .map { lookup.call(it) }
76
- .then { Results.sequence(it) }
77
- .map { implementation(constraint, union_body(vs), it) }
78
- end
79
-
80
- def derive_struct(constraint, struct_sym, args, registry, lookup, entry_name)
81
- fields = struct_fields(struct_sym, args, registry)
82
-
83
- fields
84
- .map { |_, type| Type.constraint('Encode.Encodable', type, nil) }
85
- .map { lookup.call(it) }
86
- .then { Results.sequence(it) }
87
- .map { implementation(constraint, struct_body(fields), it) }
88
- end
89
-
90
- def struct_body(fields)
91
- fields
92
- .each_with_index
93
- .map { |(name, _), idx| field_assignment(name, idx) }
94
- .then { [:list, it] }
95
- end
96
-
97
- def field_assignment(name, idx)
98
- [:call,
99
- [:struct_constructor, ASSIGNMENT, 3],
100
- [
101
- column_name(name),
102
- '?',
103
- [:list,
104
- [[:call, [:impl_arg, idx, 'encoder'], [[:access, [:var, 'f'], name.to_s]]]],
105
- ],
106
- ],
107
- ]
108
- end
109
-
110
- def column_name(field)
111
- field
112
- .to_s
113
- .then { it.end_with?('_') ? it.delete_suffix('_') : it }
114
- .then { Lexer::KEYWORDS.include?(it) ? it : field.to_s }
115
- end
116
-
117
- def encodable_dep(variant, registry)
118
- variant
119
- .args
120
- .first
121
- .then { instantiate(it, {}, registry) }
122
- .then { Type.constraint('Encode.Encodable', it, nil) }
123
- end
124
-
125
- def union_body(variants)
126
- variants
127
- .each_with_index
128
- .map { |v, idx| [[:constructor, v.qualified_name, ['x']], [assignment(v, idx)]] }
129
- .then { [:case, [:var, 'f'], it] }
130
- end
131
-
132
- def assignment(variant, idx)
133
- [:call,
134
- [:struct_constructor, ASSIGNMENT, 3],
135
- [
136
- wire_name(variant),
137
- '?',
138
- [:list, [[:call, [:impl_arg, idx, 'encoder'], [[:var, 'x']]]]],
139
- ],
140
- ]
141
- .then { [:list, [it]] }
142
- end
143
-
144
- def failed(constraint, entry_name)
145
- Err[
146
- Error::DerivationFailed.new(
147
- entry_name, constraint.origin&.range, constraint:, trace: [],
148
- )
149
- ]
150
- end
151
-
152
- def implementation(constraint, body, deps)
153
- Symbol::Implementation.new(
154
- module_name: nil,
155
- interface: Symbol.type_ref_from_qualified_name(constraint.interface),
156
- type: constraint.type,
157
- type_params: [],
158
- constraints: [],
159
- functions: { 'to_assigns' => Symbol::DerivedFunction.new(params: ['f'], body:) },
160
- deps:,
161
- extends: [],
162
- decl_span: nil,
163
- )
164
- end
165
- end
166
- end
167
- end
168
- end
169
- end
170
- end