The Full OAT Language Type System March 24, 2011 n Constant int b Constant bool cstr Constant string id Identifiers cid Class identifiers,, m Index typ ::= Types bot bottom bool bool int int ref reference ref? nullable ref ::= References string string cid class typ[] array unop ::= Unary operators - unary signed negation! unary logical negation unary bitwise negation binop ::= Binary operators + binary signed addition * binary signed multiplication - binary signed subtraction == binary equality!= binary inequality < binary signed less-than <= binary signed less-than or equals > binary signed greater-than >= binary signed greater-than or equals & binary bool bitwise and binary bool bitwise or [&] binary int bitwise and 1
[ ] binary int bitwise or << binary shift left >> binary logical shift right >>> binary arithmetic shift right const ::= Constants null null b bool n int cstr string path ::= Paths this.id identifiers in this class lhs or call.id path identifiers, e.g, a.b.f().c call ::= Calls id( exp ) global functions super.id( exp ) super methods path( exp ) path methods, e.g. a.f().b.g() lhs or call ::= Left-hand sides or calls lhs left-hand sides call calls lhs ::= Left-hand sides id variables path paths lhs or call[exp] array index exp ::= Expressions const constant this this new [exp 1 ]( fun id->exp 2 ) new new cid( exp ) constructor lhs or call left-hand sides or calls binop exp 1 exp 2 binarith unop exp unarith exp opt ::= Optional expressions None none Some exp some init ::= Initializer exp exp 1..m { init } array 2
vdecl ::= Variable declarations typ id =init; vdecls ::= A list of variable declarations ɛ nil vdecl vdecls cons stmt ::= Statements lhs=exp; assignments call; call fail (exp); fail if (exp)stmt stmt opt if if?(ref id=exp)stmt stmt opt if null cast (cid id=exp)stmt stmt opt cast while (exp)stmt while for (vdecls; exp opt ; stmt opt )stmt for {bloc} bloc stmt opt ::= Optional statements None none Some stmt some bloc ::= Blocs vdecls stmt args ::= A list of arguments ɛ typ id,args rtyp ::= Return types unit unit typ types efdecl ::= External function declarations rtyp id(args) extern fdecl ::= Function declarations typ id(args){bloc return exp; } unit id(args){bloc return ; } cinits ::= A list of field initialization ɛ nil this.id =init; cinits cons ctor ::= Constructors 3
new (args)( exp )cinits{bloc} cid ext ::= Optional extensions None base <:cid extension fields ::= A list of field declarations ɛ nil typ id; fields cons fdecls ::= A list of function declarations ɛ nil fdecl fdecls cons cdecl ::= Classes class cid cid ext {fields ctor fdecls}; gdecl ::= Global declarations vdecl constants fdecl function declarations efdecl external function declarations cdecl class declarations prog ::= Programs ɛ gdecl prog γ ::= Variable contexts empty γ, id : typ cons Γ ::= A stac of variable contexts empty Γ; γ cons ftyp ::= Function types ( typ )->rtyp ptyp ::= Path types typ ftyp ::= Function contexts empty, id : ftyp cons 4
Θ ::= Method contexts empty Θ, id : ftyp cons Φ ::= Field contexts empty Φ, id : typ cons Σ ::= Class signatures empty Σ,cid cid ext {Φ; typ ; Θ} cons cid opt ::= Optional class Some cid some in the scope of class cid None none, otherwise typ opt ::= Optional typ, the return of hasfield None none Some typ some ftyp opt ::= Optional ftyp, the return of hasmethod None none Some ftyp some Σ typ Σ shows that typ is well-formed. Σ bool TYP BOOL Σ int TYP INT Σ ref TYP REF Σ r ref Σ ref? TYP NULLABLE Σ r ref Σ shows that ref is well-formed. Σ r string REF STRING cid cid ext {Φ; typ ; Θ} Σ Σ r cid REF CLASS 5
Σ typ Σ r typ[] REF ARRAY Σ typ 1 <:typ 2 Σ shows that typ 1 is a subtype of typ 2. Σ bool<:bool ST BOOL Σ int<:int ST INT Σ r ref 1 <:ref 2 Σ ref 1 <:ref 2 ST REF Σ r ref 1 <:ref 2 Σ ref 1?<:ref 2? ST NULLABLE Σ r ref 1 <:ref 2 Σ ref 1 <:ref 2? ST REF NULLABLE Σ bot<:ref? ST NULL NULLABLE Σ r ref 1 <:ref 2 Σ shows that ref 1 is a sub-reference of ref 2. Σ r string<:string SR STRING Σ c cid 1 <:cid 2 Σ r cid 1 <:cid 2 SR CLASS Σ r typ[]<:typ[] SR ARRAY Σ c cid 1 <:cid 2 Σ shows that cid 1 is a sub-class of cid 2. cid cid ext {Φ; typ ; Θ} Σ Σ c cid<:cid SC REF Σ 1,cid 1 <:cid 2 {Φ; typ ; Θ},Σ2 c cid 1 <:cid 2 SC INHERITANCE Σ c cid 1 <:cid 2 Σ c cid 2 <:cid 3 Σ c cid 1 <:cid 3 SC TRANS 6
hasfield Σ cid.id=typ opt Chec if cid has a field id. cid cid ext {Φ; typ ; Θ} Σ id:typ Φ hasfield Σ cid.id=some typ HASFIELD BASE SOME cid None{Φ; typ ; Θ} Σ id Φ hasfield Σ cid.id=none HASFIELD BASE NONE cid 1 <:cid 2 {Φ; typ ; Θ} Σ id Φ hasfield Σ cid2.id=typ opt hasfield Σ cid 1.id=typ opt HASFIELD INHERITANCE hasmethod Σ cid.id=ftyp opt Chec if cid has a method id. cid cid ext {Φ; typ ; Θ} Σ id:ftyp Θ hasmethod Σ cid.id=some ftyp HASMETHOD BASE SOME cid None{Φ; typ ; Θ} Σ id Θ hasmethod Σ cid.id =None HASMETHOD BASE NONE cid 1 <:cid 2 {Φ; typ ; Θ} Σ id Θ hasmethod Σ cid2.id=ftyp opt hasmethod Σ cid 1.id=ftyp opt HASMETHOD INHERITANCE const:typ const has type typ. null:bot CONST BOT b:bool CONST BOOL n:int CONST INT cstr:string CONST STRING binop:ftyp binop is of type ftyp. +:(int int)->int BINTYP PLUS 7
*:(int int)->int BINTYP TIMES -:(int int)->int BINTYP MINUS ==:(typ typ)->bool BINTYP EQ!=:(typ typ)->bool BINTYP NEQ <:(int int)->bool BINTYP LT <=:(int int)->bool BINTYP LTE >:(int int)->bool BINTYP GE >=:(int int)->bool BINTYP GTE [&]:(int int)->int BINTYP IAND &:(bool bool)->bool BINTYP AND [ ]:(int int)->int BINTYP IOR :(bool bool)->bool BINTYP OR <<:(int int)->int BINTYP SHL >>:(int int)->int BINTYP SHR >>>:(int int)->int BINTYP SAR unop:ftyp unop is of type ftyp. 8
-:(int)->int UTYP NEG!:(bool)->bool UTYP LOGNOT :(int)->int UTYP NOT Σ; ; Γ; cid opt p path:ptyp Σ,, Γ and cid opt show that path has type ptyp. hasfield Σ cid.id=some typ hasmethod Σ cid.id=none Σ; ; Γ; Some cid p this.id:typ P THIS FIELD hasmethod Σ cid.id=some ftyp hasfield Σ cid.id=none Σ; ; Γ; Some cid p this.id:ftyp P THIS METHOD Σ; ; Γ; cid opt l lhs or call:cid hasfield Σ cid.id=some typ hasmethod Σ cid.id=none Σ; ; Γ; cid opt p lhs or call.id:typ P PATH FIELD Σ; ; Γ; cid opt l lhs or call:cid hasmethod Σ cid.id=some ftyp hasfield Σ cid.id=none Σ; ; Γ; cid opt p lhs or call.id:ftyp P PATH METHOD Σ; ; Γ; cid opt call:rtyp Σ,, Γ and cid opt show that call has type rtyp. id:( typ )->rtyp Σ; ; Γ; cidopt exp <:typ Σ; ; Γ; cid opt id( exp ):rtyp CALL FUNC id id:( typ )->rtyp Σ; ; Γ; cidopt exp <:typ Σ; ; Γ; cid opt id( exp ):rtyp CALL BUILTIN cid 1 <:cid 2 {Φ; typ ; Θ} Σ hasmethod Σ cid2.id=some ( typ )->rtyp Σ; ; Γ; cid opt exp <:typ Σ; ; Γ; Some cid 1 super.id( exp ):rtyp CALL SUPER METHOD Σ; ; Γ; cid opt p path:( typ )->rtyp Σ; ; Γ; cidopt exp <:typ Σ; ; Γ; cid opt path( exp ):rtyp CALL PATH METHOD Σ; ; Γ; cid opt l lhs or call:typ Σ,, Γ and cid opt show that lhs or call has type typ. 9
Σ; ; Γ; cid opt lhs:typ Σ; ; Γ; cid opt l lhs:typ LC LHS Σ; ; Γ; cid opt call:typ Σ; ; Γ; cid opt l call:typ LC CALL Σ; ; Γ; cid opt lhs:typ Σ,, Γ and cid opt show that lhs has type typ. id:typ Γ Σ; ; Γ; cid opt id:typ LHS VAR Σ; ; Γ; cid opt p path:typ Σ; ; Γ; cid opt path:typ LHS PATH Σ; ; Γ; cid opt l lhs or call:typ[] Σ; ; Γ; cid opt exp:int Σ; ; Γ; cid opt lhs or call[exp]:typ LHS INDEX Σ; ; Γ; cid opt exp:typ Σ,, Γ and cid opt show that exp has type typ. const:typ Σ; ; Γ; cid opt const:typ EXP CONST Σ; ; Γ; Some cid this:cid EXP THIS Σ; ; Γ; cid opt exp 1 :int Σ; ; (Γ; (id : int)); cid opt exp 2 :typ Σ; ; Γ; cid opt new [exp 1 ]( fun id->exp 2 ):typ[] EXP NEW cid cid ext {Φ; typ ; Θ} Σ Σ; ; Γ; cidopt exp <:typ Σ; ; Γ; cid opt new cid( exp ):cid EXP CTOR Σ; ; Γ; cid opt l lhs or call:typ Σ; ; Γ; cid opt lhs or call:typ EXP LHS OR CALL Σ; ; Γ; cid opt exp 1 <:typ 1 Σ; ; Γ; cid opt exp 2 <:typ 2 binop:(typ 1 typ 2 )->typ Σ; ; Γ; cid opt binop exp 1 exp 2 :typ EXP BINARITH Σ; ; Γ; cid opt exp<:typ 1 unop:(typ 1 )->typ Σ; ; Γ; cid opt unop exp:typ EXP UNARITH Σ; ; Γ; cid opt exp opt :typ Σ,, Γ and cid opt show that exp opt is well-formed. 10
Σ; ; Γ; cid opt None:bool OPT EXP NONE Σ; ; Γ; cid opt exp:bool Σ; ; Γ; cid opt Some exp:bool OPT EXP SOME Σ; ; Γ; cid opt exp<:typ Σ,, Γ and cid opt show that exp has a subtype of typ. Σ; ; Γ; cid opt exp:typ Σ typ <:typ Σ; ; Γ; cid opt exp<:typ EXPSUB INTRO Σ; ; Γ; cid opt i init:typ Σ,, Γ and cid opt show that init has type typ. Σ; ; Γ; cid opt exp:typ Σ; ; Γ; cid opt i exp:typ INIT EXP Σ; ; Γ; cid opt i init :typ 1..m typ 1..m =typ Σ; ; Γ; cid opt i { init 1..m }:typ[] INIT ARRAY Σ; ; Γ; cid opt init<:typ Σ,, Γ and cid opt show that init has a subtype of typ. Σ; ; Γ; cid opt i init:typ Σ typ <:typ Σ; ; Γ; cid opt init<:typ SINIT INTRO Σ; ; Γ; cid opt vdecls:γ vdecls are well-formed under Σ,, Γ and cid opt, and extend the context to be Γ. Σ; ; Γ; cid opt ɛ:γ VDECLS NIL Σ; ; (Γ; γ); cid opt init<:typ Σ typ id and γ Σ; ; (Γ; (γ, id : typ)); cid opt vdecls:γ Σ; ; (Γ; γ); cid opt typ id=init; vdecls:γ VDECLS CONS Σ; ; Γ; cid opt stmt: o Σ,, Γ and cid opt show that stmt is well-formed. Σ; ; Γ; cid opt lhs:typ Σ; ; Γ; cid opt exp:typ Σ; ; Γ; cid opt lhs=exp; : o STMT ASSIGN Σ; ; Γ; cid opt call:unit Σ; ; Γ; cid opt call; : o STMT CALL Σ; ; Γ; cid opt exp:string Σ; ; Γ; cid opt fail (exp); : o STMT FAIL 11
Σ; ; Γ; cid opt exp:bool Σ; ; Γ; cid opt stmt: o Σ; ; Γ; cid opt stmt opt : o Σ; ; Γ; cid opt if (exp)stmt stmt opt : o STMT IF Σ; ; Γ; cid opt exp:ref? Σ; ; (Γ; (id : ref )); cid opt stmt: o Σ; ; Γ; cid opt stmt opt : o Σ; ; Γ; cid opt if?(ref id=exp)stmt stmt opt : o STMT IFNULL Σ; ; Γ; cid opt exp:cid Σ cid<:cid Σ; ; (Γ; (id : cid)); cid opt stmt: o Σ; ; Γ; cid opt stmt opt : o Σ; ; Γ; cid opt cast (cid id=exp)stmt stmt opt : o STMT CAST Σ; ; (Γ; ); cid opt vdecls:γ Σ; ; Γ ; cid opt exp opt :bool Σ; ; Γ ; cid opt stmt opt : o Σ; ; Γ ; cid opt stmt: o Σ; ; Γ; cid opt for (vdecls; exp opt ; stmt opt )stmt: o STMT FOR Σ; ; Γ; cid opt exp:bool Σ; ; Γ; cid opt stmt: o Σ; ; Γ; cid opt while (exp)stmt: o STMT WHILE Σ; ; Γ; cid opt bloc: o Σ; ; Γ; cid opt {bloc}: o STMT BLOCK Σ; ; Γ; cid opt bloc: o Σ,, Γ and cid opt show that bloc is well-formed. Σ; ; (Γ; ); cid opt vdecls:γ Σ; ; Γ ; cid opt stmt : o Σ; ; Γ; cid opt vdecls stmt : o BLOCK INTRO Σ; ; Γ; cid opt stmt opt : o Σ,, Γ and cid opt show that op stmt is well-formed. Σ; ; Γ; cid opt None: o OPT STMT NONE Σ; ; Γ; cid opt stmt: o Σ; ; Γ; cid opt Some stmt: o OPT STMT SOME Σ; ; Γ args:γ args are well-formed under Σ, and Γ, and extend the context to be Γ. Σ; ; Γ ɛ:γ ARGS NIL id and γ Σ typ Σ; ; (Γ; γ, id : typ) args:γ Σ; ; (Γ; γ) typ id,args:γ ARGS CONS 12
Σ; ; Γ; cid opt fdecl: o Σ,, Γ and cid opt show that fdecl is well-formed. Σ; ; (Γ; ) args:γ Σ; ; (Γ ; ); cid opt vdecls:γ Σ; ; Γ ; cid opt stmt : o Σ; ; Γ ; cid opt exp<:typ Σ typ Σ; ; Γ; cid opt typ id(args){vdecls stmt return exp; }: o FDECL FUNC Σ; ; (Γ; ) args:γ Σ; ; (Γ ; ); cid opt vdecls:γ Σ; ; Γ ; cid opt stmt : o Σ; ; Γ; cid opt unit id(args){vdecls stmt return ; }: o FDECL PROC Σ id:ftyp can override cid ext Σ shows that id with type ftyp can override parent class cid ext. Σ id:ftyp can override None OR OBJECT hasmethod Σ cid.id =None Σ id:ftyp can override <:cid OR NOMETHOD hasmethod Σ cid.id=some ( typ )->typ Σ typ <:typ Σ id:( typ )->typ can override <:cid Σ typ<:typ OR FUNC hasmethod Σ cid.id=some ( typ )->unit Σ typ <:typ Σ id:( typ )->unit can override <:cid OR PROC cid ext ; Φ fields:φ Extending Φ to be Φ by adding field declarations with parent class cid ext. cid ext ; Φ ɛ:φ GENF NIL id Φ None; Φ, id : typ fields:φ None; Φ typ id; fields:φ GENF BASE id Φ hasfield Σ cid.id=none <:cid; Φ, id : typ fields:φ <:cid; Φ typ id; fields:φ GENF INHERITANCE Σ; cid ext ; Φ; Θ fdecls:θ Extending Θ to be Θ by adding method declaratons with parent class cid ext. Σ; cid ext ; Φ; Θ ɛ:θ GENM NIL 13
id Φ and Θ Σ; cid ext ; Φ; Θ, id : ( typ )->typ fdecls:θ Σ; cid ext ; Φ; Θ typ id(typ id ){vdecls stmt return exp; } fdecls:θ GENM TYP id Φ and Θ Σ; cid ext ; Φ; Θ, id : ( typ )->unit fdecls:θ Σ; cid ext ; Φ; Θ unit id(typ id ){vdecls stmt return ; } fdecls:θ GENM UNIT Σ fields: o Σ shows that fields is well-formed. Σ ɛ: o WFF NIL Σ typ Σ fields: o Σ typ id; fields: o WFF CONS Σ; ; Γ; cid fdecl: o A method fdecl of class cid is well-formed. Σ; ; Γ; Some cid typ id(typ id ){vdecls stmt return exp; }: o cid cid ext Σ Σ id:( typ )->typ can override cidext Σ; ; Γ; cid typ id(typ id ){vdecls stmt return exp; }: o WFM TYP Σ; ; Γ; Some cid unit id(typ id ){vdecls stmt return ; }: o cid cid ext Σ Σ id:( typ )->unit can override cidext Σ; ; Γ; cid unit id(typ id ){vdecls stmt return ; }: o WFM UNIT Σ; ; Γ; cid cinits: o Σ, and Γ show that cinits is well-formed. Σ; ; Γ; cid ɛ: o CINITS NIL cid cid ext {Φ; typ ; Θ} Σ id:typ Φ Σ; ; Γ; None init<:typ Σ; ; Γ; cid cinits: o Σ; ; Γ; cid this.id=init; cinits: o CINITS CONS Σ; ; Γ; cid ctor: o ctor is well-formed. Σ; ; (Γ; ) typ id :Γ Σ; ; Γ ; cid this. name=cid; cinits: o Σ; ; Γ ; Some cid bloc: o Σ; ; Γ; cid new (typ id )( )cinits{bloc}: o CTOR BASE 14
Σ; ; (Γ; ) typ id :Γ cid 1 <:cid 2 {Φ; typ ; Θ} Σ cid 2 cid ext 2 {Φ 2 ; typ ; Θ2 } Σ Σ; ; Γ ; None exp <:typ Σ; ; Γ ; cid 1 this. name=cid 1 ; cinits: o Σ; ; Γ ; Some cid 1 bloc: o Σ; ; Γ; cid 1 new (typ id )( exp )cinits{bloc}: o CTOR INHERITANCE Σ; ; Γ cdecl: o cdecl is well-formed. Σ fields: o Σ; ; Γ; cid ctor: o Σ; ; Γ; cid fdecl : o Σ; ; Γ class cid cid ext {fields ctor fdecl };: o CDECL INTRO Σ; prog:σ ; Extending contexts by adding function and class declarations. Σ; ɛ:σ; GENSD NIL Σ; prog:σ ; Σ; vdecl prog:σ ; GENSD VDECL cid Σ cid ext Σ cid ext ; fields:φ Σ; cid ext ; Φ; fdecl :Θ Σ,cid cid ext {Φ; typ ; Θ}; prog:σ ; Σ; class cid cid ext {fields new (typ id )( expm m )cinits{bloc} fdecl }; prog:σ ; GENSD CDECL id Σ;, id : ( typ )->rtyp prog:σ ; Σ; rtyp id(typ id ) extern prog:σ ; GENSD EFUNC id Σ;, id : ( typ )->typ prog:σ ; Σ; typ id(typ id ){vdecls stmt return exp; } prog:σ ; GENSD FUNC TYP id Σ;, id : ( typ )->unit prog:σ ; Σ; unit id(typ id ){vdecls stmt return ; } prog:σ ; GENSD FUNC UNIT Σ; ; Γ prog: o Σ, and Γ show that prog is well-formed. Σ; ; Γ ɛ: o PROG NIL Σ typ Σ; ; ; None init<:typ id and Γ Σ; ; γ, id : typ prog: o Σ; ; γ typ id=init; prog: o PROG VDECL Σ; ; Γ; None fdecl: o Σ; ; Γ prog: o Σ; ; Γ fdecl prog: o PROG FDECL 15
Σ; ; Γ cdecl: o Σ; ; Γ prog: o Σ; ; Γ cdecl prog: o PROG CDECL prog: o prog is well-formed. Obect None { name: String ; ɛ; get name:()-> String }; prog:σ; Σ; ; prog: o prog: o WF INTRO 16