1 # coding: utf-8
2 # frozen_string_literal: true
3
4
5
6 module Umu
7
8 module Value
9
10 module Core
11
12 module Union
13
14 class Datum < Abstract
15 def self.base_type_sym
16 :Datum
17 end
18
19
20 def self.order_num
21 __LINE__
22 end
23
24
25 define_class_method(
26 :meth_make,
27 :make, [:'tag:contents:'],
28 [VCA::Symbol, VC::Top], self
29 )
30 def self.meth_make(_loc, _env, _event, tag, contents)
31 ASSERT.kind_of tag, VCA::Symbol
32 ASSERT.kind_of contents, VC::Top
33
34 VC.make_datum tag.val, contents
35 end
36
37
38 attr_reader :tag_sym, :contents
39
40 def initialize(tag_sym, contents)
41 ASSERT.kind_of tag_sym, ::Symbol
42 ASSERT.kind_of contents, VC::Top
43
44 super()
45
46 @tag_sym = tag_sym
47 @contents = contents
48 end
49
50
51 define_instance_method(
52 :meth_tag,
53 :tag, [],
54 [], VCA::Symbol
55 )
56 def meth_tag(_loc, _env, _event)
57 VC.make_symbol self.tag_sym
58 end
59
60
61 def to_s
62 format "%s %s", self.tag_sym.to_s, self.contents.to_s
63 end
64
65
66 def pretty_print(q)
67 q.text format("%s ", self.tag_sym.to_s)
68 q.pp self.contents
69 end
70
71
72 define_instance_method(
73 :meth_to_string,
74 :'to-s', [],
75 [], VCA::String
76 )
77 def meth_to_string(loc, env, event)
78 VC.make_string(
79 format("%s %s",
80 self.tag_sym.to_s,
81 self.contents.meth_to_string(loc, env, event).val
82 )
83 )
84 end
85
86
87 define_instance_method(
88 :meth_is_equal,
89 :'==', [],
90 [VC::Top], VCA::Bool
91 )
92 def meth_is_equal(loc, env, event, other)
93 ASSERT.kind_of other, VC::Top
94
95 VC.make_bool(
96 super.true? && self.tag_sym == other.tag_sym
97 )
98 end
99
100
101 define_instance_method(
102 :meth_is_less_than,
103 :'<', [],
104 [VCU::Datum], VCA::Bool
105 )
106 def meth_is_less_than(loc, env, event, other)
107 ASSERT.kind_of other, VCU::Datum
108
109 unless other.contents.kind_of?(self.contents.class)
110 raise X::TypeError.new(
111 loc,
112 env,
113 "Expected a %s, but %s : %s",
114 self.contents.type_sym,
115 other.contents.to_s,
116 other.contents.type_sym
117 )
118 end
119
120 VC.make_bool(
121 if self.tag_sym == other.tag_sym
122 self.contents.meth_is_less_than(
123 loc, env, event, other.contents
124 ).true?
125 else
126 self.tag_sym < other.tag_sym
127 end
128 )
129 end
130 end
131 Datum.freeze
132
133 end # Umu::Value::Core::Union
134
135
136 module_function
137
138 def make_datum(tag_sym, contents)
139 ASSERT.kind_of tag_sym, ::Symbol
140 ASSERT.kind_of contents, VC::Top
141
142 Union::Datum.new(tag_sym, contents).freeze
143 end
144
145 end # Umu::Value::Core
146
147 end # Umu::Value
148
149 end # Umu