Browse Source

Delete monty.sol

master
Benjamin Lannon 6 years ago
parent
commit
1e785c3f38
  1. 472
      monty.sol

472
monty.sol

@ -1,472 +0,0 @@
TOK = {LPAREN = 1, RPAREN = 2, INT = 3, BOOL = 4, NAME = 5, QUOTE = 6, EOF = 7}
keys = []
for k in TOK do keys:insert(#keys, k) end
for k in keys do TOK[TOK[k]]=k end
token = {
new = func (type, value)
return {type = type, value = value, __index = token}
end,
pretty = func(self)
tname = TOK[self.type]
tval = tostring(self.value)
return '{'+tname+':'+tval+'}'
end
}
tokenizer = {
WS = " "+chr(8)+chr(9)+chr(10),
NAMESET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=+-*/.<>?!@$%^~",
DIGITS = "0123456789",
EOF = {},
new = func (str)
res = {str = str, pushed = None, __index = tokenizer}
res:init()
return res
end,
init = func(self)
--print('In init, self is', self)
res.cur = res:token()
res.next = res:token()
end,
next_char = func(self)
if self.pushed == None then
--print('In next_char, self is', self)
--print('In next_char, self.str is', self.str)
if self.str:eof() then return self.EOF end
res = self.str:read(1)
else
--print('Retrieving from pushback', self.pushed)
res = self.pushed[0]
self.pushed = self.pushed:sub(1)
if self.pushed == "" then self.pushed = None end
end
--print(res)
return res
end,
push_back = func(self, s)
--print('Pushing back', s)
if s == self.EOF then print('WARNING: Attempted to push_back EOF'); return end
if self.pushed == None then
self.pushed = s
else
self.pushed = s + self.pushed
end
--print('self.pushed:', self.pushed)
end,
token = func (self)
--print('In token, self is', self)
--print('In token, self.str is', self.str)
c = self:next_char()
while !(c == self.EOF) do
if c == "" then return token.new(TOK.EOF, None) end
if c == "(" then return token.new(TOK.LPAREN, c) end
if c == ")" then return token.new(TOK.RPAREN, c) end
if self.NAMESET:find(c) >= 0 then
--print('{NAME}')
name = c
c = self:next_char()
while 1 do
found = 0
if self.NAMESET:find(c) >= 0 then found = 1 end
if self.DIGITS:find(c) >= 0 then found = 1 end
if !found then break end
name += c
c = self:next_char()
if c == self.EOF then continue end
end
self:push_back(c)
return token.new(TOK.NAME, name)
end
if self.DIGITS:find(c) >= 0 then
val = c
c = self:next_char()
while self.DIGITS:find(c) >= 0 do
val += c
c = self:next_char()
if c == self.EOF then continue end
end
self:push_back(c)
return token.new(TOK.INT, toint(val))
end
if c == "#" then
c = self:next_char()
if c == "t" then return token.new(TOK.BOOL, 1) end
if c == "f" then return token.new(TOK.BOOL, 0) end
error("Invalid value for bool literal: "+c)
end
if c == "'" then return token.new(TOK.QUOTE, c) end
if self.WS:find(c) >= 0 then
c = self:next_char()
continue
end
if c == ";" then
c = self:next_char()
while 1 do
if c == chr(10) then break end
c = self:next_char()
end
c = self:next_char()
continue
end
error("Invalid character in token stream: "+c)
end
return token.new(TOK.EOF, None)
end,
advance = func(self)
self.cur = self.next
self.next = self:token()
end
}
ttreegen = {
new = func(tok)
return {tok = tok, __index = ttreegen}
end,
generate = func(self, consume)
res = self.TT_DISPATCH[self.tok.cur.type](self, self.tok.cur)
if None == consume then self.tok:advance() end
return res
end,
TT_DISPATCH = {
[TOK.LPAREN] = func(self, tok)
toklist = []
self.tok:advance()
tok = self.tok.cur
while 1 do
if tok.type == TOK.RPAREN then break end
if tok.type == TOK.EOF then error('Encountered EOF while matching delimiter') end
toklist:insert(#toklist, self.TT_DISPATCH[tok.type](self, tok))
self.tok:advance()
tok = self.tok.cur
end
return toklist
end,
[TOK.RPAREN] = func(self, tok)
error("Unexpected right parenthesis")
end,
[TOK.INT] = func(self, tok)
return tok
end,
[TOK.BOOL] = func(self, tok)
return tok
end,
[TOK.NAME] = func(self, tok)
return tok
end,
[TOK.QUOTE] = func(self, tok)
self.tok:advance()
tok.quoting = self:generate(0)
return tok
end,
[TOK.EOF] = func(self, tok)
return None
end
}
}
EX = {CALL=1, ASSIGN=2, FUNCDECL=3, SCOPE=4, IFELSE=5, DATUM=6, LIT=7, REF=8, LIST=9}
keys = []
for k in EX do keys:insert(#keys, k) end
for k in keys do EX[EX[k]]=k end
node = {
new = func(type, value)
return {type=type, value=value, __index=node}
end,
pretty = func(self) return self.PRETTY_DISPATCH[self.type](self) end
PRETTY_DISPATCH = {
[EX.CALL] = func(self)
return '<CALL NAME='+(self.value.name)+' ARGS='+tostring(self.value.args:copy():map(func(i) if !(None == i) then return i:pretty() else return tostring(i) end end))+'>'
end,
[EX.ASSIGN] = func(self)
return '<ASSIGN NAME='+(self.value.name)+' VALUE='+(self.value.value:pretty())+'>'
end,
[EX.FUNCDECL] = func(self)
return '<FUNCDECL PARAMS='+tostring(self.value.params)+' BODY='+(self.value.body:pretty())+'>'
end,
[EX.SCOPE] = func(self)
return '<SCOPE '+(self.value:copy():map(func(i) return i:pretty() end))+'>'
end,
[EX.IFELSE] = func(self)
return '<IFELSE COND='+(self.value.cond:pretty())+' IFT='+(self.value.ift:pretty())+' IFF='+(self.value.iff:pretty())+'>'
end,
[EX.DATUM] = func(self)
return '#'+tostring(self.value)
end,
[EX.LIT] = func(self)
if type(self.value) == 'list' then
return '/'+tostring(self.value:copy():map(func(i) return i:pretty() end))
end
return '/'+tostring(self.value)
end,
[EX.REF] = func(self)
--print('In EX.REF, self is', self)
res = '@'+tostring(self.value)
--print('In EX.REF, returning', res)
return res
end,
[EX.LIST] = func(self)
--print('In EX.LIST, self is', self)
return '<LIST '+(self.value:copy():map(func(i) return i:pretty() end))+'>'
end
}
}
parser = {
new = func(ttgen)
return {ttgen = ttgen, __index = parser}
end,
parse = func(self, tt)
if type(tt) == 'map' then
--print('In parse, self is', self)
--print('In parse, tt is', tt)
--print('In parse, dispatch to', self.TT_PARSE_DISPATCH[tt.type])
res = self.TT_PARSE_DISPATCH[tt.type](self, tt)
else
name = tt[0]
if !(name.type == TOK.NAME) then
error('Expected name as first element of expression-list')
end
rest = tt:copy()
rest:remove(0)
sc = self.SCALL_DISPATCH[name.value]
if !(None == sc) then
sc = None
res = self.SCALL_DISPATCH[name.value](self, rest)
else
res = node.new(EX.CALL, {name=name.value, args=rest:map(func(i) return self:parse(i) end)})
end
end
--print('In parse, returning', res:pretty())
return res
end,
TT_PARSE_DISPATCH = {
[TOK.INT] = func(self, tok)
return node.new(EX.LIT, tok.value)
end,
[TOK.BOOL] = func(self, tok)
return node.new(EX.LIT, tok.value)
end,
[TOK.NAME] = func(self, tok)
--print('In TOK.NAME, tok is', tok)
res = node.new(EX.REF, tok.value)
--print('In TOK.NAME, returning', res)
return res
end,
[TOK.QUOTE] = func(self, tok)
return self:parse_datum(tok.quoting)
end
},
SCALL_DISPATCH = {
define = func(self, args)
name = args[0]
if !(name.type == TOK.NAME) then error('Define: expected name as first argument') end
value = self:parse(args[1])
return node.new(EX.ASSIGN, {name=name.value, value=value})
end,
["if"] = func(self, args)
cond = self:parse(args[0])
ift = self:parse(args[1])
iff = self:parse(args[2])
return node.new(EX.IFELSE, {cond=cond, ift=ift, iff=iff})
end,
begin = func(self, args)
args:map(func(i) return self:parse(i) end)
return node.new(EX.LIST, args)
end,
lambda = func(self, args)
--print('Lambda args:', args)
params = args[0]
if !(type(params) == 'list') then error('Lambda: expected parameters as first argument (got '+tostring(params)+')') end
params:map(func(i)
if !(type(i) == 'map') then error('Lambda: expected name token in argument list (got sublist)') end
if !(i.type == TOK.NAME) then error('Lambda: expected name token in argument list (got '+(i:pretty())+')') end
return i.value
end)
body = args:copy()
body:remove(0)
--print('Lambda body:', body)
body:map(func(i) return self:parse(i) end)
return node.new(EX.FUNCDECL, {params=params, body=node.new(EX.LIST, body)})
end,
let = func(self, args)
defs = args[0]
if !(type(defs) == 'list') then error('Let: expected list of bindings are first argument') end
defs:map(func(i)
if !(type(i) == 'list') then error('Let: expected a binding entry') end
return self.SCALL_DISPATCH.define(self, i)
end)
body = args:copy()
body:remove(0)
body:map(func(i) return self:parse(i) end)
return node.new(EX.SCOPE, defs+body)
end,
letrec = func(self, args)
defs = args[0]
if !(type(defs) == 'list') then error('Let: expected list of bindings are first argument') end
defs:map(func(i)
if !(type(i) == 'list') then error('Let: expected a binding entry') end
return self.SCALL_DISPATCH.define(self, i)
end)
body = args:copy()
body:remove(0)
body:map(func(i) return self:parse(i) end)
return node.new(EX.LIST, defs+body)
end
}
parse_datum = func(self, tt)
if type(tt) == 'map' then
return self.TT_PARSE_DATUM_DISPATCH[tt.type](self, tt)
else
list = []
for tok in tt do
list:insert(#list, self:parse_datum(tok))
end
return node.new(EX.LIT, list)
end
end,
TT_PARSE_DATUM_DISPATCH = {
[TOK.INT] = func(self, tok)
return node.new(EX.LIT, tok.value)
end,
[TOK.BOOL] = func(self, tok)
return node.new(EX.LIT, tok.value)
end,
[TOK.NAME] = func(self, tok)
return node.new(EX.LIT, tok.value)
end,
[TOK.QUOTE] = func(self, tok)
return self:parse(tok.quoting)
end
},
run = func(self)
tt = self.ttgen:generate()
list = []
while 1 do
if None == tt then break end
--if type(tt) == 'list' then
list:insert(#list, self:parse(tt))
--end
tt = self.ttgen:generate()
end
--print('In run, list is', list)
return node.new(EX.LIST, list)
end
}
converter = {
new = func(p)
return {parser=p, __index = converter}
end,
make = func(self, node)
--print('In make, node is a', EX[node.type], 'of value', node)
res = self.MAKE_DISPATCH[node.type](self, node)
--print('In make, returning', res)
if type(res) == "astnode" then ast.print(res) end
return res
end,
MAKE_DISPATCH = {
[EX.CALL] = func(self, node)
e = parse('f()').stmtlist[0].expr
e.expr.ident = node.value.name
args = node.value.args:copy():map(func(i) return self:make(i) end)
--print('In EX.CALL, replacement args are', args)
e.args = args
--print('In EX.CALL, args are', e.args)
return e
end,
[EX.ASSIGN] = func(self, node)
e = parse('a = b').stmtlist[0].expr
e.ident = node.value.name
e.value = self:make(node.value.value)
return e
end,
[EX.FUNCDECL] = func(self, node)
e = parse('func() None None end').stmtlist[0].expr
params = node.value.params
--print('In EX.FUNCDECL, params are', params)
e.args = params
--print('In EX.FUNCDECL, args are', e.args)
e.body.stmtlist = self:make(node.value.body)
return e
end,
[EX.SCOPE] = func(self, node)
e = parse('(func() None None end)()').stmtlist[0].expr
node.type = EX.LIST
e.expr.body.stmtlist = self:make(node)
node.type = EX.SCOPE
return e
end,
[EX.IFELSE] = func(self, node)
e = parse('(func() if None then return None else return None end end)()').stmtlist[0].expr
e.expr.body.stmtlist[0].cond = self:make(node.value.cond)
e.expr.body.stmtlist[0].iftrue.stmtlist[0].ret = self:make(node.value.ift)
e.expr.body.stmtlist[0].iffalse.stmtlist[0].ret = self:make(node.value.iff)
return e
end,
[EX.DATUM] = func(self, node) error('EX.DATUM: Not implemented') end,
[EX.LIT] = func(self, node)
if type(node.value) == 'list' then
e = parse('[None]').stmtlist[0].expr
e.list = node.value:copy():map(func(i) return self:make(i) end)
else
e = parse('None').stmtlist[0].expr
if type(node.value) == "int" then
e.littype = ast.LIT_INT
e.ival = node.value
end
if type(node.value) == "string" then
e.littype = ast.LIT_STRING
e.str = node.value
end
end
return e
end,
[EX.REF] = func(self, node)
e = parse('a').stmtlist[0].expr
e.ident = node.value
return e
end,
[EX.LIST] = func(self, node)
e = parse('func() None end').stmtlist[0].expr
l = node.value:copy()
l:map(func(i)
s = parse('None').stmtlist[0]
s.expr = self:make(i)
return s
end)
lastidx = (#l) - 1
r = parse('return None').stmtlist[0]
r.ret = l[lastidx].expr
l[lastidx] = r
--print('In EX.LIST, e is now' e)
e.body.stmtlist = l
return e.body.stmtlist
end
},
run = func(self)
list = self:make(self.parser:run())
res = parse('(func() None None end)()')
--print('In run, list is', list)
--for i in list do ast.print(i) end
res.stmtlist[0].expr.expr.body.stmtlist = list
return res
end
}
_G = debug.globals()
_G['+'] = func(a, b) return a + b end
_G['-'] = func(a, b) return a - b end
_G['*'] = func(a, b) return a * b end
_G['/'] = func(a, b) return a / b end
_G['<'] = func(a, b) return a < b end
_G['>'] = func(a, b) return a > b end
_G['<='] = func(a, b) return a <= b end
_G['>='] = func(a, b) return a >= b end
_G['=='] = func(a, b) return a == b end
_G['eq'] = _G['==']
_G['or'] = func(a, b) return a || b end
_G['and'] = func(a, b) return a && b end
Loading…
Cancel
Save