6.2. Objects
-
CoreCpp.Typing.expr[complete] -
CoreCpp.Eval.expr[complete] -
CoreCpp.Program.allFields[complete] -
CoreCpp.Program.chain[complete]
The expression new C(args) allocates one location per field of the whole chain of C, the root base first, then the tagged record, and runs the constructors from the root base down, each with this bound to the object, the one of C with the arguments and the others with none, since there are no initialiser lists.
A class without a constructor is created by new C() and keeps the default values.
\dfrac{C \mapsto \mathtt{class}\ C\ \{\ldots C(p_1\,x_1, \ldots, p_k\,x_k)\ \{c\} \ldots\} \qquad \text{arguments as in T-Call}}{\Gamma \vdash \mathtt{new}\ C(e_1, \ldots, e_k) : C*}\;\textsf{(T-New)}
\dfrac{\begin{array}{c} f_1 \ldots f_n \text{ the fields of the chain of } C\qquad (\ell_i, \sigma_i) = \mathrm{alloc}(\sigma_{i-1}, \mathrm{default}\,\tau_i) \\ (\ell, \sigma') = \mathrm{alloc}(\sigma_n, \mathsf{obj}\,C\,[f_1 \mapsto \ell_1, \ldots, f_n \mapsto \ell_n]) \\ \text{the constructors of the chain run from the root down} \\ \text{with } \mathtt{this} \mapsto \ell \text{, giving } \sigma'' \end{array}}{\rho, \sigma \vdash \mathtt{new}\ C(e_1, \ldots, e_k) \Rightarrow \mathsf{loc}\,\ell, \sigma''}\;\textsf{(New)}
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.2.1●4 definitions
Associated Lean declarations
-
CoreCpp.Typing.expr[complete]
-
CoreCpp.Eval.expr[complete]
-
CoreCpp.Program.allFields[complete]
-
CoreCpp.Program.chain[complete]
-
CoreCpp.Typing.expr[complete] -
CoreCpp.Eval.expr[complete] -
CoreCpp.Program.allFields[complete] -
CoreCpp.Program.chain[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, σ'
-
defdefined in CoreCpp/Syntax.leancomplete
def CoreCpp.Program.allFields (p : CoreCpp.Program) (c : String) : List (CoreCpp.Field × String)
def CoreCpp.Program.allFields (p : CoreCpp.Program) (c : String) : List (CoreCpp.Field × String)
Every field of a class, the fields of the root base first, each with the class that declares it.
-
opaquedefined in CoreCpp/Syntax.leancomplete
opaque CoreCpp.Program.chain (p : CoreCpp.Program) (c : String) (fuel : Nat := 64) : List CoreCpp.ClassDecl
opaque CoreCpp.Program.chain (p : CoreCpp.Program) (c : String) (fuel : Nat := 64) : List CoreCpp.ClassDecl
The chain of a class, the class itself, its base, the base of the base and so on. A cycle or an unknown base ends the chain, and the type checker rejects both.
-
CoreCpp.Eval.runMember[complete] -
CoreCpp.Typing.checkArgs[complete]
The call of a member body, a method, a constructor or a destructor, binds this to the location \ell of the receiver as an alias and the parameters as in the call of a function, by value with a fresh copy and by reference with an alias. The return frees the copies and the locals of the body, never the receiver.
\dfrac{\begin{array}{c} p_i = \tau_i \Rightarrow \rho, \sigma'_{i-1} \vdash e_i \Rightarrow v_i, \sigma_i,\ (\ell_i, \sigma'_i) = \mathrm{alloc}(\sigma_i, v_i) \\ p_i = \tau_i\& \Rightarrow \rho, \sigma'_{i-1} \vdash e_i \Rightarrow_{\ell} \ell_i, \sigma'_i \\ \rho_m = [\mathtt{this} \mapsto \ell, x_1 \mapsto \ell_1, \ldots, x_k \mapsto \ell_k]\qquad \rho_m, \sigma'_k \vdash c \Rightarrow r, \rho', \sigma'' \end{array}}{\mathrm{member}\ \ell\ (e_1, \ldots, e_k) \Rightarrow v, \sigma'' \setminus (\{\ell_i \mid p_i \text{ by value}\} \cup (\rho' \setminus \rho_m))}\;\textsf{(Member)}
With \mathsf{normal} in place of \mathsf{ret}\,v the result is \mathsf{void} for a void member and error otherwise.
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.2.2●2 definitions
Associated Lean declarations
-
CoreCpp.Eval.runMember[complete]
-
CoreCpp.Typing.checkArgs[complete]
-
CoreCpp.Eval.runMember[complete] -
CoreCpp.Typing.checkArgs[complete]
-
opaquedefined in CoreCpp/Eval.leancomplete
opaque CoreCpp.Eval.runMember (fs : CoreCpp.FunEnv) (ρ : CoreCpp.Env) (σ : CoreCpp.Store) (l : CoreCpp.Loc) (ps : List CoreCpp.Param) (body : List CoreCpp.Cmd) (es : List CoreCpp.Expr) (ret : CoreCpp.Ty) (who : String) : CoreCpp.M (CoreCpp.Val × CoreCpp.Store)
opaque CoreCpp.Eval.runMember (fs : CoreCpp.FunEnv) (ρ : CoreCpp.Env) (σ : CoreCpp.Store) (l : CoreCpp.Loc) (ps : List CoreCpp.Param) (body : List CoreCpp.Cmd) (es : List CoreCpp.Expr) (ret : CoreCpp.Ty) (who : String) : CoreCpp.M (CoreCpp.Val × CoreCpp.Store)
The call of a member body, a method, a constructor or a destructor, with this bound to the location ℓ of the receiver and the arguments bound as in Call, by value with a fresh copy and by reference with an alias. The return frees the copies and the locals of the body, never the receiver. ``` for each i, left to right, with σ'₀ = σ, pᵢ = τᵢ ρ, σ'ᵢ₋₁ ⊢ eᵢ ⇒ vᵢ, σᵢ (ℓᵢ, σ'ᵢ) = alloc σᵢ vᵢ pᵢ = τᵢ& ρ, σ'ᵢ₋₁ ⊢ eᵢ ⇒ₗ ℓᵢ, σ'ᵢ ρ_m = [this ↦ ℓ, x₁ ↦ ℓ₁, …, xₖ ↦ ℓₖ] ρ_m, σ'ₖ ⊢ c ⇒ r, ρ', σ'' ────────────────────────────────────────────────────────────── (Member) member ℓ (e₁, …, eₖ) ⇒ v, σ'' ∖ ({ℓᵢ | pᵢ by value} ∪ (ρ' ∖ ρ_m)) ``` -
opaquedefined in CoreCpp/Typing.leancomplete
opaque CoreCpp.Typing.checkArgs (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) (f : String) (ps : List CoreCpp.Param) (es : List CoreCpp.Expr) : CoreCpp.T Unit
opaque CoreCpp.Typing.checkArgs (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) (f : String) (ps : List CoreCpp.Param) (es : List CoreCpp.Expr) : CoreCpp.T Unit
The arguments of a call against the parameters, by value with ◁ and by reference with ⊢ₗ, shared by T-Call, T-New and T-Method.
-
CoreCpp.Typing.methodCall[complete] -
CoreCpp.Eval.expr[complete] -
CoreCpp.Eval.resolve[complete] -
CoreCpp.Program.findMethod[complete]
A method call e.m(args) needs a receiver of class type and e->m(args) a receiver of pointer type. The method is the nearest m in the chain of the static class of the receiver, it must be visible, and the arguments are checked as in a call. An unqualified call m(args) inside a member body is this->m(args).
\dfrac{\begin{array}{c} \Gamma \vdash e : C\qquad C \text{ has } \tau\ m(p_1\,x_1, \ldots, p_k\,x_k) \text{ visible from } \Gamma \\ \text{arguments as in T-Call} \end{array}}{\Gamma \vdash e.m(e_1, \ldots, e_k) : \tau}\;\textsf{(T-Method)}
\dfrac{\begin{array}{c} \Gamma \vdash e : C*\qquad C \text{ has } \tau\ m(\ldots) \text{ visible from } \Gamma \\ \text{arguments as in T-Call} \end{array}}{\Gamma \vdash e\mathtt{->}m(e_1, \ldots, e_k) : \tau}\;\textsf{(T-MethodArrow)}
\dfrac{\begin{array}{c} \rho, \sigma \vdash e \Rightarrow_{\ell} \ell, \sigma_0 \text{ or } \rho, \sigma \vdash e \Rightarrow \mathsf{loc}\,\ell, \sigma_0\qquad \sigma_0(\ell) = \mathsf{obj}\,T\,[\ldots] \\ S \text{ the static class of } e \\ m \mapsto \tau\ m(\ldots)\{c\} \text{ nearest } S \text{, or nearest } T \text{ when virtual} \\ \mathrm{member}\ \ell\ (e_1, \ldots, e_k) \Rightarrow v, \sigma' \end{array}}{\rho, \sigma \vdash e.m(e_1, \ldots, e_k) \Rightarrow v, \sigma'}\;\textsf{(MethodCall)}
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.2.3●4 definitions
Associated Lean declarations
-
CoreCpp.Typing.methodCall[complete]
-
CoreCpp.Eval.expr[complete]
-
CoreCpp.Eval.resolve[complete]
-
CoreCpp.Program.findMethod[complete]
-
CoreCpp.Typing.methodCall[complete] -
CoreCpp.Eval.expr[complete] -
CoreCpp.Eval.resolve[complete] -
CoreCpp.Program.findMethod[complete]
-
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`.
-
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, σ'
-
defdefined in CoreCpp/Eval.leancomplete
def CoreCpp.Eval.resolve (fs : CoreCpp.FunEnv) (s t m : String) (sig : Option (List CoreCpp.Ty)) : CoreCpp.M (CoreCpp.Method × String)
def CoreCpp.Eval.resolve (fs : CoreCpp.FunEnv) (s t m : String) (sig : Option (List CoreCpp.Ty)) : CoreCpp.M (CoreCpp.Method × String)
The method m of class s with the signature the type checker chose, the nearest in the chain of s, dispatched by the tag t when that method is virtual. The signature picks one member of an overload set, and without it, in an unannotated program, the first of the name serves.
-
defdefined in CoreCpp/Syntax.leancomplete
def CoreCpp.Program.findMethod (p : CoreCpp.Program) (c m : String) : Option (CoreCpp.Method × String)
def CoreCpp.Program.findMethod (p : CoreCpp.Program) (c m : String) : Option (CoreCpp.Method × String)
The method m as seen from class c, the nearest declaration in the chain, with the class that declares it. With m overloaded it is the first of the overload set, and `findMethods` gives them all.