racket/collects/profjWizard/union.ss
2008-02-24 21:27:36 +00:00

240 lines
6.6 KiB
Scheme

#cs
(module union mzscheme
(require "data-defs.scm"
"class.scm"
mzlib/contract
mzlib/etc
mzlib/list)
(provide/contract
[make-union ((Union) (boolean? boolean? string?) . opt-> . string?)]
)
#| Usage:
(make-union a-union toString? template?)
create a Java implementation of a datatype specification using an
interface and N variants.
The first optional boolean parameter specifies whether we want toString
in the class hiearchy. Default: true
The second optional boolean parameter specifies whether we want
a draft method template in comments. Default: true
|#
;; ------------------------------------------------------------------------
;; Construct a union as a collection of Java classes
;; String (Listof VariantClass) -> String
(define make-union
(opt-lambda (the-union [toString? #t][template? #t][language BEGINNER])
(define type (dt-type the-union))
(define met* (dt-methods the-union))
(string-append
(car (purpose-statement (dt-purpose the-union)))
(interface type template? met*)
"\n"
(enumerate-with-separator
(map (lambda (sc)
(make-class `(,(car sc) ,type ,(cadr sc) ,(variant-purpose sc))
toString?
template?
language
'()
met*))
(dt-variants the-union))
"\n"))))
;; String Boolean [Listof Method] -> String
(define (interface type template? methods)
(apply string-append
`(,(format abstractF type)
;; constant fields, e.g.,
;; int NORTH = 0;
;; shouldn't be allowed yet
,@(map (lambda (x) (format " ~a;\n" (method x))) methods)
;; optional abstract template
""
,endclf)))
;; String (listof Field) Boolean? -> String
(define (abstractClass type fields template?)
`(...
,@(if (not template?)
(list "")
`( ,cmnt/*
,warnin
,purpos
,absteg
,cmnt*/))
...))
;; Abstract Class
(define abstractF "interface ~a {\n")
(define absteg " abstract ??? mmm();\n")
#| Tests:
(require (lib "testing.scm" "testing"))
(test== (interface "Foo" #f '())
(string-append
"interface Foo {\n"
"}\n")
"simple interface")
(test== (interface "Foo" #f '(("double" "distance" "int" "int")))
(string-append
"interface Foo {\n"
" double distance(int x,int y);\n"
"}\n")
"simple interface with methods")
(make-union
(make-dt "AList" '() '(("MT" ()) ("Cons" (("int" "first") ("AList" "rest")))) "")
#f #f)
(test==
(make-union
(make-dt "AList" '() '(("MT" ()) ("Cons" (("int" "first") ("AList" "rest")))) "")
#f #f)
(apply string-append
`(
"interface AList {\n"
"}\n"
"\n"
"class MT implements AList {\n"
"\n"
" MT() {\n"
" }\n"
"}\n"
"\n"
"class Cons implements AList {\n"
" int first;\n"
" AList rest;\n"
"\n"
" Cons(int first, AList rest) {\n"
" this.first = first;\n"
" this.rest = rest;\n"
" }\n"
"}\n"
)
)
"partial make union")
(test==
(make-union
(make-dt "AList"
;; common methods:
'(("???" "mmm"))
;; variants:
'(("MT" ())
("Cons" (("int" "first") ("AList" "rest")))) "")
#t #t PROFESSIONAL)
(apply string-append
`(
"interface AList {\n"
" ??? mmm();\n"
"}\n"
"\n"
"class MT implements AList {\n"
"\n"
" MT() {\n"
" }\n"
"\n"
"/*\n"
,warnin
" public ??? mmm() {\n"
" }\n"
"*/\n"
"\n"
" public String toString() {\n"
" return \"new MT(\" + \")\";\n"
" }\n"
"}\n"
"\n"
"class Cons implements AList {\n"
" int first;\n"
" AList rest;\n"
"\n"
" Cons(int first, AList rest) {\n"
" this.first = first;\n"
" this.rest = rest;\n"
" }\n"
"\n"
"/*\n"
,warnin
" public ??? mmm() {\n"
" ... this.first ...\n"
" ... this.rest.mmm(...) ...\n"
" }\n"
"*/\n"
"\n"
" public String toString() {\n"
" return \"new Cons(\" + first + \",\" + rest.toString() + \")\";\n"
" }\n"
"}\n"
)
)
"full make union")
(test==
(make-union
(make-dt "AList" '() '(("MT" ()) ("Cons" (("int" "first") ("AList" "rest")))) "hello world")
#f #f)
(apply string-append
`("// hello world\n"
"interface AList {\n"
"}\n"
"\n"
"class MT implements AList {\n"
"\n"
" MT() {\n"
" }\n"
"}\n"
"\n"
"class Cons implements AList {\n"
" int first;\n"
" AList rest;\n"
"\n"
" Cons(int first, AList rest) {\n"
" this.first = first;\n"
" this.rest = rest;\n"
" }\n"
"}\n"
)
)
"make union with purpose statement")
(test==
(make-union
(make-dt
"AList" '() '(("MT" ()) ("Cons" (("int" "first") ("AList" "rest")) "pair")) "hello world")
#f #f)
(apply string-append
`("// hello world\n"
"interface AList {\n"
"}\n"
"\n"
"class MT implements AList {\n"
"\n"
" MT() {\n"
" }\n"
"}\n"
"\n"
"// pair\n"
"class Cons implements AList {\n"
" int first;\n"
" AList rest;\n"
"\n"
" Cons(int first, AList rest) {\n"
" this.first = first;\n"
" this.rest = rest;\n"
" }\n"
"}\n"
)
)
"make union with purpose statement for variants")
|#
)