Approaching Alt expression parsing
This commit is contained in:
@@ -4,9 +4,10 @@ Multiline comments /*will not
|
||||
split*/ an output expression. This should parse as one line of output.
|
||||
Comments at the end of lines won't parse as part of the Output. // I'm my own expression!
|
||||
You can {insert} the values of expressions.
|
||||
{you} can start an output line with an insert expression.
|
||||
{you} can start an output line with an insert expression. {and_end_one}
|
||||
{shuffle: Things get weird|when you start to use sequence expressions.}
|
||||
{once: And they don't get any easier|{when you nest them|{insert}}}!
|
||||
// If you don't believe me, just look at ParserTest.hx!!
|
||||
{once: And they don't get any {easier}|{when you nest them|{insert}}}!
|
||||
|
||||
You can {
|
||||
if (flag) "insert" else "interpolate"
|
||||
|
||||
43
hank/Alt.hx
43
hank/Alt.hx
@@ -1,5 +1,8 @@
|
||||
package hank;
|
||||
|
||||
import haxe.ds.Option;
|
||||
using Extensions.OptionExtender;
|
||||
|
||||
enum AltBehavior {
|
||||
Sequence;
|
||||
OnceOnly;
|
||||
@@ -7,9 +10,42 @@ enum AltBehavior {
|
||||
Shuffle;
|
||||
}
|
||||
|
||||
typedef Alt = {
|
||||
@:allow(hank.AltInstance)
|
||||
class Alt {
|
||||
var behavior: AltBehavior;
|
||||
var outputs: Array<Output>;
|
||||
|
||||
static var behaviorMap = [
|
||||
'>' => Sequence,
|
||||
'!' => OnceOnly,
|
||||
'&' => Cycle,
|
||||
'~' => Shuffle,
|
||||
'seq:' => Sequence,
|
||||
'once:' => OnceOnly,
|
||||
'cycle:' => Cycle,
|
||||
'shuffle:' => Shuffle
|
||||
];
|
||||
|
||||
public function new(behavior: AltBehavior, outputs: Array<Output>) {
|
||||
this.behavior = behavior;
|
||||
this.outputs = outputs;
|
||||
}
|
||||
|
||||
public static function parse(buffer: HankBuffer): Option<Alt> {
|
||||
var rawExpr = buffer.findNestedExpression('{', '}').unwrap().checkValue();
|
||||
var expr = rawExpr.substr(1, rawExpr.length-2);
|
||||
|
||||
for (prefix in behaviorMap.keys()) {
|
||||
if (StringTools.startsWith(expr, prefix)) {
|
||||
var _outputs = StringTools.trim(expr.substr(prefix.length));
|
||||
|
||||
buffer.take(rawExpr.length);
|
||||
return Some(new Alt(behaviorMap[prefix], []));
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
class AltInstance {
|
||||
@@ -18,10 +54,7 @@ class AltInstance {
|
||||
var random: Random;
|
||||
|
||||
public function new(behavior: AltBehavior, outputs: Array<Output>, random: Random) {
|
||||
this.alt = {
|
||||
behavior: behavior,
|
||||
outputs: outputs
|
||||
};
|
||||
this.alt = new Alt(behavior, outputs);
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class BufferSlice {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
public function checkValue() {
|
||||
public function checkValue(): String {
|
||||
if (!buffer.position().equals(anchorPosition)) {
|
||||
throw 'Tried to access an expired BufferSlice.';
|
||||
}
|
||||
@@ -91,7 +91,7 @@ class HankBuffer {
|
||||
return s;
|
||||
}
|
||||
|
||||
public function indexOf(s: String) {
|
||||
public function indexOf(s: String): Int {
|
||||
return cleanBuffer.indexOf(s);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class HankBuffer {
|
||||
}
|
||||
|
||||
/** Peek at contents buffer waiting further ahead in the buffer **/
|
||||
public function peekAhead(start: Int, length: Int) {
|
||||
public function peekAhead(start: Int, length: Int): String {
|
||||
return cleanBuffer.substr(start, length);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,18 +27,10 @@ class Output {
|
||||
|
||||
while (!buffer.isEmpty()) {
|
||||
var endSegment = buffer.length();
|
||||
var findHaxeExpression = buffer.findNestedExpression('{', '}');
|
||||
var findAltExpression = buffer.findNestedExpression('{{', '}}', 0, false); // Single brace expressions trip up the double brace search, so don't throw exceptions
|
||||
switch (findHaxeExpression) {
|
||||
var findBraceExpression = buffer.findNestedExpression('{', '}');
|
||||
switch (findBraceExpression) {
|
||||
case Some(slice):
|
||||
if (slice.start < endSegment)
|
||||
endSegment = slice.start;
|
||||
default:
|
||||
}
|
||||
switch (findAltExpression) {
|
||||
case Some(slice):
|
||||
if (slice.start < endSegment)
|
||||
endSegment = slice.start;
|
||||
endSegment = slice.start;
|
||||
default:
|
||||
}
|
||||
if (endSegment == buffer.length() || endSegment != 0) {
|
||||
@@ -47,7 +39,9 @@ class Output {
|
||||
if (peekLine.length < endSegment) {
|
||||
var text = buffer.takeLine().unwrap();
|
||||
trace(text);
|
||||
parts.push(Text(text));
|
||||
if (text.length > 0) {
|
||||
parts.push(Text(text));
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
var text = buffer.take(endSegment);
|
||||
@@ -55,11 +49,7 @@ class Output {
|
||||
parts.push(Text(text));
|
||||
}
|
||||
} else {
|
||||
if (buffer.indexOf('{{') == 0) {
|
||||
parts.push(parseAltExpression(buffer));
|
||||
} else {
|
||||
parts.push(parseHaxeExpression(buffer));
|
||||
}
|
||||
parts.push(parseBraceExpression(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +68,16 @@ class Output {
|
||||
return new Output(parts);
|
||||
}
|
||||
|
||||
public static function parseHaxeExpression(buffer: HankBuffer) {
|
||||
public static function parseBraceExpression(buffer: HankBuffer): OutputType {
|
||||
switch (Alt.parse(buffer)) {
|
||||
case Some(altExpression):
|
||||
return AltExpression(altExpression);
|
||||
default:
|
||||
return parseHaxeExpression(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public static function parseHaxeExpression(buffer: HankBuffer): OutputType {
|
||||
var rawExpression = buffer.findNestedExpression('{', '}').unwrap().checkValue();
|
||||
// Strip out the enclosing braces
|
||||
var hExpression = rawExpression.substr(1, rawExpression.length - 2);
|
||||
@@ -88,8 +87,4 @@ class Output {
|
||||
buffer.take(rawExpression.length);
|
||||
return HExpression(hExpression);
|
||||
}
|
||||
|
||||
public static function parseAltExpression(buffer: HankBuffer) {
|
||||
return AltExpression({behavior: Cycle, outputs:[]});
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import hank.Parser;
|
||||
import hank.Parser.HankAST;
|
||||
import hank.Output;
|
||||
import hank.Output.OutputType;
|
||||
import hank.Alt;
|
||||
import hank.Alt.AltBehavior;
|
||||
|
||||
class ParserTest extends utest.Test {
|
||||
var ast: HankAST;
|
||||
@@ -25,6 +27,21 @@ class ParserTest extends utest.Test {
|
||||
assertNextExpr(EOutput(new Output([Text("A line won't be interrupted or anything.")])));
|
||||
assertNextExpr(EOutput(new Output([Text("Multiline comments an output expression. This should parse as one line of output.")])));
|
||||
assertNextExpr(EOutput(new Output([Text("Comments at the end of lines won't parse as part of the Output.")])));
|
||||
assertNextExpr(EOutput(new Output([Text("You can "), HExpression("insert"), Text(" the values of expressions.")])));
|
||||
assertNextExpr(EOutput(new Output([HExpression("you"), Text(" can start an output line with an insert expression. "), HExpression("and_end_one")])));
|
||||
|
||||
assertNextExpr(
|
||||
EOutput(new Output([
|
||||
AltExpression(
|
||||
new Alt(
|
||||
Shuffle,
|
||||
[
|
||||
new Output([Text("Things get weird"), Text("when you start to use sequence expressions.")])
|
||||
]
|
||||
)
|
||||
)
|
||||
]))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user