;; BF IR Emitter ;; Jon Simons (simonsj at ccs dot neu dot edu) ;; August, 2007 ;; ------------------------------------------------------------------------- ;; This module emits the BF Intermediate Representation. ;; ;; The emitted code is just a pseudo-S expression that can be used ;; to visualize the BF IR. ;; ;; Here is a "key" for interpreting how the different IR constructs ;; are output: ;; ;; P is a number representing a pointer location. For LOOPs and MULs, ;; this is the pointer location at the beginning of that expression. ;; For all other operations, this is the pointer to the memory location ;; being operated on. ;; ;; N is a number representing how many times the given operation is ;; performed. ;; ;; (INC N P) ;; (DEC N P) ;; (LT N) ;; (RT N) ;; (OUT P) ;; (IN P) ;; (LOOP P ...) ;; (MUL P ...) ;; ------------------------------------------------------------------------- (module bf-emit-ir mzscheme (provide emit) ;; For AST structs (require "../bf-ast-to-ir.scm") ;; Emit Utils (require "bf-emit-util.scm") (require scheme/list) ;; emit : (list of EXPRs) -> string (define (emit AST) (apply string-append (reverse (emit-helper AST () 0)))) (define (emit-helper AST acc indent) ;; Here emit and emit+ are helpers for padding and formatting ;; strings to be emitted (let ((emit (case-lambda (() (error "emitting nothing?")) ((x) (pad x indent)) (args (pad (apply format args) indent))))) (if (null? AST) acc (let* ((expr (car AST)) (type (EXPR-type expr)) (N (EXPR-N expr)) (ptr (EXPR-ptr expr)) (exprs (EXPR-exprs expr)) (str (case type ((inc) (emit "(INC ~v ~v)~%" N ptr)) ((dec) (emit "(DEC ~v ~v)~%" N ptr)) ((rt) (emit "(RT ~v)~%" N)) ((lt) (emit "(LT ~v)~%" N)) ((out) (emit "(OUT ~v)~%" ptr)) ((in) (emit "(IN ~v)~%" ptr)) ((loop) (string-append (emit "(LOOP ~v~%" ptr) (apply string-append (reverse (emit-helper exprs () (+ 2 indent)))) (emit ")~%"))) ((mul) (string-append (emit "(MUL ~v~%" ptr) (apply string-append (reverse (emit-helper exprs () (+ 2 indent)))) (emit ")~%"))) ((zero) (emit "(ZERO ~v)~%" ptr)) (else (error "Unknown type " type))))) (emit-helper (cdr AST) (cons str acc) indent))))) )