1 # coding: utf-8
2 # frozen_string_literal: true
3
4
5
6 module Umu
7
8 module AbstractSyntax
9
10 module Core
11
12 module Declaration
13
14 class MutualRecursive < Abstract
15 attr_reader :bindings
16
17
18 def initialize(loc, bindings)
19 ASSERT.kind_of loc, LOC::Entry
20 ASSERT.kind_of bindings, ::Hash
21 ASSERT.assert (bindings.size >= 2), bindings.inspect
22
23 super(loc)
24
25 @bindings = bindings
26 end
27
28
29 def to_s
30 format(
31 "%%VAL %%REC %s",
32 self.bindings.map { |sym, target|
33 format "%s = %s", sym.to_s, target.lam_expr.to_s
34 }.join(" %%AND ")
35 )
36 end
37
38
39 def pretty_print(q)
40 q.text '%VAL %REC '
41
42 fst_sym, fst_target = self.bindings.first
43 __pretty_print_binding__ q, fst_sym, fst_target
44
45 not_fst_bindings = self.bindings.reject { |sym, _| sym == fst_sym }
46 not_fst_bindings.each do |sym, target|
47 q.breakable ''
48
49 q.text ' %AND '
50 __pretty_print_binding__ q, sym, target
51 end
52 end
53
54
55 private
56
57 def __pretty_print_binding__(q, sym, target)
58 q.text format("%s = ", sym.to_s)
59 PRT.group q do
60 q.pp target
61 end
62 end
63
64
65 def __evaluate__(env)
66 ASSERT.kind_of env, E::Entry
67
68 env.va_extend_bindings self.bindings
69 end
70 end
71
72
73
74 module_function
75
76 def make_mutual_recursive(loc, bindings)
77 ASSERT.kind_of loc, LOC::Entry
78 ASSERT.kind_of bindings, ::Hash
79
80 MutualRecursive.new(loc, bindings.freeze).freeze
81 end
82
83 end # Umu::AbstractSyntax::Core::Declaration
84
85 end # Umu::AbstractSyntax::Core
86
87 end # Umu::AbstractSyntax
88
89 end # Umu