2015-04-18 14:50:51 +00:00
//: Jump primitives
2015-04-17 18:22:59 +00:00
2015-05-17 07:52:23 +00:00
: ( scenario jump_can_skip_instructions )
2016-03-08 09:30:14 +00:00
def main [
2015-05-17 07:52:23 +00:00
jump 1 : offset
2015-07-28 21:33:22 +00:00
1 : number < - copy 1
2015-05-17 07:52:23 +00:00
]
2016-03-21 09:25:52 +00:00
+ run : jump { 1 : " offset " }
- run : { 1 : " number " } < - copy { 1 : " literal " }
2015-05-17 07:52:23 +00:00
- mem : storing 1 in location 1
2015-04-17 17:31:17 +00:00
: ( before " End Primitive Recipe Declarations " )
JUMP ,
2015-02-20 01:28:25 +00:00
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " jump " , JUMP ) ;
2015-09-30 09:18:05 +00:00
: ( before " End Primitive Recipe Checks " )
2015-02-20 01:28:25 +00:00
case JUMP : {
2015-09-30 09:18:05 +00:00
if ( SIZE ( inst . ingredients ) ! = 1 ) {
2016-03-21 09:25:52 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " 'jump' requires exactly one ingredient, but got " < < to_original_string ( inst ) < < ' \n ' < < end ( ) ;
2015-07-25 21:19:28 +00:00
break ;
}
2015-09-30 09:18:05 +00:00
if ( ! is_mu_scalar ( inst . ingredients . at ( 0 ) ) ) {
2016-02-26 21:04:55 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " first ingredient of 'jump' should be a label or offset, but got " < < inst . ingredients . at ( 0 ) . original_string < < ' \n ' < < end ( ) ;
2015-07-25 21:19:28 +00:00
break ;
}
2015-09-30 09:18:05 +00:00
break ;
}
: ( before " End Primitive Recipe Implementations " )
case JUMP : {
2015-05-10 15:34:12 +00:00
assert ( current_instruction ( ) . ingredients . at ( 0 ) . initialized ) ;
2015-06-04 01:00:11 +00:00
current_step_index ( ) + = ingredients . at ( 0 ) . at ( 0 ) + 1 ;
2015-10-29 19:09:23 +00:00
trace ( 9998 , " run " ) < < " jumping to instruction " < < current_step_index ( ) < < end ( ) ;
2015-06-04 01:00:11 +00:00
continue ; // skip rest of this instruction
2015-02-20 01:28:25 +00:00
}
2015-05-17 07:52:23 +00:00
//: special type to designate jump targets
: ( before " End Mu Types Initialization " )
2015-11-06 19:06:58 +00:00
put ( Type_ordinal , " offset " , 0 ) ;
2015-02-20 01:28:25 +00:00
2015-04-24 17:19:03 +00:00
: ( scenario jump_backward )
2016-03-08 09:30:14 +00:00
def main [
2015-03-17 05:47:28 +00:00
jump 1 : offset # 0 - +
2015-05-21 19:36:59 +00:00
jump 3 : offset # | + - + 1
2015-03-17 05:47:28 +00:00
# \ / / \ |
jump - 2 : offset # 2 + - - > + |
] # \ / 3
2016-03-21 09:25:52 +00:00
+ run : jump { 1 : " offset " }
+ run : jump { - 2 : " offset " }
+ run : jump { 3 : " offset " }
2015-02-20 02:25:25 +00:00
2015-04-17 17:31:17 +00:00
: ( before " End Primitive Recipe Declarations " )
JUMP_IF ,
2015-02-20 02:25:25 +00:00
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " jump-if " , JUMP_IF ) ;
2015-09-30 09:18:05 +00:00
: ( before " End Primitive Recipe Checks " )
2015-02-20 02:25:25 +00:00
case JUMP_IF : {
2015-09-30 09:18:05 +00:00
if ( SIZE ( inst . ingredients ) ! = 2 ) {
2016-03-21 09:25:52 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " 'jump-if' requires exactly two ingredients, but got " < < to_original_string ( inst ) < < ' \n ' < < end ( ) ;
2015-07-25 21:19:28 +00:00
break ;
}
2015-09-30 09:18:05 +00:00
if ( ! is_mu_scalar ( inst . ingredients . at ( 0 ) ) ) {
2016-02-26 21:04:55 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " 'jump-if' requires a boolean for its first ingredient, but got " < < inst . ingredients . at ( 0 ) . original_string < < ' \n ' < < end ( ) ;
2015-07-25 21:19:28 +00:00
break ;
}
2015-09-30 09:18:05 +00:00
if ( ! is_mu_scalar ( inst . ingredients . at ( 1 ) ) ) {
2016-02-26 21:04:55 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " 'jump-if' requires a label or offset for its second ingredient, but got " < < inst . ingredients . at ( 0 ) . original_string < < ' \n ' < < end ( ) ;
2015-07-25 21:19:28 +00:00
break ;
}
2015-09-30 09:18:05 +00:00
break ;
}
: ( before " End Primitive Recipe Implementations " )
case JUMP_IF : {
2015-05-10 15:34:12 +00:00
assert ( current_instruction ( ) . ingredients . at ( 1 ) . initialized ) ;
2015-05-07 22:06:53 +00:00
if ( ! ingredients . at ( 0 ) . at ( 0 ) ) {
2015-10-29 19:09:23 +00:00
trace ( 9998 , " run " ) < < " jump-if fell through " < < end ( ) ;
2015-02-20 02:25:25 +00:00
break ;
}
2015-06-04 01:00:11 +00:00
current_step_index ( ) + = ingredients . at ( 1 ) . at ( 0 ) + 1 ;
2015-10-29 19:09:23 +00:00
trace ( 9998 , " run " ) < < " jumping to instruction " < < current_step_index ( ) < < end ( ) ;
2015-06-04 01:00:11 +00:00
continue ; // skip rest of this instruction
2015-02-20 02:25:25 +00:00
}
2015-04-24 17:19:03 +00:00
: ( scenario jump_if )
2016-03-08 09:30:14 +00:00
def main [
2015-07-28 21:33:22 +00:00
jump - if 999 , 1 : offset
123 : number < - copy 1
2015-02-20 02:25:25 +00:00
]
2016-03-21 09:25:52 +00:00
+ run : jump - if { 999 : " literal " } , { 1 : " offset " }
2015-02-20 02:25:25 +00:00
+ run : jumping to instruction 2
2016-03-21 09:25:52 +00:00
- run : { 1 : " number " } < - copy { 1 : " literal " }
2015-05-21 19:36:59 +00:00
- mem : storing 1 in location 123
2015-02-20 02:25:25 +00:00
2015-04-24 17:19:03 +00:00
: ( scenario jump_if_fallthrough )
2016-03-08 09:30:14 +00:00
def main [
2015-07-28 21:33:22 +00:00
jump - if 0 , 1 : offset
123 : number < - copy 1
2015-02-20 02:25:25 +00:00
]
2016-03-21 09:25:52 +00:00
+ run : jump - if { 0 : " literal " } , { 1 : " offset " }
2015-02-20 02:25:25 +00:00
+ run : jump - if fell through
2016-03-21 09:25:52 +00:00
+ run : { 123 : " number " } < - copy { 1 : " literal " }
2015-03-24 06:59:59 +00:00
+ mem : storing 1 in location 123
2015-02-20 02:25:25 +00:00
2015-04-17 17:31:17 +00:00
: ( before " End Primitive Recipe Declarations " )
JUMP_UNLESS ,
2015-02-20 02:25:25 +00:00
: ( before " End Primitive Recipe Numbers " )
2015-11-06 19:06:58 +00:00
put ( Recipe_ordinal , " jump-unless " , JUMP_UNLESS ) ;
2015-09-30 09:18:05 +00:00
: ( before " End Primitive Recipe Checks " )
2015-02-20 02:25:25 +00:00
case JUMP_UNLESS : {
2015-09-30 09:18:05 +00:00
if ( SIZE ( inst . ingredients ) ! = 2 ) {
2016-03-21 09:25:52 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " 'jump-unless' requires exactly two ingredients, but got " < < to_original_string ( inst ) < < ' \n ' < < end ( ) ;
2015-07-25 21:19:28 +00:00
break ;
}
2015-09-30 09:18:05 +00:00
if ( ! is_mu_scalar ( inst . ingredients . at ( 0 ) ) ) {
2016-02-26 21:04:55 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " 'jump-unless' requires a boolean for its first ingredient, but got " < < inst . ingredients . at ( 0 ) . original_string < < ' \n ' < < end ( ) ;
2015-07-25 21:19:28 +00:00
break ;
}
2015-09-30 09:18:05 +00:00
if ( ! is_mu_scalar ( inst . ingredients . at ( 1 ) ) ) {
2016-02-26 21:04:55 +00:00
raise < < maybe ( get ( Recipe , r ) . name ) < < " 'jump-unless' requires a label or offset for its second ingredient, but got " < < inst . ingredients . at ( 0 ) . original_string < < ' \n ' < < end ( ) ;
2015-07-25 21:19:28 +00:00
break ;
}
2015-09-30 09:18:05 +00:00
break ;
}
: ( before " End Primitive Recipe Implementations " )
case JUMP_UNLESS : {
2015-05-10 15:34:12 +00:00
assert ( current_instruction ( ) . ingredients . at ( 1 ) . initialized ) ;
2015-05-07 22:06:53 +00:00
if ( ingredients . at ( 0 ) . at ( 0 ) ) {
2015-10-29 19:09:23 +00:00
trace ( 9998 , " run " ) < < " jump-unless fell through " < < end ( ) ;
2015-02-20 02:25:25 +00:00
break ;
}
2015-06-04 01:00:11 +00:00
current_step_index ( ) + = ingredients . at ( 1 ) . at ( 0 ) + 1 ;
2015-10-29 19:09:23 +00:00
trace ( 9998 , " run " ) < < " jumping to instruction " < < current_step_index ( ) < < end ( ) ;
2015-06-04 01:00:11 +00:00
continue ; // skip rest of this instruction
2015-02-20 02:25:25 +00:00
}
2015-04-24 17:19:03 +00:00
: ( scenario jump_unless )
2016-03-08 09:30:14 +00:00
def main [
2015-07-28 21:33:22 +00:00
jump - unless 0 , 1 : offset
123 : number < - copy 1
2015-02-20 02:25:25 +00:00
]
2016-03-21 09:25:52 +00:00
+ run : jump - unless { 0 : " literal " } , { 1 : " offset " }
2015-02-20 02:25:25 +00:00
+ run : jumping to instruction 2
2016-03-21 09:25:52 +00:00
- run : { 123 : " number " } < - copy { 1 : " literal " }
2015-05-21 19:36:59 +00:00
- mem : storing 1 in location 123
2015-02-20 02:25:25 +00:00
2015-04-24 17:19:03 +00:00
: ( scenario jump_unless_fallthrough )
2016-03-08 09:30:14 +00:00
def main [
2015-07-28 21:33:22 +00:00
jump - unless 999 , 1 : offset
123 : number < - copy 1
2015-02-20 02:25:25 +00:00
]
2016-03-21 09:25:52 +00:00
+ run : jump - unless { 999 : " literal " } , { 1 : " offset " }
2015-02-20 02:25:25 +00:00
+ run : jump - unless fell through
2016-03-21 09:25:52 +00:00
+ run : { 123 : " number " } < - copy { 1 : " literal " }
2015-03-24 06:59:59 +00:00
+ mem : storing 1 in location 123