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 Identifier
17
18 class Abstract < Unary::Abstract; end
19
20
21
22 class Short < Abstract
23 alias sym obj
24
25
26 def initialize(loc, sym)
27 ASSERT.kind_of sym, ::Symbol
28
29 super
30 end
31
32
33 def to_s
34 self.sym.to_s
35 end
36
37
38 private
39
40 def __evaluate__(env, _event)
41 ASSERT.kind_of env, E::Entry
42
43 value = env.va_lookup self.sym, self.loc
44 ASSERT.kind_of value, VC::Top
45 end
46 end
47
48
49
50 class Long < Abstract
51 alias head_id obj
52 attr_reader :tail_ids
53
54
55 def initialize(loc, head_id, tail_ids)
56 ASSERT.kind_of head_id, Short
57 ASSERT.kind_of tail_ids, ::Array
58
59 super(loc, head_id)
60
61 @tail_ids = tail_ids
62 end
63
64
65 def to_s
66 if tail_ids.empty?
67 self.head_id.to_s
68 else
69 format("%s::%s",
70 self.head_id.to_s,
71 self.tail_ids.map(&:to_s).join('::')
72 )
73 end
74 end
75
76
77 private
78
79 def __evaluate__(env, _event)
80 ASSERT.kind_of env, E::Entry
81
82 init_value = env.va_lookup self.head_id.sym, self.head_id.loc
83 ASSERT.kind_of init_value, VC::Top
84
85 unless init_value.kind_of? VC::Struct::Entry
86 raise X::TypeError.new(
87 self.head_id.loc,
88 env,
89 "For identifier: '%s', expected a Struct, but %s : %s",
90 self.head_id.sym.to_s,
91 init_value.to_s,
92 init_value.type_sym.to_s
93 )
94 end
95
96 final_value, _sym = self.tail_ids.inject(
97 [init_value, self.head_id.sym]
98 ) {
99 |(value, parent_sym ), id|
100 ASSERT.kind_of value, VC::Top
101 ASSERT.kind_of parent_sym, ::Symbol
102 ASSERT.kind_of id, Short
103
104 #pp({value: value.class, sym: parent_sym, id: id})
105
106 unless value.kind_of? VC::Struct::Entry
107 raise X::TypeError.new(
108 id.loc,
109 env,
110 "For identifier: '%s', expected a Struct, but %s : %s",
111 parent_sym.to_s,
112 value.to_s,
113 value.type_sym.to_s
114 )
115 end
116
117 [value.select(id.sym, id.loc, env), id.sym]
118 }
119 ASSERT.kind_of final_value, VC::Top
120 end
121 end
122
123 class Short < Abstract
124
125
126 end
127
128 end # Umu::AbstractSyntax::Core::Expression::Unary::Identifier
129
130 end # Umu::AbstractSyntax::Core::Expression::Unary
131
132
133 module_function
134
135 def make_identifier(loc, sym)
136 ASSERT.kind_of loc, LOC::Entry
137 ASSERT.kind_of sym, ::Symbol
138
139 Unary::Identifier::Short.new(loc, sym).freeze
140 end
141
142
143 def make_long_identifier(loc, head_id, tail_ids)
144 ASSERT.kind_of head_id, Unary::Identifier::Short
145 ASSERT.kind_of tail_ids, ::Array
146
147 Unary::Identifier::Long.new(loc, head_id, tail_ids.freeze).freeze
148 end
149
150 end # Umu::AbstractSyntax::Core::Expression
151
152 end # Umu::AbstractSyntax::Core
153
154 end # Umu::AbstractSyntax
155
156 end # Umu