to_code now adds quotes around strings.

to_code for map now includes keys.
This maans that the basic script-functions test passes.
This commit is contained in:
Twan van Laarhoven
2020-04-26 17:35:14 +02:00
parent 2e897edbbf
commit c324c8bbbb
5 changed files with 55 additions and 24 deletions
+11 -11
View File
@@ -22,11 +22,11 @@ extern ScriptValueP dependency_dummy;
// A dummy type used during dependency analysis,
// it simply supresses all error messages.
class DependencyDummy : public ScriptIterator {
public:
virtual ScriptType type() const { return SCRIPT_DUMMY; }
virtual String typeName() const { return _("dummy"); }
virtual ScriptValueP next(ScriptValueP*) { return ScriptValueP(); }
virtual ScriptValueP dependencyName(const ScriptValue&, const Dependency&) const { return dependency_dummy; }
public:
ScriptType type() const override { return SCRIPT_DUMMY; }
String typeName() const override { return _("dummy"); }
ScriptValueP next(ScriptValueP*,int*) override { return ScriptValueP(); }
ScriptValueP dependencyName(const ScriptValue&, const Dependency&) const override { return dependency_dummy; }
};
ScriptValueP dependency_dummy(new DependencyDummy);
@@ -43,19 +43,19 @@ public:
: a(a), b(b)
{}
virtual ScriptType type() const { return SCRIPT_DUMMY; }
virtual String typeName() const { return _("union of ") + a->typeName() + _(" and ") + b->typeName(); }
ScriptType type() const override { return SCRIPT_DUMMY; }
String typeName() const override { return _("union of ") + a->typeName() + _(" and ") + b->typeName(); }
virtual ScriptValueP dependencies(Context& ctx, const Dependency& dep) const {
ScriptValueP dependencies(Context& ctx, const Dependency& dep) const override {
return unified( a->dependencies(ctx,dep), b->dependencies(ctx,dep));
}
virtual ScriptValueP makeIterator(ScriptValueP thisP) const {
ScriptValueP makeIterator(const ScriptValueP& thisP) const override {
return unified(a->makeIterator(a), b->makeIterator(b));
}
virtual ScriptValueP dependencyMember(const String& name, const Dependency& dep) const {
ScriptValueP dependencyMember(const String& name, const Dependency& dep) const override {
return unified(a->dependencyMember(name,dep), b->dependencyMember(name,dep));
}
virtual ScriptValueP dependencyName(const ScriptValue& container, const Dependency& dep) const {
ScriptValueP dependencyName(const ScriptValue& container, const Dependency& dep) const override {
return unified(a->dependencyName(container,dep), b->dependencyName(container,dep));
}
private:
+3 -2
View File
@@ -75,7 +75,7 @@ struct ScriptIterator : public ScriptValue {
CompareWhat compareAs(String&, void const*&) const override;
/// Return the next item for this iterator, or ScriptValueP() if there is no such item
ScriptValueP next(ScriptValueP* key_out = nullptr) override = 0;
ScriptValueP next(ScriptValueP* key_out = nullptr, int* index_out = nullptr) override = 0;
ScriptValueP makeIterator(const ScriptValueP& thisP) const override;
};
@@ -98,9 +98,10 @@ template <typename Collection>
class ScriptCollectionIterator : public ScriptIterator {
public:
ScriptCollectionIterator(const Collection* col) : pos(0), col(col) {}
ScriptValueP next(ScriptValueP* key_out) override {
ScriptValueP next(ScriptValueP* key_out, int* index_out) override {
if (pos < col->size()) {
if (key_out) *key_out = to_script((int)pos);
if (index_out) *index_out = (int)pos;
return to_script(col->at(pos++));
} else {
return ScriptValueP();
+35 -8
View File
@@ -46,7 +46,7 @@ ScriptValueP ScriptValue::eval(Context&, bool) const {
return delay_error(ScriptErrorConversion(typeName(), _TYPE_("function")));
}
ScriptValueP ScriptValue::next(ScriptValueP* key_out) {
ScriptValueP ScriptValue::next(ScriptValueP* key_out, int* index_out) {
throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator"));
}
ScriptValueP ScriptValue::makeIterator(const ScriptValueP&) const {
@@ -183,9 +183,10 @@ public:
ScriptRangeIterator(int start, int end)
: pos(start), start(start), end(end)
{}
ScriptValueP next(ScriptValueP* key_out) override {
ScriptValueP next(ScriptValueP* key_out, int* index_out) override {
if (pos <= end) {
if (key_out) *key_out = to_script(pos-start);
if (index_out) *index_out = (int)pos;
return to_script(pos++);
} else {
return ScriptValueP();
@@ -288,6 +289,22 @@ ScriptValueP to_script(double v) {
// ----------------------------------------------------------------------------- : String type
String quote_string(String const& str) {
String out;
out.reserve(str.size() + 2);
out += _('"');
FOR_EACH_CONST(c, str) {
if (c == _('"') || c == _('\\')) { out += _('\\'); out += c; }
else if (c == _('\1')) out += _("\\<");
else if (c == _('\n')) out += _("\\n");
else if (c == _('\r')) out += _("\\r");
else if (c == _('\t')) out += _("\\t");
else out += c;
}
out += _('"');
return out;
}
// String values
class ScriptString : public ScriptValue {
public:
@@ -295,6 +312,9 @@ public:
ScriptType type() const override { return SCRIPT_STRING; }
String typeName() const override { return _TYPE_("string") + _(" (\"") + (value.size() < 30 ? value : value.substr(0,30) + _("...")) + _("\")"); }
String toString() const override { return value; }
String toCode() const override {
return quote_string(value);
}
double toDouble() const override {
double d;
if (value.ToDouble(&d)) {
@@ -437,10 +457,15 @@ String ScriptCollectionBase::toCode() const {
String ret = _("[");
bool first = true;
ScriptValueP it = makeIterator();
while (ScriptValueP v = it->next()) {
ScriptValueP key;
int index = -1;
while (ScriptValueP v = it->next(&key,&index)) {
if (!first) ret += _(",");
first = false;
// todo: include keys
if (index == -1) {
ret += key->toCode();
ret += _(":");
}
ret += v->toCode();
}
ret += _("]");
@@ -454,12 +479,14 @@ class ScriptCustomCollectionIterator : public ScriptIterator {
public:
ScriptCustomCollectionIterator(ScriptCustomCollection const* col, ScriptValueP const& col_owned)
: col(col), col_owned(col_owned), pos(0), it(col->key_value.begin()) {}
ScriptValueP next(ScriptValueP* key_out) override {
ScriptValueP next(ScriptValueP* key_out, int* index_out) override {
if (pos < col->value.size()) {
if (key_out) *key_out = to_script((int)pos);
if (index_out) *index_out = (int)pos;
return col->value.at(pos++);
} else if (it != col->key_value.end()) {
if (key_out) *key_out = to_script(it->first);
if (index_out) *index_out = -1;
return (it++)->second;
} else {
return ScriptValueP();
@@ -498,14 +525,14 @@ class ScriptConcatCollectionIterator : public ScriptIterator {
public:
ScriptConcatCollectionIterator(const ScriptValueP& itA, const ScriptValueP& itB)
: itA(itA), itB(itB) {}
ScriptValueP next(ScriptValueP* key_out) override {
ScriptValueP next(ScriptValueP* key_out, int* index_out) override {
if (itA) {
ScriptValueP v = itA->next(key_out);
ScriptValueP v = itA->next(key_out, index_out);
if (v) return v;
else itA = ScriptValueP();
}
// TODO: somehow fix up the keys
return itB->next(key_out);
return itB->next(key_out, index_out);
}
private:
ScriptValueP itA, itB;
+4 -2
View File
@@ -104,8 +104,10 @@ public:
*/
virtual ScriptValueP makeIterator(const ScriptValueP& thisP = ScriptValueP()) const;
/// Return the next item for this iterator, or ScriptValueP() if there is no such item
/** If key_out != 0, then it will recieve the key of the item */
virtual ScriptValueP next(ScriptValueP* key_out = nullptr);
/** If key_out != nullptr, then it will receive the key of the item
* If index_out != nullptr, then it will receive to index of the item if it is in an indexable container
*/
virtual ScriptValueP next(ScriptValueP* key_out = nullptr, int* index_out = nullptr);
/// Return the number of items in this value (assuming it is a collection)
virtual int itemCount() const;
/// Get a member at the given index
+2 -1
View File
@@ -93,6 +93,7 @@ assert( length([]) == 0)
assert( length([1]) == 1)
assert( length([1,2]) == 2)
assert( length([a:1,b:2]) == 2)
assert( length([1,2,3] + [4,5]) == 5)
assert( length("") == 0)
assert( length("1") == 1)
assert( length("12") == 2)
@@ -183,7 +184,7 @@ assert(to_code("abc") == "\"abc\"")
assert(to_code("\\\<\n\r\t") == "\"\\\\\\<\\n\\r\\t\"")
assert(to_code(1) == "1")
assert(to_code([1,2,3]) == "[1,2,3]")
assert(to_code([x:"y"]) == "[x:\"y\"]")
assert(to_code([x:"y"]) == "[\"x\":\"y\"]")
# count_chosen
assert( count_chosen("") == 0 )