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 Product
13
14 class Abstract < Object
15 include Enumerable
16
17 attr_reader :fst_obj, :snd_obj, :tail_objs
18
19
20 def initialize(fst_obj, snd_obj, tail_objs)
21 ASSERT.kind_of fst_obj, ::Object
22 ASSERT.kind_of snd_obj, ::Object
23 ASSERT.kind_of tail_objs, ::Array
24
25 super()
26
27 @fst_obj = fst_obj
28 @snd_obj = snd_obj
29 @tail_objs = tail_objs
30 end
31
32
33 def objs
34 [self.fst_obj, self.snd_obj] + self.tail_objs
35 end
36
37
38 def arity
39 2 + self.tail_objs.size
40 end
41
42
43 def each
44 yield self.fst_obj
45
46 yield self.snd_obj
47
48 self.tail_objs.each do |obj|
49 yield obj
50 end
51 end
52
53
54 def select_by_number(sel_num, loc, env)
55 ASSERT.kind_of sel_num, ::Integer
56 ASSERT.kind_of loc, LOC::Entry
57
58 value = case sel_num
59 when 1
60 self.fst_obj
61 when 2
62 self.snd_obj
63 else
64 unless 3 <= sel_num && sel_num <= self.arity
65 raise X::SelectionError.new(
66 loc,
67 env,
68 "Selector expected 1..%d, but %d",
69 self.arity, sel_num
70 )
71 end
72
73 self.tail_objs[sel_num - 3]
74 end
75
76 ASSERT.kind_of value, VC::Top
77 end
78 end
79
80 end # Umu::Value::Core::Product
81
82 end # Umu::Value::Core
83
84 end # Umu::Value
85
86 end # Umu