1
0
Fork 0
mirror of https://github.com/Oreolek/ink-instead.git synced 2024-06-30 22:04:58 +03:00

damn nested choices

This commit is contained in:
premek 2016-12-04 01:38:27 +01:00
parent 2e2fd68e4f
commit e9909003b0
6 changed files with 125 additions and 16 deletions

View file

@ -1,12 +1,19 @@
require "util" require "util"
local lpeg = require "lpeg" local lpeg = require "lpeg"
lpeg.locale(lpeg) lpeg.locale(lpeg)
local S,C,Ct,Cc,Cg,Cf,P,V = lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cf, lpeg.P, lpeg.V local S,C,Ct,Cc,Cg,Cb,Cf,Cmt,P,V =
local parserLogger = print lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cb, lpeg.Cf, lpeg.Cmt,
lpeg.P, lpeg.V
local sp = S" \t" ^0 + -1 local concat = function (p)
local wh = S" \t\r\n" ^0 + -1 return Cf(p, function (a,b) return a..b end)
local nl = S"\r\n" ^1 + -1 end
local parserLogger = print
local eof = -1
local sp = S" \t" ^0 + eof
local wh = S" \t\r\n" ^0 + eof
local nl = S"\r\n" ^1 + eof
local id = (lpeg.alpha + '_') * (lpeg.alnum + '_')^0 local id = (lpeg.alpha + '_') * (lpeg.alnum + '_')^0
local addr = C(id) * ('.' * C(id))^-1 local addr = C(id) * ('.' * C(id))^-1
@ -26,23 +33,41 @@ local divert = divertEnd + divertJump
local knotHead = P('=')^2/'knot' * wh * C(id) * wh * P('=')^0 * wh local knotHead = P('=')^2/'knot' * wh * C(id) * wh * P('=')^0 * wh
local stitchHead = P('=')^1/'stitch' * wh * C(id) * wh * P('=')^0 * wh local stitchHead = P('=')^1/'stitch' * wh * C(id) * wh * P('=')^0 * wh
local optionDiv = '[' * C((P(1) - ']')^0) * ']' local optDiv = '[' * C((P(1) - ']')^0) * ']'
local optStars = concat(wh * C(P'*') * (sp * C'*')^0)
local optStarsSameIndent = Cmt(Cb("indent") * optStars,
function (s, i, a, b) return a == b end)
local optStarsLEIndent = Cmt(Cb("indent") * optStars,
function (s, i, backtrack, this)
return string.len(this) <= string.len(backtrack)
end)
local ink = P({ local ink = P({
"lines", "lines",
knott = Ct(knotHead * (V'line'-knotHead)^0 * wh), knotKnot = Ct(knotHead * (V'line'-knotHead)^0 * wh),
stitch = Ct(stitchHead * (V'line'-stitchHead)^0 * wh), knotStitch = Ct(stitchHead * (V'line'-stitchHead)^0 * wh),
knot = V'knotKnot' + V'knotStitch',
stmt = glue + divert + V'knott' + V'stitch' + optionDiv + comm, stmt = glue + divert + V'knot' + optDiv + comm,
text = C((1-nl-V'stmt')^1) *wh, text = C((1-nl-V'stmt')^1) *wh,
textE = C((1-nl-V'stmt')^0) *wh, textE = C((1-nl-V'stmt')^0) *wh,
optionAnsWithDiv = V'textE' * optionDiv * V'textE' * wh, optAnsWithDiv = V'textE' * optDiv * V'textE' * wh,
optionAnsWithoutDiv = V'textE' * Cc ''* Cc ''* wh, -- huh? optAnsWithoutDiv = V'textE' * Cc ''* Cc ''* wh, -- huh?
optionHead = P'*'/'option' * sp * (V'optionAnsWithDiv' + V'optionAnsWithoutDiv'), optAns = V'optAnsWithDiv' + V'optAnsWithoutDiv',
option = Ct(V'optionHead' * (V'line'-V'optionHead'-V'knott'-V'stitch')^0 * wh), --TODO which can by toplevel only?
choice = Ct(Cc'choice' * V'option'^1), -- TODO clean this
opt = Cg(optStars,'indent') *
Ct(Cc'option' * sp * V'optAns' * (V'line'-V'optLEIndent'-V'knot')^0 * wh), --TODO which can by toplevel only?
optSameIndent = Ct(Cc'option' * optStarsSameIndent * sp * V'optAns' * (V'line'-V'optLEIndent'-V'knot')^0 * wh),
optLEIndent = Ct(Cc'option' * optStarsLEIndent * sp * V'optAns' * (V'line'-V'optLEIndent'-V'knot')^0 * wh),
opts = (V'opt'*V'optSameIndent'^0),
choice = Ct(Cc'choice' * V'opts')/function(t) t.indent=nil; return t end,
para = Ct(Cc'para' * V'text'), para = Ct(Cc'para' * V'text'),

View file

@ -12,13 +12,17 @@ function testText() doTestS(
{{"para", "Hello world"}} {{"para", "Hello world"}}
) end ) end
function testOptS() doTestS( function testOpt1() doTestS(
'* "I am somewhat tired[."]," I repeated.', '* "I am somewhat tired[."]," I repeated.',
{{'choice', {"option", '"I am somewhat tired', '."', '," I repeated.'}}} {{'choice', {"option", '"I am somewhat tired', '."', '," I repeated.'}}}
) end ) end
function testBasic() doTest('basic') end function testBasic() doTest('basic') end
function testChoices() doTest('choices') end function testChoices() doTest('choices') end
function testNest() doTest('nested') end
function testNest2() doTest('nested2') end
function testKnot() doTest('knot') end

30
test/knot.lua Normal file
View file

@ -0,0 +1,30 @@
return {
ink=[[
=== the_orient_express ===
= in_first_class
...
= in_third_class
...
= in_the_guards_van
...
...
= missed_the_train
...
== the_orient_express =
======== the_orient_express ===
=stitch
]],
expected={
{
"knot",
"the_orient_express",
{"stitch", "in_first_class", {"para", "..."}},
{"stitch", "in_third_class", {"para", "..."}},
{"stitch", "in_the_guards_van", {"para", "..."}, {"para", "..."}},
{"stitch", "missed_the_train", {"para", "..."}}
},
{"knot", "the_orient_express"},
{"knot", "the_orient_express", {"stitch", "stitch"}}
}
}

19
test/nested.lua Normal file
View file

@ -0,0 +1,19 @@
return {
ink=[[
* "Murder!"
** A
* "Suicide!"
]], expected= {
{
"choice",
{
"option",
'"Murder!"',
"",
"",
{"choice", {"option", "A", "", ""}}
},
{"option", '"Suicide!"', "", ""}
}
}
}

31
test/nested2.lua Normal file
View file

@ -0,0 +1,31 @@
return {
ink=[[
"Well, Poirot? Murder or suicide?"
* "Murder"
"And who did it?"
* * "Detective-Inspector Japp!"
* * "Captain Hastings!"
* * "Myself!"
* "Suicide"
]],
expected = {
{"para", '"Well, Poirot? Murder or suicide?"'},
{
"choice",
{
"option",
'"Murder"',
"",
"",
{"para", '"And who did it?"'},
{
"choice",
{"option", '"Detective-Inspector Japp!"', "", ""},
{"option", '"Captain Hastings!"', "", ""},
{"option", '"Myself!"', "", ""}
}
},
{"option", '"Suicide"', "", ""}
}
}
}

View file

@ -37,6 +37,7 @@ end
function tprint (tbl, indent) function tprint (tbl, indent)
if not indent then indent = 0 end if not indent then indent = 0 end
if type(tbl)=='string' then print(tbl); return end
for k, v in pairs(tbl) do for k, v in pairs(tbl) do
formatting = string.rep(" ", indent) .. k .. ": " formatting = string.rep(" ", indent) .. k .. ": "
if type(v) == "table" then if type(v) == "table" then
@ -56,4 +57,3 @@ function read(file)
f:close() f:close()
return content return content
end end