Skip to content

Instantly share code, notes, and snippets.

@sam-github
Created March 6, 2012 23:26
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sam-github/1989745 to your computer and use it in GitHub Desktop.
Save sam-github/1989745 to your computer and use it in GitHub Desktop.
Example of a lua DSL language
#!/usr/bin/env lua
--[[
dsl-print [some.dsl]
Example of a lua DSL language, that can use function call or assignment to define
keys, and uses call sequence to implicitly define nesting.
]]
function dsl(code, file)
local loaded, estr = loadstring(code, file)
if not loaded then
return nil, estr
end
local _sections = { file = file };
local _section
local _links
local _link
local G = {
BeginSection = function(section)
_section = { section = section }
_links = {}
_section.links = _links
table.insert(_sections, _section)
end;
EndSection = function()
_section = nil
end;
Link = function(link)
_link = { link = link }
table.insert(_links, _link)
end;
href = function(href)
_link.href = href
end;
title = function(title)
_link.title = title
end;
}
local env = setmetatable({}, {
__index = function(t, k)
return G[k]
end;
__newindex = function(t, k, v)
if G[k] then
G[k](v)
else
rawset(t, k, v)
end
end;
})
setfenv(loaded, env)
local ok, estr = pcall(loaded)
if not ok then
return nil, estr
end
return _sections
end
function dump(t, lead)
lead = lead or ""
for k,v in pairs(t) do
if type(v) == "table" then
if type(k) == "number" then
k = "["..k.."]"
end
print(lead..k.." =")
dump(v, lead.." ")
else
print(lead..k.." = "..tostring(v))
end
end
end
file = "(--)"
code = [[
BeginSection "news"
Link "C-programming"
href = "etc."
title "a book on C"
Link = "I love lua"
href "etc."
title = "an essay"
BeginSection "other"
Link "yes, yes" href = "http..." title = "a title"
-- Because you can't have a call or assignment with no argument, either remove
-- EndSection from your language (its unnecessary), or call it with an
-- argument.
EndSection ""
]]
if arg[1] then
file = arg[1]
local f = assert(io.open(arg[1], "r"))
code = f:read"*a"
end
t = assert(dsl(code, file))
dump(t)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment