The Sol Programming Language!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

monty.sol 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. TOK = {LPAREN = 1, RPAREN = 2, INT = 3, BOOL = 4, NAME = 5, QUOTE = 6, EOF = 7}
  2. keys = []
  3. for k in TOK do keys:insert(#keys, k) end
  4. for k in keys do TOK[TOK[k]]=k end
  5. token = {
  6. new = func (type, value)
  7. return {type = type, value = value, __index = token}
  8. end,
  9. pretty = func(self)
  10. tname = TOK[self.type]
  11. tval = tostring(self.value)
  12. return '{'+tname+':'+tval+'}'
  13. end
  14. }
  15. tokenizer = {
  16. WS = " "+chr(8)+chr(9)+chr(10),
  17. NAMESET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=+-*/.<>?!@$%^~",
  18. DIGITS = "0123456789",
  19. EOF = {},
  20. new = func (str)
  21. res = {str = str, pushed = None, __index = tokenizer}
  22. res:init()
  23. return res
  24. end,
  25. init = func(self)
  26. --print('In init, self is', self)
  27. res.cur = res:token()
  28. res.next = res:token()
  29. end,
  30. next_char = func(self)
  31. if self.pushed == None then
  32. --print('In next_char, self is', self)
  33. --print('In next_char, self.str is', self.str)
  34. if self.str:eof() then return self.EOF end
  35. res = self.str:read(1)
  36. else
  37. --print('Retrieving from pushback', self.pushed)
  38. res = self.pushed[0]
  39. self.pushed = self.pushed:sub(1)
  40. if self.pushed == "" then self.pushed = None end
  41. end
  42. --print(res)
  43. return res
  44. end,
  45. push_back = func(self, s)
  46. --print('Pushing back', s)
  47. if s == self.EOF then print('WARNING: Attempted to push_back EOF'); return end
  48. if self.pushed == None then
  49. self.pushed = s
  50. else
  51. self.pushed = s + self.pushed
  52. end
  53. --print('self.pushed:', self.pushed)
  54. end,
  55. token = func (self)
  56. --print('In token, self is', self)
  57. --print('In token, self.str is', self.str)
  58. c = self:next_char()
  59. while !(c == self.EOF) do
  60. if c == "" then return token.new(TOK.EOF, None) end
  61. if c == "(" then return token.new(TOK.LPAREN, c) end
  62. if c == ")" then return token.new(TOK.RPAREN, c) end
  63. if self.NAMESET:find(c) >= 0 then
  64. --print('{NAME}')
  65. name = c
  66. c = self:next_char()
  67. while 1 do
  68. found = 0
  69. if self.NAMESET:find(c) >= 0 then found = 1 end
  70. if self.DIGITS:find(c) >= 0 then found = 1 end
  71. if !found then break end
  72. name += c
  73. c = self:next_char()
  74. if c == self.EOF then continue end
  75. end
  76. self:push_back(c)
  77. return token.new(TOK.NAME, name)
  78. end
  79. if self.DIGITS:find(c) >= 0 then
  80. val = c
  81. c = self:next_char()
  82. while self.DIGITS:find(c) >= 0 do
  83. val += c
  84. c = self:next_char()
  85. if c == self.EOF then continue end
  86. end
  87. self:push_back(c)
  88. return token.new(TOK.INT, toint(val))
  89. end
  90. if c == "#" then
  91. c = self:next_char()
  92. if c == "t" then return token.new(TOK.BOOL, 1) end
  93. if c == "f" then return token.new(TOK.BOOL, 0) end
  94. error("Invalid value for bool literal: "+c)
  95. end
  96. if c == "'" then return token.new(TOK.QUOTE, c) end
  97. if self.WS:find(c) >= 0 then
  98. c = self:next_char()
  99. continue
  100. end
  101. if c == ";" then
  102. c = self:next_char()
  103. while 1 do
  104. if c == chr(10) then break end
  105. c = self:next_char()
  106. end
  107. c = self:next_char()
  108. continue
  109. end
  110. error("Invalid character in token stream: "+c)
  111. end
  112. return token.new(TOK.EOF, None)
  113. end,
  114. advance = func(self)
  115. self.cur = self.next
  116. self.next = self:token()
  117. end
  118. }
  119. ttreegen = {
  120. new = func(tok)
  121. return {tok = tok, __index = ttreegen}
  122. end,
  123. generate = func(self, consume)
  124. res = self.TT_DISPATCH[self.tok.cur.type](self, self.tok.cur)
  125. if None == consume then self.tok:advance() end
  126. return res
  127. end,
  128. TT_DISPATCH = {
  129. [TOK.LPAREN] = func(self, tok)
  130. toklist = []
  131. self.tok:advance()
  132. tok = self.tok.cur
  133. while 1 do
  134. if tok.type == TOK.RPAREN then break end
  135. if tok.type == TOK.EOF then error('Encountered EOF while matching delimiter') end
  136. toklist:insert(#toklist, self.TT_DISPATCH[tok.type](self, tok))
  137. self.tok:advance()
  138. tok = self.tok.cur
  139. end
  140. return toklist
  141. end,
  142. [TOK.RPAREN] = func(self, tok)
  143. error("Unexpected right parenthesis")
  144. end,
  145. [TOK.INT] = func(self, tok)
  146. return tok
  147. end,
  148. [TOK.BOOL] = func(self, tok)
  149. return tok
  150. end,
  151. [TOK.NAME] = func(self, tok)
  152. return tok
  153. end,
  154. [TOK.QUOTE] = func(self, tok)
  155. self.tok:advance()
  156. tok.quoting = self:generate(0)
  157. return tok
  158. end,
  159. [TOK.EOF] = func(self, tok)
  160. return None
  161. end
  162. }
  163. }
  164. EX = {CALL=1, ASSIGN=2, FUNCDECL=3, SCOPE=4, IFELSE=5, DATUM=6, LIT=7, REF=8, LIST=9}
  165. keys = []
  166. for k in EX do keys:insert(#keys, k) end
  167. for k in keys do EX[EX[k]]=k end
  168. node = {
  169. new = func(type, value)
  170. return {type=type, value=value, __index=node}
  171. end,
  172. pretty = func(self) return self.PRETTY_DISPATCH[self.type](self) end
  173. PRETTY_DISPATCH = {
  174. [EX.CALL] = func(self)
  175. 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))+'>'
  176. end,
  177. [EX.ASSIGN] = func(self)
  178. return '<ASSIGN NAME='+(self.value.name)+' VALUE='+(self.value.value:pretty())+'>'
  179. end,
  180. [EX.FUNCDECL] = func(self)
  181. return '<FUNCDECL PARAMS='+tostring(self.value.params)+' BODY='+(self.value.body:pretty())+'>'
  182. end,
  183. [EX.SCOPE] = func(self)
  184. return '<SCOPE '+(self.value:copy():map(func(i) return i:pretty() end))+'>'
  185. end,
  186. [EX.IFELSE] = func(self)
  187. return '<IFELSE COND='+(self.value.cond:pretty())+' IFT='+(self.value.ift:pretty())+' IFF='+(self.value.iff:pretty())+'>'
  188. end,
  189. [EX.DATUM] = func(self)
  190. return '#'+tostring(self.value)
  191. end,
  192. [EX.LIT] = func(self)
  193. if type(self.value) == 'list' then
  194. return '/'+tostring(self.value:copy():map(func(i) return i:pretty() end))
  195. end
  196. return '/'+tostring(self.value)
  197. end,
  198. [EX.REF] = func(self)
  199. --print('In EX.REF, self is', self)
  200. res = '@'+tostring(self.value)
  201. --print('In EX.REF, returning', res)
  202. return res
  203. end,
  204. [EX.LIST] = func(self)
  205. --print('In EX.LIST, self is', self)
  206. return '<LIST '+(self.value:copy():map(func(i) return i:pretty() end))+'>'
  207. end
  208. }
  209. }
  210. parser = {
  211. new = func(ttgen)
  212. return {ttgen = ttgen, __index = parser}
  213. end,
  214. parse = func(self, tt)
  215. if type(tt) == 'map' then
  216. --print('In parse, self is', self)
  217. --print('In parse, tt is', tt)
  218. --print('In parse, dispatch to', self.TT_PARSE_DISPATCH[tt.type])
  219. res = self.TT_PARSE_DISPATCH[tt.type](self, tt)
  220. else
  221. name = tt[0]
  222. if !(name.type == TOK.NAME) then
  223. error('Expected name as first element of expression-list')
  224. end
  225. rest = tt:copy()
  226. rest:remove(0)
  227. sc = self.SCALL_DISPATCH[name.value]
  228. if !(None == sc) then
  229. sc = None
  230. res = self.SCALL_DISPATCH[name.value](self, rest)
  231. else
  232. res = node.new(EX.CALL, {name=name.value, args=rest:map(func(i) return self:parse(i) end)})
  233. end
  234. end
  235. --print('In parse, returning', res:pretty())
  236. return res
  237. end,
  238. TT_PARSE_DISPATCH = {
  239. [TOK.INT] = func(self, tok)
  240. return node.new(EX.LIT, tok.value)
  241. end,
  242. [TOK.BOOL] = func(self, tok)
  243. return node.new(EX.LIT, tok.value)
  244. end,
  245. [TOK.NAME] = func(self, tok)
  246. --print('In TOK.NAME, tok is', tok)
  247. res = node.new(EX.REF, tok.value)
  248. --print('In TOK.NAME, returning', res)
  249. return res
  250. end,
  251. [TOK.QUOTE] = func(self, tok)
  252. return self:parse_datum(tok.quoting)
  253. end
  254. },
  255. SCALL_DISPATCH = {
  256. define = func(self, args)
  257. name = args[0]
  258. if !(name.type == TOK.NAME) then error('Define: expected name as first argument') end
  259. value = self:parse(args[1])
  260. return node.new(EX.ASSIGN, {name=name.value, value=value})
  261. end,
  262. ["if"] = func(self, args)
  263. cond = self:parse(args[0])
  264. ift = self:parse(args[1])
  265. iff = self:parse(args[2])
  266. return node.new(EX.IFELSE, {cond=cond, ift=ift, iff=iff})
  267. end,
  268. begin = func(self, args)
  269. args:map(func(i) return self:parse(i) end)
  270. return node.new(EX.LIST, args)
  271. end,
  272. lambda = func(self, args)
  273. --print('Lambda args:', args)
  274. params = args[0]
  275. if !(type(params) == 'list') then error('Lambda: expected parameters as first argument (got '+tostring(params)+')') end
  276. params:map(func(i)
  277. if !(type(i) == 'map') then error('Lambda: expected name token in argument list (got sublist)') end
  278. if !(i.type == TOK.NAME) then error('Lambda: expected name token in argument list (got '+(i:pretty())+')') end
  279. return i.value
  280. end)
  281. body = args:copy()
  282. body:remove(0)
  283. --print('Lambda body:', body)
  284. body:map(func(i) return self:parse(i) end)
  285. return node.new(EX.FUNCDECL, {params=params, body=node.new(EX.LIST, body)})
  286. end,
  287. let = func(self, args)
  288. defs = args[0]
  289. if !(type(defs) == 'list') then error('Let: expected list of bindings are first argument') end
  290. defs:map(func(i)
  291. if !(type(i) == 'list') then error('Let: expected a binding entry') end
  292. return self.SCALL_DISPATCH.define(self, i)
  293. end)
  294. body = args:copy()
  295. body:remove(0)
  296. body:map(func(i) return self:parse(i) end)
  297. return node.new(EX.SCOPE, defs+body)
  298. end,
  299. letrec = func(self, args)
  300. defs = args[0]
  301. if !(type(defs) == 'list') then error('Let: expected list of bindings are first argument') end
  302. defs:map(func(i)
  303. if !(type(i) == 'list') then error('Let: expected a binding entry') end
  304. return self.SCALL_DISPATCH.define(self, i)
  305. end)
  306. body = args:copy()
  307. body:remove(0)
  308. body:map(func(i) return self:parse(i) end)
  309. return node.new(EX.LIST, defs+body)
  310. end
  311. }
  312. parse_datum = func(self, tt)
  313. if type(tt) == 'map' then
  314. return self.TT_PARSE_DATUM_DISPATCH[tt.type](self, tt)
  315. else
  316. list = []
  317. for tok in tt do
  318. list:insert(#list, self:parse_datum(tok))
  319. end
  320. return node.new(EX.LIT, list)
  321. end
  322. end,
  323. TT_PARSE_DATUM_DISPATCH = {
  324. [TOK.INT] = func(self, tok)
  325. return node.new(EX.LIT, tok.value)
  326. end,
  327. [TOK.BOOL] = func(self, tok)
  328. return node.new(EX.LIT, tok.value)
  329. end,
  330. [TOK.NAME] = func(self, tok)
  331. return node.new(EX.LIT, tok.value)
  332. end,
  333. [TOK.QUOTE] = func(self, tok)
  334. return self:parse(tok.quoting)
  335. end
  336. },
  337. run = func(self)
  338. tt = self.ttgen:generate()
  339. list = []
  340. while 1 do
  341. if None == tt then break end
  342. --if type(tt) == 'list' then
  343. list:insert(#list, self:parse(tt))
  344. --end
  345. tt = self.ttgen:generate()
  346. end
  347. --print('In run, list is', list)
  348. return node.new(EX.LIST, list)
  349. end
  350. }
  351. converter = {
  352. new = func(p)
  353. return {parser=p, __index = converter}
  354. end,
  355. make = func(self, node)
  356. --print('In make, node is a', EX[node.type], 'of value', node)
  357. res = self.MAKE_DISPATCH[node.type](self, node)
  358. --print('In make, returning', res)
  359. if type(res) == "astnode" then ast.print(res) end
  360. return res
  361. end,
  362. MAKE_DISPATCH = {
  363. [EX.CALL] = func(self, node)
  364. e = parse('f()').stmtlist[0].expr
  365. e.expr.ident = node.value.name
  366. args = node.value.args:copy():map(func(i) return self:make(i) end)
  367. --print('In EX.CALL, replacement args are', args)
  368. e.args = args
  369. --print('In EX.CALL, args are', e.args)
  370. return e
  371. end,
  372. [EX.ASSIGN] = func(self, node)
  373. e = parse('a = b').stmtlist[0].expr
  374. e.ident = node.value.name
  375. e.value = self:make(node.value.value)
  376. return e
  377. end,
  378. [EX.FUNCDECL] = func(self, node)
  379. e = parse('func() None None end').stmtlist[0].expr
  380. params = node.value.params
  381. --print('In EX.FUNCDECL, params are', params)
  382. e.args = params
  383. --print('In EX.FUNCDECL, args are', e.args)
  384. e.body.stmtlist = self:make(node.value.body)
  385. return e
  386. end,
  387. [EX.SCOPE] = func(self, node)
  388. e = parse('(func() None None end)()').stmtlist[0].expr
  389. node.type = EX.LIST
  390. e.expr.body.stmtlist = self:make(node)
  391. node.type = EX.SCOPE
  392. return e
  393. end,
  394. [EX.IFELSE] = func(self, node)
  395. e = parse('(func() if None then return None else return None end end)()').stmtlist[0].expr
  396. e.expr.body.stmtlist[0].cond = self:make(node.value.cond)
  397. e.expr.body.stmtlist[0].iftrue.stmtlist[0].ret = self:make(node.value.ift)
  398. e.expr.body.stmtlist[0].iffalse.stmtlist[0].ret = self:make(node.value.iff)
  399. return e
  400. end,
  401. [EX.DATUM] = func(self, node) error('EX.DATUM: Not implemented') end,
  402. [EX.LIT] = func(self, node)
  403. if type(node.value) == 'list' then
  404. e = parse('[None]').stmtlist[0].expr
  405. e.list = node.value:copy():map(func(i) return self:make(i) end)
  406. else
  407. e = parse('None').stmtlist[0].expr
  408. if type(node.value) == "int" then
  409. e.littype = ast.LIT_INT
  410. e.ival = node.value
  411. end
  412. if type(node.value) == "string" then
  413. e.littype = ast.LIT_STRING
  414. e.str = node.value
  415. end
  416. end
  417. return e
  418. end,
  419. [EX.REF] = func(self, node)
  420. e = parse('a').stmtlist[0].expr
  421. e.ident = node.value
  422. return e
  423. end,
  424. [EX.LIST] = func(self, node)
  425. e = parse('func() None end').stmtlist[0].expr
  426. l = node.value:copy()
  427. l:map(func(i)
  428. s = parse('None').stmtlist[0]
  429. s.expr = self:make(i)
  430. return s
  431. end)
  432. lastidx = (#l) - 1
  433. r = parse('return None').stmtlist[0]
  434. r.ret = l[lastidx].expr
  435. l[lastidx] = r
  436. --print('In EX.LIST, e is now' e)
  437. e.body.stmtlist = l
  438. return e.body.stmtlist
  439. end
  440. },
  441. run = func(self)
  442. list = self:make(self.parser:run())
  443. res = parse('(func() None None end)()')
  444. --print('In run, list is', list)
  445. --for i in list do ast.print(i) end
  446. res.stmtlist[0].expr.expr.body.stmtlist = list
  447. return res
  448. end
  449. }
  450. _G = debug.globals()
  451. _G['+'] = func(a, b) return a + b end
  452. _G['-'] = func(a, b) return a - b end
  453. _G['*'] = func(a, b) return a * b end
  454. _G['/'] = func(a, b) return a / b end
  455. _G['<'] = func(a, b) return a < b end
  456. _G['>'] = func(a, b) return a > b end
  457. _G['<='] = func(a, b) return a <= b end
  458. _G['>='] = func(a, b) return a >= b end
  459. _G['=='] = func(a, b) return a == b end
  460. _G['eq'] = _G['==']
  461. _G['or'] = func(a, b) return a || b end
  462. _G['and'] = func(a, b) return a && b end