More satsifying Stream fixes
This commit is contained in:
@@ -140,13 +140,9 @@ class Reader {
|
|||||||
public static final terminators = [")", "]", "}", '"', "/*", "\n", " "];
|
public static final terminators = [")", "]", "}", '"', "/*", "\n", " "];
|
||||||
|
|
||||||
public static function nextToken(stream:Stream, expect:String) {
|
public static function nextToken(stream:Stream, expect:String) {
|
||||||
switch (stream.takeUntilOneOf(terminators)) {
|
switch (stream.takeUntilOneOf(terminators, true)) {
|
||||||
case Some(tok) if (tok.length > 0):
|
case Some(tok) if (tok.length > 0):
|
||||||
return tok;
|
return tok;
|
||||||
case None if (stream.content.length > 0):
|
|
||||||
var tok = stream.content;
|
|
||||||
stream.dropChars(stream.content.length);
|
|
||||||
return tok;
|
|
||||||
default:
|
default:
|
||||||
stream.error('Expected $expect');
|
stream.error('Expected $expect');
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -165,10 +165,15 @@ class Stream {
|
|||||||
dropChars(content.length - trimmed.length);
|
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);
|
var indices = [for (term in terminators) content.indexOf(term)].filter((idx) -> idx >= 0);
|
||||||
if (indices.length == 0)
|
if (indices.length == 0) {
|
||||||
return None;
|
return if (allowEOF) {
|
||||||
|
Some(takeRest());
|
||||||
|
} else {
|
||||||
|
None;
|
||||||
|
}
|
||||||
|
}
|
||||||
var firstIndex = Math.floor(indices.fold(Math.min, indices[0]));
|
var firstIndex = Math.floor(indices.fold(Math.min, indices[0]));
|
||||||
return takeChars(firstIndex);
|
return takeChars(firstIndex);
|
||||||
}
|
}
|
||||||
@@ -184,8 +189,18 @@ class Stream {
|
|||||||
return Some(toReturn);
|
return Some(toReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function takeRest():String {
|
||||||
|
var toReturn = content;
|
||||||
|
dropChars(content.length);
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
public function takeLine():Option<String> {
|
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 {
|
public function expect(whatToExpect:String, f:Void->Option<String>):String {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
(set pp (or pp (new Map<String,String>)))
|
(set pp (or pp (new Map<String,String>)))
|
||||||
(when (stream.isEmpty) (return pp))
|
(when (stream.isEmpty) (return pp))
|
||||||
(let [key (stream.expect "passport key" (lambda [] (stream.takeUntilAndDrop ":")))
|
(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))
|
(dictSet pp key value))
|
||||||
(if (= #|"\n\n"|# (try (stream.expect "paragraph break" (lambda [] (stream.peekChars 2))) (catch [e] "")))
|
(if (= #|"\n\n"|# (try (stream.expect "paragraph break" (lambda [] (stream.peekChars 2))) (catch [e] "")))
|
||||||
(begin (stream.dropWhitespace) pp)
|
(begin (stream.dropWhitespace) pp)
|
||||||
|
|||||||
Reference in New Issue
Block a user