Jedi 5.0 extends Jedi 4.0 by adding type checking. This is a major extension.
-> 3 + 2
type = Exact
value = 5
-> def foo = lambda(x: Inexact, y: Inexact) x * x + y
type = Notification
value = ok
-> foo
type = (Inexact, Inexact)=>Inexact
value = closure
-> def point = object{ def xc = 3.1; def yc = 2.7 }
type = Notification
value = ok
-> point
type = {xc: Inexact; yc: Inexact}
value = object
-> var("Hello")
type = [Text]
value = [Hello]
->
Type checking is done in the console's execute method, before executing the expression:
def execute(cmmd: String): String
= {
val tree = parsers.parseAll(parsers.expression, cmmd)
tree match {
case tree: parsers.Failure
=> throw new SyntaxException(tree)
case _ => {
val
exp = tree.get // get the expression
from the tree
val tp = exp.getType(globalEnv)
println("type = " +
tp)
if (tp == PrimitiveType.FAIL) throw new
TypeException
val result = exp.execute(globalEnv) // execute the expression
result.toString // return string representation of result
}
}
}
We will add a new package to Jedi called type (my version of Scala didn't let me create a package with this name, so I called mine tp).
Here's a class diagram of the new package:
· Every value now has an associated type.
· The default type of a value is PrimitiveType.Value
· Types are values.
· The default type of a type is PrimitiveType.Type.
· Types can be compared using == and <.
· The type of an environment/object (i.e., env.type) is an EnvType, which associates identifiers with the types of their associated values in env.
· Given an EnvType, it's possible to compute the type of an expression.
· If an expression e contains a type error, then e.getType(tenv) = PrimitiveType.Fail.
· The goal of type checking is to ensure type consistency:
exp.execute(env).type == exp.getType(env.type)