Implement text serialization of strings

Use json.encode/json.decode.  This gets some strings wrong but it
should be enough to make more progress.

Testing with hardcoded strings is already getting awkward.

Change-Id: Ie0b168bec611ed93da13fff90f86232bb56c713f
Reviewed-on: https://dart-review.googlesource.com/c/87663
Reviewed-by: Daniel Hillerström <hillerstrom@google.com>
Commit-Queue: Kevin Millikin <kmillikin@google.com>
This commit is contained in:
Kevin Millikin 2018-12-20 11:12:49 +00:00 committed by commit-bot@chromium.org
parent cc5c78cfd2
commit ff44e27c5a
4 changed files with 60 additions and 4 deletions

View file

@ -4,6 +4,8 @@
library kernel.serializer_combinators;
import 'dart:convert' show json;
import '../ast.dart' show Expression;
import 'text_serializer.dart' show ExpressionTagger;
@ -28,7 +30,23 @@ class Nothing extends TextSerializer<void> {
bool get isEmpty => true;
}
// == Serializer/deserializers for basic Dart types
class DartString extends TextSerializer<String> {
const DartString();
String readFrom(Iterator<Object> stream) {
if (stream.current is! String) {
throw StateError("expected an atom, found a list");
}
String result = json.decode(stream.current);
stream.moveNext();
return result;
}
void writeTo(StringBuffer buffer, String object) {
buffer.write(json.encode(object));
}
}
class DartInt extends TextSerializer<int> {
const DartInt();

View file

@ -21,6 +21,8 @@ class TextIterator implements Iterator<Object /* String | TextIterator */ > {
static int space = ' '.codeUnitAt(0);
static int lparen = '('.codeUnitAt(0);
static int rparen = ')'.codeUnitAt(0);
static int dquote = '"'.codeUnitAt(0);
static int bslash = '\\'.codeUnitAt(0);
final String input;
int index;
@ -44,11 +46,33 @@ class TextIterator implements Iterator<Object /* String | TextIterator */ > {
}
void skipToEndOfAtom() {
bool isQuoted = false;
if (index < input.length && input.codeUnitAt(index) == dquote) {
++index;
isQuoted = true;
}
do {
if (index >= input.length) return;
int codeUnit = input.codeUnitAt(index);
if (codeUnit == space || codeUnit == rparen) return;
++index;
if (isQuoted) {
// Terminator.
if (codeUnit == dquote) {
++index;
return;
}
// Escaped double quote.
if (codeUnit == bslash &&
index < input.length + 1 &&
input.codeUnitAt(index + 1) == dquote) {
index += 2;
} else {
++index;
}
} else {
// Terminator.
if (codeUnit == space || codeUnit == rparen) return;
++index;
}
} while (true);
}

View file

@ -13,6 +13,7 @@ import '../visitor.dart' show ExpressionVisitor;
class ExpressionTagger extends ExpressionVisitor<String> {
const ExpressionTagger();
String visitStringLiteral(StringLiteral _) => "string";
String visitIntLiteral(IntLiteral _) => "int";
String visitDoubleLiteral(DoubleLiteral _) => "double";
String visitBoolLiteral(BoolLiteral _) => "bool";
@ -21,17 +22,26 @@ class ExpressionTagger extends ExpressionVisitor<String> {
// ==== Serializers for BasicLiterals
const TextSerializer<BasicLiteral> basicLiteralSerializer = Case([
"string",
"int",
"double",
"bool",
"null"
], [
stringLiteralSerializer,
intLiteralSerializer,
doubleLiteralSerializer,
boolLiteralSerializer,
nullLiteralSerializer
]);
const TextSerializer<StringLiteral> stringLiteralSerializer =
Wrapped(unwrapStringLiteral, wrapStringLiteral, DartString());
String unwrapStringLiteral(StringLiteral literal) => literal.value;
StringLiteral wrapStringLiteral(String value) => new StringLiteral(value);
const TextSerializer<IntLiteral> intLiteralSerializer =
Wrapped(unwrapIntLiteral, wrapIntLiteral, DartInt());

View file

@ -31,13 +31,17 @@ String writeBasicLiteral(BasicLiteral literal) {
void test() {
List<String> failures = [];
List<String> tests = [
"(string \"Hello, 'string'!\")",
"(string \"Hello, \\\"string\\\"!\")",
"(string \"Yeah nah yeah, here is\\nthis really long string haiku\\n"
"blowing in the wind\\n\")",
"(int 42)",
"(int 0)",
"(int -1001)",
"(double 3.14159)",
"(bool true)",
"(bool false)",
"(null)"
"(null)",
];
for (var test in tests) {
var literal = readBasicLiteral(test);