065-goto.scm (1656B)
1 ;; tests/cc-cg/65-goto.scm — goto + labelled statements, forward and back (§F.4). 2 ;; Models a counter that uses goto for both forward skip and backward jump: 3 ;; int main(void) { 4 ;; int s = 0; 5 ;; int i = 0; 6 ;; loop: 7 ;; if (i >= 3) goto done; 8 ;; s = s + 1; 9 ;; i = i + 1; 10 ;; goto loop; 11 ;; done: 12 ;; return s; /* 3 */ 13 ;; } 14 ;; 15 ;; Exercises cg-emit-label / cg-goto. C labels are function-qualified 16 ;; globals, so forward refs work even when loop/switch scopes are nested. 17 18 (let* ((cg (cg-init)) 19 (params (cg-fn-begin cg "main" '() %t-i32)) 20 (s-sl (cg-alloc-slot cg 4 4)) 21 (i-sl (cg-alloc-slot cg 4 4)) 22 (s-sym (%sym "s" 'var 'auto %t-i32 s-sl)) 23 (i-sym (%sym "i" 'var 'auto %t-i32 i-sl))) 24 ;; s = 0; i = 0; 25 (cg-push-sym cg s-sym) (cg-push-imm cg %t-i32 0) 26 (cg-assign cg) (cg-pop cg) 27 (cg-push-sym cg i-sym) (cg-push-imm cg %t-i32 0) 28 (cg-assign cg) (cg-pop cg) 29 30 ;; loop: 31 (cg-emit-label cg "loop") 32 ;; if (i >= 3) goto done; 33 (cg-push-sym cg i-sym) (cg-load cg) 34 (cg-push-imm cg %t-i32 3) 35 (cg-binop cg 'ge) 36 (cg-if cg (lambda () (cg-goto cg "done"))) 37 ;; s = s + 1; 38 (cg-push-sym cg s-sym) 39 (cg-push-sym cg s-sym) (cg-load cg) 40 (cg-push-imm cg %t-i32 1) 41 (cg-binop cg 'add) 42 (cg-assign cg) (cg-pop cg) 43 ;; i = i + 1; 44 (cg-push-sym cg i-sym) 45 (cg-push-sym cg i-sym) (cg-load cg) 46 (cg-push-imm cg %t-i32 1) 47 (cg-binop cg 'add) 48 (cg-assign cg) (cg-pop cg) 49 ;; goto loop; 50 (cg-goto cg "loop") 51 ;; done: 52 (cg-emit-label cg "done") 53 (cg-push-sym cg s-sym) (cg-load cg) 54 (cg-return cg) 55 (cg-fn-end cg) 56 (write-bv-fd 1 (cg-finish cg)))