1 # coding: utf-8
2 # frozen_string_literal: true
3
4
5
6 module Umu
7
8 module ConcreteSyntax
9
10 module Core
11
12 module Expression
13
14 module Nary
15
16 module Branch
17
18 module Rule
19
20 class If < Abstraction::HasHead
21 alias head_expr head
22
23 def initialize(loc, head_expr, body_expr)
24 ASSERT.kind_of head_expr, CSCE::Abstract
25 ASSERT.kind_of body_expr, CSCE::Abstract
26
27 super
28 end
29
30
31 def to_s
32 format "%s %%THEN %s", self.head_expr, self.body_expr
33 end
34
35
36 def pretty_print(q)
37 q.pp self.head_expr
38 q.text ' %THEN '
39 q.pp self.body_expr
40 end
41 end
42
43 end # Umu::ConcreteSyntax::Core::Expression::Nary::Branch::Rule
44
45
46
47 class If < Expression::Abstract
48 attr_reader :if_rule, :elsif_rules, :else_expr
49
50
51 def initialize(loc, if_rule, elsif_rules, else_expr)
52 ASSERT.kind_of if_rule, Nary::Branch::Rule::If
53 ASSERT.kind_of elsif_rules, ::Array
54 ASSERT.kind_of else_expr, CSCE::Abstract
55
56 super(loc)
57
58 @if_rule = if_rule
59 @elsif_rules = elsif_rules
60 @else_expr = else_expr
61 end
62
63
64 def to_s
65 rules_string = if self.elsif_rules.empty?
66 ' '
67 else
68 format(" %s ",
69 self.elsif_rules.map { |rule|
70 '%ELSIF ' + rule.to_s
71 }.join(' ')
72 )
73 end
74
75 format("%%IF %s%s%%ELSE %s",
76 self.if_rule.to_s,
77 rules_string,
78 self.else_expr.to_s
79 )
80 end
81
82
83 def pretty_print(q)
84 PRT.group q, bb:'(', eb:')' do
85 PRT.group q, bb:'%IF ' do
86 q.pp self.if_rule
87 end
88
89 self.elsif_rules.each do |rule|
90 q.breakable
91
92 PRT.group q, bb:'%ELSIF ' do
93 q.pp rule
94 end
95 end
96
97 q.breakable
98
99 PRT.group q, bb:'%ELSE ' do
100 q.pp self.else_expr
101 end
102 end
103 end
104
105
106 private
107
108 def __desugar__(env, event)
109 new_env = env.enter event
110
111 ASCE.make_if(
112 self.loc,
113
114 ([self.if_rule] + self.elsif_rules).map { |rule|
115 ASSERT.kind_of rule, Nary::Branch::Rule::If
116
117 ASCE.make_rule(
118 rule.loc,
119 rule.head_expr.desugar(new_env),
120 rule.body_expr.desugar(new_env)
121 )
122 },
123
124 self.else_expr.desugar(new_env)
125 )
126 end
127 end
128
129 end # Umu::ConcreteSyntax::Core::Expression::Nary::Branch
130
131 end # Umu::ConcreteSyntax::Core::Expression::Nary
132
133
134 module_function
135
136 def make_if(loc, if_rule, elsif_rules, else_expr)
137 ASSERT.kind_of loc, LOC::Entry
138 ASSERT.kind_of if_rule, Nary::Branch::Rule::If
139 ASSERT.kind_of elsif_rules, ::Array
140 ASSERT.kind_of else_expr, CSCE::Abstract
141
142 Nary::Branch::If.new(loc, if_rule, elsif_rules, else_expr).freeze
143 end
144
145
146 def make_if_rule(loc, head_expr, body_expr)
147 ASSERT.kind_of loc, LOC::Entry
148 ASSERT.kind_of head_expr, CSCE::Abstract
149 ASSERT.kind_of body_expr, CSCE::Abstract
150
151 Nary::Branch::Rule::If.new(
152 loc, head_expr, body_expr
153 ).freeze
154 end
155
156 end # Umu::ConcreteSyntax::Core::Expression
157
158 end # Umu::ConcreteSyntax::Core
159
160 end # Umu::ConcreteSyntax
161
162 end # Umu