copied some compiler stuff from old code&cleaned up a bit, not tested much
[swf2.git] / compile / compiler.lisp
blob600b02a34dba93f0915cb6ad6c123dd923526654
1 (in-package :as3-compiler)
3 ;;;
4 (defclass compiler-context ()
5 ((class-names :initform () :accessor class-names)
6 (function-names :initform () :accessor function-names)))
8 (defparameter *compiler-context* (make-instance 'compiler-context))
10 ;;; track data about a lambda (or scope in general, defun/let/etc)
11 ;;; local variables, etc
12 (defclass lambda-context ()
13 ;; using an alist for local name-index mapping, so we can push/pop
14 ;; state a bit more easily than with hash tables...
15 ((locals :initform () :accessor locals)))
17 (defparameter *current-lambda* nil)
19 (defun make-lambda-context (args)
20 (let ((lc (make-instance 'lambda-context)))
21 (push (cons 'this 0) (locals lc))
22 (loop for i in args
23 for j from 1
24 do (push (cons i j) (locals lc)))
25 (format t "lambda context lc = ~s ~%" (locals lc))
26 lc))
28 (defun get-lambda-local-index (name)
29 (cdr (assoc name (locals *current-lambda*) :test 'string=)))
31 (defmacro with-lambda-context ((&rest args) &body body)
32 `(let ((*current-lambda* (make-lambda-context '(,@args))))
33 ,@body))
35 ;;; top level (internal?) compiler interface
36 ;;; returns assembly corresponding to FORM
37 (defgeneric scompile (form))
39 (defmethod scompile ((form string))
40 `((:push-string ,form)))
42 (defmethod scompile ((form integer))
43 ;; possibly should have more control than just assuming anything < 2^31
44 ;; is int (as well as range checking, etc)
45 (if (> form (expt 2 31))
46 `((:push-uint ,form))
47 `((:push-int ,form))))
49 (defmethod scompile ((form real))
50 `((:push-double ,form)))
52 (defmethod scompile ((form symbol))
53 (let ((i (get-lambda-local-index form)))
54 (if i
55 `((:get-local ,i))
56 (error "unknown local ~s?" form))))
58 (defmacro define-constants (&body constants)
59 `(progn
60 ,@(loop for i in constants
61 collect `(defmethod scompile ((form (eql ,(car i))))
62 '((,(second i)))))))
63 (define-constants
64 (:true :push-true)
65 (:false :push-false)
66 (:nan :push-nan)
67 (:undefined :push-undefined)
68 (:null :push-null))
70 ;;; interface for implementing special forms
72 (defgeneric scompile-cons (car cdr))
74 (defmethod scompile ((form cons))
75 (scompile-cons (car form) (cdr form)))
77 (defmacro define-special (name (&rest args) &body body)
78 (let ((car (gensym "CAR"))
79 (cdr (gensym "CDR")))
80 `(defmethod scompile-cons ((,car (eql ',name)) ,cdr)
81 (destructuring-bind ,args ,cdr
82 ,@body))))
84 #||
85 (scompile "foo")
86 (scompile :true)
87 (scompile 123.45)
88 ||#