Skip to content

Commit

Permalink
Precompute variables in the book.
Browse files Browse the repository at this point in the history
  • Loading branch information
astrochili committed Feb 4, 2021
1 parent 1e47cc9 commit 571fd16
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
51 changes: 50 additions & 1 deletion narrator/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ function Constructor.constructBook(items)
local construction = {
currentKnot = '_',
currentStitch = '_',
variablesToCompute = { }
}

construction.book = {
Expand All @@ -271,6 +272,7 @@ function Constructor.constructBook(items)

Constructor.addNode(construction, items)
Constructor.clear(construction.book.tree)
Constructor.computeVariables(construction)

return construction.book
end
Expand Down Expand Up @@ -300,6 +302,9 @@ function Constructor:addNode(items, isRestricted)
elseif item.type == 'constant' then
-- name, value
Constructor.addConstant(self, item.name, item.value)
elseif item.type == 'variable' then
-- name, value
Constructor.addVariable(self, item.name, item.value)
elseif item.type == 'knot' then
-- knot
Constructor.addKnot(self, item.knot)
Expand All @@ -312,7 +317,7 @@ function Constructor:addNode(items, isRestricted)
elseif item.type == 'sequence' then
-- sequence, shuffle, alts
Constructor.addSequence(self, item.sequence, item.shuffle, item.alts)
elseif item.type == 'variable' or item.type == 'assignment' then
elseif item.type == 'assignment' then
-- level, name, value, temp
Constructor.addAssignment(self, item.level, item.name, item.value, item.temp)
elseif item.type == 'paragraph' then
Expand Down Expand Up @@ -344,6 +349,10 @@ function Constructor:addConstant(constant, value)
self.book.constants[constant] = value
end

function Constructor:addVariable(variable, value)
self.variablesToCompute[variable] = value
end

function Constructor:addKnot(knot)
self.currentKnot = knot
self.currentStitch = '_'
Expand Down Expand Up @@ -595,6 +604,46 @@ function Constructor:addItem(level, item)
table.insert(node, item)
end

function Constructor:computeVariable(variable, value)
local constant = self.book.constants[value]
if constant then
self.book.variables[variable] = constant
return
end

local listExpression = value:match('%(([%s%w%.,_]*)%)')
local itemExpressions = listExpression and lume.array(listExpression:gmatch('[%w_%.]+')) or { value }
local listVariable = listExpression and { } or nil

for _, itemExpression in ipairs(itemExpressions) do
local listPart, itemPart = itemExpression:match('([%w_]+)%.([%w_]+)')
itemPart = itemPart or itemExpression

for listName, listItems in pairs(self.book.lists) do
local listIsValid = listPart == nil or listPart == listName
local itemIsFound = lume.find(listItems, itemPart)

if listIsValid and itemIsFound then
listVariable = listVariable or { }
listVariable[listName] = listVariable[listName] or { }
listVariable[listName][itemPart] = true
end
end
end

if listVariable then
self.book.variables[variable] = listVariable
else
self.book.variables[variable] = lume.deserialize(value)
end
end

function Constructor:computeVariables()
for variable, value in pairs(self.variablesToCompute) do
Constructor.computeVariable(self, variable, value)
end
end

function Constructor.clear(tree)
for knot, node in pairs(tree) do
for stitch, node in pairs(node) do
Expand Down
2 changes: 1 addition & 1 deletion test/units/lists-queries.ink
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ LIST Props = champagne_glass, newspaper

VAR BallroomContents = (Alfred, Batman, newspaper)
VAR HallwayContents = (Robin, champagne_glass)
VAR roomState = HallwayContents
VAR roomState = (Robin, champagne_glass)

-> room
== room
Expand Down

0 comments on commit 571fd16

Please sign in to comment.