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 Expression
13
14 module Unary
15
16 module Container
17
18 module Named
19
20 class Label < Unary::Abstract
21 alias sym obj
22
23
24 def initialize(loc, sym)
25 ASSERT.kind_of sym, ::Symbol
26
27 super
28 end
29
30
31 def hash
32 self.sym.hash
33 end
34
35
36 def eql?(other)
37 self.sym.eql? other.sym
38 end
39
40
41 def to_s
42 self.sym.to_s + ':'
43 end
44
45
46 def pretty_print(q)
47 q.text self.to_s
48 end
49 end
50
51
52
53 class Entry < Abstraction::Expressions
54 attr_reader :index_by_label
55
56
57 def initialize(loc, exprs, index_by_label)
58 ASSERT.kind_of exprs, ::Array
59 ASSERT.assert exprs.size >= 2
60 ASSERT.kind_of index_by_label, ::Hash
61
62 @index_by_label = index_by_label.freeze
63
64 super(loc, exprs)
65 end
66
67
68 def each
69 self.index_by_label.each do |label, index|
70 yield label, self.exprs[index]
71 end
72 end
73
74
75 def to_s
76 format("(%s)",
77 self.map { |label, expr|
78 format "%s%s", label.to_s, expr.to_s
79 }.join(' ')
80 )
81 end
82
83
84 def pretty_print(q)
85 PRT.group_for_enum q, self, bb:'(', eb:')', join:' ' do
86 |(label, expr)|
87
88 q.pp label
89 q.pp expr
90 end
91 end
92
93
94 private
95
96 def __evaluate__(env, event)
97 ASSERT.kind_of env, E::Entry
98 ASSERT.kind_of event, E::Tracer::Event
99
100 new_env = env.enter event
101
102 VC.make_named_tuple(
103 self.index_by_label.inject({}) { |hash, (label, index)|
104 hash.merge(label.sym => index)
105 },
106
107 *(self.exprs.map { |expr| expr.evaluate(new_env).value })
108 )
109 end
110 end
111
112 end # Umu::AbstractSyntax::Core::Expression::Unary::Container::Named
113
114 end # Umu::AbstractSyntax::Core::Expression::Unary::Container
115
116 end # Umu::AbstractSyntax::Core::Expression::Unary
117
118
119 module_function
120
121 def make_named_tuple_label(loc, sym)
122 ASSERT.kind_of loc, LOC::Entry
123 ASSERT.kind_of sym, ::Symbol
124
125 Unary::Container::Named::Label.new(loc, sym).freeze
126 end
127
128
129 def make_named_tuple(loc, exprs, index_by_label)
130 ASSERT.kind_of loc, LOC::Entry
131 ASSERT.kind_of exprs, ::Array
132 ASSERT.kind_of index_by_label, ::Hash
133
134 Unary::Container::Named::Entry.new(
135 loc, exprs.freeze, index_by_label.freeze
136 ).freeze
137 end
138
139 end # Umu::AbstractSyntax::Core::Expression
140
141 end # Umu::AbstractSyntax::Core
142
143 end # Umu::AbstractSyntax
144
145 end # Umu