1
-
2
1
class Lisp
3
2
4
- @definitions = { }
5
- @variables = { }
6
-
7
- def self . evaluate ( operation , operands , scopes )
8
-
9
- operands = operands . map { |operand | fetchVariableValue ( operand , scopes ) }
10
- result = 0
11
- if operation == '+'
12
- result = operands . reduce { |a , b | a . to_i +b . to_i }
13
- elsif operation == '-'
14
- result = operands . reduce { |a , b | a . to_i -b . to_i }
15
- elsif operation == '*'
16
- result = operands . reduce { |a , b | a . to_i *b . to_i }
17
- elsif operation == '/'
18
- result = operands . reduce { |a , b | a . to_i /b . to_i }
19
- else
20
- result = evaluateByDefinition ( operation , operands )
3
+ def self . parse ( input )
4
+ tokens = input . split
5
+ i = 0
6
+ @definitions = { "" => { } }
7
+ @variables = { "" => { } }
8
+ while i < tokens . size do
9
+ token = tokens [ i ]
10
+ if token == 'define' and tokens [ i +1 ] == '('
11
+ i , name = parseDefinitions ( tokens , i , "" )
12
+ elsif token == 'define'
13
+ @variables [ "" ] . update ( tokens [ i +1 ] => tokens [ i +2 ] )
14
+ i = i + 2
15
+ elsif token != '(' and token != ')'
16
+ result , i = executeStmt ( tokens , i , [ "" ] , { } )
17
+ end
18
+ i = i + 1
21
19
end
22
- return result
20
+ result
23
21
end
24
22
25
- def self . fetchVariableValue ( var , scopes )
26
- value = nil
27
- scopes . each { |scope | value = variables [ scope ] [ var ] if ( variables [ scope ] [ var ] != nil }
23
+ def self . parseDefinitions ( tokens , i , scope_name )
24
+ method_name = tokens [ i +2 ]
25
+ current_scope = scope_name +"." +method_name
26
+ @definitions = @definitions . merge ( { current_scope => { } } )
27
+ private_definitions = { }
28
+ params = [ ]
29
+ i = i + 3
30
+ token = tokens [ i ]
28
31
29
- if ( value != nil )
30
- return value
31
- else
32
- return var
33
- end
32
+ while true do
33
+ token = tokens [ i ]
34
+ if token == ')'
35
+ break
36
+ end
37
+ params . push ( token )
38
+ i = i + 1
34
39
end
35
40
36
- def self . evaluateByDefinition ( operation , operands )
37
- if @definitions . include? operation
38
- param = @definitions [ operation ] [ 0 ]
39
- stmt = @definitions [ operation ] [ 1 ]
40
- i = 0
41
- while i < param . size do
42
- stmt = stmt . sub ( param [ i ] , operands [ i ] )
43
- i = i + 1
44
- end
45
-
46
- return execute ( stmt )
41
+ i = i + 1
42
+ token = tokens [ i ]
43
+ stmts = [ ]
44
+
45
+ count = -1
46
+ while true do
47
+ token = tokens [ i ]
48
+ if token == 'define' and tokens [ i +1 ] == '('
49
+ i , name = parseDefinitions ( tokens , i , current_scope )
50
+ private_definitions . update ( name => current_scope )
51
+ @definitions [ current_scope ] [ name ] [ 2 ] = @definitions [ current_scope ] [ name ] [ 2 ] . merge ( private_definitions )
52
+ elsif token == ')' and count == 0
53
+ break
54
+ elsif token == '('
55
+ count = count + 1
56
+ stmts . push ( token )
57
+ elsif token == ')'
58
+ count = count - 1
59
+ stmts . push ( token )
47
60
else
48
- puts "Unexpected operation"
49
- return 0
61
+ stmts . push ( token )
50
62
end
63
+ i = i + 1
51
64
end
65
+ i = i + 1
66
+ stmts . push ( token )
67
+ @definitions [ scope_name ] = @definitions [ scope_name ] . merge ( { method_name => [ params , stmts , private_definitions ] } )
68
+ return i , method_name
69
+ end
52
70
53
- def self . execute ( input )
54
- tokens = input . split
55
-
56
- operands = [ ]
57
- operation = tokens [ 1 ]
58
- i = 2
59
- while i < tokens . size do
60
- token = tokens [ i ]
61
-
62
- if token == '('
63
- temp_tokens = [ ]
64
- temp_tokens . push ( token )
65
- while token != ')'
66
- i = i +1
67
- token = tokens [ i ]
68
- temp_tokens . push ( token )
69
- end
70
- operands . push ( execute ( temp_tokens . join ( ' ' ) ) )
71
- elsif token != ')'
72
- operands . push ( token ) ;
73
- end
74
- prevToken = token
75
- i = i + 1
76
- end
77
- return evaluate ( operation , operands )
78
- end
71
+ def self . executeStmt ( tokens , i , scopes , private_definitions )
79
72
80
- def self . parse ( scope_name , input )
81
- tokens = input . split
82
- i = 0
83
- @definitions = { "" => { } }
84
- while i < tokens . size do
85
- token = tokens [ i ]
86
- if token == 'define'
87
- i = parseDefinitions ( tokens , i , "" )
88
- end
89
- i = i + 1
73
+ while true
74
+ if tokens [ i ] == "("
75
+ i = i +1
76
+ else
77
+ break
90
78
end
91
- @definitions
92
79
end
93
80
94
- def self . parseDefinitions ( tokens , i , scope_name )
95
- method_name = tokens [ i +2 ]
96
- @definitions . merge ( { scope_name +"." +method_name => { } } )
97
- params = [ ]
98
- i = i + 3
81
+ puts "executing stmt = " + tokens [ i ]
82
+
83
+ operands = [ ]
84
+ operation = tokens [ i ]
85
+ i = i + 1
86
+ while true do
99
87
token = tokens [ i ]
100
88
101
- while true do
102
- token = tokens [ i ]
103
- if token == ')'
104
- break
105
- end
106
- params . push ( token )
107
- i = i + 1
89
+ if token == '('
90
+ operand , i = executeStmt ( tokens , i + 1 , scopes , private_definitions )
91
+ operands . push ( operand )
92
+ elsif token != ')'
93
+ operands . push ( token )
94
+ elsif token == ')'
95
+ break
108
96
end
109
-
110
97
i = i + 1
111
- token = tokens [ i ]
112
- stmts = [ ]
113
-
114
- count = 0
115
- while true do
116
- token = tokens [ i ]
117
- if token == 'define'
118
- i = parseDefinitions ( tokens , i , scope_name +"." +method_name )
119
- elsif token == ')' and count == 0
120
- break
121
- elsif token == '('
122
- count = count + 1
123
- elsif token == ')'
124
- count = count - 1
125
- end
126
- stmts . push ( token )
127
- i = i + 1
98
+ end
99
+ return evaluate ( operation , operands , scopes , private_definitions ) , i
100
+ end
101
+
102
+ def self . evaluate ( operation , operands , scopes , private_definition )
103
+
104
+ if operation == 'define'
105
+ @variables [ scopes . last ] . update ( operands [ 0 ] => operands [ 1 ] )
106
+ result = 0
107
+ else
108
+
109
+ operands = operands . map { |operand | fetchVariableValue ( operand , scopes ) }
110
+ if operation == '+'
111
+ result = operands . reduce { |a , b | a . to_i + b . to_i }
112
+ elsif operation == '-'
113
+ result = operands . reduce { |a , b | a . to_i - b . to_i }
114
+ elsif operation == '*'
115
+ result = operands . reduce { |a , b | a . to_i * b . to_i }
116
+ elsif operation == '/'
117
+ result = operands . reduce { |a , b | a . to_i / b . to_i }
118
+ else
119
+ result = evaluateByDefinition ( operation , operands , scopes , private_definition )
128
120
end
129
- stmts . push ( token )
130
- @definitions [ scope_name ] = @definitions [ scope_name ] . merge ( { method_name => [ params , stmts . join ( ' ' ) ] } )
131
- return i
132
121
end
133
122
134
- def self . definitions
135
- @definitions
123
+ puts "scopes " + scopes . join ( ',' ) . to_s
124
+ puts "operation " + operation . to_s
125
+ puts "operands " + operands . join ( ',' ) . to_s
126
+ puts "result " + result . to_s
127
+
128
+ return result
129
+ end
130
+
131
+ def self . evaluateByDefinition ( operation , operands , scopes , private_definitions )
132
+ function_scope = ""
133
+ if private_definitions . include? operation
134
+ function_scope = private_definitions [ operation ]
135
+ end
136
+ if @definitions [ function_scope ] . include? operation
137
+ params = @definitions [ function_scope ] [ operation ] [ 0 ]
138
+ stmt = @definitions [ function_scope ] [ operation ] [ 1 ]
139
+ private_definitions = @definitions [ function_scope ] [ operation ] [ 2 ]
140
+ @variables . update ( { operation => { } } )
141
+ params . each_with_index { |param , i | @variables [ operation ] . update ( { param => operands [ i ] } ) }
142
+ scopes . push ( operation )
143
+ result , i = executeStmt ( stmt , 1 , scopes , private_definitions )
144
+ while ( i < stmt . size - 2 ) do
145
+ result , i = executeStmt ( stmt , i + 1 , scopes , private_definitions )
146
+ end
147
+ scopes . delete ( operation )
148
+ return result
149
+ else
150
+ puts "Unexpected operation" + operation
151
+ return 0
136
152
end
153
+ end
137
154
155
+ def self . fetchVariableValue ( var , scopes )
156
+ result = nil
157
+ scopes . each { |scope | result = @variables [ scope ] [ var ] if @variables [ scope ] [ var ] != nil }
158
+ if ( result != nil )
159
+ return result
160
+ else
161
+ return var
138
162
end
163
+ end
164
+
165
+ def self . definitions
166
+ @definitions
167
+ end
168
+
169
+ def self . variables
170
+ @variables
171
+ end
172
+
173
+
174
+ end
139
175
140
- Lisp . parse ( "( define ( add a b ) ( + a b ) )" )
176
+ Lisp . parse ( "( define ( fun1 a b c ) ( define ( fun2 a f ) ( * a f ) ) ( define x 1 ) ( + a b ( - b c ) ( fun2 c b ) a x ) ) ( define x 11 ) ( + x ( fun1 1 2 3 ) )" )
177
+ Lisp . parse ( "( define ( sum-of-square x y ) ( + ( square x ) ( square y ) ) ( define ( square x ) ( * x x ) ) ( sum-of-square 3 4 )" )
0 commit comments