Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
Implement special forms: match, curve, coalesce
Browse files Browse the repository at this point in the history
Port 'match'

Implement curve

Implement coalesce
  • Loading branch information
Anand Thakker committed Jul 21, 2017
1 parent 7b436d8 commit ca091ab
Show file tree
Hide file tree
Showing 8 changed files with 758 additions and 4 deletions.
5 changes: 5 additions & 0 deletions cmake/core-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,13 @@ set(MBGL_CORE_FILES
src/mbgl/style/conversion/stringify.hpp

# style/expression
include/mbgl/style/expression/case.hpp
include/mbgl/style/expression/coalesce.hpp
include/mbgl/style/expression/compound_expression.hpp
include/mbgl/style/expression/curve.hpp
include/mbgl/style/expression/expression.hpp
include/mbgl/style/expression/let.hpp
include/mbgl/style/expression/match.hpp
include/mbgl/style/expression/parse.hpp
include/mbgl/style/expression/parsing_context.hpp
include/mbgl/style/expression/type.hpp
Expand Down
Empty file.
116 changes: 116 additions & 0 deletions include/mbgl/style/expression/coalesce.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#pragma once

#include <map>
#include <mbgl/util/interpolate.hpp>
#include <mbgl/style/expression/expression.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
#include <mbgl/style/conversion.hpp>

namespace mbgl {
namespace style {
namespace expression {

class TypedCoalesce : public TypedExpression {
public:
using Args = std::vector<std::unique_ptr<TypedExpression>>;
TypedCoalesce(const type::Type& type, Args args_) :
TypedExpression(type),
args(std::move(args_))
{}

EvaluationResult evaluate(const EvaluationParameters& params) const override {
for (auto it = args.begin(); it != args.end(); it++) {
const auto& result = (*it)->evaluate(params);
if (!result && (std::next(it) != args.end())) {
continue;
}
return result;
}

return Null;
}

bool isFeatureConstant() const override {
for (const auto& arg : args) {
if (!arg->isFeatureConstant()) return false;
}
return true;
}

bool isZoomConstant() const override {
for (const auto& arg : args) {
if (!arg->isZoomConstant()) return false;
}
return true;
}

private:
Args args;
};

class UntypedCoalesce : public UntypedExpression {
public:
using Args = std::vector<std::unique_ptr<UntypedExpression>>;

UntypedCoalesce(const std::string& key, Args args_) :
UntypedExpression(key),
args(std::move(args_))
{}

template <typename V>
static ParseResult parse(const V& value, const ParsingContext& ctx) {
using namespace mbgl::style::conversion;
assert(isArray(value));
auto length = arrayLength(value);
if (length < 2) {
return CompileError {
"Expected at least one argument to \"coalesce\".",
ctx.key()
};
}

Args args;
for (std::size_t i = 1; i < length; i++) {
auto parsed = parseExpression(arrayMember(value, i), ParsingContext(ctx, {i}, {"coalesce"}));
if (parsed.template is<CompileError>()) {
return parsed;
}
args.push_back(std::move(parsed.template get<std::unique_ptr<UntypedExpression>>()));
}
return std::make_unique<UntypedCoalesce>(ctx.key(), std::move(args));
}

TypecheckResult typecheck(std::vector<CompileError>& errors) const override {
optional<type::Type> outputType;
TypedCoalesce::Args checkedArgs;

for (const auto& arg : args) {
auto checked = arg->typecheck(errors);
if (!checked) {
continue;
}
if (!outputType) {
outputType = (*checked)->getType();
} else {
const auto& error = matchType(*outputType, (*checked)->getType());
if (error) {
errors.push_back({ *error, arg->getKey() });
continue;
}
}

checkedArgs.push_back(std::move(*checked));
}

if (errors.size() > 0) return TypecheckResult();

return TypecheckResult(std::make_unique<TypedCoalesce>(*outputType, std::move(checkedArgs)));
}

private:
Args args;
};

} // namespace expression
} // namespace style
} // namespace mbgl
Loading

0 comments on commit ca091ab

Please sign in to comment.