summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnand Thakker <github@anandthakker.net>2017-07-10 09:03:36 -0400
committerAnand Thakker <github@anandthakker.net>2017-07-10 09:03:36 -0400
commit2893112609489ae007b087474ac7a2349c0c04d9 (patch)
tree5224fbe61dd4ab632ff8149eea851b07031ac58b
parent945cdebe9b37c3de764d382cf216d55ee0b7fce6 (diff)
downloadqtlocation-mapboxgl-2893112609489ae007b087474ac7a2349c0c04d9.tar.gz
Parse literal arrays and objects
-rw-r--r--include/mbgl/style/expression/expression.hpp55
-rw-r--r--include/mbgl/style/expression/parse.hpp11
-rw-r--r--include/mbgl/style/function/type.hpp4
-rw-r--r--src/mbgl/style/function/type.cpp2
4 files changed, 49 insertions, 23 deletions
diff --git a/include/mbgl/style/expression/expression.hpp b/include/mbgl/style/expression/expression.hpp
index a3e69e4bb3..e36db1b3c7 100644
--- a/include/mbgl/style/expression/expression.hpp
+++ b/include/mbgl/style/expression/expression.hpp
@@ -93,10 +93,7 @@ using namespace mbgl::style::conversion;
class LiteralExpression : public Expression {
public:
- LiteralExpression(std::string key, float value_) : Expression(key, type::Primitive::Number), value(value_) {}
- LiteralExpression(std::string key, const std::string& value_) : Expression(key, type::Primitive::String), value(value_) {}
- LiteralExpression(std::string key, const mbgl::Color& value_) : Expression(key, type::Primitive::Color), value(value_) {}
- LiteralExpression(std::string key, const NullValue&) : Expression(key, type::Primitive::Null), value(Null) {}
+ LiteralExpression(std::string key, type::Type type, Value value_) : Expression(key, type), value(value_) {}
EvaluationResult evaluate(const EvaluationParameters&) const override {
return value;
@@ -104,31 +101,51 @@ public:
template <class V>
static ParseResult parse(const V& value, const ParsingContext& ctx) {
- if (isUndefined(value))
- return std::make_unique<LiteralExpression>(ctx.key(), Null);
-
+ const Value& parsedValue = parseValue(value);
+ const type::Type& type = parsedValue.match(
+ [&](float) -> type::Type { return type::Primitive::Number; },
+ [&](const std::string&) -> type::Type { return type::Primitive::String; },
+ [&](const mbgl::Color&) -> type::Type { return type::Primitive::Color; },
+ [&](const NullValue&) -> type::Type { return type::Primitive::Null; },
+ [&](const std::unordered_map<std::string, Value>&) -> type::Type { return type::Primitive::Object; },
+ [&](const std::vector<Value>& arr) -> type::Type {
+ // TODO
+ return type::Array(type::Primitive::Value, arr.size());
+ }
+ );
+ return std::make_unique<LiteralExpression>(ctx.key(), type, parsedValue);
+ }
+
+private:
+ template <class V>
+ static Value parseValue(const V& value) {
+ if (isUndefined(value)) return Null;
if (isObject(value)) {
- return CompileError {ctx.key(), "Unimplemented: object literals"};
+ std::unordered_map<std::string, Value> result;
+ eachMember(value, [&] (const std::string& k, const V& v) -> optional<conversion::Error> {
+ result.emplace(k, parseValue(v));
+ return {};
+ });
+ return result;
}
-
if (isArray(value)) {
- return CompileError {ctx.key(), "Unimplemented: array literals"};
+ std::vector<Value> result;
+ const auto length = arrayLength(value);
+ for(std::size_t i = 0; i < length; i++) {
+ result.emplace_back(parseValue(arrayMember(value, i)));
+ }
+ return result;
}
optional<mbgl::Value> v = toValue(value);
assert(v);
return v->match(
- [&] (std::string s) { return std::make_unique<LiteralExpression>(ctx.key(), s); },
- [&] (bool b) { return std::make_unique<LiteralExpression>(ctx.key(), b); },
- [&] (auto f) {
- auto number = numericValue<float>(f);
- assert(number);
- return std::make_unique<LiteralExpression>(ctx.key(), *number);
- }
+ [&] (const std::string& s) -> Value { return s; },
+ [&] (bool b) -> Value { return b; },
+ [&] (auto f) -> Value { return *numericValue<float>(f); }
);
}
-
-private:
+
Value value;
};
diff --git a/include/mbgl/style/expression/parse.hpp b/include/mbgl/style/expression/parse.hpp
index 1f5802d4fb..cba2231988 100644
--- a/include/mbgl/style/expression/parse.hpp
+++ b/include/mbgl/style/expression/parse.hpp
@@ -37,7 +37,8 @@ ParseResult parseExpression(const V& value, const ParsingContext& context)
using namespace mbgl::style::conversion;
if (isArray(value)) {
- if (arrayLength(value) == 0) {
+ const std::size_t length = arrayLength(value);
+ if (length == 0) {
CompileError error = {
"Expected an array with at least one element. If you wanted a literal array, use [\"literal\", []].",
context.key()
@@ -55,6 +56,14 @@ ParseResult parseExpression(const V& value, const ParsingContext& context)
return error;
}
+ if (*op == "literal") {
+ if (length != 2) return CompileError {
+ "'literal' expression requires exactly one argument, but found " + std::to_string(length - 1) + " instead.",
+ context.key()
+ };
+ return LiteralExpression::parse(arrayMember(value, 1), ParsingContext(context, {1}, {"literal"}));
+ }
+
if (*op == "+") return LambdaExpression::parse<PlusExpression>(value, context);
if (*op == "-") return LambdaExpression::parse<MinusExpression>(value, context);
if (*op == "*") return LambdaExpression::parse<TimesExpression>(value, context);
diff --git a/include/mbgl/style/function/type.hpp b/include/mbgl/style/function/type.hpp
index 94f710c005..19897ac77f 100644
--- a/include/mbgl/style/function/type.hpp
+++ b/include/mbgl/style/function/type.hpp
@@ -42,7 +42,7 @@ public:
static Primitive Object;
// It's weird for this to be on Primitive. Where should it go?
- static Type Value;
+ static ValueType Value;
private:
std::string name;
@@ -60,7 +60,7 @@ private:
class Array {
public:
Array(ValueType itemType_) : itemType(itemType_) {}
- Array(ValueType itemType_, int N_) : itemType(itemType_), N(N_) {}
+ Array(ValueType itemType_, std::size_t N_) : itemType(itemType_), N(N_) {}
std::string getName() const {
return "array";
}
diff --git a/src/mbgl/style/function/type.cpp b/src/mbgl/style/function/type.cpp
index fbfe6efbc3..5e1a95433f 100644
--- a/src/mbgl/style/function/type.cpp
+++ b/src/mbgl/style/function/type.cpp
@@ -12,7 +12,7 @@ Primitive Primitive::Color = {"Color"};
Primitive Primitive::Object = {"Object"};
// Need to add Array(Types::Value) to the member list somehow...
-Type Primitive::Value = Variant({
+ ValueType Primitive::Value = Variant({
Primitive::Null,
Primitive::String,
Primitive::Number,