@@ -3,55 +3,50 @@ use crate::script::CallError;
33use crate :: tokenizer:: Op ;
44use crate :: { ScriptIter , ScriptType } ;
55use core:: convert:: TryInto ;
6+ use core:: fmt:: { self , Debug , Formatter } ;
67use rustc_hash:: FxHashMap ;
78use std:: collections:: hash_map:: Entry ;
89use std:: rc:: Rc ;
910
10- #[ derive( Debug ) ]
1111pub ( crate ) struct CallArgs {
1212 store_in : Option < u16 > ,
1313 func : Box < str > ,
1414 args : Box < [ u16 ] > ,
1515}
1616
17- #[ derive( Debug ) ]
1817pub ( crate ) enum Instruction {
1918 Call ( Box < ( u16 , CallArgs ) > ) ,
2019 CallSelf ( Box < CallArgs > ) ,
2120 CallGlobal ( Box < CallArgs > ) ,
2221 //Iter(Box<dyn Iterator<Item = Rc<dyn ScriptType>>>),
2322 //Jmp(u32),
2423 //JmpIf(u16, u32),
25-
2624 RetSome ,
2725 RetNone ,
2826
2927 IterConst ( Box < ( u16 , u32 , Box < dyn ScriptIter > ) > ) ,
3028 IterJmp ( u16 , u32 ) ,
3129
32- /*
30+ /*
3331 AndJmp(u16, u16, u32),
3432 OrJmp(u16, u16, u32),
3533 Xor(u16, u16, u32),
3634 Eq,
3735 Neq,
38- */
39-
36+ */
4037 Add ( u16 , u16 , u16 ) ,
4138 //Sub(u16, u16, u16),
4239 Mul ( u16 , u16 , u16 ) ,
4340 //Div(u16, u16, u16),
4441 //Rem(u16, u16, u16),
45-
4642 Move ( u16 , u16 ) ,
47-
48- /*
43+ /*
4944 AddConst,
5045 SubConst,
5146 MulConst,
5247 DivConst,
5348 RemConst,
54- */
49+ */
5550}
5651
5752#[ derive( Debug ) ]
@@ -66,7 +61,7 @@ pub(crate) struct ByteCode {
6661 code : Vec < Instruction > ,
6762 param_count : u16 ,
6863 var_count : u16 ,
69- consts : Vec < Rc < dyn ScriptType > > ,
64+ consts : Vec < Rc < dyn ScriptType > > ,
7065}
7166
7267#[ derive( Debug ) ]
@@ -97,12 +92,12 @@ pub enum EnvironmentError {
9792impl ByteCode {
9893 pub ( crate ) fn parse (
9994 function : Function ,
100- methods : & FxHashMap < & str , ( ) > ,
95+ methods : & FxHashMap < & str , ( ) > ,
10196 locals : & FxHashMap < Box < str > , u16 > ,
10297 ) -> Result < Self , ByteCodeError > {
10398 let mut instr = Vec :: new ( ) ;
10499 let mut vars = FxHashMap :: with_hasher ( Default :: default ( ) ) ;
105- let mut consts = Vec :: new ( ) ;
100+ let mut consts = Vec :: new ( ) ;
106101 let param_count = function. parameters . len ( ) as u16 ;
107102 for p in function. parameters {
108103 if vars. insert ( p, vars. len ( ) as u16 ) . is_some ( ) {
@@ -112,11 +107,11 @@ impl ByteCode {
112107 let mut var_count = vars. len ( ) as u16 ;
113108 let vars = Self :: parse_block (
114109 & function. lines ,
115- methods,
110+ methods,
116111 locals,
117112 & mut instr,
118113 & mut vars,
119- & mut consts,
114+ & mut consts,
120115 & mut var_count,
121116 0 ,
122117 ) ?;
@@ -125,43 +120,47 @@ impl ByteCode {
125120 _ => instr. push ( Instruction :: RetNone ) ,
126121 }
127122
128- if consts. len ( ) > 0 {
129- // All consts are using the upper-most registers, move them downwards
130- let offset = ( u16:: MAX - consts. len ( ) as u16 ) . wrapping_add ( 1 ) ;
131- for i in instr. iter_mut ( ) {
132- use Instruction :: * ;
133- let conv = |c : & mut u16 | if * c >= offset { * c = u16:: MAX - * c + vars } ;
134- match i {
135- Call ( box ( _, ca) ) | CallSelf ( box ca) | CallGlobal ( box ca) => {
136- for a in ca. args . iter_mut ( ) {
137- conv ( a) ;
138- }
139- }
140- Move ( _, a) => conv ( a) ,
141- Add ( _, a, b) | Mul ( _, a, b) => {
142- conv ( a) ;
143- conv ( b) ;
144- }
145- IterConst ( _) | IterJmp ( _, _) | RetSome | RetNone => ( ) ,
146- }
147- }
148- }
123+ if consts. len ( ) > 0 {
124+ // All consts are using the upper-most registers, move them downwards
125+ let offset = ( u16:: MAX - consts. len ( ) as u16 ) . wrapping_add ( 1 ) ;
126+ for i in instr. iter_mut ( ) {
127+ use Instruction :: * ;
128+ let conv = |c : & mut u16 | {
129+ if * c >= offset {
130+ * c = u16:: MAX - * c + vars
131+ }
132+ } ;
133+ match i {
134+ Call ( box ( _, ca) ) | CallSelf ( box ca) | CallGlobal ( box ca) => {
135+ for a in ca. args . iter_mut ( ) {
136+ conv ( a) ;
137+ }
138+ }
139+ Move ( _, a) => conv ( a) ,
140+ Add ( _, a, b) | Mul ( _, a, b) => {
141+ conv ( a) ;
142+ conv ( b) ;
143+ }
144+ IterConst ( _) | IterJmp ( _, _) | RetSome | RetNone => ( ) ,
145+ }
146+ }
147+ }
149148
150149 Ok ( Self {
151150 code : instr,
152151 var_count : vars,
153152 param_count,
154- consts,
153+ consts,
155154 } )
156155 }
157156
158157 fn parse_block < ' a > (
159158 lines : & Lines < ' a > ,
160- methods : & FxHashMap < & str , ( ) > ,
159+ methods : & FxHashMap < & str , ( ) > ,
161160 locals : & FxHashMap < Box < str > , u16 > ,
162161 instr : & mut Vec < Instruction > ,
163162 vars : & mut FxHashMap < & ' a str , u16 > ,
164- consts : & mut Vec < Rc < dyn ScriptType > > ,
163+ consts : & mut Vec < Rc < dyn ScriptType > > ,
165164 curr_var_count : & mut u16 ,
166165 mut min_var_count : u16 ,
167166 ) -> Result < u16 , ByteCodeError > {
@@ -176,13 +175,15 @@ impl ByteCode {
176175 let mut args = Vec :: with_capacity ( arguments. len ( ) ) ;
177176 // TODO move this to `parse_expression`
178177 for a in arguments {
179- let mut add_const = |v| {
180- consts. push ( v) ;
181- u16:: MAX - consts. len ( ) as u16 + 1
182- } ;
178+ let mut add_const = |v| {
179+ consts. push ( v) ;
180+ u16:: MAX - consts. len ( ) as u16 + 1
181+ } ;
183182 args. push ( match a {
184183 Expression :: Atom ( a) => match a {
185- Atom :: String ( a) => add_const ( Rc :: new ( a. to_string ( ) . into_boxed_str ( ) ) ) ,
184+ Atom :: String ( a) => {
185+ add_const ( Rc :: new ( a. to_string ( ) . into_boxed_str ( ) ) )
186+ }
186187 Atom :: Integer ( a) => add_const ( Rc :: new ( * a) ) ,
187188 Atom :: Real ( a) => add_const ( Rc :: new ( * a) ) ,
188189 Atom :: Name ( a) => todo ! ( "call {:?}" , a) ,
@@ -200,9 +201,11 @@ impl ByteCode {
200201 match a {
201202 Expression :: Atom ( a) => {
202203 args. push ( match a {
203- Atom :: String ( a) => add_const ( Rc :: new ( a. to_string ( ) . into_boxed_str ( ) ) ) ,
204- Atom :: Integer ( a) => add_const ( Rc :: new ( * a) ) ,
205- Atom :: Real ( a) => add_const ( Rc :: new ( * a) ) ,
204+ Atom :: String ( a) => add_const ( Rc :: new (
205+ a. to_string ( ) . into_boxed_str ( ) ,
206+ ) ) ,
207+ Atom :: Integer ( a) => add_const ( Rc :: new ( * a) ) ,
208+ Atom :: Real ( a) => add_const ( Rc :: new ( * a) ) ,
206209 Atom :: Name ( a) => todo ! ( "call {:?}" , a) ,
207210 } ) ;
208211 }
@@ -229,11 +232,11 @@ impl ByteCode {
229232 func : ( * func) . into ( ) ,
230233 args : args. into_boxed_slice ( ) ,
231234 } ) ;
232- instr. push ( if methods. contains_key ( func) {
233- Instruction :: CallSelf ( args)
234- } else {
235- Instruction :: CallGlobal ( args)
236- } ) ;
235+ instr. push ( if methods. contains_key ( func) {
236+ Instruction :: CallSelf ( args)
237+ } else {
238+ Instruction :: CallGlobal ( args)
239+ } ) ;
237240 }
238241 Statement :: For { var, expr, lines } => {
239242 let reg = vars. len ( ) . try_into ( ) . expect ( "Too many variables" ) ;
@@ -261,11 +264,11 @@ impl ByteCode {
261264 let ip = instr. len ( ) as u32 ;
262265 min_var_count = Self :: parse_block (
263266 lines,
264- methods,
267+ methods,
265268 locals,
266269 instr,
267270 vars,
268- consts,
271+ consts,
269272 curr_var_count,
270273 min_var_count,
271274 ) ?;
@@ -440,10 +443,10 @@ impl ByteCode {
440443 vars. resize_with ( self . var_count as usize , || {
441444 Rc :: new ( ( ) ) as Rc < dyn ScriptType >
442445 } ) ;
443- vars. extend ( self . consts . iter ( ) . cloned ( ) ) ;
446+ vars. extend ( self . consts . iter ( ) . cloned ( ) ) ;
444447 let mut ip = 0 ;
445448 let mut iterators = Vec :: new ( ) ;
446- let mut call_args = Vec :: new ( ) ;
449+ let mut call_args = Vec :: new ( ) ;
447450 loop {
448451 let err_roob = || RunError :: RegisterOutOfBounds ;
449452 let err_uf = || RunError :: UndefinedFunction ;
@@ -461,12 +464,12 @@ impl ByteCode {
461464 args,
462465 } ,
463466 ) ) => {
464- for & a in args. iter ( ) {
465- call_args. push ( vars. get ( a as usize ) . ok_or ( err_roob ( ) ) ?. clone ( ) ) ;
466- }
467- let obj = vars. get ( * reg as usize ) . ok_or ( err_roob ( ) ) ?. as_ref ( ) ;
468- let r = obj. call ( func, & call_args[ ..] ) . map_err ( err_call) ?;
469- call_args. clear ( ) ;
467+ for & a in args. iter ( ) {
468+ call_args. push ( vars. get ( a as usize ) . ok_or ( err_roob ( ) ) ?. clone ( ) ) ;
469+ }
470+ let obj = vars. get ( * reg as usize ) . ok_or ( err_roob ( ) ) ?. as_ref ( ) ;
471+ let r = obj. call ( func, & call_args[ ..] ) . map_err ( err_call) ?;
472+ call_args. clear ( ) ;
470473 if let Some ( reg) = store_in {
471474 * vars. get_mut ( * reg as usize ) . ok_or ( err_roob ( ) ) ? = r;
472475 }
@@ -476,11 +479,11 @@ impl ByteCode {
476479 func,
477480 args,
478481 } ) => {
479- for & a in args. iter ( ) {
480- call_args. push ( vars. get ( a as usize ) . ok_or ( err_roob ( ) ) ?. clone ( ) ) ;
481- }
482- let r = env. call ( func, & call_args[ ..] ) . map_err ( err_env) ?;
483- call_args. clear ( ) ;
482+ for & a in args. iter ( ) {
483+ call_args. push ( vars. get ( a as usize ) . ok_or ( err_roob ( ) ) ?. clone ( ) ) ;
484+ }
485+ let r = env. call ( func, & call_args[ ..] ) . map_err ( err_env) ?;
486+ call_args. clear ( ) ;
484487 if let Some ( reg) = store_in {
485488 * vars. get_mut ( * reg as usize ) . ok_or ( err_roob ( ) ) ? = r;
486489 }
@@ -490,18 +493,20 @@ impl ByteCode {
490493 func,
491494 args,
492495 } ) => {
493- for & a in args. iter ( ) {
494- call_args. push ( vars. get ( a as usize ) . ok_or ( err_roob ( ) ) ?. clone ( ) ) ;
495- }
496- let r = functions. get ( func) . ok_or ( RunError :: UndefinedFunction ) ?;
497- let r = r. run ( functions, locals, & call_args[ ..] , env) ?;
498- call_args. clear ( ) ;
499- // SAFETY: ditto
496+ for & a in args. iter ( ) {
497+ call_args. push ( vars. get ( a as usize ) . ok_or ( err_roob ( ) ) ?. clone ( ) ) ;
498+ }
499+ let r = functions. get ( func) . ok_or ( RunError :: UndefinedFunction ) ?;
500+ let r = r. run ( functions, locals, & call_args[ ..] , env) ?;
501+ call_args. clear ( ) ;
502+ // SAFETY: ditto
500503 if let Some ( reg) = store_in {
501504 * vars. get_mut ( * reg as usize ) . ok_or ( err_roob ( ) ) ? = r;
502505 }
503506 }
504- RetSome => break Ok ( vars. first ( ) . ok_or ( RunError :: RegisterOutOfBounds ) ?. clone ( ) ) ,
507+ RetSome => {
508+ break Ok ( vars. first ( ) . ok_or ( RunError :: RegisterOutOfBounds ) ?. clone ( ) )
509+ }
505510 RetNone => break Ok ( Rc :: new ( ( ) ) ) ,
506511 IterConst ( box ( reg, jmp_ip, iter) ) => {
507512 let mut iter = iter. iter ( ) ;
@@ -542,11 +547,11 @@ impl ByteCode {
542547 . get_mut ( * r as usize )
543548 . ok_or ( RunError :: RegisterOutOfBounds ) ? = e;
544549 }
545- /*
550+ /*
546551 DupConst(r, c) => {
547552 *vars.get_mut(*r as usize).ok_or(err_roob())? = c.clone();
548553 }
549- */
554+ */
550555 _ => todo ! ( "{:?}" , instr) ,
551556 }
552557 } else {
@@ -585,3 +590,32 @@ impl Environment {
585590 . unwrap ( ) )
586591 }
587592}
593+
594+ /// This returns each instruction on oneline instead of 5+ with the default Debug
595+ impl Debug for Instruction {
596+ fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
597+ use Instruction :: * ;
598+ match self {
599+ Call ( box ( r, a) ) => write ! ( f, "call {}, {:?}" , r, a) ,
600+ CallSelf ( a) => write ! ( f, "call self, {:?}" , a) ,
601+ CallGlobal ( a) => write ! ( f, "call env, {:?}" , a) ,
602+ Move ( a, b) => write ! ( f, "move {:?}, {:?}" , a, b) ,
603+ RetSome => write ! ( f, "ret 0" ) ,
604+ RetNone => write ! ( f, "ret none" ) ,
605+ IterConst ( box ( r, p, i) ) => write ! ( f, "iter {}, {}, {:?}" , r, p, i) ,
606+ IterJmp ( r, p) => write ! ( f, "iterjmp {}, {}" , r, p) ,
607+ Add ( r, a, b) => write ! ( f, "add {}, {}, {}" , r, a, b) ,
608+ Mul ( r, a, b) => write ! ( f, "mul {}, {}, {}" , r, a, b) ,
609+ }
610+ }
611+ }
612+
613+ impl Debug for CallArgs {
614+ fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
615+ if let Some ( n) = self . store_in {
616+ write ! ( f, "{}, \" {}\" , {:?}" , n, self . func, self . args)
617+ } else {
618+ write ! ( f, "none, \" {}\" , {:?}" , self . func, self . args)
619+ }
620+ }
621+ }
0 commit comments