(module ast mzscheme
(require (lib "contract.ss")
(planet "contract-utils.ss" ("cobbe" "contract-utils.plt" 1 0))
(planet "inspector.ss" ("dherman" "inspector.plt" 1 0)))
(define BINARY-PRIMS '(+ - * == and or))
(define UNARY-PRIMS '(zero? null? not))
(define RESERVED-WORDS '(class Object new ref set send super this cast let
int bool null true false))
(define reserved?
(lambda (x)
(or (and (memq x RESERVED-WORDS) #t)
(binary-prim-name? x)
(unary-prim-name? x))))
(define binary-prim-name? (lambda (x) (and (memq x BINARY-PRIMS) #t)))
(define unary-prim-name? (lambda (x) (and (memq x UNARY-PRIMS) #t)))
(define id? (lambda (x) (and (symbol? x) (not (reserved? x)))))
(define type-name?
(lambda (x)
(or (eq? x 'int)
(eq? x 'bool)
(class-name? x))))
(define field-name? id?)
(define method-name? id?)
(define defn-name? id?)
(define class-name?
(lambda (x)
(or (eq? x 'Object) (defn-name? x))))
(define arg-name? id?)
(with-public-inspector
(define-struct program (classes main))
(define-struct class (name superclass fields methods))
(define-struct field (type class name))
(define-struct method (type name arg-names arg-types body))
(define-struct expr ())
(define-struct (new expr) (type))
(define-struct (var-ref expr) (var))
(define-struct (nil expr) ())
(define-struct (ref expr) (object field))
(define-struct (tagged-ref expr) (object class field))
(define-struct (set expr) (object field rhs))
(define-struct (tagged-set expr) (object class field rhs))
(define-struct (send expr) (object method args))
(define-struct (super expr) (method args))
(define-struct (tagged-super expr) (type method args))
(define-struct (cast expr) (type object))
(define-struct (cj-let expr) (lhs rhs body))
(define-struct (num-lit expr) (val))
(define-struct (bool-lit expr) (val))
(define-struct (unary-prim expr) (rator rand))
(define-struct (binary-prim expr) (rator rand1 rand2))
(define-struct (if-expr expr) (test then else))
(define-struct type ())
(define-struct (ground-type type) (name))
(define-struct (class-type type) (name))
(define-struct (any-type type) ())
)
(define type=? equal?)
(define src-expr?
(lambda (x)
(and (expr? x)
(not (tagged-ref? x))
(not (tagged-set? x))
(not (tagged-super? x)))))
(define tagged-expr?
(lambda (x)
(and (expr? x)
(not (ref? x))
(not (set? x))
(not (super? x)))))
(define (type->sexpr type)
(cond
[(ground-type? type) (ground-type-name type)]
[(class-type? type) (class-type-name type)]
[(any-type? type) '_!_]))
(provide/contract
[struct program ([classes hash-table?]
[main expr?])]
[struct class ([name class-type?]
[superclass (union false/c class?)]
[fields (listof field?)]
[methods (listof method?)])]
[struct field ([type type?]
[class class-type?]
[name field-name?])]
[struct method ([type type?]
[name method-name?]
[arg-names (listof arg-name?)]
[arg-types (listof type?)]
[body expr?])]
[type? predicate/c]
[struct ground-type ([name (symbols 'int 'bool)])]
[struct class-type ([name class-name?])]
[struct any-type ()]
[expr? predicate/c]
[struct new ([type class-type?])]
[struct var-ref ([var (union id? (symbols 'this))])]
[struct nil ()]
[struct ref ([object expr?]
[field field-name?])]
[struct tagged-ref ([object expr?]
[class class-type?]
[field field-name?])]
[struct set ([object expr?]
[field field-name?]
[rhs expr?])]
[struct tagged-set ([object expr?]
[class class-type?]
[field field-name?]
[rhs expr?])]
[struct send ([object expr?]
[method method-name?]
[args (listof expr?)])]
[struct super ([method method-name?]
[args (listof expr?)])]
[struct tagged-super ([type class-type?]
[method method-name?]
[args (listof expr?)])]
[struct cast ([type class-type?]
[object expr?])]
[struct cj-let ([lhs id?]
[rhs expr?]
[body expr?])]
[struct num-lit ([val integer?])]
[struct bool-lit ([val boolean?])]
[struct unary-prim ([rator unary-prim-name?]
[rand expr?])]
[struct binary-prim ([rator binary-prim-name?]
[rand1 expr?]
[rand2 expr?])]
[struct if-expr ([test expr?]
[then expr?]
[else expr?])]
[type=? (-> type? type? boolean?)]
[src-expr? predicate/c]
[tagged-expr? predicate/c]
[type->sexpr (-> type? sexp/c)]
[class-name? predicate/c]
[defn-name? predicate/c]
[type-name? predicate/c]
[field-name? predicate/c]
[method-name? predicate/c]
[arg-name? predicate/c]
[binary-prim-name? predicate/c]
[unary-prim-name? predicate/c]
[id? predicate/c]))