/** * A transformation from the signed integer arithmetic language * to "unsignedArith.l" + "pairs.l" + "logic.l" + "locals.l" * * Integers are encoded as pairs (n,s) where n is the absolute * value and s is false for positive and true for negative values * (s can be either true or false for n=0) * * @author Jacob Andersen */ let target = "unsignedArith.l" + "pairs.l" + "logic.l" + "locals.l" in let signedExtension = "signedArith.l" \ "unsignedArith.l" in idx(signedExtension) + (| "unsignedArith.l" -> (target + signedExtension) [ Exp -> Exp ] Exp.zero = 'cons(#0,#f)' ; Exp.succ = 'let x = $1 in negative?(x) ? cons(--car(x),#t) : cons(++car(x),#f)' ; Exp.pred = 'let x = $1 in positive?(x) ? cons(--car(x),#f) : cons(++car(x),#t)' ; Exp.add = 'let a = cons($1,$2) in let numX = car(car(a)) in let signX = cdr(car(a)) in let numY = car(cdr(a)) in let signY = cdr(cdr(a)) in (signX ^ signY) ? (zero?(numX - numY) ? cons(numY - numX, signY) : cons(numX - numY, signX)) : cons(numX + numY,signX)' ; Exp.sub = 'let a = cons($1,$2) in let numX = car(car(a)) in let signX = cdr(car(a)) in let numY = car(cdr(a)) in let signY = cdr(cdr(a)) in (signX ^ signY) ? cons(numX + numY, signX) : zero?(numX - numY) ? cons(numY - numX, !signX) : cons(numX - numY, signX)' ; Exp.mul = 'let a = cons($1,$2) in cons(car(car(a)) * car(cdr(a)), cdr(car(a)) ^ cdr(cdr(a)))' ; Exp.iszero = 'zero?(car($1))' ; Exp.paren = Exp.paren($1) ; |) | idx(target) + (| signedExtension -> target [ Exp -> Exp ] Exp.ispos = 'let x = $1 in !(zero?(car(x)) | cdr(x))' ; Exp.isneg = 'let x = $1 in cdr(x) & !zero?(car(x))' ; |)