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