Last active
May 18, 2023 21:21
-
-
Save RealNeGate/be130523b1294d2f857387157d3775ea to your computer and use it in GitHub Desktop.
This file contains 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
inspect = require "inspect" | |
function sm_parse(source) | |
local states = {} | |
for line in source:gmatch("[^\r\n]+") do | |
local tokens = {} | |
for w in line:gmatch("[^%s]+") do tokens[#tokens + 1] = w end | |
-- yell at the user about missing arrows | |
if tokens[2] ~= "->" then | |
print("error: missing ->") | |
return nil | |
end | |
if tokens[4] == "->" then | |
local curr = states[tokens[1]] | |
if curr == nil then | |
-- make new state node | |
curr = {} | |
states[tokens[1]] = curr | |
end | |
if states[tokens[5]] == nil then | |
-- make new state node | |
states[tokens[5]] = {} | |
end | |
curr[tokens[3]] = tokens[5] | |
end | |
end | |
return states | |
end | |
-- example line: state -> input -> next | |
function sm_compile(source) | |
local states = sm_parse(source) | |
local str = {} | |
local function s(a) str[#str + 1] = a end | |
s('function FINAL() end') | |
for k, v in pairs(states) do | |
-- edges | |
s('function '..k..'(input)') | |
for input, edge in pairs(v) do | |
s([[ if input == "]] .. input .. [[" then return ]] .. edge .. [[(coroutine.yield("]]..edge..[[")) end]]) | |
end | |
s(' return FINAL(coroutine.yield("FINAL"))') | |
s("end") | |
end | |
s('return a') | |
local source = table.concat(str, "\n") | |
local code, errors = load(source) | |
if code ~= nil then | |
local sm = coroutine.create(code()) | |
return function(input) | |
return coroutine.resume(sm, input) | |
end | |
else | |
print(errors) | |
return nil | |
end | |
end | |
function sm_interpret(source) | |
local code = sm_parse(source) | |
local state = "a" | |
return function(input) | |
state = code[state][input] | |
if state == "FINAL" then | |
return nil | |
end | |
return state | |
end | |
end | |
--[[ | |
Here's some example code (you can replace with sm_compile if you | |
wish to compile the state machine into a lua function) | |
sm = sm_interpret[[ | |
a -> a-down -> b | |
a -> b-down -> c | |
c -> a-down -> d | |
]] | |
--]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment