1 // Copyright 2016-2021 Doug Moen
2 // Licensed under the Apache License, version 2.0
3 // See accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0
4 
5 #include <libcurv/phrase.h>
6 
7 namespace curv {
8 
9 /// In the grammar, a <list> phrase is zero or more constituent phrases
10 /// separated by commas or semicolons.
11 /// This function iterates over each constituent phrase.
12 void
each_item(Phrase & phrase,std::function<void (Phrase &)> func)13 each_item(Phrase& phrase, std::function<void(Phrase&)> func)
14 {
15     if (dynamic_cast<Empty_Phrase*>(&phrase))
16         return;
17     if (auto commas = dynamic_cast<Comma_Phrase*>(&phrase)) {
18         for (auto& i : commas->args_)
19             func(*i.expr_);
20         return;
21     }
22     if (auto semis = dynamic_cast<Semicolon_Phrase*>(&phrase)) {
23         for (auto& i : semis->args_)
24             func(*i.expr_);
25         return;
26     }
27     func(phrase);
28 }
29 
30 Shared<const Phrase>
strip_parens(Shared<const Phrase> ph)31 strip_parens(Shared<const Phrase> ph)
32 {
33     for (;;) {
34         auto p = cast<const Paren_Phrase>(ph);
35         if (p == nullptr) break;
36         ph = p->body_;
37     }
38     return ph;
39 }
40 
41 Shared<const Phrase>
nub_phrase(Shared<const Phrase> ph)42 nub_phrase(Shared<const Phrase> ph)
43 {
44     for (;;) {
45         if (auto pr = cast<const Program_Phrase>(ph)) {
46             ph = pr->body_;
47             continue;
48         }
49         if (auto let = cast<const Let_Phrase>(ph)) {
50             ph = let->body_;
51             continue;
52         }
53         if (auto where = cast<const Where_Phrase>(ph)) {
54             ph = where->left_;
55             continue;
56         }
57         if (auto p = cast<const Paren_Phrase>(ph)) {
58             if (isa<Empty_Phrase>(p->body_))
59                 break;
60             if (isa<Comma_Phrase>(p->body_))
61                 break;
62             ph = p->body_;
63             continue;
64         }
65         break;
66     }
67     return ph;
68 }
69 
70 Shared<const Phrase>
func_part(Shared<const Phrase> ph)71 func_part(Shared<const Phrase> ph)
72 {
73     auto cp = cast<const Call_Phrase>(ph);
74     if (cp != nullptr)
75         return cp->function_;
76     else
77         return ph;
78 }
79 
80 Shared<const Phrase>
arg_part(Shared<const Phrase> ph)81 arg_part(Shared<const Phrase> ph)
82 {
83     auto cp = cast<const Call_Phrase>(ph);
84     if (cp != nullptr)
85         return cp->arg_;
86     else
87         return ph;
88 }
89 
90 } // namespace curv
91