More satsifying Stream fixes

This commit is contained in:
2021-04-05 20:28:21 -06:00
parent cc76199a72
commit ff2c5f77d4
3 changed files with 21 additions and 10 deletions

View File

@@ -140,13 +140,9 @@ class Reader {
public static final terminators = [")", "]", "}", '"', "/*", "\n", " "];
public static function nextToken(stream:Stream, expect:String) {
switch (stream.takeUntilOneOf(terminators)) {
switch (stream.takeUntilOneOf(terminators, true)) {
case Some(tok) if (tok.length > 0):
return tok;
case None if (stream.content.length > 0):
var tok = stream.content;
stream.dropChars(stream.content.length);
return tok;
default:
stream.error('Expected $expect');
return null;

View File

@@ -165,10 +165,15 @@ class Stream {
dropChars(content.length - trimmed.length);
}
public function takeUntilOneOf(terminators:Array<String>):Option<String> {
public function takeUntilOneOf(terminators:Array<String>, allowEOF:Bool = false):Option<String> {
var indices = [for (term in terminators) content.indexOf(term)].filter((idx) -> idx >= 0);
if (indices.length == 0)
return None;
if (indices.length == 0) {
return if (allowEOF) {
Some(takeRest());
} else {
None;
}
}
var firstIndex = Math.floor(indices.fold(Math.min, indices[0]));
return takeChars(firstIndex);
}
@@ -184,8 +189,18 @@ class Stream {
return Some(toReturn);
}
public function takeRest():String {
var toReturn = content;
dropChars(content.length);
return toReturn;
}
public function takeLine():Option<String> {
return takeUntilAndDrop("\n");
return switch (takeUntilAndDrop("\n")) {
case Some(line): Some(line);
case None if (content.length > 0): Some(takeRest());
default: None;
};
}
public function expect(whatToExpect:String, f:Void->Option<String>):String {

View File

@@ -2,7 +2,7 @@
(set pp (or pp (new Map<String,String>)))
(when (stream.isEmpty) (return pp))
(let [key (stream.expect "passport key" (lambda [] (stream.takeUntilAndDrop ":")))
value (stream.expect "passport value" (lambda [] (stream.takeUntilOneOf [" " #|"\n"|#])))]
value (stream.expect "passport value" (lambda [] (stream.takeUntilOneOf [" " "\n"] true)))]
(dictSet pp key value))
(if (= #|"\n\n"|# (try (stream.expect "paragraph break" (lambda [] (stream.peekChars 2))) (catch [e] "")))
(begin (stream.dropWhitespace) pp)