From bcaa281e6c6569452a798034c37da7e0d6a047a7 Mon Sep 17 00:00:00 2001 From: Enrico Lumetti Date: Sat, 1 May 2021 00:06:37 +0200 Subject: [PATCH] Implement and test explicate-control --- explicate-control.scm | 32 +++++++++++++++++++++ test-explicate-control.scm | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 explicate-control.scm create mode 100644 test-explicate-control.scm diff --git a/explicate-control.scm b/explicate-control.scm new file mode 100644 index 0000000..8efbc43 --- /dev/null +++ b/explicate-control.scm @@ -0,0 +1,32 @@ +#lang racket + +(require racket/fixnum) + +(provide explicate-control) + +(define (explicate-control sexp) + (match sexp + [`(program ,info ,exp) + `(program ,info ,(explicate-control-tail exp))])) + +; after a remove-complex-opera*, all expressions +; are compatible with C0 +(define (explicate-control-tail exp) + (match exp + [(? fixnum?) `(return ,exp)] + [(? symbol?) `(return ,exp)] + [`(read) `(return ,exp)] + [`(- ,e) `(return ,exp)] + [`(+ ,e1 ,e2) `(return ,exp)] + [`(let ([,var ,rexp]) ,body) + (explicate-control-assign var rexp (explicate-control-tail body))])) + +; stmt := (assign var exp) +; tail := (return exp) / (seq stmt tail) +(define (explicate-control-assign var exp c0-body) `() + (match exp + [`(let ([,v ,x]) ,b) (explicate-control-assign v x (explicate-control-assign var b c0-body))] + [_ `(seq (assign ,var ,exp) ,c0-body)])) + + + diff --git a/test-explicate-control.scm b/test-explicate-control.scm new file mode 100644 index 0000000..1fc4636 --- /dev/null +++ b/test-explicate-control.scm @@ -0,0 +1,59 @@ +#lang racket + +(require "test-util.scm") +(require "remove-complex-oper.scm") +(require "explicate-control.scm") +(require "c2.scm") + +(define programs + (list + `(program () (+ 2 3)) + `(program () (+ (- 2) 3)) + `(program () + (let ([y (let ([x 20]) + (+ x (let ([x 22]) x)))]) y)) + `(program () + (let ([a 42]) + (let ([b a]) + b))) + + `(program () (+ (let ([x (+ (- 1) 2)]) (+ x 2)) (+ 4 5))))) + + + +(define (pass program) (explicate-control (remove-complex-opera* program))) + +(test-eq + (pass (list-ref programs 0)) + `(program () + (return (+ 2 3)))) + +(test-eq + (pass (list-ref programs 1)) + `(program () + (seq (assign tmp.1 (- 2)) + (return (+ tmp.1 3))))) + +(test-eq + (pass (list-ref programs 2)) + `(program () + (seq (assign x.1 20) + (seq (assign x.2 22) + (seq (assign y.1 (+ x.1 x.2)) + (return y.1)))))) + +(test-eq + (pass (list-ref programs 3)) + `(program () + (seq (assign a.1 42) + (seq (assign b.1 a.1) + (return b.1))))) + +(test-eq + (pass (list-ref programs 4)) + `(program () + (seq (assign tmp.1 (- 1)) + (seq (assign x.1 (+ tmp.1 2)) + (seq (assign tmp.2 (+ x.1 2)) + (seq (assign tmp.3 (+ 4 5)) + (return (+ tmp.2 tmp.3))))))))