chiark / gitweb /
src/{module-impl,utilities}.lisp: Make `#line' work when pretty-printing.
[sod] / src / codegen-test.lisp
CommitLineData
dea4d055
MW
1;;; -*-lisp-*-
2;;;
3;;; Tests for code generator
4;;;
5;;; (c) 2009 Straylight/Edgeware
6;;;
7
8;;;----- Licensing notice ---------------------------------------------------
9;;;
e0808c47 10;;; This file is part of the Sensible Object Design, an object system for C.
dea4d055
MW
11;;;
12;;; SOD is free software; you can redistribute it and/or modify
13;;; it under the terms of the GNU General Public License as published by
14;;; the Free Software Foundation; either version 2 of the License, or
15;;; (at your option) any later version.
16;;;
17;;; SOD is distributed in the hope that it will be useful,
18;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;;; GNU General Public License for more details.
21;;;
22;;; You should have received a copy of the GNU General Public License
23;;; along with SOD; if not, write to the Free Software Foundation,
24;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26(cl:in-package #:sod-test)
27
28;;;--------------------------------------------------------------------------
29
30(defclass gcd-codegen-test (test-case)
31 (codegen))
32(add-test *sod-test-suite* (get-suite gcd-codegen-test))
33
34(defun make-gcd (codegen)
35
36 (codegen-push codegen)
37 (loop for (name init) in '(("aa" 1) ("bb" 0))
38 do (ensure-var codegen name (c-type int) init))
39 (codegen-push codegen)
40 (with-temporary-var (codegen r (c-type int))
41 (emit-inst codegen(make-set-inst r "u%v"))
42 (with-temporary-var (codegen q (c-type int))
43 (emit-inst codegen (make-set-inst q "u/v"))
44 (with-temporary-var (codegen a (c-type int))
45 (emit-insts codegen
46 (list (make-set-inst a "aa")
47 (make-set-inst "aa" "bb")
48 (make-set-inst "bb"
49 (format nil "~A - ~A*bb" a q))))))
50 (emit-insts codegen (list (make-set-inst "u" "v")
51 (make-set-inst "v" r))))
52 (emit-inst codegen (make-while-inst "v" (codegen-pop-block codegen)))
53 (emit-inst codegen (make-if-inst "a" (make-set-inst "*a" "aa") nil))
54 (deliver-expr codegen :return "u")
55 (codegen-pop-function codegen "gcd"
56 (c-type (fun int
57 ("u" int)
58 ("v" int)
59 ("a" (* int)))))
60
61 (codegen-push codegen)
62 (loop for (name init) in '(("u" "atoi(argv[1])")
63 ("v" "atoi(argv[2])")
64 ("a"))
65 do (ensure-var codegen name (c-type int) init))
66 (ensure-var codegen "g" (c-type int)
67 (make-call-inst "gcd" (list "u" "v" "&a")))
68 (emit-inst codegen (make-expr-inst
69 (make-call-inst "printf"
70 (list "\"%d*%d == %d (mod %d)\\n\""
71 "a" "u" "g" "v"))))
72 (deliver-expr codegen :return 0)
73 (codegen-pop-function codegen "main"
74 (c-type (fun int
75 ("argc" int)
76 ("argv" ([] string))))))
77
78(defmethod set-up ((test gcd-codegen-test))
79 (with-slots (codegen) test
80 (setf codegen (make-instance 'codegen))
81 (make-gcd codegen)))
82
83(def-test-method check-output ((test gcd-codegen-test) :run nil)
84 (assert-princ (codegen-functions (slot-value test 'codegen))
85 "(static int gcd(int u, int v, int *a)
86 {
87 int aa = 1;
88 int bb = 0;
89
90 while (v) {
91 int sod__v0;
92 int sod__v1;
93 int sod__v2;
94
95 sod__v0 = u%v;
96 sod__v1 = u/v;
97 sod__v2 = aa;
98 aa = bb;
99 bb = sod__v2 - sod__v1*bb;
100 u = v;
101 v = sod__v0;
102 }
103 if (a) *a = aa;
104 return (u);
105 }
106
107
108 static int main(int argc, char *argv[])
109 {
110 int u = atoi(argv[1]);
111 int v = atoi(argv[2]);
112 int a;
113 int g = gcd(u, v, &a);
114
115 printf(\"%d*%d == %d (mod %d)\\n\", a, u, g, v);
116 return (0);
117 }
118
119 )"))
120
121;;;----- That's all, folks --------------------------------------------------