Skip to content

Instantly share code, notes, and snippets.

@armornick
Last active December 21, 2015 15:58
Show Gist options
  • Save armornick/6329914 to your computer and use it in GitHub Desktop.
Save armornick/6329914 to your computer and use it in GitHub Desktop.
Kaleidoscope parser made with LPeg
-- debug helper function
function _dump (t)
local ttype = type(t)
if ttype == "table" then
local vals = {}
for k,v in pairs(t) do
table.insert(vals, _dump(k) .. " = " .. _dump(v))
end
return "{"..table.concat(vals, " , ").."}"
elseif ttype == "string" then
return string.format('%q', t)
else
return tostring(t)
end
end
function dump(t) print(_dump(t)) end
function vdump(...)
local t = {...}
for k,v in pairs(t) do
dump(v)
end
end
--------------------------------
local lpeg = require"lpeg"
local R, S, V, P = lpeg.R, lpeg.S, lpeg.V, lpeg.P
local C, Ct, Cmt, Cg, Cb, Cc = lpeg.C, lpeg.Ct, lpeg.Cmt, lpeg.Cg, lpeg.Cb, lpeg.Cc
lpeg.locale(lpeg)
local digit, alnum, alpha, space, xdigit, punct = lpeg.digit, lpeg.alnum, lpeg.alpha, lpeg.space, lpeg.xdigit, lpeg.punct
local ws = (space^0)
local comment = P'#' * (1 - S"\r\n")^0 * S"\r\n"^1
ws = ws * comment^-1
--------------------------------
function sym(chars) return ws * P(chars) end
local keywords = {}
local function key(chars)
keywords[chars] = true
return ws * chars * -alnum
end
TokenTypes = {}
local function mark(name)
TokenTypes[name] = true
return function (...)
return {name, ...}
end
end
--------------------------------
local ident = ws * C( alpha * alnum ^ 0 ) * -alnum
ident = Cmt(ident, function(i, p, name)
if keywords[name] then return false end
return true, name
end) / mark"Ident"
local number = ws * C( digit ^ 1 * (P"." * digit^1)^-1 + digit ^ 0 * P"." * digit^1 ) * -alnum
number = number / mark"Number"
local op = ws * C(S"+/*-<>=:!?^$"^1) / mark"Operator"
local equals = sym"="
local comma = sym","
local arglist = (sym"(" * (ident^0) * sym")") / mark"ArgList"
local statement, ifstat, fn, fncall, extern, program = V"statement", V"ifstat", V"fn", V"fncall", V"extern", V"program"
local expr, exprlist, atom, forstat, vardecl, varstat = V"expr", V"exprlist", V"atom", V"forstat", V"vardecl", V"varstat"
local G = P{ program,
program = (ws * (fn + extern + statement)^1 * ws * -1) / mark"Program";
extern = (key"extern" * ident * arglist * sym";") / mark"ExternDecl";
fn = (key"def" * ident * arglist * statement * sym";"^-1) / mark"Function";
statement = (ifstat + forstat + expr) * sym";"^-1;
ifstat = (key"if" * expr * key"then" * expr * key"else" * expr) / mark"IfStatement";
forstat = (key"for" * ident * equals * expr * comma * expr * (comma * number)^-1 * key"in" * expr) / mark"ForStatement";
exprlist = (sym"(" * ( expr * (sym"," * expr)^0 )^0 * sym")") / mark"ExprList" ;
expr = ws * (atom * (op * atom)^0) / mark"Expr";
atom = op^-1 * (fncall + number + ident);
fncall = (ident * exprlist) / mark"FnCall";
}
--------------------------------
return G
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment