167 lines
3.6 KiB
Lua
167 lines
3.6 KiB
Lua
require("interpret")
|
|
|
|
local nelli_scope = Scope()
|
|
local function B(abstract,callback)
|
|
nelli_scope:insert(
|
|
Binding(
|
|
interpret(abstract),
|
|
callback
|
|
)
|
|
)
|
|
end
|
|
B("print (text)",function(s,e)
|
|
log(s:evaluate(e.text))
|
|
end)
|
|
B("text (literal)",function(s,e)
|
|
return e.literal:text()
|
|
end)
|
|
B("do (expressions)",function(s,e)
|
|
scope = Scope()
|
|
scope.parent = s
|
|
local res
|
|
print(e.expressions)
|
|
for item in iterate(e.expressions.items) do
|
|
if type_of(item) ~= Expression then
|
|
error(
|
|
string.format(
|
|
"Unexpected words '%s' in 'do' expression.",
|
|
tostring(item)
|
|
)
|
|
)
|
|
end
|
|
res = scope:evaluate(item)
|
|
end
|
|
return res
|
|
end)
|
|
B("if (predicate) then (expression)",function(s,e)
|
|
if s:evaluate(e.predicate) then
|
|
return s:evaluate(e.expression)
|
|
end
|
|
end)
|
|
B("true",function(s,e) return true end)
|
|
B("false",function(s,e) return false end)
|
|
B("(constant) = (expression)",function(s,e)
|
|
local value = s:evaluate(e.expression)
|
|
s:insert(
|
|
Binding(e.constant:text(),function(s,e)
|
|
return value
|
|
end)
|
|
)
|
|
end)
|
|
B("format (string) with (terms)",function(s,e)
|
|
local items = {}
|
|
for expression in iterate(e.terms.items) do
|
|
table.insert(items,s:evaluate(expression))
|
|
end
|
|
return string.format(
|
|
s:evaluate(e.string),
|
|
table.unpack(items)
|
|
)
|
|
end)
|
|
B("while (predicate) (expression)",function(s,e)
|
|
while s:evaluate(e.predicate) do
|
|
s:evaluate(e.expression)
|
|
end
|
|
end)
|
|
B("repeat (expression) while (predicate)",function(s,e)
|
|
while true do
|
|
s:evaluate(e.expression)
|
|
if not s:evaluate(e.predicate) then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
B("repeat (expression) until (predicate)",function(s,e)
|
|
while true do
|
|
s:evaluate(e.expression)
|
|
if s:evaluate(e.predicate) then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
B("new table",function(s,e)
|
|
return {}
|
|
end)
|
|
B("(index) of (table)",function(s,e)
|
|
return s:evaluate(e.table)[s:evaluate(e.index)]
|
|
end)
|
|
B("set (index) of (table) to (item)",function(s,e)
|
|
s:evaluate(e.table)[s:evaluate(e.index)]
|
|
end)
|
|
B("macro (macro) expands to (expression)",function(s,e)
|
|
s:insert(Binding(e.abstract,function(_s,_e)
|
|
for identifier,expression in pairs(_e) do
|
|
|
|
end
|
|
_s:evaluate(e.expression)
|
|
end)
|
|
end)
|
|
B("define (abstract) as (expression)",function(s,e)
|
|
s:insert(Binding(e.abstract,function(_s,_e)
|
|
return s:evaluate(e.expression)
|
|
end))
|
|
end)
|
|
local List = class("List")
|
|
function List:new(...) do
|
|
self.items = {...}
|
|
end
|
|
B("new list",function(s,e)
|
|
return List()
|
|
end)
|
|
B("insert (item) into (list)",function(s,e)
|
|
|
|
end)
|
|
B("insert (item) into (list) at (index)",function(s,e)
|
|
|
|
end)
|
|
B("remove (needle) from (haystack)",function(s,e)
|
|
|
|
end)
|
|
B("remove from (haystack) at (index)",function(s,e)
|
|
s:evaluate(e.haystack)
|
|
end)
|
|
|
|
local Variable = class()
|
|
function Variable:new()
|
|
end
|
|
function Variable:set(item)
|
|
self.data = item
|
|
end
|
|
function Variable:get()
|
|
return self.data
|
|
end
|
|
B("let (variable)",function(s,e)
|
|
local variable = Variable()
|
|
s:insert(
|
|
Binding(e.variable,function(s,e)
|
|
return variable
|
|
end)
|
|
)
|
|
return variable
|
|
end)
|
|
B("set (variable) to (expression)",function(s,e)
|
|
local var = s:evaluate(e.variable)
|
|
local value = s:evaluate(e.expression)
|
|
assert_meta(Variable)(var)
|
|
var:set(value)
|
|
end)
|
|
B("get (variable)",function(s,e)
|
|
local var = s:evaluate(e.variable)
|
|
assert_meta(Variable)(var)
|
|
return var:get(value)
|
|
end)
|
|
for item in iterate(nelli_scope.bindings) do
|
|
print(item.template)
|
|
end
|
|
|
|
local args = {...}
|
|
local function main()
|
|
-- Take arguments as neli files to read and interpret
|
|
for _,parameter in pairs(args) do
|
|
local root = interpret(read(parameter))
|
|
nelli_scope:evaluate(root)
|
|
end
|
|
end
|
|
|
|
main()
|