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 )
recipe main [
jump 1 : offset
2015-07-28 21:33:22 +00:00
1 : number < - copy 1
2015-05-17 07:52:23 +00:00
]
2015-05-21 19:36:59 +00:00
+ run : jump 1 : offset
2015-07-28 21:33:22 +00:00
- run : 1 : number < - copy 1
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-07-04 16:40:50 +00:00
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 ) {
2015-10-07 05:15:45 +00:00
raise_error < < maybe ( Recipe [ r ] . name ) < < " 'jump' requires exactly one ingredient, but got " < < inst . to_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 ( 0 ) ) ) {
2015-10-07 05:15:45 +00:00
raise_error < < maybe ( 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-07-04 16:40:50 +00:00
Type_ordinal [ " offset " ] = 0 ;
2015-02-20 01:28:25 +00:00
2015-04-24 17:19:03 +00:00
: ( scenario jump_backward )
2015-02-20 01:28:25 +00:00
recipe 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
2015-05-21 19:36:59 +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-07-04 16:40:50 +00:00
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 ) {
2015-10-07 05:15:45 +00:00
raise_error < < maybe ( Recipe [ r ] . name ) < < " 'jump-if' requires exactly two ingredients, but got " < < inst . to_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 ( 0 ) ) ) {
2015-10-07 05:15:45 +00:00
raise_error < < maybe ( 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 ) ) ) {
2015-10-07 05:15:45 +00:00
raise_error < < maybe ( 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 )
2015-02-20 02:25:25 +00:00
recipe 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
]
2015-07-28 21:33:22 +00:00
+ run : jump - if 999 , 1 : offset
2015-02-20 02:25:25 +00:00
+ run : jumping to instruction 2
2015-07-28 21:33:22 +00:00
- run : 1 : number < - copy 1
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 )
2015-02-20 02:25:25 +00:00
recipe 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
]
2015-07-28 21:33:22 +00:00
+ run : jump - if 0 , 1 : offset
2015-02-20 02:25:25 +00:00
+ run : jump - if fell through
2015-07-28 21:33:22 +00:00
+ run : 123 : number < - copy 1
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-07-04 16:40:50 +00:00
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 ) {
2015-10-07 05:15:45 +00:00
raise_error < < maybe ( Recipe [ r ] . name ) < < " 'jump-unless' requires exactly two ingredients, but got " < < inst . to_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 ( 0 ) ) ) {
2015-10-07 05:15:45 +00:00
raise_error < < maybe ( 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 ) ) ) {
2015-10-07 05:15:45 +00:00
raise_error < < maybe ( 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 )
2015-02-20 02:25:25 +00:00
recipe 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
]
2015-07-28 21:33:22 +00:00
+ run : jump - unless 0 , 1 : offset
2015-02-20 02:25:25 +00:00
+ run : jumping to instruction 2
2015-07-28 21:33:22 +00:00
- run : 123 : number < - copy 1
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 )
2015-02-20 02:25:25 +00:00
recipe 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
]
2015-07-28 21:33:22 +00:00
+ run : jump - unless 999 , 1 : offset
2015-02-20 02:25:25 +00:00
+ run : jump - unless fell through
2015-07-28 21:33:22 +00:00
+ run : 123 : number < - copy 1
2015-03-24 06:59:59 +00:00
+ mem : storing 1 in location 123