bool ArgDef::Validate(ExpressionEvaluator evaluator, ExpressionPtr &expr, string &error) const { if (expr) { if (auto sexp = TypeHelper::GetValue<Sexp>(expr)) { auto &args = sexp->Args; if (!args.empty()) { ExpressionPtr fnExpr = move(args.front()); args.pop_front(); if (auto fn = TypeHelper::GetValue<Function>(fnExpr)) { bool result = ValidateArgs(evaluator, args, error); args.push_front(move(fnExpr)); return result; } else throw invalid_argument("first argument in sexp must be a function"); } else throw invalid_argument("sexp requires at least one argument"); } else error = "Expected: Sexp. Actual: " + expr->Type().Name(); } else throw invalid_argument("ExpressionPtr is empty"); return error.empty(); }
bool ArgDef::CheckArg(ExpressionEvaluator evaluator, ExpressionPtr &arg, const TypeInfo &expectedType, size_t argNum, string &error) const { if (arg && TypeHelper::TypeMatches(expectedType, arg->Type()) || evaluator(arg)) { if (&expectedType == &Literal::TypeInstance && &arg->Type() == &Quote::TypeInstance) { return true; } if (!TypeHelper::TypeMatches(expectedType, arg->Type())) { error = "Argument " + to_string(argNum) + ": Expected " + expectedType.Name() + ", got " + arg->Type().Name(); return false; } else return true; } else { error = "Argument " + to_string(argNum) + ": Failed to evaluate"; return false; } }
bool TypeHelper::IsAtom(const ExpressionPtr &expr) { return IsAtom(expr->Type()); }