Make Continuation an ADT with `continue` op. Clearer? Shrug.
catseye
9 years ago
206 | 206 | | Obj Object |
207 | 207 | | Objs [Object] |
208 | 208 | |
209 | type Continuation = ContObj -> ContObj | |
210 | ||
211 | data ContJ = ContJ Continuation | |
212 | instance Show ContJ where | |
213 | show (ContJ _) = "" | |
214 | instance Eq ContJ where | |
215 | ContJ _ == ContJ _ = False | |
216 | ||
209 | -- | |
210 | -- A continuation represents the remaining (sub-)computation(s) in a | |
211 | -- computation. | |
212 | -- | |
213 | data Continuation = Continuation (ContObj -> ContObj) | |
214 | ||
215 | instance Show Continuation where | |
216 | show (Continuation _) = "" | |
217 | instance Eq Continuation where | |
218 | Continuation _ == Continuation _ = False | |
219 | ||
220 | continue (Continuation f) contObj = | |
221 | f contObj -- straightforward enuff | |
222 | ||
223 | -- | |
224 | -- An object is anything else. Including, maybe, a continuation. | |
225 | -- | |
217 | 226 | data Object = IntVal Integer |
218 | 227 | | ObjVal String (Map Name Object) |
219 | | ContVal (Map Name Object) ContJ | |
228 | | ContVal (Map Name Object) Continuation | |
220 | 229 | | Null |
221 | 230 | deriving (Show, Eq) |
222 | 231 | |
243 | 252 | Nothing -> error "No Main class with main() method found" |
244 | 253 | Just mainMethod -> |
245 | 254 | let |
246 | final = ContJ id | |
255 | final = Continuation id | |
247 | 256 | r = callMethod p (ContVal EmptyMap final) mainMethod [] |
248 | 257 | in |
249 | 258 | case r of |
264 | 273 | case (length actuals) - (length formals) of |
265 | 274 | 0 -> |
266 | 275 | let |
267 | self = (ContVal EmptyMap (ContJ id)) -- NO NOT REALLY | |
276 | self = (ContVal EmptyMap (Continuation id)) -- NO NOT REALLY | |
268 | 277 | ctx = buildContext formals actuals |
269 | 278 | ctx' = set "self" self ctx |
270 | 279 | ctx'' = set "other" other ctx' |
271 | 280 | in |
272 | evalStatement p ctx'' stmt id | |
281 | evalStatement p ctx'' stmt (Continuation id) | |
273 | 282 | n | n > 0 -> |
274 | 283 | error "Too many parameters passed to method" |
275 | 284 | n | n < 0 -> |
285 | 294 | evalStatement p ctx (Block []) cc = |
286 | 295 | Ctx ctx |
287 | 296 | evalStatement p ctx (Block (stmt:rest)) cc = |
288 | evalStatement p ctx stmt (\(Ctx ctx') -> | |
297 | evalStatement p ctx stmt (Continuation $ \(Ctx ctx') -> | |
289 | 298 | evalStatement p ctx' (Block rest) cc) |
290 | 299 | |
291 | 300 | evalStatement p ctx (Conditional e s1 s2) cc = |
292 | evalExpr p ctx e (\(Obj value) -> | |
301 | evalExpr p ctx e (Continuation $ \(Obj value) -> | |
293 | 302 | case value of |
294 | 303 | Null -> evalStatement p ctx s2 cc |
295 | 304 | _ -> evalStatement p ctx s1 cc) |
296 | 305 | |
297 | 306 | evalStatement p ctx (Transfer dest e) _ = |
298 | evalExpr p ctx e (\(Obj value) -> | |
299 | evalExpr p ctx dest (\(Obj (ContVal m (ContJ k))) -> | |
307 | evalExpr p ctx e (Continuation $ \(Obj value) -> | |
308 | evalExpr p ctx dest (Continuation $ \(Obj (ContVal m (Continuation k))) -> | |
300 | 309 | k $ Obj value)) |
301 | 310 | |
302 | 311 | evalStatement p ctx (Assign name e) cc = |
303 | evalExpr p ctx e (\(Obj value) -> | |
312 | evalExpr p ctx e (Continuation $ \(Obj value) -> | |
304 | 313 | case get name ctx of |
305 | Nothing -> cc $ Ctx $ set name value ctx | |
314 | Nothing -> continue cc $ Ctx $ set name value ctx | |
306 | 315 | Just _ -> error ("Attempted re-assignment of bound name " ++ name)) |
307 | 316 | |
308 | 317 | --------------------------------------------------- |
311 | 320 | evalExpr p ctx (Get [name]) cc = |
312 | 321 | case get name ctx of |
313 | 322 | Nothing -> error ("Name " ++ name ++ " not in scope") |
314 | Just val -> cc $ Obj val | |
323 | Just val -> continue cc $ Obj val | |
315 | 324 | evalExpr p ctx (Get (name:names)) cc = |
316 | evalExpr p ctx (Get names) (\(Obj value) -> | |
317 | cc $ Obj $ getAttribute name value) | |
325 | evalExpr p ctx (Get names) (Continuation $ \(Obj value) -> | |
326 | continue cc $ Obj $ getAttribute name value) | |
318 | 327 | |
319 | 328 | evalExpr p ctx (Call [localName, methodName] exprs) cc = |
320 | evalExprs p ctx exprs [] (\(Objs actuals) -> | |
321 | evalExpr p ctx (Get [localName]) (\(Obj (ObjVal className attrs)) -> | |
329 | evalExprs p ctx exprs [] (Continuation $ \(Objs actuals) -> | |
330 | evalExpr p ctx (Get [localName]) (Continuation $ \(Obj (ObjVal className attrs)) -> | |
322 | 331 | let |
323 | 332 | Just klass = getClass className p |
324 | 333 | Just method = getMethod methodName klass |
325 | newOther = ContVal ctx $ ContJ cc | |
334 | newOther = ContVal ctx $ cc | |
326 | 335 | in |
327 | 336 | callMethod p newOther method actuals)) |
328 | 337 | |
329 | 338 | evalExpr p ctx (Mod names pairs) cc = |
330 | cc $ Obj Null | |
339 | continue cc $ Obj Null | |
331 | 340 | |
332 | 341 | evalExpr p ctx (IntLit i) cc = |
333 | cc $ Obj $ IntVal (evalIntLit i) | |
342 | continue cc $ Obj $ IntVal (evalIntLit i) | |
334 | 343 | |
335 | 344 | evalExpr p ctx (New className) cc = |
336 | cc $ Obj $ ObjVal className EmptyMap | |
345 | continue cc $ Obj $ ObjVal className EmptyMap | |
337 | 346 | |
338 | 347 | --------------------------------------------------- |
339 | 348 | |
340 | 349 | evalExprs p ctx [] vals cc = |
341 | cc $ Objs vals | |
350 | continue cc $ Objs vals | |
342 | 351 | |
343 | 352 | evalExprs p ctx (expr:exprs) vals cc = |
344 | evalExpr p ctx expr (\(Obj val) -> | |
353 | evalExpr p ctx expr (Continuation $ \(Obj val) -> | |
345 | 354 | evalExprs p ctx exprs (val:vals) cc) |
346 | 355 | |
347 | 356 | --------------------------------------------------- |