Browse Source

Moved all sol files to programs directory

Benjamin Lannon 5 years ago
parent
commit
7f34aeb132
6 changed files with 1023 additions and 0 deletions
  1. 42
    0
      programs/dump.sol
  2. 86
    0
      programs/interp.sol
  3. 472
    0
      programs/monty.sol
  4. 1
    0
      programs/subtest.sol
  5. 411
    0
      programs/test.sol
  6. 11
    0
      programs/test_monty.sol

+ 42
- 0
programs/dump.sol View File

@@ -0,0 +1,42 @@
1
+func dump(obj, indent)
2
+	if None == indent then
3
+		indent = 0
4
+		seen = {}
5
+	end
6
+	io.stdout:write(" "*indent)
7
+	if type(obj) == "list" then
8
+		buf = buffer.fromobject(obj)
9
+		addr = buf:address()
10
+		if None != seen[obj] then
11
+			print("...("+addr+")")
12
+			return
13
+		end
14
+		seen[obj] = 1
15
+		print("[")
16
+		for elem in obj do
17
+			dump(elem, indent+2)
18
+		end
19
+		print(" "*indent+"] =("+addr+")")
20
+		return
21
+	end
22
+	if type(obj) == "map" then
23
+		buf = buffer.fromobject(obj)
24
+		addr = buf:address()
25
+		if None != seen[obj] then
26
+			print("...("+addr+")")
27
+			return
28
+		end
29
+		seen[obj] = 1
30
+		print("{")
31
+		for key in obj do
32
+			io.stdout:write(" "*(indent+2))
33
+			prepr(key, ":")
34
+			dump(obj[key], indent+4)
35
+		end
36
+		print(" "*indent+"} =("+addr+")")
37
+		return
38
+	end
39
+	prepr(obj)
40
+end
41
+
42
+dump.closure.seen = {}

+ 86
- 0
programs/interp.sol View File

@@ -0,0 +1,86 @@
1
+-- The Solterpreter! A simple command-line interface for the compiler.
2
+
3
+print('Solterpreter/Viperpreter v0.1')
4
+print('(Runtime version ', debug.version, ')')
5
+
6
+__interp = {
7
+	running = 1,
8
+	buffer = '',
9
+	ps1 = '>>> ',
10
+	ps2 = '... ',
11
+	stmt_stack=0,
12
+}
13
+
14
+func exit()
15
+	__interp.running=0
16
+end
17
+
18
+quit = exit
19
+
20
+while __interp.running do
21
+	if #__interp.buffer then
22
+		__interp.prompt = __interp.ps2
23
+	else
24
+		__interp.prompt = __interp.ps1
25
+	end
26
+	__interp.line = readline.readline(__interp.prompt)
27
+	if #__interp.line then readline.add_history(__interp.line) end
28
+	--prepr(__interp.line)
29
+	--prepr(__interp)
30
+	if (__interp.line:sub(-4, None)=="then") then
31
+		__interp.buffer+=__interp.line+" "
32
+		__interp.stmt_stack+=1
33
+	else
34
+		if (__interp.line:sub(-2, None)=="do") then
35
+			__interp.buffer+=__interp.line+" "
36
+			__interp.stmt_stack-=1
37
+		else
38
+			if __interp.line:sub(-1, None)=="\" then
39
+				__interp.buffer+=__interp.line:sub(0, -1)+" "
40
+			else
41
+				__interp.buffer+=__interp.line+" "
42
+				if __interp.line:sub(-3, None)=="end" then
43
+					__interp.stmt_stack-=1
44
+				end
45
+				if __interp.stmt_stack<=0 then
46
+					__interp.stmt_stack=0
47
+					__interp.program = try(parse, __interp.buffer)
48
+					if !__interp.program[0] then
49
+						print('Syntax error')
50
+					else
51
+						if !(try(func() __interp.program[1].stmtlist[0].type end)[0]) then
52
+							print('NULL program error')
53
+						else
54
+							if __interp.program[1].stmtlist[0].type == ast.ST_EXPR then
55
+								__interp.program[1] = __interp.program[1].stmtlist[0].expr
56
+								__interp.isexpr = 1
57
+							else
58
+								__interp.isexpr = 0
59
+							end
60
+							__interp.result = try(__interp.program[1])
61
+							if !__interp.result[0] then
62
+								print(__interp.result[1])
63
+								print(__interp.result[2])
64
+								for ent in __interp.result[2] do
65
+									st = ent[0]
66
+									scope = ent[1]
67
+									if st.type == ast.ST_LIST then continue end
68
+									print('In', st, 'at', st.loc.line, ',', st.loc.col, ':')
69
+									ast.print(st)
70
+									print(scope)
71
+									print('---')
72
+								end
73
+							else
74
+								if __interp.isexpr then
75
+									prepr(__interp.result[1])
76
+									_ = __interp.result[1]
77
+								end
78
+							end
79
+						end
80
+					end
81
+					__interp.buffer=''
82
+				end
83
+			end
84
+		end
85
+	end
86
+end

+ 472
- 0
programs/monty.sol View File

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

+ 1
- 0
programs/subtest.sol View File

@@ -0,0 +1 @@
1
+print("Hello from subtest!")

+ 411
- 0
programs/test.sol View File

@@ -0,0 +1,411 @@
1
+print('--- Empty functions')
2
+
3
+func f() end
4
+
5
+print(f())
6
+
7
+print('--- While loop')
8
+a = 1
9
+while a < 10 do
10
+	print(a)
11
+	a += 1
12
+end
13
+
14
+print("--- Range")
15
+
16
+func mul9(b)
17
+	for i in range(#b) do
18
+		b[i] *= 9
19
+	end
20
+end
21
+
22
+l = [1 2 3 4 5]
23
+print(range(#l))
24
+print("--- Iter list")
25
+for i in l do print(i) end
26
+print("--- Index list")
27
+for i in range(#l) do print(i, l[i]) end
28
+print('--- mul9')
29
+mul9(l)
30
+for i in l do print(i) end
31
+print('--- Iter mul9')
32
+for i in range(#l) do print(i, l[i]) end
33
+
34
+print("--- Mapgen")
35
+
36
+PI = 3.14159265358979
37
+
38
+d = {
39
+	integer = 1
40
+	string = "hello"
41
+	submap = {
42
+		stamina = 100
43
+		health = 42.0
44
+	}
45
+	sublist = [1 1 2 3 5 8],
46
+	["this time with spaces"] = PI*2,
47
+	[1 + 5] = 1 + 5,
48
+	[1 + 9] = 1 + 9
49
+}
50
+
51
+print(d)
52
+print('--- Map iter')
53
+for i in d do print(i, d[i]) end
54
+
55
+print('--- try')
56
+
57
+func bad(x)
58
+	print(x)
59
+	return x.c()
60
+end
61
+
62
+test1 = {c = func() return 15 end}
63
+test2 = {}
64
+
65
+print(try(bad, test1))
66
+print(try(bad, test2))
67
+
68
+print(bad(test1))
69
+--print(bad(test2))
70
+
71
+print('--- Induced errors')
72
+
73
+func raise(x)
74
+	error(x)
75
+end
76
+
77
+print(try(raise, "lp0 on fire"))
78
+
79
+print('--- Indexing')
80
+
81
+print(d["integer"])
82
+print(d.integer)
83
+d.integer += 5
84
+print(d.integer)
85
+
86
+print('--- Function binding')
87
+
88
+func outer(a)
89
+	func inner(b)
90
+		return a+b
91
+	end
92
+	inner.closure.a = a
93
+	return inner
94
+end
95
+
96
+i = outer(5)
97
+print(i(3), i(4), i(5))
98
+j = outer(8)
99
+print(j(3), j(4), j(5))
100
+
101
+print('--- Iterators')
102
+
103
+func myiter()
104
+	if i>10 then return StopIteration end
105
+	i+=1
106
+	return i-1
107
+end
108
+myiter.closure.i = 1
109
+
110
+for i in myiter do print(i) end
111
+
112
+print('--- Method calls')
113
+
114
+d = {a = func(a, b) print(a, b) end}
115
+
116
+d.a(1, 2)
117
+d:a(3)
118
+
119
+print('--- Special methods')
120
+
121
+d = {__index = func(obj, key) print('Index', obj, key) return key end,
122
+     __setindex = func(obj, key, val) print('SetIndex', obj, key, val) end,
123
+     __call = func(obj, arg1, arg2) print('Call', obj, arg1, arg2) return arg1 end}
124
+
125
+print(d[3], d[5])
126
+
127
+d.a = 7
128
+
129
+print(d("q", "r"))
130
+
131
+e = {a=1, b=2}
132
+d = {__index = e, __setindex = e}
133
+
134
+print(d, d.a, d.b)
135
+
136
+d.c = 5
137
+d.b = 7
138
+
139
+print(d, e)
140
+
141
+print('--- Data sharing')
142
+
143
+d = {}
144
+e = [1 2 3 4 5]
145
+d.a = e
146
+d.b = e
147
+
148
+print(d)
149
+
150
+e[2]=7
151
+e[3]="c"
152
+
153
+print(d)
154
+
155
+d.a:insert(#(d.a), "q")
156
+d.b:remove(1)
157
+d.a[3]="f"
158
+
159
+print(d)
160
+
161
+print('--- Arithmetic structure operations')
162
+
163
+print('ab'+'cd')
164
+print('l'+'ol'*32)
165
+print([1 2 3]+[4 5])
166
+print([1 2 3]*5)
167
+print({a=1 b=2}+{c=3})
168
+
169
+print('--- Map/filter')
170
+
171
+l = [1 2 3 4 5]
172
+print(l)
173
+
174
+l:map(func (i) return i*3 end)
175
+print(l)
176
+
177
+l:filter(func (i) return i & 1 end)
178
+print(l)
179
+
180
+print('--- Map/filter chain')
181
+
182
+print([1 2 3 4 5]:map(func (i) return i * 3 end):filter(func (i) return i & 1 end))
183
+
184
+print('--- Exec/eval')
185
+
186
+exec('print("Hello from exec!")')
187
+print(eval('5 + 3'))
188
+execfile('subtest.sol')
189
+
190
+print('--- Modulus')
191
+
192
+print(5%3)
193
+print(13%5)
194
+print(15%15)
195
+
196
+print('--- Special function manipulation')
197
+
198
+func foo(x)
199
+	return x
200
+end
201
+
202
+print(foo)
203
+foo.name = "bar"
204
+print(foo)
205
+
206
+func something()
207
+	return i
208
+end
209
+
210
+something.closure = {i=[1, 2, 3]}
211
+print(something())
212
+
213
+cl = something.closure
214
+cl.i:insert(0, "b")
215
+print(something())
216
+
217
+print('--- Function body swapping')
218
+
219
+func a()
220
+	return 0
221
+end
222
+
223
+func b()
224
+	return 2
225
+end
226
+
227
+print(a, a())
228
+print(b, b())
229
+
230
+print(a.stmt)
231
+print(b.stmt)
232
+
233
+temp = a.stmt
234
+a.stmt = b.stmt
235
+b.stmt = temp
236
+
237
+print(a, a())
238
+print(b, b())
239
+
240
+newbody = parse('return 4')
241
+print(newbody)
242
+
243
+a.stmt = newbody
244
+b.stmt = newbody
245
+
246
+print(a, a())
247
+print(b, b())
248
+
249
+print('--- More complicated ASTs')
250
+
251
+print(outer, outer.stmt, outer.stmt.stmtlist)
252
+
253
+print('--- Exec- and eval-by-parse')
254
+
255
+parse('print("Hello from parse()!")')()
256
+print(parse('5 + 3').stmtlist[0].expr())
257
+
258
+print('--- Mutating ASTs')
259
+
260
+func f()
261
+	return 5 + 7
262
+end
263
+
264
+print(f, f.stmt, f())
265
+
266
+f.stmt.stmtlist[0].ret.right.ival = 11
267
+
268
+print(f, f.stmt, f())
269
+
270
+func g()
271
+	a=1
272
+	b=2
273
+	print("a=", a, ", b=", b)
274
+end
275
+
276
+print(g, g.stmt, g())
277
+
278
+g.stmt.stmtlist[1].expr.value = parse('a').stmtlist[0].expr
279
+
280
+print(g, g.stmt, g())
281
+
282
+print('--- AST Environments')
283
+
284
+code = parse('print("a is", a, "and b is", b"); a = 4; b = 5')
285
+print(code)
286
+code()
287
+
288
+d = {a=1, b=2}
289
+print(d)
290
+code(d)
291
+print(d)
292
+e = {a="hello", b=["world"]}
293
+print(e)
294
+code(e)
295
+print(e)
296
+
297
+e = {a=1, b=2}
298
+d = {__index = e}
299
+print(d)
300
+print(e)
301
+code(d)
302
+print(d)
303
+print(e)
304
+
305
+print('--- Basic buffers')
306
+
307
+print('(buffer.fromstring = ', buffer.fromstring, ')')
308
+b = buffer.fromstring("Hello, world!")
309
+print(b)
310
+print('(b.get = ', b.get, ')')
311
+print(b:get(buffer.type.cstr))
312
+b:set(buffer.type.char, "Q")
313
+b:set(buffer.type.char, "L", 2)
314
+print(b:get(buffer.type.cstr))
315
+print(b:get(buffer.type.cstr, 5))
316
+print(b:get(buffer.type.uint32))
317
+--b:set(buffer.type.double, 1.243416560929)
318
+b:set(buffer.type.uint32, 1886545252)
319
+print(b:get(buffer.type.uint32))
320
+print(b:get(buffer.type.cstr))
321
+q = buffer.fromaddress(b:address(), b:size())
322
+print(q:get(buffer.type.cstr))
323
+q:set(buffer.type.cstr, "Goodbye!")
324
+print(q:get(buffer.type.cstr), b:get(buffer.type.cstr))
325
+
326
+s = "A string!"
327
+b = buffer.fromobject(s)
328
+prepr(s)
329
+print('...is a', buffer.objtype[b:get(buffer.type.int, 0)])
330
+print('(buffer.sizeof.ptr = ', buffer.sizeof.ptr, ')')
331
+print('(buffer.sizeof.int = ', buffer.sizeof.int, ')')
332
+print('(buffer.sizeof.int*2 = ', buffer.sizeof.int*2, ')')
333
+print('(buffer.sizeof.int*2 + buffer.sizeof.ptr = ', buffer.sizeof.int*2 + (buffer.sizeof.ptr), ')')
334
+bs = b:get(buffer.type.ptr, buffer.sizeof.int*2 + (buffer.sizeof.ptr))
335
+print('...string buffer:', bs)
336
+print('...with value:', bs:get(buffer.type.cstr))
337
+
338
+print('--- IO redirection')
339
+
340
+oldstdout = io.stdout
341
+io.stdout = io.open('stdout', io.MODE_WRITE|io.MODE_TRUNCATE)
342
+
343
+print('A line!')
344
+print('An object:', {a=1, b=2, c="turkey"})
345
+print('Something mysterious :o')
346
+io.stdout:write('Writing directly to a file :D')
347
+io.stdout:flush()
348
+
349
+io.stdout = oldstdout
350
+
351
+print('...restored stdout.')
352
+
353
+f = io.open('stdout', io.MODE_READ)
354
+s = f:read(io.ALL)
355
+print('Buffered output was:')
356
+prepr(s)
357
+f = None
358
+
359
+print('...second time.')
360
+
361
+io.stdout = io.open('stdout', io.MODE_WRITE|io.MODE_TRUNCATE)
362
+
363
+print('Hey there!')
364
+print('l'+'ol'*32)
365
+io.stdout:flush()
366
+
367
+io.stdout = oldstdout
368
+
369
+print('...restored.')
370
+print('Output was:')
371
+prepr(io.open('stdout', io.MODE_READ):read(io.ALL))
372
+
373
+print('--- Substrings')
374
+
375
+s = 'This is a test!'
376
+prepr(s)
377
+prepr(s:sub(1, -1))
378
+prepr(s:sub(3, -3))
379
+prepr(s:sub(3, 5))
380
+prepr(s:sub(3, 11))
381
+prepr(s:sub(-1000, -1000))
382
+
383
+print('--- Splitting')
384
+s = 'This is a test!'
385
+prepr(s)
386
+prepr(s:split(' '))
387
+prepr(s:split('i'))
388
+prepr(s:split('0'))
389
+prepr(s:split('aeiou'))
390
+
391
+l = s:split(' ')
392
+for i in l do
393
+	prepr(i, type(i))
394
+end
395
+
396
+print('--- Continue/break')
397
+
398
+l = range(10)
399
+for i in l do
400
+	print(i)
401
+	if i >= 5 then break end
402
+end
403
+
404
+print('---')
405
+
406
+for i in l do
407
+	if i%2 == 0 then continue end
408
+	print(i)
409
+end
410
+
411
+print('--- All done!')

+ 11
- 0
programs/test_monty.sol View File

@@ -0,0 +1,11 @@
1
+execfile('monty.sol')
2
+t = tokenizer.new(io.open('/tmp/monty', io.MODE_READ))
3
+ttg = ttreegen.new(t)
4
+p = parser.new(ttg)
5
+c = converter.new(p)
6
+stmt = c:run()
7
+print('Resulting statement:')
8
+ast.print(stmt)
9
+print('---Running results begin here---')
10
+stmt()
11
+io.stdin:read(io.LINE)

Loading…
Cancel
Save