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)13each_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)31strip_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)42nub_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)71func_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)81arg_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