161 lines
4.7 KiB
Lua
161 lines
4.7 KiB
Lua
require("parse")
|
|
|
|
-- TODO: This should really be a separate API and module
|
|
-- please break it out
|
|
-- Interpret some text
|
|
function interpret(content,uri,chain)
|
|
-- LOCALS
|
|
-- The pattern for words inbetween expressions
|
|
local expressionWordPattern = "(.*)"
|
|
-- The patterns to open and close expressions,
|
|
-- the words scattered inbetween them will be matches
|
|
local expressionOpenPattern = "%("
|
|
local expressionClosePattern = "%)"
|
|
local subExpressionOpenPattern = "%:"
|
|
local subExpressionClosePattern = "%,"
|
|
local blockOpenPattern = "%{"
|
|
local blockClosePattern = "%}"
|
|
local blockDelimiterPattern = "[;]+"
|
|
-- So that all functions have access to eachother
|
|
local consume,
|
|
consumeExpression,
|
|
processWords,
|
|
processClosure,
|
|
processOpening,
|
|
consumeBlock,
|
|
consumeText,
|
|
consumeNumber
|
|
|
|
|
|
local consumer = Consumer(content)
|
|
local function expression(...)
|
|
return Expression(...):locate(
|
|
string.format(
|
|
"%i:%i",
|
|
consumer.row,
|
|
consumer.col
|
|
),uri)
|
|
end
|
|
local baseExpression = expression()
|
|
|
|
-- FUNCTIONS
|
|
-- Consume an expression, with its sub expressions
|
|
-- given that an opening has just been consumed
|
|
local singleLineStringPattern = "\""
|
|
local function singleLineStringMeal(current,match)
|
|
return function(words,_)
|
|
current:insert(words,consumer:consume({
|
|
[match] = function(words,_)
|
|
return expression({"text",Expression({words})})
|
|
end
|
|
}))
|
|
end
|
|
end
|
|
local multiLineStringOpenPattern = "%[%["
|
|
local multiLineStringClosePattern = "%]%]"
|
|
local function multiLineStringMeal(current,match)
|
|
return function(words,_)
|
|
current:insert(words,consumer:consume({
|
|
["[\n\r]"] = function()
|
|
error("Incomplete string literal")
|
|
end,
|
|
[match] = function(words,_)
|
|
return expression({"text",Expression({words})})
|
|
end
|
|
}))
|
|
end
|
|
end
|
|
local uriOpenPattern = "<"
|
|
local uriClosePattern = ">"
|
|
local function URIMeal(current,match)
|
|
return function(words,_)
|
|
current:insert(words,consumer:consume({
|
|
["[\n\r]"] = function()
|
|
current:error("Incomplete URI literal")
|
|
end,
|
|
[match] = function(path)
|
|
return read(path)
|
|
end
|
|
}))
|
|
end
|
|
end
|
|
local function expressionMeal(current)
|
|
return function(words,_)
|
|
current:insert(words,consumeExpression())
|
|
end
|
|
end
|
|
function consumeBlock()
|
|
local expressions = {}
|
|
local current = expression()
|
|
local loop = true
|
|
while loop do
|
|
local expr = consumer:consume({
|
|
[uriOpenPattern] = URIMeal(current,uriClosePattern),
|
|
[expressionOpenPattern] = expressionMeal(current),
|
|
[multiLineStringOpenPattern] =
|
|
multiLineStringMeal(
|
|
current,multiLineStringClosePattern),
|
|
[singleLineStringPattern] =
|
|
singleLineStringMeal(
|
|
current,singleLineStringPattern),
|
|
[blockDelimiterPattern] = function(words,_)
|
|
if current:empty() then
|
|
error("Extravenous semicolon.")
|
|
end
|
|
table.insert(expressions,current)
|
|
current = expression()
|
|
end,
|
|
[blockClosePattern] = function(words,_)
|
|
current:insert(words)
|
|
loop = false
|
|
end
|
|
})
|
|
end
|
|
if #current.items ~= 0 then
|
|
table.insert(expressions,current)
|
|
end
|
|
return expression(expressions)
|
|
end
|
|
function consumeExpression()
|
|
local current = expression()
|
|
-- Loop, adding new expressions and words,
|
|
-- until closing that is
|
|
local loop = true
|
|
while loop do
|
|
local remaining = consumer:remaining()
|
|
local expr = consumer:consume({
|
|
[uriOpenPattern] = URIMeal(current,uriClosePattern),
|
|
[expressionOpenPattern] = expressionMeal(current),
|
|
[multiLineStringOpenPattern] =
|
|
multiLineStringMeal(
|
|
current,multiLineStringClosePattern),
|
|
[singleLineStringPattern] =
|
|
singleLineStringMeal(
|
|
current,singleLineStringPattern),
|
|
[expressionOpenPattern] = expressionMeal(current),
|
|
[expressionClosePattern] = function(words,_)
|
|
current:insert(words)
|
|
loop = false
|
|
end,
|
|
[blockOpenPattern] = function(words,_)
|
|
current:insert(
|
|
words,
|
|
consumeBlock()
|
|
)
|
|
end,
|
|
["$"] = function(words,last)
|
|
current:insert(remaining)
|
|
loop = false
|
|
end
|
|
})
|
|
-- This single line below made me procrastinate life for a total of 4 hours on instagram reels; lock in.
|
|
-- if not expr then print("brk") break end -- Since now closing
|
|
end
|
|
return current
|
|
end
|
|
return consumeExpression()
|
|
-- TODO: check for later expressions please?
|
|
end
|
|
|
|
return _G
|