Last active
August 29, 2015 14:21
-
-
Save fowlmouth/23416b8607337623a330 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import macros | |
macro echoCode (x:varargs[untyped]): stmt = | |
var call = newCall("echo") | |
let high = len(x)-1 | |
for i in 0 .. high: | |
let item = x[i] | |
let code = repr(item) | |
call.add( | |
quote do: `code`, | |
newLit(": "), | |
quote do: `item` | |
) | |
if i < high: | |
call.add newLit ", " | |
if len(call) > 1: | |
return call | |
type MatchLocation* = object | |
line*, col*: int | |
index*: int | |
proc binarySearch [T] (a: openArray[T], key: T): int = | |
## binary search for `key` in `a`. Returns insertion index. | |
## adapted from nim stdlib algorithm module | |
var b = len(a) | |
while result < b: | |
var mid = (result + b) div 2 | |
if a[mid] < key: result = mid + 1 | |
else: b = mid | |
if result >= len(a): result = -1 | |
proc findLineCol (input:InputState; index:int): MatchLocation = | |
result.index = index | |
if input.newlines.len == 0: | |
# no newlines edgecase | |
result.line = 0 | |
result.col = index | |
return | |
var line = input.newlines.binarySearch(index) | |
echoCode index, line, input.newlines | |
if line == -1: line = <len(input.newlines) | |
let line_index = | |
if line == 0: 0 | |
else: input.newlines[<line] | |
#let line_index = input.newlines[line] # index of the newline | |
stdout.write " " | |
echoCode line_index | |
result.line = line | |
result.col = index - line_index | |
proc loc* (input:var InputState; index:int): MatchLocation = | |
if input.newlines.isNil: | |
input.newlines = newseq[int]() | |
var i = 0 | |
while i < len(input.str): | |
if input.str[i] == '\L': | |
input.newlines.add i | |
elif input.str[i] == '\r' and input.str[i+1] == '\L': | |
input.newlines.add i | |
inc i, 1 | |
inc i,1 | |
result = input.findLineCol index |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import glossolalia | |
type Node = object | |
s: string | |
locA,locB: MatchLocation | |
grammar(Node): | |
proc dbgNode [N] (r:Rule[N]): Rule[N] = | |
Rule[N]( | |
m: proc(input:var InputState): Match[N] = | |
result = r.m(input) | |
if result.kind == mNodes: | |
for n in result.nodes: | |
echo n | |
echo "____________" | |
) | |
proc saveNode (match:string; locA,locB:MatchLocation): Node = | |
Node(s: match, locA: locA, locB: locB) | |
whitespace := | |
+(str("\r\L") or chr({'\L',' ','\t'})) | |
test_rule := | |
?whitespace and | |
chr('A').repeat(0,3).save(saveNode).dbgNode and | |
?whitespace and | |
chr('B').repeat(0,3).save(saveNode).dbgNode and | |
?whitespace and | |
chr('C').repeat(0,3).save(saveNode).dbgNode and | |
?whitespace | |
let tests = [ | |
"AAABBBCCC", | |
"AAA\LBBB\LCCC", | |
"\LAAA\LBBB\LCCC\L" | |
] | |
for t in tests: | |
let m = test_rule.match(t) | |
if m: | |
for x in m.nodes: | |
echo x | |
else: | |
echo "failed to match ", t | |
echo "#######################################" | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(s: AAA, locA: (line: 0, col: 0, index: 0), locB: (line: 0, col: 3, index: 3)) | |
____________ | |
(s: BBB, locA: (line: 0, col: 3, index: 3), locB: (line: 0, col: 6, index: 6)) | |
____________ | |
(s: CCC, locA: (line: 0, col: 6, index: 6), locB: (line: 0, col: 9, index: 9)) | |
____________ | |
(s: AAA, locA: (line: 0, col: 0, index: 0), locB: (line: 0, col: 3, index: 3)) | |
(s: BBB, locA: (line: 0, col: 3, index: 3), locB: (line: 0, col: 6, index: 6)) | |
(s: CCC, locA: (line: 0, col: 6, index: 6), locB: (line: 0, col: 9, index: 9)) | |
####################################### | |
index: 0, line: 0, input.newlines: @[3, 7] | |
line_index: 0 | |
index: 3, line: 0, input.newlines: @[3, 7] | |
line_index: 0 | |
(s: AAA, locA: (line: 0, col: 0, index: 0), locB: (line: 0, col: 3, index: 3)) | |
____________ | |
index: 4, line: 1, input.newlines: @[3, 7] | |
line_index: 3 | |
index: 7, line: 1, input.newlines: @[3, 7] | |
line_index: 3 | |
(s: BBB, locA: (line: 1, col: 1, index: 4), locB: (line: 1, col: 4, index: 7)) | |
____________ | |
index: 8, line: -1, input.newlines: @[3, 7] | |
line_index: 3 | |
index: 11, line: -1, input.newlines: @[3, 7] | |
line_index: 3 | |
(s: CCC, locA: (line: 1, col: 5, index: 8), locB: (line: 1, col: 8, index: 11)) | |
____________ | |
(s: AAA, locA: (line: 0, col: 0, index: 0), locB: (line: 0, col: 3, index: 3)) | |
(s: BBB, locA: (line: 1, col: 1, index: 4), locB: (line: 1, col: 4, index: 7)) | |
(s: CCC, locA: (line: 1, col: 5, index: 8), locB: (line: 1, col: 8, index: 11)) | |
####################################### | |
index: 1, line: 1, input.newlines: @[0, 4, 8, 12] | |
line_index: 0 | |
index: 4, line: 1, input.newlines: @[0, 4, 8, 12] | |
line_index: 0 | |
(s: AAA, locA: (line: 1, col: 1, index: 1), locB: (line: 1, col: 4, index: 4)) | |
____________ | |
index: 5, line: 2, input.newlines: @[0, 4, 8, 12] | |
line_index: 4 | |
index: 8, line: 2, input.newlines: @[0, 4, 8, 12] | |
line_index: 4 | |
(s: BBB, locA: (line: 2, col: 1, index: 5), locB: (line: 2, col: 4, index: 8)) | |
____________ | |
index: 9, line: 3, input.newlines: @[0, 4, 8, 12] | |
line_index: 8 | |
index: 12, line: 3, input.newlines: @[0, 4, 8, 12] | |
line_index: 8 | |
(s: CCC, locA: (line: 3, col: 1, index: 9), locB: (line: 3, col: 4, index: 12)) | |
____________ | |
(s: AAA, locA: (line: 1, col: 1, index: 1), locB: (line: 1, col: 4, index: 4)) | |
(s: BBB, locA: (line: 2, col: 1, index: 5), locB: (line: 2, col: 4, index: 8)) | |
(s: CCC, locA: (line: 3, col: 1, index: 9), locB: (line: 3, col: 4, index: 12)) | |
####################################### |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment