@@ -98,35 +98,16 @@ impl EnvironmentStack {
98
98
}
99
99
}
100
100
101
- pub struct Frame {
102
- instructions : Vec < Opcode > ,
103
- ip : i32 ,
104
- num_of_blocks : i32 ,
105
- }
106
-
107
- impl Frame {
108
- #[ inline( always) ]
109
- fn new ( instructions : Vec < Opcode > ) -> Frame {
110
- Frame {
111
- instructions,
112
- ip : 0 ,
113
- num_of_blocks : 0 ,
114
- }
115
- }
116
- }
117
-
118
101
pub struct VM {
119
102
pub stack : Vec < Value > ,
120
103
env_stack : EnvironmentStack ,
121
- frames : Vec < Frame > ,
122
104
}
123
105
124
106
impl VM {
125
- pub fn new ( instructions : Vec < Opcode > ) -> VM {
107
+ pub fn new ( ) -> VM {
126
108
Self {
127
109
stack : vec ! [ ] ,
128
110
env_stack : EnvironmentStack :: new ( ) ,
129
- frames : vec ! [ Frame :: new( instructions) ] ,
130
111
}
131
112
}
132
113
@@ -154,13 +135,11 @@ impl VM {
154
135
155
136
#[ inline( always) ]
156
137
fn begin_environment ( & mut self , var_count : usize ) {
157
- self . current_frame_mut ( ) . num_of_blocks += 1 ;
158
138
self . env_stack . begin_environment ( var_count)
159
139
}
160
140
161
141
#[ inline( always) ]
162
142
fn end_environment ( & mut self ) {
163
- self . current_frame_mut ( ) . num_of_blocks -= 1 ;
164
143
self . env_stack . end_environment ( )
165
144
}
166
145
@@ -174,38 +153,13 @@ impl VM {
174
153
self . env_stack . set ( scope_index, index, value)
175
154
}
176
155
177
- #[ inline( always) ]
178
- fn current_frame ( & self ) -> & Frame {
179
- unsafe { self . frames . get_unchecked ( self . frames . len ( ) - 1 ) }
180
- }
181
-
182
- #[ inline( always) ]
183
- fn current_frame_mut ( & mut self ) -> & mut Frame {
184
- self . frames . last_mut ( ) . unwrap ( )
185
- }
186
-
187
- #[ inline( always) ]
188
- fn current_frame_instruction ( & self ) -> Opcode {
189
- let curr_frame = self . current_frame ( ) ;
190
-
191
- curr_frame. instructions [ curr_frame. ip as usize ] . clone ( )
192
- }
193
-
194
- #[ inline( always) ]
195
- fn push_frame ( & mut self , instructions : Vec < Opcode > ) {
196
- self . frames . push ( Frame :: new ( instructions) ) ;
197
- }
198
-
199
- #[ inline( always) ]
200
- fn pop_frame ( & mut self ) {
201
- self . frames . pop ( ) ;
202
- }
203
-
204
- pub fn interpret ( & mut self ) -> Result < ( ) , RuntimeError > {
205
- while self . current_frame ( ) . ip < self . current_frame ( ) . instructions . len ( ) as i32 {
206
- let instruction = self . current_frame_instruction ( ) ;
156
+ pub fn interpret ( & mut self , instructions : Vec < Opcode > ) -> Result < Value , RuntimeError > {
157
+ let mut ip = 0 ;
158
+ let mut num_of_blocks = 0 ;
159
+ while ip < instructions. len ( ) as i32 {
160
+ let instruction = instructions. get ( ip as usize ) . unwrap ( ) ;
207
161
match instruction {
208
- Opcode :: Const ( val) => self . push ( val) ,
162
+ Opcode :: Const ( val) => self . push ( val. clone ( ) ) ,
209
163
Opcode :: Add => {
210
164
let left = self . pop ( ) ;
211
165
let right = self . pop ( ) ;
@@ -240,36 +194,38 @@ impl VM {
240
194
self . push ( Value :: Bool ( !is_equal ( left, right) ) )
241
195
}
242
196
Opcode :: Jmp ( offset) => {
243
- self . current_frame_mut ( ) . ip += offset;
197
+ ip += offset;
244
198
continue ;
245
199
}
246
200
Opcode :: JmpFalse ( offset) => {
247
201
let operand = self . pop ( ) ;
248
202
249
203
if !is_truthy ( operand) {
250
- self . current_frame_mut ( ) . ip += offset;
204
+ ip += offset;
251
205
continue ;
252
206
}
253
207
}
254
208
Opcode :: Pop => {
255
209
self . pop ( ) ;
256
210
}
257
211
Opcode :: Block ( var_count) => {
258
- self . begin_environment ( var_count) ;
212
+ num_of_blocks += 1 ;
213
+ self . begin_environment ( * var_count) ;
259
214
}
260
215
Opcode :: EndBlock => {
216
+ num_of_blocks -= 1 ;
261
217
self . end_environment ( ) ;
262
218
}
263
219
Opcode :: Let ( index) => {
264
220
let value = self . pop ( ) ;
265
221
266
- self . define ( index, value) ;
222
+ self . define ( * index, value) ;
267
223
}
268
224
Opcode :: Get {
269
225
scope_index : scope,
270
226
index,
271
227
} => {
272
- let val = self . get ( scope, index) ;
228
+ let val = self . get ( * scope, * index) ;
273
229
274
230
self . push ( val) ;
275
231
}
@@ -279,12 +235,12 @@ impl VM {
279
235
} => {
280
236
let value = self . stack_top ( ) ;
281
237
282
- self . set ( scope, index, value. clone ( ) ) ;
238
+ self . set ( * scope, * index, value. clone ( ) ) ;
283
239
}
284
240
Opcode :: Array ( size) => {
285
241
let mut values = vec ! [ ] ;
286
242
287
- for _ in 0 ..size {
243
+ for _ in 0 ..( * size) {
288
244
values. push ( self . pop ( ) ) ;
289
245
}
290
246
@@ -332,15 +288,15 @@ impl VM {
332
288
333
289
match operand {
334
290
Value :: Fn ( instructions, param_count) => {
335
- if arg_count != param_count {
291
+ if ( * arg_count) != param_count {
336
292
panic ! ( )
337
293
}
338
294
339
- self . push_frame ( instructions) ;
340
- continue ;
295
+ let value = self . interpret ( instructions) ? ;
296
+ self . push ( value ) ;
341
297
}
342
298
Value :: BuiltInFn ( f, param_count) => {
343
- if arg_count != param_count {
299
+ if ( * arg_count) != param_count {
344
300
panic ! ( )
345
301
}
346
302
@@ -357,35 +313,34 @@ impl VM {
357
313
Opcode :: Ret => {
358
314
let operand = self . pop ( ) ;
359
315
360
- for _ in 0 ..self . current_frame ( ) . num_of_blocks {
316
+ for _ in 0 ..num_of_blocks {
361
317
self . end_environment ( ) ;
362
318
}
363
319
364
- self . pop_frame ( ) ;
365
- self . push ( operand) ;
320
+ return Ok ( operand) ;
366
321
}
367
322
Opcode :: FnStart ( param_count) => {
368
- self . begin_environment ( param_count) ;
323
+ num_of_blocks += 1 ;
324
+ self . begin_environment ( * param_count) ;
369
325
370
- for i in 0 ..param_count {
326
+ for i in 0 ..( * param_count) {
371
327
let arg = self . pop ( ) ;
372
328
self . define ( i, arg) ;
373
329
}
374
330
}
375
331
Opcode :: FnEnd => {
332
+ num_of_blocks -= 1 ;
376
333
self . end_environment ( ) ;
377
- self . pop_frame ( ) ;
378
- self . push ( Value :: Nil ) ;
379
334
}
380
335
Opcode :: GetGlobal { index } => {
381
- let val = self . env_stack . stack [ 0 ] [ index] . clone ( ) ;
336
+ let val = self . env_stack . stack [ 0 ] [ * index] . clone ( ) ;
382
337
383
338
self . push ( val) ;
384
339
}
385
340
Opcode :: SetGlobal { index } => {
386
341
let value = self . stack_top ( ) ;
387
342
388
- self . env_stack . stack [ 0 ] [ index] = value. clone ( ) ;
343
+ self . env_stack . stack [ 0 ] [ * index] = value. clone ( ) ;
389
344
}
390
345
Opcode :: Index => {
391
346
let value = self . pop ( ) ;
@@ -402,7 +357,7 @@ impl VM {
402
357
}
403
358
}
404
359
Opcode :: Continue => {
405
- let mut current_instruction = self . current_frame_instruction ( ) ;
360
+ let mut current_instruction = instruction ;
406
361
let mut new_blocks = 0 ;
407
362
while !matches ! ( current_instruction, Opcode :: LoopUpdate ) {
408
363
// Sync env_stack
@@ -419,8 +374,8 @@ impl VM {
419
374
}
420
375
_ => { }
421
376
}
422
- self . current_frame_mut ( ) . ip += 1 ;
423
- current_instruction = self . current_frame_instruction ( ) ;
377
+ ip += 1 ;
378
+ current_instruction = instructions . get ( ip as usize ) . unwrap ( ) ;
424
379
}
425
380
}
426
381
// Labels
@@ -429,10 +384,10 @@ impl VM {
429
384
Opcode :: LoopEnd => { }
430
385
}
431
386
432
- self . current_frame_mut ( ) . ip += 1 ;
387
+ ip += 1 ;
433
388
}
434
389
435
- Ok ( ( ) )
390
+ Ok ( Value :: Nil )
436
391
}
437
392
}
438
393
0 commit comments