6.1. Classes and visibility
-
CoreCpp.ClassDecl[complete] -
CoreCpp.Field[complete] -
CoreCpp.Method[complete] -
CoreCpp.Ctor[complete] -
CoreCpp.Dtor[complete] -
CoreCpp.Vis[complete] -
CoreCpp.Typing.cls[complete] -
CoreCpp.Typing.memberEnv[complete]
A class has an optional base, fields and methods with a visibility, at most one constructor named after the class and at most one destructor. Members before the first section label are private, as in C++.
The class is well formed when the base exists and the chain is acyclic, the fields have types with values and repeat no field of a base, the members have distinct names, a method that redefines a method of a base finds it virtual there, carries override and keeps the signature, the constructor of the base takes no parameters, and every member body is well typed under this.
\dfrac{\begin{array}{c} B \text{ exists, chain acyclic}\qquad \text{fields storable, well formed, new in the chain} \\ \text{each redefined } m \text{ is virtual in the base, marked override, same signature} \\ B \text{ has no constructor or one without parameters} \\ [\mathtt{this} \mapsto C*, p_1, \ldots, p_k] \vdash c \dashv \Gamma' \text{ for each member body} \end{array}}{\vdash \mathtt{class}\ C\ \mathtt{:}\ \mathtt{public}\ B\ \{ \ldots \}}\;\textsf{(T-Class)}
The context of a member body binds this to C* and the parameters as variables, so the current class is the class of this in \Gamma.
Lean code for Definition6.1.1●8 definitions
Associated Lean declarations
-
CoreCpp.ClassDecl[complete]
-
CoreCpp.Field[complete]
-
CoreCpp.Method[complete]
-
CoreCpp.Ctor[complete]
-
CoreCpp.Dtor[complete]
-
CoreCpp.Vis[complete]
-
CoreCpp.Typing.cls[complete]
-
CoreCpp.Typing.memberEnv[complete]
-
CoreCpp.ClassDecl[complete] -
CoreCpp.Field[complete] -
CoreCpp.Method[complete] -
CoreCpp.Ctor[complete] -
CoreCpp.Dtor[complete] -
CoreCpp.Vis[complete] -
CoreCpp.Typing.cls[complete] -
CoreCpp.Typing.memberEnv[complete]
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.ClassDecl : Type
structure CoreCpp.ClassDecl : Type
A class, with an optional base class, fields, methods, at most one constructor and at most one destructor. Names are qualified by their namespace, `N::C`.
Fields
name : String
The name of the class, qualified by its namespace when it has one.
base : Option String
The base class, when the class derives from one.
fields : List CoreCpp.Field
The fields declared by the class itself.
methods : List CoreCpp.Method
The methods declared by the class itself.
ctor : Option CoreCpp.Ctor
The constructor, when the class declares one.
dtor : Option CoreCpp.Dtor
The destructor, when the class declares one.
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.Field : Type
structure CoreCpp.Field : Type
A field of a class.
Fields
ty : CoreCpp.Ty
The type of the field.
name : String
The name of the field.
vis : CoreCpp.Vis
The visibility of the field.
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.Method : Type
structure CoreCpp.Method : Type
A method, defined inside the class. `isVirtual` marks `virtual`, which makes the call dispatch by the class tag of the receiver, and `isOverride` marks `override`, required on a method that redefines a `virtual` one. An operator member is a method whose name is `operator` followed by the operator, `operator+` or `operator[]`, which the type checker reaches by rewriting the infix form.
Fields
name : String
The name of the method.
ret : CoreCpp.Ty
The result type.
params : List CoreCpp.Param
The parameters.
body : List CoreCpp.Cmd
The body, run with `this` bound to the receiver.
vis : CoreCpp.Vis
The visibility of the method.
isVirtual : Bool
Whether the method is declared `virtual`.
isOverride : Bool
Whether the method is declared `override`.
retRef : Bool
Whether the method returns a reference, `τ& m(…)`, so that a call to it denotes the location the body returns.
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.Ctor : Type
structure CoreCpp.Ctor : Type
The constructor of a class, named after the class and run by `new` after the fields are allocated.
Fields
params : List CoreCpp.Param
The parameters of the constructor.
body : List CoreCpp.Cmd
The body, run by `new C(args)` after the fields are allocated.
-
structuredefined in CoreCpp/Syntax.leancomplete
structure CoreCpp.Dtor : Type
structure CoreCpp.Dtor : Type
The destructor of a class, `~C()`, run by `delete` before the locations of the object leave the store.
Fields
body : List CoreCpp.Cmd
The body, run by `delete` before the object leaves the store.
isVirtual : Bool
Whether the destructor is declared `virtual`, which makes `delete` through a pointer to the base well defined.
-
inductivedefined in CoreCpp/Syntax.leancomplete
inductive CoreCpp.Vis : Type
inductive CoreCpp.Vis : Type
Visibility of a member. Members before any section label are private, as in C++.
Constructors
CoreCpp.Vis.pub : CoreCpp.Vis
A public member, visible to every expression.
CoreCpp.Vis.priv : CoreCpp.Vis
A private member, visible only inside a member body of the class that declares it.
-
defdefined in CoreCpp/Typing.leancomplete
def CoreCpp.Typing.cls (p : CoreCpp.Program) (c : CoreCpp.ClassDecl) : CoreCpp.T Unit
def CoreCpp.Typing.cls (p : CoreCpp.Program) (c : CoreCpp.ClassDecl) : CoreCpp.T Unit
A class is well formed when the conditions below hold. Its base exists and the chain of bases has no cycle. Its fields have types that carry values, are themselves well formed, and repeat no field of a base. Its members have distinct names, and each method redefines only a method the base declares virtual, carrying override and the same signature. The constructor of the base, if the base has one, takes no parameters. Every member body is well typed under `this`. ``` B exists, chain acyclic fields storable, well formed, new in the chain for each method m of C. if some base has m then that m is virtual, m is override and the signatures agree for each override m of C. some base has a virtual m B has no constructor or one with no parameters [this ↦ C*, params] ⊢ body ⊣ Γ' for each member body ──────────────────────────────────────────────────────────────── (T-Class) ⊢ class C : public B { … } ``` -
defdefined in CoreCpp/Typing.leancomplete
def CoreCpp.Typing.memberEnv (c : String) (ps : List CoreCpp.Param) : CoreCpp.TEnv
def CoreCpp.Typing.memberEnv (c : String) (ps : List CoreCpp.Param) : CoreCpp.TEnv
The context of a member body, `this` bound to a pointer to the class and the parameters as variables.
-
CoreCpp.TEnv.self[complete] -
CoreCpp.Typing.fieldType[complete] -
CoreCpp.Typing.methodCall[complete]
A private member declared in class K is visible exactly when \Gamma(\mathtt{this}) = K*. Visibility is thus a typing rule, and the public section of a class is the signature of an abstract data type while the private section is its representation, reachable only from the member bodies of the class.
\dfrac{C \text{ has } \tau\ f \text{ declared in } K \qquad f \text{ public or } \Gamma(\mathtt{this}) = K*}{\Gamma \vdash e.f : \tau \text{ for } \Gamma \vdash e : C}\;\textsf{(Visible)}
The same premise applies to methods, Definition 6.2.3.
Some of the implementations are partial, so Lean records opaque constants that carry the type and not the body, and no property of them is proved here.
Lean code for Definition6.1.2●3 definitions
Associated Lean declarations
-
CoreCpp.TEnv.self[complete]
-
CoreCpp.Typing.fieldType[complete]
-
CoreCpp.Typing.methodCall[complete]
-
CoreCpp.TEnv.self[complete] -
CoreCpp.Typing.fieldType[complete] -
CoreCpp.Typing.methodCall[complete]
-
defdefined in CoreCpp/Typing.leancomplete
def CoreCpp.TEnv.self (Γ : CoreCpp.TEnv) : Option String
def CoreCpp.TEnv.self (Γ : CoreCpp.TEnv) : Option String
The current class, the class of `this` when Γ binds it, inside a method, a constructor or a destructor.
-
defdefined in CoreCpp/Typing.leancomplete
def CoreCpp.Typing.fieldType (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) (c f : String) : CoreCpp.T CoreCpp.Ty
def CoreCpp.Typing.fieldType (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) (c f : String) : CoreCpp.T CoreCpp.Ty
The type of field f of class C as seen from Γ, or the error. A private field is visible only when Γ(this) is the class that declares it. ``` C has τ f declared in K f public or Γ(this) = K* ──────────────────────────────────────────────────── (Visible) ```
-
opaquedefined in CoreCpp/Typing.leancomplete
opaque CoreCpp.Typing.methodCall (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) (recv : CoreCpp.Expr) (arrow : Bool) (m : String) (es : List CoreCpp.Expr) : CoreCpp.T CoreCpp.Ty
opaque CoreCpp.Typing.methodCall (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) (recv : CoreCpp.Expr) (arrow : Bool) (m : String) (es : List CoreCpp.Expr) : CoreCpp.T CoreCpp.Ty
The rules T-Method and T-MethodArrow, see `expr`.
-
CoreCpp.Typing.expr[complete] -
CoreCpp.Eval.expr[complete] -
CoreCpp.Eval.lval[complete]
Inside a member body this is the location of the receiver. It is bound in \rho by the call as an alias, never a variable, and it evaluates to a pointer. An unqualified name that is not a variable denotes the member of this, both in the type checker and in the evaluator.
\dfrac{\Gamma(\mathtt{this}) = C*}{\Gamma \vdash \mathtt{this} : C*}\;\textsf{(T-This)}
\dfrac{x \notin \Gamma \qquad \Gamma(\mathtt{this}) = C* \qquad \Gamma \vdash \mathtt{this}\mathtt{->}x : \tau}{\Gamma \vdash x : \tau}\;\textsf{(T-VarField)}
The same holds of a call. An unqualified name that is neither a variable nor a function of the program is a member of the receiver.
\dfrac{\begin{array}{c} f \notin \Gamma\qquad f \text{ is no function of the program}\qquad \Gamma(\mathtt{this}) = C* \\ \Gamma \vdash \mathtt{this}\mathtt{->}f(e_1, \ldots, e_k) : \tau \end{array}}{\Gamma \vdash f(e_1, \ldots, e_k) : \tau}\;\textsf{(T-CallThis)}
\dfrac{\rho(\mathtt{this}) = \ell}{\rho, \sigma \vdash \mathtt{this} \Rightarrow \mathsf{loc}\,\ell, \sigma}\;\textsf{(This)}
\dfrac{x \notin \rho \qquad \rho(\mathtt{this}) = \ell \qquad \sigma(\ell) = \mathsf{obj}\,C\,[\ldots x \mapsto \ell_x \ldots]}{\rho, \sigma \vdash x \Rightarrow_{\ell} \ell_x, \sigma}\;\textsf{(LocVarField)}
The implementations are partial, so Lean records opaque constants that carry the type and not the body, and no property of them is proved here.
Lean code for Definition6.1.3●3 definitions
Associated Lean declarations
-
CoreCpp.Typing.expr[complete]
-
CoreCpp.Eval.expr[complete]
-
CoreCpp.Eval.lval[complete]
-
CoreCpp.Typing.expr[complete] -
CoreCpp.Eval.expr[complete] -
CoreCpp.Eval.lval[complete]
-
opaquedefined in CoreCpp/Typing.leancomplete
opaque CoreCpp.Typing.expr (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) : CoreCpp.Expr → CoreCpp.T CoreCpp.Ty
opaque CoreCpp.Typing.expr (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) : CoreCpp.Expr → CoreCpp.T CoreCpp.Ty
Γ ⊢ e : τ
-
opaquedefined in CoreCpp/Eval.leancomplete
opaque CoreCpp.Eval.expr (fs : CoreCpp.FunEnv) (ρ : CoreCpp.Env) (σ : CoreCpp.Store) (e : CoreCpp.Expr) : CoreCpp.M (CoreCpp.Val × CoreCpp.Store)
opaque CoreCpp.Eval.expr (fs : CoreCpp.FunEnv) (ρ : CoreCpp.Env) (σ : CoreCpp.Store) (e : CoreCpp.Expr) : CoreCpp.M (CoreCpp.Val × CoreCpp.Store)
ρ, σ ⊢ e ⇒ v, σ'
-
opaquedefined in CoreCpp/Eval.leancomplete
opaque CoreCpp.Eval.lval (fs : CoreCpp.FunEnv) (ρ : CoreCpp.Env) (σ : CoreCpp.Store) (e : CoreCpp.Expr) : CoreCpp.M (CoreCpp.Loc × CoreCpp.Store)
opaque CoreCpp.Eval.lval (fs : CoreCpp.FunEnv) (ρ : CoreCpp.Env) (σ : CoreCpp.Store) (e : CoreCpp.Expr) : CoreCpp.M (CoreCpp.Loc × CoreCpp.Store)
ρ, σ ⊢ e ⇒ₗ ℓ, σ', the expressions that denote a location. A variable, a dereferenced pointer, a field of an object, a field through a pointer and an element of a vector. ``` ρ(x) = ℓ ρ, σ ⊢ e ⇒ loc ℓ, σ' ──────────────────── (LocVar) ────────────────────── (LocDeref) nullptr is error ρ, σ ⊢ x ⇒ₗ ℓ, σ ρ, σ ⊢ *e ⇒ₗ ℓ, σ' ``` ``` ρ, σ ⊢ e ⇒ₗ ℓ, σ' σ'(ℓ) = obj C [… f ↦ ℓ_f …] ─────────────────────────────────────────────── (LocField) ρ, σ ⊢ e.f ⇒ₗ ℓ_f, σ' ``` ``` ρ, σ ⊢ e ⇒ loc ℓ, σ' σ'(ℓ) = obj C [… f ↦ ℓ_f …] ────────────────────────────────────────────────── (LocArrow) e->f is (*e).f ρ, σ ⊢ e->f ⇒ₗ ℓ_f, σ' ``` An element of a vector is a use of the library, the rule LocLib.