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 Binary
15
16 class KindOf < Binary::Abstract
17 alias expr lhs_expr
18 alias class_id rhs
19 attr_reader :opt_type_sym
20
21
22 def initialize(loc, expr, class_id, opt_type_sym)
23 ASSERT.kind_of expr, ASCE::Abstract
24 ASSERT.kind_of class_id, ASCEU::Identifier::Short
25 ASSERT.opt_kind_of opt_type_sym, ::Symbol
26
27 super(loc, expr, class_id)
28
29 @opt_type_sym = opt_type_sym
30 end
31
32
33 def to_s
34 format("(%s%s %%KIND-OF? %s)",
35 self.expr.to_s,
36
37 if self.opt_type_sym
38 format " : %s", self.opt_type_sym
39 else
40 ''
41 end,
42
43 self.class_id.to_s
44 )
45 end
46
47
48 private
49
50 def __evaluate__(env, event)
51 ASSERT.kind_of env, E::Entry
52 ASSERT.kind_of event, E::Tracer::Event
53
54 rhs_signat = env.ty_lookup self.class_id.sym, self.loc
55 ASSERT.kind_of rhs_signat, ECTSC::Base
56
57 lhs_value = self.expr.evaluate(env.enter event).value
58 ASSERT.kind_of lhs_value, VC::Top
59
60 if self.opt_type_sym
61 type_signat = env.ty_lookup self.opt_type_sym, self.loc
62 ASSERT.kind_of type_signat, ECTSC::Base
63
64 unless env.ty_kind_of?(lhs_value, type_signat)
65 raise X::TypeError.new(
66 self.loc,
67 env,
68 "Expected a %s, but %s : %s",
69 self.opt_type_sym,
70 lhs_value,
71 lhs_value.type_sym
72 )
73 end
74 end
75
76 VC.make_bool env.ty_kind_of?(lhs_value, rhs_signat)
77 end
78 end
79
80 end # Umu::AbstractSyntax::Core::Expression::Binary
81
82
83 module_function
84
85 def make_test_kind_of(loc, expr, class_id, opt_type_sym = nil)
86 ASSERT.kind_of loc, LOC::Entry
87 ASSERT.kind_of expr, ASCE::Abstract
88 ASSERT.kind_of class_id, ASCEU::Identifier::Short
89 ASSERT.opt_kind_of opt_type_sym, ::Symbol
90
91 Binary::KindOf.new(loc, expr, class_id, opt_type_sym).freeze
92 end
93
94 end # Umu::AbstractSyntax::Core::Expression
95
96 end # Umu::AbstractSyntax::Core
97
98 end # Umu::AbstractSyntax
99
100 end # Umu