Created
March 6, 2012 23:26
Example of a lua DSL language
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
#!/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