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 module Simple
15
16 class Abstract < Declaration::Abstract
17 attr_reader :sym
18
19
20 def initialize(loc, sym)
21 ASSERT.kind_of sym, ::Symbol
22
23 super(loc)
24
25 @sym = sym
26 end
27 end
28
29
30
31 class Value < Abstract
32 attr_reader :expr
33 attr_reader :opt_type_sym
34
35
36 def initialize(loc, sym, expr, opt_type_sym)
37 ASSERT.kind_of expr, ASCE::Abstract
38 ASSERT.opt_kind_of opt_type_sym, ::Symbol
39
40 super(loc, sym)
41
42 @expr = expr
43 @opt_type_sym = opt_type_sym
44 end
45
46
47 def to_s
48 format("%%VAL %s%s = %s",
49 self.sym.to_s,
50
51 if self.opt_type_sym
52 format " : %s", self.opt_type_sym
53 else
54 ''
55 end,
56
57 self.expr.to_s
58 )
59 end
60
61
62 def pretty_print(q)
63 q.text format("%%VAL %s%s = ",
64 self.sym.to_s,
65
66 if self.opt_type_sym
67 format " : %s", self.opt_type_sym
68 else
69 ''
70 end
71 )
72 PRT.group q do
73 q.pp self.expr
74 end
75 end
76
77
78 private
79
80 def __evaluate__(env)
81 ASSERT.kind_of env, E::Entry
82
83 result = self.expr.evaluate env
84 ASSERT.kind_of result, ASR::Value
85 value = result.value
86
87 if self.opt_type_sym
88 type_sym = opt_type_sym
89
90 signat = env.ty_lookup type_sym, self.loc
91 ASSERT.kind_of signat, ECTSC::Base
92 unless env.ty_kind_of?(value, signat)
93 raise X::TypeError.new(
94 self.loc,
95 env,
96 "Expected a %s, but %s : %s",
97 type_sym,
98 value,
99 value.type_sym
100 )
101 end
102 end
103
104 env.va_extend_value self.sym, value
105 end
106 end
107
108
109
110 class Recursive < Abstract
111 attr_reader :lam_expr
112
113
114 def initialize(loc, sym, lam_expr)
115 ASSERT.kind_of lam_expr, ASCEN::Lambda::Entry
116
117 super(loc, sym)
118
119 @lam_expr = lam_expr
120 end
121
122
123 def to_s
124 format "%%VAL %%REC %s = %s", self.sym.to_s, self.lam_expr.to_s
125 end
126
127
128 def pretty_print(q)
129 q.text format("%%VAL %%REC %s = ", self.sym.to_s)
130 PRT.group q do
131 q.pp self.lam_expr
132 end
133 end
134
135
136 private
137
138 def __evaluate__(env)
139 ASSERT.kind_of env, E::Entry
140
141 env.va_extend_recursive self.sym, self.lam_expr
142 end
143 end
144
145 end # Umu::AbstractSyntax::Core::Declaration::Simple
146
147
148
149 module_function
150
151 def make_value(loc, sym, expr, opt_type_sym = nil)
152 ASSERT.kind_of loc, LOC::Entry
153 ASSERT.kind_of sym, ::Symbol
154 ASSERT.kind_of expr, ASCE::Abstract
155 ASSERT.opt_kind_of opt_type_sym, ::Symbol
156
157 Simple::Value.new(loc, sym, expr, opt_type_sym).freeze
158 end
159
160
161 def make_recursive(loc, sym, lam_expr)
162 ASSERT.kind_of loc, LOC::Entry
163 ASSERT.kind_of sym, ::Symbol
164 ASSERT.kind_of lam_expr, ASCEN::Lambda::Entry
165
166 Simple::Recursive.new(loc, sym, lam_expr).freeze
167 end
168
169 end # Umu::AbstractSyntax::Core::Declaration
170
171 end # Umu::AbstractSyntax::Core
172
173 end # Umu::AbstractSyntax
174
175 end # Umu