| 1 | (******************************************************************************* |
|---|
| 2 | Copyright 2008 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 | component DynamicSemantics |
|---|
| 19 | import Map.{...} |
|---|
| 20 | import Syntax.{...} |
|---|
| 21 | export DynamicSemantics |
|---|
| 22 | |
|---|
| 23 | (* Runtime value ***************************************************************) |
|---|
| 24 | trait RuntimeValue comprises { Val, FnValue } |
|---|
| 25 | getter asString(): String |
|---|
| 26 | getValue(): Value |
|---|
| 27 | toSource(): String |
|---|
| 28 | end |
|---|
| 29 | |
|---|
| 30 | object Val(v: Value) extends RuntimeValue |
|---|
| 31 | getter asString() = v.asString |
|---|
| 32 | getValue() = v |
|---|
| 33 | toSource() = v.toSource() |
|---|
| 34 | end |
|---|
| 35 | |
|---|
| 36 | object FnValue(fun: FnExpr, sigma: Map[\String, RuntimeValue\]) |
|---|
| 37 | extends RuntimeValue |
|---|
| 38 | getter asString() = "(" fun.asString ", " sigma ")" |
|---|
| 39 | getValue() = fun |
|---|
| 40 | toSource() = fun.toSource() |
|---|
| 41 | end |
|---|
| 42 | |
|---|
| 43 | (* Runtime value factories *****************************************************) |
|---|
| 44 | val(expr: Value) = Val(expr) |
|---|
| 45 | val(expr: FnExpr, sigma: Map[\String, RuntimeValue\]) = FnValue(expr, sigma) |
|---|
| 46 | |
|---|
| 47 | (* Function table **************************************************************) |
|---|
| 48 | (* function name |-> function expression *) |
|---|
| 49 | fdecls: Map[\String, FnExpr\] := {[\String, FnExpr\]} |
|---|
| 50 | |
|---|
| 51 | (* Initialize the helper table *) |
|---|
| 52 | initDynamic() = atomic fdecls := {[\String, FnExpr\]} |
|---|
| 53 | |
|---|
| 54 | (* Dynamic environment *********************************************************) |
|---|
| 55 | (* variable name |-> runtime value *) |
|---|
| 56 | emptyEnv: Map[\String, RuntimeValue\] = {[\String, RuntimeValue\]} |
|---|
| 57 | |
|---|
| 58 | (* Evaluate a given expression in a given environment *) |
|---|
| 59 | (* True is a value which does not require further evaluation. *) |
|---|
| 60 | opr VDASH(sigma: Map[\String, RuntimeValue\], expr: True) = val(expr) |
|---|
| 61 | |
|---|
| 62 | (* False is a value which does not require further evaluation. *) |
|---|
| 63 | opr VDASH(sigma: Map[\String, RuntimeValue\], expr: False) = val(expr) |
|---|
| 64 | |
|---|
| 65 | (* A pair of FnExpr and its defined environment is a value |
|---|
| 66 | which do not require further evaluation. |
|---|
| 67 | *) |
|---|
| 68 | opr VDASH(sigma: Map[\String, RuntimeValue\], expr: FnExpr) = val(expr, sigma) |
|---|
| 69 | |
|---|
| 70 | (* If a given variable is a function name |
|---|
| 71 | then returns the corresponding function expression of the function |
|---|
| 72 | else get the value of a given variable from the environment. |
|---|
| 73 | Throws an unbound variable exception |
|---|
| 74 | if the variable is not found in the environment. |
|---|
| 75 | *) |
|---|
| 76 | opr VDASH(sigma: Map[\String, RuntimeValue\], expr: Var) = do |
|---|
| 77 | name = expr.name |
|---|
| 78 | if f <- fdecls.member(name) |
|---|
| 79 | then val(f, emptyEnv) |
|---|
| 80 | else if v <- sigma.member(name) |
|---|
| 81 | then v |
|---|
| 82 | else throw FailCalled("Unbound variable: " expr.name) |
|---|
| 83 | end |
|---|
| 84 | end |
|---|
| 85 | end |
|---|
| 86 | |
|---|
| 87 | (* Evaluate the function expression and the argument expression. |
|---|
| 88 | Bound the parameter of the function value to the argument value. |
|---|
| 89 | Evaluate the body expression of the function value. |
|---|
| 90 | *) |
|---|
| 91 | opr VDASH(sigma: Map[\String, RuntimeValue\], expr: App) = do |
|---|
| 92 | typecase f = sigma VDASH expr.function of |
|---|
| 93 | FnValue => function = f.fun |
|---|
| 94 | sigma' = f.sigma.add(function.param, sigma VDASH expr.argument) |
|---|
| 95 | sigma' VDASH function.body |
|---|
| 96 | else => throw FailCalled("Type error: " f) |
|---|
| 97 | end |
|---|
| 98 | end |
|---|
| 99 | |
|---|
| 100 | (* If the condition expression evaluates to True |
|---|
| 101 | then evaluate the "then" branch |
|---|
| 102 | else evaluate the "else" branch. |
|---|
| 103 | Throws a type error |
|---|
| 104 | if the condition expression does not evaluate to True or False. |
|---|
| 105 | *) |
|---|
| 106 | opr VDASH(sigma: Map[\String, RuntimeValue\], expr: If) = |
|---|
| 107 | typecase c = (sigma VDASH expr.cond).getValue() of |
|---|
| 108 | True => sigma VDASH expr.thenB |
|---|
| 109 | False => sigma VDASH expr.elseB |
|---|
| 110 | else => throw FailCalled("Type error: " c) |
|---|
| 111 | end |
|---|
| 112 | |
|---|
| 113 | (* Evaluate a given program. *) |
|---|
| 114 | opr VDASH(p: Program) = do |
|---|
| 115 | atomic fdecls := fdecls.add(fd.name, FnExpr(fd.param, fd.body)), fd <- p.decls |
|---|
| 116 | emptyEnv VDASH p.expr |
|---|
| 117 | end |
|---|
| 118 | |
|---|
| 119 | end |
|---|