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 Apply < Binary::Abstract
17 alias opr_expr lhs_expr
18 alias opnd_head_expr rhs
19 attr_reader :opnd_tail_exprs
20
21
22 def initialize(loc, opr_expr, opnd_head_expr, opnd_tail_exprs)
23 ASSERT.kind_of opr_expr, ASCE::Abstract
24 ASSERT.kind_of opnd_head_expr, ASCE::Abstract
25 ASSERT.kind_of opnd_tail_exprs, ::Array
26
27 super(loc, opr_expr, opnd_head_expr)
28
29 @opnd_tail_exprs = opnd_tail_exprs
30 end
31
32
33 def to_s
34 format("(%s %s)",
35 self.opr_expr,
36 self.opnd_exprs.map(&:to_s).join(' ')
37 )
38 end
39
40
41 def pretty_print(q)
42 PRT.group q, bb:'(', eb:')' do
43 q.pp self.opr_expr
44
45 self.opnd_exprs.each do |expr|
46 q.breakable
47
48 q.pp expr
49 end
50 end
51 end
52
53
54 def opnd_exprs
55 [self.opnd_head_expr] + self.opnd_tail_exprs
56 end
57
58
59 private
60
61 def __evaluate__(env, event)
62 ASSERT.kind_of env, E::Entry
63 ASSERT.kind_of event, E::Tracer::Event
64
65 new_env = env.enter event
66
67 opr_result = self.opr_expr.evaluate new_env
68 ASSERT.kind_of opr_result, ASR::Value
69
70 opnd_head_result = self.opnd_head_expr.evaluate new_env
71 ASSERT.kind_of opnd_head_result, ASR::Value
72
73 opnd_tail_values = self.opnd_tail_exprs.map { |expr|
74 ASSERT.kind_of expr, ASCE::Abstract
75
76 result = expr.evaluate new_env
77 ASSERT.kind_of result, ASR::Value
78
79 result.value
80 }
81
82 value = opr_result.value.apply(
83 opnd_head_result.value, opnd_tail_values, self.loc, new_env
84 )
85
86 ASSERT.kind_of value, VC::Top
87 end
88 end
89
90 end # Umu::AbstractSyntax::Core::Expression::Binary
91
92
93 module_function
94
95 def make_apply(loc, opr_expr, opnd_head_expr, opnd_tail_exprs = [])
96 ASSERT.kind_of loc, LOC::Entry
97 ASSERT.kind_of opr_expr, ASCE::Abstract
98 ASSERT.kind_of opnd_head_expr, ASCE::Abstract
99 ASSERT.kind_of opnd_tail_exprs, ::Array
100
101 Binary::Apply.new(
102 loc, opr_expr, opnd_head_expr, opnd_tail_exprs.freeze
103 ).freeze
104 end
105
106 end # Umu::AbstractSyntax::Core::Expression
107
108 end # Umu::AbstractSyntax::Core
109
110 end # Umu::AbstractSyntax
111
112 end # Umu