File: exprcomp.jas

package info (click to toggle)
jasmin-sable 2.4.0-4
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,232 kB
  • ctags: 1,458
  • sloc: java: 9,167; xml: 109; makefile: 19; csh: 16; sh: 1
file content (116 lines) | stat: -rw-r--r-- 3,182 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
;;; Simple arithmetic expression compiler for jas in jas.
;;;
;;; The compiler is defined in the function
;;; compile-expression
;;;
;;; use as (for instance)
;;; (compile-expression (quote (+ (* 2 (+ 1 3)) 1)))
;;;
;;; This will generate a standalone program called results.class
;;; Run the bytecode interpreter on it as:
;;;
;;; % java results
;;;
;;; which will print the result of the expression

(define compile-expression
  (lambda (expr)
    (real-compile-expression expr)
    (dump-code)))

;; The fun part...

(define real-compile-expression
  (lambda (expr)
    (cond

     ((num? expr)
      (compile-number expr))

     (1 (progn
         (real-compile-expression (get-op1 expr))
         (real-compile-expression (get-op2 expr))
         (compile-op (get-op expr))
         (set! cur-stack-height (- cur-stack-height 1)))))))

;; Ah well. Back to boring bookkeeping.


(define compile-number
  (lambda (num)
    (append-insn (bipush num))
    (set! cur-stack-height (+ 1 cur-stack-height))
    (cond
     ((< max-stack-height cur-stack-height)
      (set! max-stack-height cur-stack-height)))))

(define compile-op
  (lambda (op)
    (cond
     ((eq? op (quote +)) (append-insn (iadd)))
     ((eq? op (quote -)) (append-insn (isub)))
     ((eq? op (quote *)) (append-insn (imul)))
     ((eq? op (quote /)) (append-insn (idiv))))))

(define get-op1
  (lambda (expr) (car (cdr expr))))
(define get-op2
  (lambda (expr) (car (cdr (cdr expr)))))
(define get-op
  (lambda (expr) (car expr)))

(define append-insn
  (lambda (insn)
    (jas-code-addinsn my-code insn)))

(define cur-stack-height 1)
(define max-stack-height 1)

(define my-code (make-code))
(define my-init-code (make-code))

                                        ; define the main() portion,
                                        ; and the call to print out the
                                        ; results.
(define append-sequence
  (lambda (code-part insn-list)
    (mapcar (lambda (insn) (jas-code-addinsn code-part insn))
            insn-list)))

(append-sequence
 my-init-code
 (quote
  ((aload_0)
   (invokenonvirtual (make-method-cpe "java/lang/Object" "<init>" "()V"))
   (return))))

(define dump-code
  (lambda ()
    (define my-env (make-class-env))
    (jas-class-setclass my-env (make-class-cpe "results"))
    (jas-class-setsuperclass my-env (make-class-cpe "java/lang/Object"))
    (jas-class-addmethod my-env acc-public "<init>" "()V" my-init-code ())
    (append-sequence
     my-code
     (quote
      ((getstatic
        (make-field-cpe "java/lang/System" "out" "Ljava/io/PrintStream;"))
       (swap)
       (invokevirtual (make-method-cpe
                       "java/io/PrintStream" "println" "(I)V"))
       (return))))
    (jas-code-stack-size my-code max-stack-height)
    (jas-class-addmethod my-env
                         (| acc-public acc-static)
                         "main" "([Ljava/lang/String;)V" my-code ())
    (jas-class-write my-env
                     (make-outputstream "results.class"))))

;;;
;;; example usage of compiler.
;;;
;;; run the compiled class with
;;; % java results
;;; to get the answer.

(compile-expression (quote (+ (* 2 (+ 1 3)) 1)))