root/trunk/ProjectFortress/demos/FeatherweightJava.fss

Revision 4130, 6.5 KB (checked in by sukyoungryu, 3 months ago)

[disambiguator] Fixed handling getters and setters in ExprDisambiguator?. Fixed libraries and tests using getters.

Line 
1(*******************************************************************************
2    Copyright 2009 Sun Microsystems, Inc.,
3    4150 Network Circle, Santa Clara, California 95054, U.S.A.
4    All rights reserved.
5
6    U.S. Government Rights - Commercial software.
7    Government users are subject to the Sun Microsystems, Inc. standard
8    license agreement and applicable provisions of the FAR and its supplements.
9
10    Use is subject to license terms.
11
12    This distribution may include materials developed by third parties.
13
14    Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered
15    trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
16 ******************************************************************************)
17
18(*
19   Implementation in the Fortress Programming Language of an Interpreter for the
20   dynamic semantics of Featherweight Java, as defined in:
21
22   Featherweight Java: A Minimal Core Calculus for Java and GJ,
23   Atsushi Igarashi and Benjamin C. Pierce,
24   ACM Transactions on Programming Languages and Systems, Vol. 23, No. 3,
25   May 2001, Pages 396-450.
26
27   Author: Eric Allen, January 2008.
28 *)
29
30component FeatherweightJava
31import List.{...}
32import Map.{...}
33export Executable
34
35(* Classes and Class tables *)
36
37object ClassTable(defs: Map[\String, Class\])
38  lookup(typ: Type) = defs[typ.name]
39
40
41  subtype(s: Type, t: Type) =
42    (s = t) OR: ((s.name =/= "Object") AND: (subtype(lookup(s).ext, t)))
43
44
45  field(v: New, n: String) requires {v.isVal()} = do
46    fields_v: List[\Decl\] = fields(v.tag)
47
48    label find
49      for i <- fields_v.indices do
50        if n = fields_v[i].name then
51          exit find with v.args[i]
52        end
53      end
54      fail("Field " n " not found in class " v.tag.name ".")
55    end find
56  end
57
58
59  fields(c: Type): List[\Decl\] = do
60    if c.name = "Object" then <|[\Decl\] |>
61    else
62      c_def: Class = defs[c.name]
63      c_def.fields.appendR[\Decl\](fields(c_def.ext))
64    end
65  end
66
67  mbody(typ: Type, m_name: String): Meth = do
68    if typ.name = "Object" then
69      fail("Method " m_name " not found.")
70    else
71      class: Class = defs[typ.name]
72
73      label find
74        for meth <- class.meths do
75          if m_name = meth.name then
76            exit find with meth
77          end
78        end
79        mbody(class.ext, m_name)
80      end find
81    end
82  end
83end
84
85
86object Class(name: String, ext: Type,
87             fields: List[\Decl\], cons: Cons, meths: List[\Meth\])
88end
89
90(* Exprs *)
91trait Expr
92  getter asString(): String
93  isVal(): Boolean = false
94  eval(CT_: ClassTable, theta: Map[\String, Expr\]): Expr
95    ensures { outcome.isVal() }
96end
97
98object Var(x: String) extends Expr
99  getter asString(): String = x
100  opr =(self, other: Var) = (x = other.x)
101  eval(CT_: ClassTable, theta: Map[\String, Expr\]): Expr = theta[x]
102end
103
104object New(tag: Type, args: List[\Expr\]) extends Expr
105  getter asString() = "new " tag.asString <|[\String\] a.asString | a <- args|>
106
107  isVal() = BIG AND[arg <- args] arg.isVal()
108
109  opr =(self, other: New) =
110    (tag = other.tag) AND (BIG AND[i <- args.indices] args[i] = other.args[i])
111
112  eval(CT_: ClassTable, theta: Map[\String, Expr\]): Expr =
113    New(tag, <|[\Expr\] arg.eval(CT_, theta) | arg <- args |>)
114end
115
116object Proj(receiver: Expr, field: String) extends Expr
117  getter asString() = (receiver.asString "." field)
118
119  opr =(self, other: Proj) =
120    (receiver = other.receiver) AND (field = other.field)
121
122  eval(CT_: ClassTable, theta: Map[\String, Expr\]): Expr =
123    CT_.field(cast[\New\](receiver.eval(CT_, theta)), field)
124end
125
126object Invk(receiver: Expr, m_name: String, args: List[\Expr\]) extends Expr
127  getter asString() = (receiver.asString "." m_name args)
128
129  opr =(self, other: Invk) =
130    (receiver = other.receiver) AND (m_name = other.m_name) AND (args = other.args)
131
132  eval(CT_: ClassTable, theta: Map[\String, Expr\]): Expr = do
133    rec_v = cast[\New\](receiver.eval(CT_, theta))
134    args_v = <|[\Expr\] arg.eval(CT_, theta) | arg <- sequential(args) |>
135    m = CT_.mbody(rec_v.tag, m_name)
136    theta' = {[\String, Expr\]"this" |-> rec_v asif Expr} UNION
137      {[\String, Expr\] x.name |-> e | (x,e) <- m.params.zip[\Expr\](args_v)}
138
139    m.body.eval(CT_, theta')
140  end
141end
142
143object Cast(typ: Type, term: Expr) extends Expr
144  getter asString() = ("(" typ.asString ")" term.asString)
145
146  opr =(self, other: Cast) = (typ = other.typ) AND (term = other.term)
147
148  eval(CT_: ClassTable, theta: Map[\String, Expr\]): Expr = do
149    cast_v = cast[\New\](term.eval(CT_, theta))
150    if (CT_ VDASH (cast_v.tag < typ)) then cast_v
151    else fail("Class cast exception: " cast_v.typ
152               " is not a subtype of " typ) end
153  end
154end
155
156(* Types *)
157object Type(name: String)
158  getter asString() = name
159  opr =(self, other:Type) = (name = other.name)
160end
161
162
163(* Syntactic Subcomponents *)
164object Decl(typ: Type, name: String)
165  getter asString() = typ " " name ";"
166end
167object Cons(tag: Type, params: List[\Decl\],
168            super: List[\Var\], this: List[\Init\])
169end
170object Init(left: String, right: String) end
171
172object Meth(return: Type, name: String, params: List[\Decl\],
173            body: Expr)
174end
175
176(* Operators *)
177opr VDASH(context: (ClassTable, Map[\String, Expr\]), terms: EvalThunk) = do
178  (terms.t1.eval(context) = terms.t2)
179end
180
181opr VDASH(context: ClassTable, types: SubtypeThunk) = do
182  context.subtype(types.typ1, types.typ2)
183end
184
185object EvalThunk(t1: Expr, t2: Expr) end
186object SubtypeThunk(typ1: Type, typ2: Type) end
187
188opr ->(t1: Expr, t2: Expr) = EvalThunk(t1, t2)
189
190opr <(typ1: Type, typ2: Type) = SubtypeThunk(typ1, typ2)
191
192(* Testing *)
193run() = do
194  obj = Type("Object")
195  newObj = New(obj, <|[\Expr\] |>)
196  x = Var("x")
197  y = Var("y")
198  this = Var("this")
199  c = Type("c")
200  n = New(c, <|newObj asif Expr|>)
201  d = Decl(obj,"_x")
202  dx = Decl(obj, "x")
203  dy = Decl(obj, "y")
204  i = Init("x","_x")
205  e = <|d|>
206  k = Cons(c, e, <|[\Var\] |>, <| i |>)
207  m = Meth(obj, "m", <|dy|>, y)
208  m' = Meth(obj, "n", <|d|>, Proj(this, "x"))
209  l = Class("c", obj, <|dx|>, k, <|m, m'|>)
210  t = {[\String,Class\]"c" |-> l}
211  p = Proj(x, "x")
212  v = Invk(x, "m", <|n asif Expr|>)
213  cst1 = Cast(c, x)
214  cst2 = Cast(obj, x)
215  v' = Invk(x, "n", <|n asif Expr|>)
216  CT_ = ClassTable(t)
217  theta0 = {[\String, Expr\]}
218  theta1 = {[\String,Expr\]"x" |-> n asif Expr, "y" |-> newObj}
219
220  assert((CT_, theta0) VDASH (n -> n))
221  assert((CT_, theta1) VDASH (x -> n))
222  assert((CT_, theta1) VDASH (y -> newObj))
223  assert((CT_, theta1) VDASH (p -> newObj))
224  assert((CT_, theta1) VDASH (v -> n))
225  assert((CT_, theta1) VDASH (v' -> newObj))
226  assert((CT_, theta1) VDASH (cst1 -> n))
227  assert((CT_, theta1) VDASH (cst2 -> n))
228end
229
230end
Note: See TracBrowser for help on using the browser.