[C++] Implement if, and, and or
diff --git a/func.cc b/func.cc
index 5f1f3fb..9d694b9 100644
--- a/func.cc
+++ b/func.cc
@@ -313,23 +313,43 @@
}
}
-void IfFunc(const vector<Value*>&, Evaluator*, string*) {
- printf("TODO(if)");
+void IfFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
+ shared_ptr<string> cond = args[0]->Eval(ev);
+ if (cond->empty()) {
+ if (args.size() > 2)
+ args[2]->Eval(ev, s);
+ } else {
+ args[1]->Eval(ev, s);
+ }
}
-void AndFunc(const vector<Value*>&, Evaluator*, string*) {
- printf("TODO(and)");
+void AndFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
+ shared_ptr<string> cond;
+ for (Value* a : args) {
+ cond = a->Eval(ev);
+ if (cond->empty())
+ return;
+ }
+ if (cond.get()) {
+ *s += *cond;
+ }
}
-void OrFunc(const vector<Value*>&, Evaluator*, string*) {
- printf("TODO(or)");
+void OrFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
+ for (Value* a : args) {
+ shared_ptr<string> cond = a->Eval(ev);
+ if (!cond->empty()) {
+ *s += *cond;
+ return;
+ }
+ }
}
void ValueFunc(const vector<Value*>&, Evaluator*, string*) {
printf("TODO(value)");
}
-void EvalFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
+void EvalFunc(const vector<Value*>& args, Evaluator* ev, string*) {
shared_ptr<string> text = args[0]->Eval(ev);
vector<AST*> asts;
Parse(*text, ev->loc(), &asts);
@@ -399,46 +419,46 @@
}
FuncInfo g_func_infos[] = {
- { "patsubst", &PatsubstFunc, 3 },
- { "strip", &StripFunc, 1 },
- { "subst", &SubstFunc, 3 },
- { "findstring", &FindstringFunc, 2 },
- { "filter", &FilterFunc, 2 },
- { "filter-out", &FilterOutFunc, 2 },
- { "sort", &SortFunc, 1 },
- { "word", &WordFunc, 2 },
- { "wordlist", &WordlistFunc, 3 },
- { "words", &WordsFunc, 1 },
- { "firstword", &FirstwordFunc, 1 },
- { "lastword", &LastwordFunc, 1 },
+ { "patsubst", &PatsubstFunc, 3, 3, false, false },
+ { "strip", &StripFunc, 1, 1, false, false },
+ { "subst", &SubstFunc, 3, 3, false, false },
+ { "findstring", &FindstringFunc, 2, 2, false, false },
+ { "filter", &FilterFunc, 2, 2, false, false },
+ { "filter-out", &FilterOutFunc, 2, 2, false, false },
+ { "sort", &SortFunc, 1, 1, false, false },
+ { "word", &WordFunc, 2, 2, false, false },
+ { "wordlist", &WordlistFunc, 3, 3, false, false },
+ { "words", &WordsFunc, 1, 1, false, false },
+ { "firstword", &FirstwordFunc, 1, 1, false, false },
+ { "lastword", &LastwordFunc, 1, 1, false, false },
- { "join", &JoinFunc, 2 },
- { "wildcard", &WildcardFunc, 1 },
- { "dir", &DirFunc, 1 },
- { "notdir", &NotdirFunc, 1 },
- { "suffix", &SuffixFunc, 1 },
- { "basename", &BasenameFunc, 1 },
- { "addsuffix", &AddsuffixFunc, 2 },
- { "addprefix", &AddprefixFunc, 2 },
- { "realpath", &RealpathFunc, 1 },
- { "abspath", &AbspathFunc, 1 },
+ { "join", &JoinFunc, 2, 2, false, false },
+ { "wildcard", &WildcardFunc, 1, 1, false, false },
+ { "dir", &DirFunc, 1, 1, false, false },
+ { "notdir", &NotdirFunc, 1, 1, false, false },
+ { "suffix", &SuffixFunc, 1, 1, false, false },
+ { "basename", &BasenameFunc, 1, 1, false, false },
+ { "addsuffix", &AddsuffixFunc, 2, 2, false, false },
+ { "addprefix", &AddprefixFunc, 2, 2, false, false },
+ { "realpath", &RealpathFunc, 1, 1, false, false },
+ { "abspath", &AbspathFunc, 1, 1, false, false },
- { "if", &IfFunc, 1 },
- { "and", &AndFunc, 1 },
- { "or", &OrFunc, 1 },
+ { "if", &IfFunc, 3, 2, false, true },
+ { "and", &AndFunc, 0, 0, true, false },
+ { "or", &OrFunc, 0, 0, true, false },
- { "value", &ValueFunc, 1 },
- { "eval", &EvalFunc, 1 },
- { "shell", &ShellFunc, 1 },
- { "call", &CallFunc, 1 },
- { "foreach", &ForeachFunc, 1 },
+ { "value", &ValueFunc, 1, 1, false, false },
+ { "eval", &EvalFunc, 1, 1, false, false },
+ { "shell", &ShellFunc, 1, 1, false, false },
+ { "call", &CallFunc, 0, 0, false, false },
+ { "foreach", &ForeachFunc, 3, 3, false, false },
- { "origin", &OriginFunc, 1 },
- { "flavor", &FlavorFunc, 1 },
+ { "origin", &OriginFunc, 1, 1, false, false },
+ { "flavor", &FlavorFunc, 1, 1, false, false },
- { "info", &InfoFunc, 1 },
- { "warning", &WarningFunc, 1 },
- { "error", &ErrorFunc, 1 },
+ { "info", &InfoFunc, 1, 1, false, false },
+ { "warning", &WarningFunc, 1, 1, false, false },
+ { "error", &ErrorFunc, 1, 1, false, false },
};
unordered_map<StringPiece, FuncInfo*>* g_func_info_map;