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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +23 -0
- data/LICENSE +21 -0
- data/README.md +386 -0
- data/exe/jade +6 -0
- data/lib/jade/ast/node.rb +44 -0
- data/lib/jade/ast/nodes.rb +35 -0
- data/lib/jade/ast/pretty_printer.rb +50 -0
- data/lib/jade/ast.rb +723 -0
- data/lib/jade/calendar/runtime.rb +15 -0
- data/lib/jade/cli/fmt.rb +96 -0
- data/lib/jade/cli/lsp.rb +13 -0
- data/lib/jade/cli/q.rb +113 -0
- data/lib/jade/cli.rb +43 -0
- data/lib/jade/clock/runtime.rb +13 -0
- data/lib/jade/codegen/boundary/cache.rb +94 -0
- data/lib/jade/codegen/boundary/specialized/list.rb +65 -0
- data/lib/jade/codegen/boundary/specialized/maybe.rb +40 -0
- data/lib/jade/codegen/boundary/specialized/record.rb +165 -0
- data/lib/jade/codegen/boundary/specialized/scalar.rb +67 -0
- data/lib/jade/codegen/boundary/specialized.rb +106 -0
- data/lib/jade/codegen/boundary.rb +189 -0
- data/lib/jade/codegen/constructor_reference.rb +18 -0
- data/lib/jade/codegen/context.rb +96 -0
- data/lib/jade/codegen/emitter.rb +81 -0
- data/lib/jade/codegen/function_call.rb +367 -0
- data/lib/jade/codegen/function_declaration.rb +199 -0
- data/lib/jade/codegen/helpers.rb +103 -0
- data/lib/jade/codegen/implementation.rb +178 -0
- data/lib/jade/codegen/inline.rb +89 -0
- data/lib/jade/codegen/inlines.rb +326 -0
- data/lib/jade/codegen/method_names.rb +54 -0
- data/lib/jade/codegen/pattern/constructor.rb +57 -0
- data/lib/jade/codegen/port_decoder.rb +77 -0
- data/lib/jade/codegen/pretty.rb +53 -0
- data/lib/jade/codegen/transforms/fold_shape.rb +222 -0
- data/lib/jade/codegen/transforms/self_call.rb +80 -0
- data/lib/jade/codegen/transforms/tail_call.rb +120 -0
- data/lib/jade/codegen/variant_declaration.rb +41 -0
- data/lib/jade/codegen.rb +400 -0
- data/lib/jade/compiler.rb +69 -0
- data/lib/jade/decode.rb +320 -0
- data/lib/jade/diagnostics/renderer.rb +121 -0
- data/lib/jade/diagnostics.rb +77 -0
- data/lib/jade/did_you_mean.rb +16 -0
- data/lib/jade/entry.rb +177 -0
- data/lib/jade/error.rb +72 -0
- data/lib/jade/formatter/accesses.rb +37 -0
- data/lib/jade/formatter/bindings.rb +29 -0
- data/lib/jade/formatter/body.rb +50 -0
- data/lib/jade/formatter/calls.rb +51 -0
- data/lib/jade/formatter/case_of.rb +31 -0
- data/lib/jade/formatter/case_of_branch.rb +59 -0
- data/lib/jade/formatter/collections.rb +78 -0
- data/lib/jade/formatter/declarations.rb +178 -0
- data/lib/jade/formatter/exposing.rb +48 -0
- data/lib/jade/formatter/function_declaration.rb +72 -0
- data/lib/jade/formatter/helper.rb +122 -0
- data/lib/jade/formatter/if_then_else.rb +64 -0
- data/lib/jade/formatter/infix_application.rb +69 -0
- data/lib/jade/formatter/lambda.rb +50 -0
- data/lib/jade/formatter/leaves.rb +111 -0
- data/lib/jade/formatter/module_node.rb +26 -0
- data/lib/jade/formatter/pattern.rb +61 -0
- data/lib/jade/formatter/type.rb +67 -0
- data/lib/jade/formatter.rb +38 -0
- data/lib/jade/frontend/comment_attacher.rb +121 -0
- data/lib/jade/frontend/desugaring/placeholder.rb +39 -0
- data/lib/jade/frontend/desugaring/resolved.rb +63 -0
- data/lib/jade/frontend/desugaring.rb +217 -0
- data/lib/jade/frontend/fixity_fixer.rb +209 -0
- data/lib/jade/frontend/forward_declaration/body.rb +30 -0
- data/lib/jade/frontend/forward_declaration/error/bad_import.rb +19 -0
- data/lib/jade/frontend/forward_declaration/error/exposed_type_not_found.rb +18 -0
- data/lib/jade/frontend/forward_declaration/error/exposed_value_not_found.rb +18 -0
- data/lib/jade/frontend/forward_declaration/error/module_not_found.rb +18 -0
- data/lib/jade/frontend/forward_declaration/error/private_type_expansion.rb +19 -0
- data/lib/jade/frontend/forward_declaration/error/tuple_arity_overflow.rb +25 -0
- data/lib/jade/frontend/forward_declaration/error/type_not_found.rb +29 -0
- data/lib/jade/frontend/forward_declaration/error/type_not_lowerable.rb +16 -0
- data/lib/jade/frontend/forward_declaration/error/unknown_extends_interface.rb +18 -0
- data/lib/jade/frontend/forward_declaration/error.rb +11 -0
- data/lib/jade/frontend/forward_declaration/function_declaration.rb +32 -0
- data/lib/jade/frontend/forward_declaration/helper.rb +91 -0
- data/lib/jade/frontend/forward_declaration/implementation.rb +63 -0
- data/lib/jade/frontend/forward_declaration/implementation_function.rb +39 -0
- data/lib/jade/frontend/forward_declaration/import_declaration.rb +115 -0
- data/lib/jade/frontend/forward_declaration/interface_declaration.rb +66 -0
- data/lib/jade/frontend/forward_declaration/interop_import_declaration.rb +99 -0
- data/lib/jade/frontend/forward_declaration/module.rb +98 -0
- data/lib/jade/frontend/forward_declaration/struct_declaration.rb +42 -0
- data/lib/jade/frontend/forward_declaration/type_declaration.rb +42 -0
- data/lib/jade/frontend/forward_declaration.rb +71 -0
- data/lib/jade/frontend/pattern_analysis/exhaustiveness.rb +65 -0
- data/lib/jade/frontend/pattern_analysis/matrix.rb +235 -0
- data/lib/jade/frontend/pattern_analysis.rb +40 -0
- data/lib/jade/frontend/semantic_analysis/assign.rb +20 -0
- data/lib/jade/frontend/semantic_analysis/body.rb +33 -0
- data/lib/jade/frontend/semantic_analysis/case_of.rb +19 -0
- data/lib/jade/frontend/semantic_analysis/case_of_branch.rb +20 -0
- data/lib/jade/frontend/semantic_analysis/char_literal.rb +14 -0
- data/lib/jade/frontend/semantic_analysis/constructor_reference.rb +64 -0
- data/lib/jade/frontend/semantic_analysis/error/circular_extends.rb +19 -0
- data/lib/jade/frontend/semantic_analysis/error/constant_not_callable.rb +24 -0
- data/lib/jade/frontend/semantic_analysis/error/constructor_not_found.rb +34 -0
- data/lib/jade/frontend/semantic_analysis/error/constructor_pattern_arity_mismatch.rb +24 -0
- data/lib/jade/frontend/semantic_analysis/error/duplicate_field.rb +18 -0
- data/lib/jade/frontend/semantic_analysis/error/duplicate_function_declaration.rb +25 -0
- data/lib/jade/frontend/semantic_analysis/error/duplicate_record_field.rb +19 -0
- data/lib/jade/frontend/semantic_analysis/error/invalid_list_rest_pattern.rb +21 -0
- data/lib/jade/frontend/semantic_analysis/error/kwargs_on_non_constructor.rb +17 -0
- data/lib/jade/frontend/semantic_analysis/error/missing_exposing_clause.rb +17 -0
- data/lib/jade/frontend/semantic_analysis/error/missing_extends_implementation.rb +21 -0
- data/lib/jade/frontend/semantic_analysis/error/missing_field.rb +20 -0
- data/lib/jade/frontend/semantic_analysis/error/missing_implementation_function.rb +19 -0
- data/lib/jade/frontend/semantic_analysis/error/module_not_found.rb +22 -0
- data/lib/jade/frontend/semantic_analysis/error/nested_task_port.rb +19 -0
- data/lib/jade/frontend/semantic_analysis/error/non_task_port.rb +22 -0
- data/lib/jade/frontend/semantic_analysis/error/orphan_implementation.rb +20 -0
- data/lib/jade/frontend/semantic_analysis/error/predicate_must_return_bool.rb +22 -0
- data/lib/jade/frontend/semantic_analysis/error/predicate_name_not_allowed.rb +25 -0
- data/lib/jade/frontend/semantic_analysis/error/shadowing_error.rb +22 -0
- data/lib/jade/frontend/semantic_analysis/error/type_args_mismatch.rb +25 -0
- data/lib/jade/frontend/semantic_analysis/error/type_param_required.rb +19 -0
- data/lib/jade/frontend/semantic_analysis/error/unbound_type_variable.rb +22 -0
- data/lib/jade/frontend/semantic_analysis/error/undefined_variable.rb +29 -0
- data/lib/jade/frontend/semantic_analysis/error/unknown_field.rb +20 -0
- data/lib/jade/frontend/semantic_analysis/error/unknown_implementation_function.rb +19 -0
- data/lib/jade/frontend/semantic_analysis/error/unused_interface_type_param.rb +24 -0
- data/lib/jade/frontend/semantic_analysis/error/value_not_exposed.rb +23 -0
- data/lib/jade/frontend/semantic_analysis/error/variable_not_found.rb +25 -0
- data/lib/jade/frontend/semantic_analysis/error.rb +40 -0
- data/lib/jade/frontend/semantic_analysis/function_call.rb +60 -0
- data/lib/jade/frontend/semantic_analysis/function_declaration.rb +58 -0
- data/lib/jade/frontend/semantic_analysis/grouping.rb +17 -0
- data/lib/jade/frontend/semantic_analysis/helper.rb +152 -0
- data/lib/jade/frontend/semantic_analysis/if_then_else.rb +20 -0
- data/lib/jade/frontend/semantic_analysis/implementation.rb +143 -0
- data/lib/jade/frontend/semantic_analysis/implementation_function.rb +16 -0
- data/lib/jade/frontend/semantic_analysis/import_declaration.rb +14 -0
- data/lib/jade/frontend/semantic_analysis/interface_declaration.rb +45 -0
- data/lib/jade/frontend/semantic_analysis/interop_import_declaration.rb +69 -0
- data/lib/jade/frontend/semantic_analysis/keyed_call/validation.rb +109 -0
- data/lib/jade/frontend/semantic_analysis/keyed_call.rb +88 -0
- data/lib/jade/frontend/semantic_analysis/lambda.rb +23 -0
- data/lib/jade/frontend/semantic_analysis/list.rb +17 -0
- data/lib/jade/frontend/semantic_analysis/literal.rb +23 -0
- data/lib/jade/frontend/semantic_analysis/member_access.rb +87 -0
- data/lib/jade/frontend/semantic_analysis/module_node.rb +27 -0
- data/lib/jade/frontend/semantic_analysis/pattern_binding.rb +27 -0
- data/lib/jade/frontend/semantic_analysis/pattern_constructor.rb +47 -0
- data/lib/jade/frontend/semantic_analysis/pattern_list.rb +33 -0
- data/lib/jade/frontend/semantic_analysis/pattern_literal.rb +17 -0
- data/lib/jade/frontend/semantic_analysis/pattern_record.rb +25 -0
- data/lib/jade/frontend/semantic_analysis/pattern_wildcard.rb +14 -0
- data/lib/jade/frontend/semantic_analysis/qualified_access.rb +14 -0
- data/lib/jade/frontend/semantic_analysis/record_access.rb +14 -0
- data/lib/jade/frontend/semantic_analysis/record_field.rb +17 -0
- data/lib/jade/frontend/semantic_analysis/record_literal.rb +21 -0
- data/lib/jade/frontend/semantic_analysis/record_update.rb +21 -0
- data/lib/jade/frontend/semantic_analysis/struct_declaration.rb +44 -0
- data/lib/jade/frontend/semantic_analysis/tuple.rb +17 -0
- data/lib/jade/frontend/semantic_analysis/type_declaration.rb +69 -0
- data/lib/jade/frontend/semantic_analysis/variable_reference.rb +27 -0
- data/lib/jade/frontend/semantic_analysis/variant_declaration.rb +18 -0
- data/lib/jade/frontend/semantic_analysis.rb +161 -0
- data/lib/jade/frontend/type_checking/canonicalize.rb +97 -0
- data/lib/jade/frontend/type_checking/constraints/deriving/decodable.rb +144 -0
- data/lib/jade/frontend/type_checking/constraints/deriving/encodable.rb +144 -0
- data/lib/jade/frontend/type_checking/constraints/deriving/eq.rb +265 -0
- data/lib/jade/frontend/type_checking/constraints/deriving/helpers.rb +59 -0
- data/lib/jade/frontend/type_checking/constraints/deriving.rb +28 -0
- data/lib/jade/frontend/type_checking/constraints.rb +101 -0
- data/lib/jade/frontend/type_checking/definition.rb +71 -0
- data/lib/jade/frontend/type_checking/env.rb +79 -0
- data/lib/jade/frontend/type_checking/error/case_of_branches_type_mismatch.rb +19 -0
- data/lib/jade/frontend/type_checking/error/derivation_failed.rb +21 -0
- data/lib/jade/frontend/type_checking/error/function_body_type_mismatch.rb +23 -0
- data/lib/jade/frontend/type_checking/error/function_call_type_mismatch.rb +37 -0
- data/lib/jade/frontend/type_checking/error/if_branch_type_mismatch.rb +19 -0
- data/lib/jade/frontend/type_checking/error/if_branches_type_mismatch.rb +18 -0
- data/lib/jade/frontend/type_checking/error/if_condition_type_mismatch.rb +17 -0
- data/lib/jade/frontend/type_checking/error/implementation_type_mismatch.rb +20 -0
- data/lib/jade/frontend/type_checking/error/list_item_type_mismatch.rb +19 -0
- data/lib/jade/frontend/type_checking/error/missing_implementation.rb +20 -0
- data/lib/jade/frontend/type_checking/error/missing_patterns.rb +26 -0
- data/lib/jade/frontend/type_checking/error/pattern_type_mismatch.rb +13 -0
- data/lib/jade/frontend/type_checking/error/port_not_decodable.rb +38 -0
- data/lib/jade/frontend/type_checking/error/record_access_type_mismatch.rb +14 -0
- data/lib/jade/frontend/type_checking/error/type_mismatch.rb +23 -0
- data/lib/jade/frontend/type_checking/error/unresolved_constraint.rb +20 -0
- data/lib/jade/frontend/type_checking/error.rb +18 -0
- data/lib/jade/frontend/type_checking/expected.rb +23 -0
- data/lib/jade/frontend/type_checking/generalization.rb +17 -0
- data/lib/jade/frontend/type_checking/generalizer.rb +38 -0
- data/lib/jade/frontend/type_checking/inference/assign.rb +58 -0
- data/lib/jade/frontend/type_checking/inference/body.rb +45 -0
- data/lib/jade/frontend/type_checking/inference/case_of.rb +102 -0
- data/lib/jade/frontend/type_checking/inference/constructor_reference.rb +21 -0
- data/lib/jade/frontend/type_checking/inference/function_call.rb +132 -0
- data/lib/jade/frontend/type_checking/inference/function_declaration.rb +70 -0
- data/lib/jade/frontend/type_checking/inference/grouping.rb +18 -0
- data/lib/jade/frontend/type_checking/inference/helpers.rb +34 -0
- data/lib/jade/frontend/type_checking/inference/if_then_else.rb +46 -0
- data/lib/jade/frontend/type_checking/inference/implementation.rb +150 -0
- data/lib/jade/frontend/type_checking/inference/import_declaration.rb +19 -0
- data/lib/jade/frontend/type_checking/inference/interface_declaration.rb +18 -0
- data/lib/jade/frontend/type_checking/inference/interop_import_declaration.rb +18 -0
- data/lib/jade/frontend/type_checking/inference/lambda.rb +87 -0
- data/lib/jade/frontend/type_checking/inference/list.rb +52 -0
- data/lib/jade/frontend/type_checking/inference/literal.rb +24 -0
- data/lib/jade/frontend/type_checking/inference/module.rb +18 -0
- data/lib/jade/frontend/type_checking/inference/pattern.rb +135 -0
- data/lib/jade/frontend/type_checking/inference/qualified_access.rb +23 -0
- data/lib/jade/frontend/type_checking/inference/record_access.rb +35 -0
- data/lib/jade/frontend/type_checking/inference/record_field.rb +19 -0
- data/lib/jade/frontend/type_checking/inference/record_literal.rb +24 -0
- data/lib/jade/frontend/type_checking/inference/record_update.rb +37 -0
- data/lib/jade/frontend/type_checking/inference/struct_declaration.rb +18 -0
- data/lib/jade/frontend/type_checking/inference/type_declaration.rb +18 -0
- data/lib/jade/frontend/type_checking/inference/variable_reference.rb +27 -0
- data/lib/jade/frontend/type_checking/inference.rb +27 -0
- data/lib/jade/frontend/type_checking/instantiation.rb +24 -0
- data/lib/jade/frontend/type_checking/loader.rb +80 -0
- data/lib/jade/frontend/type_checking/placeholder.rb +12 -0
- data/lib/jade/frontend/type_checking/port_resolution.rb +123 -0
- data/lib/jade/frontend/type_checking/result.rb +41 -0
- data/lib/jade/frontend/type_checking/scheme.rb +20 -0
- data/lib/jade/frontend/type_checking/state.rb +52 -0
- data/lib/jade/frontend/type_checking/substitution.rb +93 -0
- data/lib/jade/frontend/type_checking/unification.rb +282 -0
- data/lib/jade/frontend/type_checking/var_gen.rb +33 -0
- data/lib/jade/frontend/type_checking.rb +129 -0
- data/lib/jade/frontend/unused_analysis.rb +41 -0
- data/lib/jade/frontend/usage_analysis/reference_index.rb +53 -0
- data/lib/jade/frontend/usage_analysis.rb +195 -0
- data/lib/jade/frontend.rb +101 -0
- data/lib/jade/interop/boundary.rb +68 -0
- data/lib/jade/interop/error.rb +84 -0
- data/lib/jade/interop/lowering/error.rb +32 -0
- data/lib/jade/interop/lowering.rb +53 -0
- data/lib/jade/interop/runtime.rb +24 -0
- data/lib/jade/interop.rb +1 -0
- data/lib/jade/lexer.rb +189 -0
- data/lib/jade/lsp/converters.rb +542 -0
- data/lib/jade/lsp/handlers.rb +340 -0
- data/lib/jade/lsp/server.rb +63 -0
- data/lib/jade/lsp/snippets.rb +100 -0
- data/lib/jade/lsp/state.rb +25 -0
- data/lib/jade/lsp.rb +16 -0
- data/lib/jade/module_loader/cache.rb +56 -0
- data/lib/jade/module_loader/dependency_graph.rb +23 -0
- data/lib/jade/module_loader/dependency_resolver.rb +48 -0
- data/lib/jade/module_loader/normalize.rb +34 -0
- data/lib/jade/module_loader/topological_sort.rb +41 -0
- data/lib/jade/module_loader.rb +127 -0
- data/lib/jade/parsing/combinators.rb +291 -0
- data/lib/jade/parsing/error.rb +154 -0
- data/lib/jade/parsing/token.rb +12 -0
- data/lib/jade/parsing/type.rb +92 -0
- data/lib/jade/parsing.rb +674 -0
- data/lib/jade/port.rb +1 -0
- data/lib/jade/registry.rb +79 -0
- data/lib/jade/result.rb +121 -0
- data/lib/jade/runtime.rb +127 -0
- data/lib/jade/source.rb +62 -0
- data/lib/jade/stdlib/basics.rb +214 -0
- data/lib/jade/stdlib/bytes.rb +70 -0
- data/lib/jade/stdlib/calendar.rb +405 -0
- data/lib/jade/stdlib/char.rb +27 -0
- data/lib/jade/stdlib/clock.rb +342 -0
- data/lib/jade/stdlib/compiled.rb +48 -0
- data/lib/jade/stdlib/decode/params.rb +154 -0
- data/lib/jade/stdlib/decode.rb +315 -0
- data/lib/jade/stdlib/dict.rb +134 -0
- data/lib/jade/stdlib/encode.rb +143 -0
- data/lib/jade/stdlib/intrinsics.rb +280 -0
- data/lib/jade/stdlib/list.rb +214 -0
- data/lib/jade/stdlib/maybe.rb +73 -0
- data/lib/jade/stdlib/result.rb +131 -0
- data/lib/jade/stdlib/set.rb +123 -0
- data/lib/jade/stdlib/string.rb +65 -0
- data/lib/jade/stdlib/task.rb +55 -0
- data/lib/jade/stdlib/tuple.rb +21 -0
- data/lib/jade/stdlib.rb +112 -0
- data/lib/jade/symbol/anonymous_record.rb +7 -0
- data/lib/jade/symbol/base.rb +15 -0
- data/lib/jade/symbol/constructor.rb +11 -0
- data/lib/jade/symbol/derived_function.rb +5 -0
- data/lib/jade/symbol/function.rb +15 -0
- data/lib/jade/symbol/function_type.rb +7 -0
- data/lib/jade/symbol/implementation.rb +17 -0
- data/lib/jade/symbol/implementation_template.rb +13 -0
- data/lib/jade/symbol/interface.rb +11 -0
- data/lib/jade/symbol/interface_function.rb +18 -0
- data/lib/jade/symbol/interop_function.rb +22 -0
- data/lib/jade/symbol/lambda.rb +7 -0
- data/lib/jade/symbol/parser.rb +79 -0
- data/lib/jade/symbol/partial_application.rb +7 -0
- data/lib/jade/symbol/record_type.rb +8 -0
- data/lib/jade/symbol/stdlib_function.rb +15 -0
- data/lib/jade/symbol/stdlib_implementation.rb +7 -0
- data/lib/jade/symbol/struct.rb +15 -0
- data/lib/jade/symbol/type_application.rb +8 -0
- data/lib/jade/symbol/type_ref.rb +11 -0
- data/lib/jade/symbol/union.rb +15 -0
- data/lib/jade/symbol/value_ref.rb +15 -0
- data/lib/jade/symbol/variable.rb +7 -0
- data/lib/jade/symbol/variant.rb +11 -0
- data/lib/jade/symbol.rb +162 -0
- data/lib/jade/task.rb +103 -0
- data/lib/jade/tasks/rspec.rb +266 -0
- data/lib/jade/tasks.rb +70 -0
- data/lib/jade/type/anonymous_record.rb +33 -0
- data/lib/jade/type/application.rb +21 -0
- data/lib/jade/type/base.rb +9 -0
- data/lib/jade/type/constraint.rb +17 -0
- data/lib/jade/type/constructor.rb +19 -0
- data/lib/jade/type/function.rb +18 -0
- data/lib/jade/type/partial_application.rb +17 -0
- data/lib/jade/type/unit.rb +15 -0
- data/lib/jade/type/var.rb +21 -0
- data/lib/jade/type.rb +259 -0
- data/lib/jade/version.rb +3 -0
- data/lib/jade.rb +55 -0
- metadata +387 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require 'jade/frontend/type_checking/placeholder'
|
|
2
|
+
require 'jade/frontend/type_checking/scheme'
|
|
3
|
+
require 'jade/frontend/type_checking/var_gen'
|
|
4
|
+
|
|
5
|
+
module Jade
|
|
6
|
+
module Frontend
|
|
7
|
+
module TypeChecking
|
|
8
|
+
Env = Data.define(
|
|
9
|
+
:entry_name, :bindings, :substitution,
|
|
10
|
+
:definitions, :var_gen, :node_types,
|
|
11
|
+
) do
|
|
12
|
+
def self.empty(var_gen = VarGen.new)
|
|
13
|
+
Env[nil, {}, Substitution::EMPTY, {}, var_gen, {}]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def fresh
|
|
17
|
+
var_gen.fresh
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def bind(key, value)
|
|
21
|
+
bindings
|
|
22
|
+
.merge(key => value)
|
|
23
|
+
.then { with(bindings: it) }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def pin_type(node_id, type)
|
|
27
|
+
with(node_types: node_types.merge(node_id => type))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Post-finalize, apply the env's substitution to every pinned
|
|
31
|
+
# type so stored types are canonical (no leftover Type::Var that
|
|
32
|
+
# the substitution would resolve).
|
|
33
|
+
def canonicalize_node_types
|
|
34
|
+
node_types
|
|
35
|
+
.transform_values { substitution.apply(it) }
|
|
36
|
+
.then { with(node_types: it) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def define(key, value)
|
|
40
|
+
definitions
|
|
41
|
+
.merge(key => value)
|
|
42
|
+
.then { with(definitions: it) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def lookup(key)
|
|
46
|
+
binding = bindings[key]
|
|
47
|
+
|
|
48
|
+
type, constraints =
|
|
49
|
+
case bindings[key]
|
|
50
|
+
in Scheme => scheme
|
|
51
|
+
Instantiation.instantiate(scheme, var_gen)
|
|
52
|
+
|
|
53
|
+
in Placeholder => placeholder
|
|
54
|
+
Scheme[placeholder.free_vars, placeholder.type, placeholder.constraints]
|
|
55
|
+
.then { Instantiation.instantiate(it, var_gen) }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
Result.init(type, constraints)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def lookup_def(key)
|
|
62
|
+
definitions[key]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def free_vars
|
|
66
|
+
bindings
|
|
67
|
+
.values
|
|
68
|
+
.flat_map(&:free_vars)
|
|
69
|
+
.flat_map { substitution.apply(it).unbound_vars }
|
|
70
|
+
.uniq(&:id)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def composose_substitution(sub)
|
|
74
|
+
with(substitution: substitution.compose(sub))
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class CaseOfBranchesTypeMismatch < Error::TypeMismatch
|
|
6
|
+
def initialize(entry, span, expected:, actual:, actual_index:)
|
|
7
|
+
super
|
|
8
|
+
@actual_index = actual_index
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def message
|
|
12
|
+
"First branch of this case statement is #{@expected} " +
|
|
13
|
+
"but #{ordinal(@actual_index)} branch is #{@actual}"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class DerivationFailed < Jade::Error
|
|
6
|
+
attr_reader :constraint
|
|
7
|
+
|
|
8
|
+
def initialize(entry, span, constraint:, trace: [])
|
|
9
|
+
@constraint = constraint
|
|
10
|
+
@trace = trace
|
|
11
|
+
super(entry:, span:)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def message
|
|
15
|
+
"#{@constraint.interface} cannot be derived for #{@constraint.type}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class FunctionBodyTypeMismatch < TypeMismatch
|
|
6
|
+
def initialize(entry, span, expected:, actual:, function_name:)
|
|
7
|
+
super
|
|
8
|
+
@function_name = function_name
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def message
|
|
12
|
+
"There's a problem with the body of `#{@function_name}` definition: " ++
|
|
13
|
+
"it returns #{@actual} but its signature says it should be #{@expected}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def label
|
|
17
|
+
"returns #{@actual}, expected #{@expected}"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class FunctionCallTypeMismatch < TypeMismatch
|
|
6
|
+
def initialize(entry, span, expected:, actual:, infix:)
|
|
7
|
+
super
|
|
8
|
+
@infix = infix
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def message
|
|
12
|
+
case @infix
|
|
13
|
+
in AST::InfixOperator(value:)
|
|
14
|
+
infix_error(value)
|
|
15
|
+
else
|
|
16
|
+
"Function call mismatch, expected #{@expected} but found #{@actual}"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def infix_error(operator)
|
|
23
|
+
if @expected.args.first != @actual.args.first
|
|
24
|
+
return "Left side of (#{operator}) expects #{@expected.args.first} but found #{@actual.args.first}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if @expected.args.last != @actual.args.last
|
|
28
|
+
return "Right side of (#{operator}) expects #{@expected.args.last} but found #{@actual.args.last}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
"Function call mismatch, expected #{@expected} but found #{@actual}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class IfBranchTypeMismatch < TypeMismatch
|
|
6
|
+
def initialize(entry, span, expected:, actual:, branch:)
|
|
7
|
+
super
|
|
8
|
+
@branch = branch == :then ? 'then' : 'else'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def message
|
|
12
|
+
"The #{@branch} branch of this if statement is expected to return" +
|
|
13
|
+
" #{@expected} but got #{@actual}"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class IfBranchesTypeMismatch < TypeMismatch
|
|
6
|
+
def initialize(entry, span, expected:, actual:)
|
|
7
|
+
super
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def message
|
|
11
|
+
"If branches must return the same type. The then branch produces " +
|
|
12
|
+
"#{@expected} but the else branch produces #{@actual}"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class IfConditionTypeMismatch < TypeMismatch
|
|
6
|
+
def initialize(entry, span, expected: Type.bool, actual:)
|
|
7
|
+
super
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def message
|
|
11
|
+
"If condition expects #{@expected} but found #{@actual}"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class ImplementationTypeMismatch < TypeMismatch
|
|
6
|
+
def initialize(entry, span, expected:, actual:, interface:, fn_name:)
|
|
7
|
+
super(entry, span, expected:, actual:)
|
|
8
|
+
@interface = interface
|
|
9
|
+
@fn_name = fn_name
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def message
|
|
13
|
+
"Implementation of #{@interface}.#{@fn_name}: " \
|
|
14
|
+
"expected #{@expected} but the provided function has type #{@actual}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class ListItemTypeMismatch < TypeMismatch
|
|
6
|
+
def initialize(entry, span, expected:, actual:, actual_index:)
|
|
7
|
+
super
|
|
8
|
+
@actual_index = actual_index
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def message
|
|
12
|
+
"The #{ordinal(@actual_index)} item does not match the previous items in the list, " +
|
|
13
|
+
"expected #{@expected} but found #{@actual}"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class MissingImplementation < Jade::Error
|
|
6
|
+
attr_reader :constraint
|
|
7
|
+
|
|
8
|
+
def initialize(entry, span, constraint:)
|
|
9
|
+
@constraint = constraint
|
|
10
|
+
super(entry:, span:)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def message
|
|
14
|
+
"No implementation of #{@constraint.interface} for #{@constraint.type}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class MissingPatterns < Jade::Error
|
|
6
|
+
def initialize(entry, span, missing_patterns:)
|
|
7
|
+
@missing_patterns = missing_patterns
|
|
8
|
+
super(entry:, span:)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def message
|
|
12
|
+
patterns_str = @missing_patterns
|
|
13
|
+
.map { |row| row.map(&:to_s).join(', ') }
|
|
14
|
+
.map { " #{it}" }
|
|
15
|
+
.join("\n")
|
|
16
|
+
"Pattern match is not exhaustive. Missing cases:\n#{patterns_str}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def label
|
|
20
|
+
"non-exhaustive pattern match"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class PortNotDecodable < Jade::Error
|
|
6
|
+
attr_reader :port_name, :arm, :type
|
|
7
|
+
|
|
8
|
+
def initialize(entry, span, port_name:, arm:, type:)
|
|
9
|
+
@port_name = port_name
|
|
10
|
+
@arm = arm
|
|
11
|
+
@type = type
|
|
12
|
+
super(entry:, span:)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def message
|
|
16
|
+
"Port `#{@port_name}` cannot decode its #{@arm} arm (`#{@type}`): " \
|
|
17
|
+
"no Decodable instance"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def label
|
|
21
|
+
"no Decodable instance for `#{@type}`"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def notes
|
|
25
|
+
[
|
|
26
|
+
Jade::Diagnostics::Annotation[
|
|
27
|
+
:help,
|
|
28
|
+
"implement Decodable for `#{@type}` so it can be decoded " \
|
|
29
|
+
"automatically, or declare the port with `Decode.Value` " \
|
|
30
|
+
"to skip auto-decoding",
|
|
31
|
+
],
|
|
32
|
+
]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class RecordAccessTypeMismatch < TypeMismatch
|
|
6
|
+
def message
|
|
7
|
+
"Something is off with this record access, it expects #{@expected} " +
|
|
8
|
+
"but found #{@actual}"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class TypeMismatch < Jade::Error
|
|
6
|
+
def initialize(entry, span, expected:, actual:, **)
|
|
7
|
+
@expected = expected
|
|
8
|
+
@actual = actual
|
|
9
|
+
super(entry:, span:)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def message
|
|
13
|
+
"Expected #{@expected} but got #{@actual}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def label
|
|
17
|
+
"expected #{@expected}, got #{@actual}"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Error
|
|
5
|
+
class UnresolvedConstraint < Jade::Error
|
|
6
|
+
attr_reader :constraint
|
|
7
|
+
|
|
8
|
+
def initialize(entry, span, constraint:)
|
|
9
|
+
@constraint = constraint
|
|
10
|
+
super(entry:, span:)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def message
|
|
14
|
+
"Unresolved constraint: #{@constraint.interface} #{@constraint.type}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'jade/error'
|
|
2
|
+
|
|
3
|
+
require 'jade/frontend/type_checking/error/type_mismatch'
|
|
4
|
+
|
|
5
|
+
require 'jade/frontend/type_checking/error/case_of_branches_type_mismatch'
|
|
6
|
+
require 'jade/frontend/type_checking/error/derivation_failed'
|
|
7
|
+
require 'jade/frontend/type_checking/error/function_body_type_mismatch'
|
|
8
|
+
require 'jade/frontend/type_checking/error/function_call_type_mismatch'
|
|
9
|
+
require 'jade/frontend/type_checking/error/if_branch_type_mismatch'
|
|
10
|
+
require 'jade/frontend/type_checking/error/if_branches_type_mismatch'
|
|
11
|
+
require 'jade/frontend/type_checking/error/if_condition_type_mismatch'
|
|
12
|
+
require 'jade/frontend/type_checking/error/missing_patterns'
|
|
13
|
+
require 'jade/frontend/type_checking/error/list_item_type_mismatch'
|
|
14
|
+
require 'jade/frontend/type_checking/error/pattern_type_mismatch'
|
|
15
|
+
require 'jade/frontend/type_checking/error/record_access_type_mismatch'
|
|
16
|
+
require 'jade/frontend/type_checking/error/unresolved_constraint'
|
|
17
|
+
require 'jade/frontend/type_checking/error/implementation_type_mismatch'
|
|
18
|
+
require 'jade/frontend/type_checking/error/missing_implementation'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
Expected = Data.define(:type, :authoritative) do
|
|
5
|
+
def check?
|
|
6
|
+
authoritative == true
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.check(type)
|
|
10
|
+
self[type, true]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.infer(type)
|
|
14
|
+
self[type, false]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def rigid_vars
|
|
18
|
+
check? ? type.unbound_vars : []
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Generalization
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
def generalize(env, type, constraints = [])
|
|
8
|
+
(type.unbound_vars + constraints.flat_map(&:unbound_vars))
|
|
9
|
+
.uniq(&:id)
|
|
10
|
+
.then { it - env.free_vars }
|
|
11
|
+
.then { Scheme[it, type, constraints] }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Generalizer
|
|
5
|
+
extend self
|
|
6
|
+
include Inference::Helpers
|
|
7
|
+
|
|
8
|
+
def generalize(env)
|
|
9
|
+
env
|
|
10
|
+
.bindings
|
|
11
|
+
.reduce(env) do |e, (k, binding)|
|
|
12
|
+
case binding
|
|
13
|
+
in Placeholder(type:, constraints:)
|
|
14
|
+
unbound_cs = constraints
|
|
15
|
+
.map { e.substitution.apply(it) }
|
|
16
|
+
.uniq
|
|
17
|
+
.select { it.unbound_vars.any? }
|
|
18
|
+
|
|
19
|
+
Generalization.
|
|
20
|
+
generalize(
|
|
21
|
+
# Remove the current placeholder and all Scheme bindings (local
|
|
22
|
+
# params/variables) so they don't pollute free_vars during
|
|
23
|
+
# generalization. Only other Placeholders contribute free_vars.
|
|
24
|
+
e.with(bindings: e.bindings.except(k).select { |_, v| v.is_a?(Placeholder) }),
|
|
25
|
+
e.substitution.apply(type),
|
|
26
|
+
unbound_cs,
|
|
27
|
+
)
|
|
28
|
+
.then { e.bind(k, it) }
|
|
29
|
+
else
|
|
30
|
+
|
|
31
|
+
next e
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'jade/frontend/pattern_analysis'
|
|
2
|
+
|
|
3
|
+
module Jade
|
|
4
|
+
module Frontend
|
|
5
|
+
module TypeChecking
|
|
6
|
+
module Inference
|
|
7
|
+
module Assign
|
|
8
|
+
extend Helpers
|
|
9
|
+
extend self
|
|
10
|
+
|
|
11
|
+
def infer(node, registry, state, expected)
|
|
12
|
+
node => AST::Assign(pattern:, expression:)
|
|
13
|
+
|
|
14
|
+
expr_state, expr_result = check(
|
|
15
|
+
expression,
|
|
16
|
+
registry,
|
|
17
|
+
state,
|
|
18
|
+
Expected.infer(state.fresh),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
pattern_state, _ = Pattern.infer(
|
|
22
|
+
pattern,
|
|
23
|
+
registry,
|
|
24
|
+
expr_state,
|
|
25
|
+
Expected.check(expr_result.type),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
final_state, residual_cs =
|
|
29
|
+
case pattern
|
|
30
|
+
in AST::Pattern::Binding(name:)
|
|
31
|
+
bind_with_residual(pattern_state, expr_state, expr_result, name)
|
|
32
|
+
else
|
|
33
|
+
[pattern_state, expr_result.constraints]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
PatternAnalysis::Exhaustiveness
|
|
37
|
+
.assert([pattern], pattern.range, final_state.env, registry, expr_result.type)
|
|
38
|
+
.then { final_state.add_errors(it) }
|
|
39
|
+
.unify_result(expr_result.with(constraints: residual_cs), expected.type)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
# Constraints whose vars are quantified into the new binding's scheme
|
|
45
|
+
# are captured by it; the rest propagate to the enclosing scope.
|
|
46
|
+
def bind_with_residual(pattern_state, expr_state, expr_result, name)
|
|
47
|
+
result = expr_result.apply(pattern_state.env.substitution)
|
|
48
|
+
scheme = generalize(expr_state.env, result.type, result.constraints)
|
|
49
|
+
|
|
50
|
+
result.constraints
|
|
51
|
+
.reject { |c| c.unbound_vars.any? { |v| scheme.quantified.any? { it.id == v.id } } }
|
|
52
|
+
.then { [pattern_state.bind(name, scheme), it] }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Jade
|
|
2
|
+
module Frontend
|
|
3
|
+
module TypeChecking
|
|
4
|
+
module Inference
|
|
5
|
+
module Body
|
|
6
|
+
extend Helpers
|
|
7
|
+
extend self
|
|
8
|
+
|
|
9
|
+
def infer(node, registry, state, expected)
|
|
10
|
+
node => AST::Body(expressions:)
|
|
11
|
+
|
|
12
|
+
*first_expressions, last_expression = expressions
|
|
13
|
+
|
|
14
|
+
first_state, first_cs = first_expressions
|
|
15
|
+
.reduce([state, []]) do |(acc, cs), expr|
|
|
16
|
+
new_state, result = check(
|
|
17
|
+
expr,
|
|
18
|
+
registry,
|
|
19
|
+
acc,
|
|
20
|
+
Expected.infer(state.fresh),
|
|
21
|
+
)
|
|
22
|
+
[new_state, cs + result.constraints]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
last_state, last_result = check(
|
|
26
|
+
last_expression,
|
|
27
|
+
registry,
|
|
28
|
+
first_state,
|
|
29
|
+
expected,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
first_cs
|
|
33
|
+
.map { last_state.env.substitution.apply(it) }
|
|
34
|
+
.then do
|
|
35
|
+
last_result
|
|
36
|
+
.with(constraints: it + last_result.constraints)
|
|
37
|
+
.then { |result| [last_state, result] }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|