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 Container
17
18 class List < Abstraction::Expressions
19 attr_reader :opt_last_expr
20
21
22 def initialize(loc, exprs, opt_last_expr)
23 ASSERT.kind_of exprs, ::Array
24 ASSERT.opt_kind_of opt_last_expr, ASCE::Abstract
25 ASSERT.assert (
26 if exprs.empty? then opt_last_expr.nil? else true end
27 )
28
29 super(loc, exprs)
30
31 @opt_last_expr = opt_last_expr
32 end
33
34
35 def to_s
36 format("[%s%s]",
37 self.map(&:to_s).join(', '),
38
39 if self.opt_last_expr
40 '|' + self.opt_last_expr.to_s
41 else
42 ''
43 end
44 )
45 end
46
47
48 def pretty_print(q)
49 PRT.group_for_enum q, self, bb:'[', eb:']', join:', '
50 end
51
52
53 private
54
55 def __evaluate__(env, event)
56 ASSERT.kind_of env, E::Entry
57 ASSERT.kind_of event, E::Tracer::Event
58
59 new_env = env.enter event
60
61 xs = self.map { |x|
62 ASSERT.kind_of x, ASCE::Abstract
63
64 x.evaluate(new_env).value
65 }
66
67 tail = if self.opt_last_expr
68 t = self.opt_last_expr.evaluate(new_env).value
69 unless t.kind_of? VCM::List::Abstract
70 raise X::TypeError.new(
71 opt_last_expr.loc,
72 env,
73 "expected a List, but %s : %s", t, t.type_sym
74 )
75 end
76
77 t
78 else
79 VC.make_nil
80 end
81
82 VC.make_list xs, tail
83 end
84 end
85
86
87 end # Umu::AbstractSyntax::Core::Expression::Unary::Container
88
89 end # Umu::AbstractSyntax::Core::Expression::Unary
90
91
92 module_function
93
94 def make_list(loc, exprs, opt_last_expr = nil)
95 ASSERT.kind_of loc, LOC::Entry
96 ASSERT.kind_of exprs, ::Array
97 ASSERT.opt_kind_of opt_last_expr, ASCE::Abstract
98
99 Unary::Container::List.new(loc, exprs.freeze, opt_last_expr).freeze
100 end
101
102 end # Umu::AbstractSyntax::Core::Expression
103
104 end # Umu::AbstractSyntax::Core
105
106 end # Umu::AbstractSyntax
107
108 end # Umu