Types and type environments for a quirk20 compiler. [Revision 0] Qtype types Tenv type environments * * * Qtype: Signature: Qtype.iVoidType: int Qtype.iNullType: int Qtype.iBoolType: int Qtype.iCharType: int Qtype.iStringType: int Qtype.iIntType: int Qtype.iDoubleType: int Qtype.iTypeId: int Qtype.iArrayType: int Qtype.iFunType: int Qtype.VOID: Qtype Qtype.NULL: Qtype Qtype.BOOLEAN: Qtype Qtype.CHAR: Qtype Qtype.STRING: Qtype Qtype.INT: Qtype Qtype.DOUBLE: Qtype Qtype.toType: Ast -> Qtype Qtype.kind: Qtype -> int Qtype.equals: Qtype x Qtype -> boolean Qtype.isSubtype: Qtype x Qtype -> boolean Qtype.typeId_name: Qtype -> Qsymbol Qtype.arrayType_elementType: Qtype -> Qtype Qtype.funType_returnType: Qtype -> Qtype Qtype.funType_arity: Qtype -> int Qtype.funType_argumentType: Qtype x int -> Qtype Qtype.write: Qtype -> Specification: iVoidType through iFunType are distinct non-negative integer constants. VOID through DOUBLE represent the primitive types of quirk20. toType translates an Ast to the corresponding Qtype. kind(T) returns one of the integer constants iVoidType through iFunType. equals(T1, T2) returns true iff T1 is equal to T2. subtype(T1, T2) returns true iff T1 is a subtype of T2. If kind(T) is iTypeId, then typeId_name(T) returns the name of the type identifier T. If kind(T) is iArrayType, then arrayType_elementType(T) returns the type that T specifies for each array element. If kind(T) is iFunType, then funType_returnType(T) returns the result type, funType_arity(T) returns the number of arguments, and funType_argumentType(T,i) returns the type of argument i (where the first argument is argument 1). write(T) writes a readable representation of T to standard output. * * * Tenv: Signature: Tenv.error: -> Tenv Tenv.empty: -> Tenv Tenv.extend: Tenv x Qsymbol x Qtype x boolean x boolean -> Tenv Tenv.extendWithClass: Tenv x Qsymbol x Tenv x Tenv -> Tenv Tenv.extendWithTenv: Tenv x Tenv -> Tenv Tenv.lookupType: Tenv x Qsymbol -> Qtype Tenv.lookupFinal: Tenv x Qsymbol -> boolean Tenv.lookupGlobal: Tenv x Qsymbol -> boolean Tenv.lookupStatic: Tenv x Qsymbol -> Tenv Tenv.lookupDynamic: Tenv x Qsymbol -> Tenv Tenv.length: Tenv -> int Tenv.identifier: Tenv x int -> Qsymbol Tenv.isError: Tenv -> boolean Tenv.initial: -> Tenv Algebraic specification: extendWithTenv (tenv0, empty()) = tenv0 extendWithTenv (tenv0, extend (tenv1, I1, T, f, g)) = extend (extendWithTenv (tenv0, tenv1), I1, T, f, g) lookupType (empty(), I1) = VOID lookupType (extend (tenv, I1, T, f, g), I1) = T lookupType (extend (tenv, I2, T, f, g), I1) = lookupType (tenv, I1) if I1 != I2 lookupType (extendWithClass(tenv, R, tenv1, tenv2), I1) = VOID lookupFinal (empty(), I1) = true lookupFinal (extend (tenv, I1, T, f, g), I1) = f lookupFinal (extend (tenv, I2, T, f, g), I1) = lookupFinal (tenv, I1) if I1 != I2 lookupFinal (extendWithClass (tenv, R, tenv1, tenv2), I1) = true lookupGlobal (empty(), I1) = true lookupGlobal (extend (tenv, I1, T, f, g), I1) = g lookupGlobal (extend (tenv, I2, T, f, g), I1) = lookupGlobal (tenv, I1) if I1 != I2 lookupGlobal (extendWithClass (tenv, R, tenv1, tenv2), I1) = true lookupStatic (empty(), I1) = error() lookupStatic (extend (tenv, I1, T, f, g), I1) = error() lookupStatic (extend (tenv, I2, T, f, g), I1) = lookupStatic (tenv, I1) if I1 != I2 lookupStatic (extendWithClass (tenv, R1, tenv1, tenv2), R1) = tenv1 lookupStatic (extendWithClass (tenv, R2, tenv1, tenv2), R1) = lookupStatic (tenv, I1) if R1 != R2 lookupDynamic (empty(), I1) = error() lookupDynamic (extend (tenv, I1, T, f, g), I1) = error() lookupDynamic (extend (tenv, I2, T, f, g), I1) = lookupDynamic (tenv, I1) if I1 != I2 lookupDynamic (extendWithClass (tenv, R1, tenv1, tenv2), R1) = tenv2 lookupDynamic (extendWithClass (tenv, R2, tenv1, tenv2), R1) = lookupDynamic (tenv, I1) if R1 != R2 length (empty()) = 0 length (extend (tenv, I1, T, f, g)) = 1 + length (tenv) length (extendWithClass (tenv, R, tenv1, tenv2)) = 0 identifier (extend (tenv, I1, T, f, g), 0) = I1 identifier (extend (tenv, I1, T, f, g), n) = identifier (tenv, n - 1) if n > 0 isError (error()) = true isError (empty()) = false isError (extend(_, _, _, _, _)) = false isError (extendWithClass(_, _, _, _)) = false Informal specification: The basic constructors are error, empty, extend, and extendWithClass. A Tenv returned by error() can be distinguish from those returned by the other basic constructors by using the isError predicate. The empty() Tenv binds no identifiers. extend(tenv,I,T,f, g) returns an extension of tenv in which the identifier I is bound to the type T, is final iff f, and is global iff g. extendWithClass(tenv,R,tenv1,tenv2) returns an extension of tenv in which the class name R is bound to two type environments, one for its static constants and methods (tenv1) and one for its dynamic fields (tenv2). lookupType(tenv,I) returns the type of I in tenv. lookupFinal(tenv,I) tells whether I is final in tenv. lookupGlobal(tenv,I) tells whether I is global in tenv. lookupStatic(tenv,R) returns the static environment associated with the class name R in tenv. lookupDynamic(tenv,R) returns the dynamic environment associated with the class name R in tenv. length(tenv) returns the number of ordinary identifiers that are bound within tenv. The identifier(_,_) operation provides a way to iterate over the ordinary identifiers that are bound within a type environment. An ordinary identifier I is bound within tenv iff there exists some int i such that 0 <= i < length(tenv) and identifier(tenv,i) returns I. Note that there may exist more than one integer i that returns the same identifier I. The initial() operation returns a type environment that contains bindings for the standard library of quirk20. This standard library is expected to evolve rapidly during the development of a quirk20 compiler.