Add failing test.
Chris Pressey
3 years ago
2971 | 2971 | | } |
2972 | 2972 | ? UnmeaningfulOutputError: x |
2973 | 2973 | |
2974 | For now at least, you cannot have a `goto` inside a loop. | |
2974 | For now at least, you cannot have a `goto` inside a `repeat` loop. | |
2975 | 2975 | |
2976 | 2976 | | define bar routine trashes x, z, n { |
2977 | 2977 | | ld x, 200 |
2988 | 2988 | |
2989 | 2989 | `goto`, as a matter of syntax, can only appear at the end |
2990 | 2990 | of a block; but it need not be the final instruction in a |
2991 | routine. It is only important that the type context at every | |
2992 | `goto` is compatible with the type context at the end of | |
2993 | the routine. | |
2991 | routine. | |
2994 | 2992 | |
2995 | 2993 | | define bar routine trashes x, z, n { |
2996 | 2994 | | ld x, 200 |
3106 | 3104 | | } |
3107 | 3105 | = ok |
3108 | 3106 | |
3107 | It is, however, important that the type context at every | |
3108 | `goto` is compatible with the type context at the end of | |
3109 | the routine. | |
3110 | ||
3111 | | define bar routine | |
3112 | | inputs x | |
3113 | | trashes x, z, n | |
3114 | | { | |
3115 | | ld x, 200 | |
3116 | | } | |
3117 | | | |
3118 | | define main routine trashes x, z, n { | |
3119 | | ld x, 0 | |
3120 | | if z { | |
3121 | | ld x, 1 | |
3122 | | goto bar | |
3123 | | } else { | |
3124 | | ld x, 0 | |
3125 | | } | |
3126 | | ld x, 1 | |
3127 | | } | |
3128 | = ok | |
3129 | ||
3130 | Here, we try to trash x before gotoing a routine that inputs x. | |
3131 | ||
3132 | | define bar routine | |
3133 | | inputs x | |
3134 | | trashes x, z, n | |
3135 | | { | |
3136 | | ld x, 200 | |
3137 | | } | |
3138 | | | |
3139 | | define main routine | |
3140 | | outputs a | |
3141 | | trashes x, z, n | |
3142 | | { | |
3143 | | ld x, 0 | |
3144 | | if z { | |
3145 | | trash x | |
3146 | | goto bar | |
3147 | | } else { | |
3148 | | trash x | |
3149 | | } | |
3150 | | ld a, 1 | |
3151 | | } | |
3152 | ? UnmeaningfulReadError: x | |
3153 | ||
3154 | Here, we declare that main outputs a, but we goto a routine that does not output a. | |
3155 | ||
3156 | | define bar routine | |
3157 | | inputs x | |
3158 | | trashes x, z, n | |
3159 | | { | |
3160 | | ld x, 200 | |
3161 | | } | |
3162 | | | |
3163 | | define main routine | |
3164 | | outputs a | |
3165 | | trashes x, z, n | |
3166 | | { | |
3167 | | ld x, 0 | |
3168 | | if z { | |
3169 | | ld x, 1 | |
3170 | | goto bar | |
3171 | | } else { | |
3172 | | ld x, 2 | |
3173 | | } | |
3174 | | ld a, 1 | |
3175 | | } | |
3176 | ? UnmeaningfulReadError | |
3177 | ||
3178 | TODO: we should have a lot more test cases for the above, here. | |
3179 | ||
3109 | 3180 | Can't `goto` a routine that outputs or trashes more than the current routine. |
3110 | 3181 | |
3111 | 3182 | | define bar routine trashes x, y, z, n { |