First strides towards parsing Output expressions

This commit is contained in:
2019-03-16 19:26:40 -06:00
parent d4946f0915
commit 901f6852ea
4 changed files with 74 additions and 6 deletions

View File

@@ -91,6 +91,14 @@ class HankBuffer {
return s;
}
public function indexOf(s: String) {
return cleanBuffer.indexOf(s);
}
public function length(): Int {
return cleanBuffer.length;
}
public function position(): Position {
return new Position(path, line, column);
}
@@ -262,7 +270,7 @@ class HankBuffer {
}
/** Return the start index and length of number of characters left the buffer before a nestable expression terminates **/
public function findNestedExpression(o: String, c: String, start: Int = 0): Option<BufferSlice> {
public function findNestedExpression(o: String, c: String, start: Int = 0, throwExceptions: Bool = true): Option<BufferSlice> {
var startIdx = start;
var endIdx = start;
var depth = 0;
@@ -276,10 +284,16 @@ class HankBuffer {
if (nextOpeningIdx == -1 && nextClosingIdx == -1) {
return None;
} else if (depth == 0 && nextOpeningIdx == -1 ) {
throw 'FUBAR';
if (throwExceptions)
throw 'Your input file $path has an expression with an unmatched closing operator $c';
else
return None;
}
else if (depth != 0 && nextClosingIdx == -1) {
throw 'FUBAR';
if (throwExceptions)
throw 'Your input file $path has an expression with an unmatched opening operator $o';
else
return None;
}
else if (nextOpeningIdx != -1 && nextOpeningIdx < nextClosingIdx) {
if (depth == 0) {

View File

@@ -1,5 +1,7 @@
package hank;
using Extensions.OptionExtender;
enum OutputType {
Text(t: String); // Pure text that is always displayed
AltExpression(a: Alt);
@@ -21,10 +23,62 @@ class Output {
}
public static function parse(buffer: HankBuffer): Output {
var parts = [];
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) {
case Some(slice):
if (slice.start < endSegment)
endSegment = slice.start;
default:
}
switch (findAltExpression) {
case Some(slice):
if (slice.start < endSegment)
endSegment = slice.start;
default:
}
if (endSegment == buffer.length() || endSegment != 0) {
var peekLine = buffer.peekLine().unwrap();
if (peekLine.length < endSegment) {
parts.push(Text(buffer.takeLine().unwrap()));
break;
} else {
parts.push(Text(buffer.take(endSegment)));
}
} else {
if (buffer.indexOf('{{') == 0) {
parts.push(parseAltExpression(buffer));
} else {
parts.push(parseHaxeExpression(buffer));
}
}
}
// Parse out optional text parts
// Find the first level of nested brace, expressions, and parse them out
return new Output([]);
return new Output(parts);
}
public static function parseHaxeExpression(buffer: HankBuffer) {
trace('parseHaxeExpresion');
var rawExpression = buffer.findNestedExpression('{', '}').unwrap().checkValue();
// Strip out the enclosing braces
var hExpression = rawExpression.substr(1, rawExpression.length - 2);
// TODO process quasiquotes??
buffer.take(rawExpression.length);
return HExpression(hExpression);
}
public static function parseAltExpression(buffer: HankBuffer) {
trace('parseAltExpression');
return AltExpression({behavior: Cycle, outputs:[]});
}
}

View File

@@ -22,7 +22,7 @@ class ParserTest extends utest.Test {
var parser = new Parser();
ast = parser.parseFile('examples/parsing/output.hank');
assertNextExpr(EOutput(new Output([Text("This file contains test cases for output expression parsing.")])));
assertNextExpr(EOutput(new Output([Text("A line won't be interrupted or anything.")])));
assertNextExpr(EOutput(new Output([Text("A line won't be interrupted or anything.")])));
}

View File

@@ -3,6 +3,6 @@ import utest.Test;
class TestMain extends Test {
public static function main() {
utest.UTest.run([new HInterfaceTest(), new HankBufferTest()/*, new ParserTest()*/]);
utest.UTest.run([new HInterfaceTest(), new HankBufferTest(), new ParserTest()]);
}
}