-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpang-003.lua
79 lines (72 loc) · 2.15 KB
/
pang-003.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
-- pang: polish notation language
local pang_version="003"
print("pang version: "..pang_version)
local pn="do if false print 2 print add 1 2 print 4 end"
local words={}
for word in string.gmatch(pn, "%S+") do
table.insert(words,word)
end
function print_function(arguments)
print(evaluate_word(arguments[1]))
return "(print returns no value)"
end
function add_function(arguments)
return evaluate_word(arguments[1])+evaluate_word(arguments[2])
end
function true_function(arguments)
return true
end
function false_function(arguments)
return false
end
function if_function(arguments)
if evaluate_word(arguments[1]) then
evaluate_word(arguments[2])
else
evaluate_word(arguments[3])
end
end
local word_definitions={["print"]={1,print_function},["add"]={2,add_function},["true"]={0,true_function},["false"]={0,false_function},["if"]={3,if_function}}
function phrase_length(word_index)
local word=words[word_index]
local length=1
if word=="do" then
while true do
if words[word_index+length]=="end" then return length+1 end
length=length+phrase_length(word_index+length)
end
end
local number=tonumber(word)
if number~=nil then return 1 end
local argument_length=word_definitions[word][1]
for argument_index=1,argument_length do
length=length+phrase_length(word_index+length)
end
return length
end
function evaluate_word(word_index)
local returned_value
local word=words[word_index]
returned_value=tonumber(word)
if returned_value~=nil then return returned_value end
local word_definition
word_definition=word_definitions[word]
if word=="do" then
local do_word_index=word_index+1
while words[do_word_index]~="end" do
evaluate_word(do_word_index)
do_word_index=do_word_index+phrase_length(do_word_index)
end
return
end
local arguments={}, arity, argument_word_index
arity=word_definition[1]
argument_word_index=word_index+1
for argument_index=1,arity do
table.insert(arguments,argument_word_index)
argument_word_index=argument_word_index+phrase_length(argument_word_index)
end
returned_value=word_definition[2](arguments)
return returned_value
end
evaluate_word(1)