From 74a5f0c4c57ff25290be3e81154439c6f865e152 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Wed, 18 Feb 2015 19:08:45 +0200 Subject: [PATCH 01/43] Doc: Punctuation review. Use --- instead of shorter dashes when needed. --- src/common/core-functions.k | 2 +- src/common/core-sorts.k | 18 ++++----- src/common/exp-syntax.k | 2 +- src/common/primitive-types.k | 6 +-- src/exec/api-core.k | 2 +- src/exec/api-threads.k | 6 +-- src/exec/configuration-exec.k | 18 ++++----- src/exec/expressions.k | 10 +++-- src/exec/method-invoke.k | 18 ++++----- src/exec/new-instance.k | 16 ++++---- src/exec/syntax-conversions.k | 8 ++-- src/exec/var-lookup.k | 14 +++---- src/prep/configuration-prep.k | 24 ++++++------ src/prep/elaboration-categories.k | 14 ++++--- src/prep/elaboration-core.k | 57 +++++++++++++++++----------- src/prep/elaboration-method-invoke.k | 2 +- src/prep/elaboration-new-instance.k | 12 ++++-- src/prep/elaboration-statements.k | 4 +- src/prep/elaboration-top-blocks.k | 4 +- src/prep/process-anonymous-classes.k | 12 ++++-- src/prep/process-class-decs.k | 8 +++- src/prep/process-class-members.k | 32 +++++++++------- src/prep/process-comp-units.k | 14 +++++-- src/prep/process-local-classes.k | 10 +++-- src/prep/process-type-names.k | 11 ++++-- 25 files changed, 186 insertions(+), 138 deletions(-) diff --git a/src/common/core-functions.k b/src/common/core-functions.k index b6e012bf..31b62efd 100644 --- a/src/common/core-functions.k +++ b/src/common/core-functions.k @@ -3,7 +3,7 @@ module CORE-FUNCTIONS imports CORE-CLASSES /*@ Returns the type associated with various K terms. The implementation is scattered among various K files. - For a type - the type itself. For a typed expression - the type component. For some raw values - their most common + For a type --- the type itself. For a typed expression - the type component. For some raw values - their most common type. */ syntax KItem ::= typeOf ( K ) [function] diff --git a/src/common/core-sorts.k b/src/common/core-sorts.k index fb8dca26..a7c83f08 100644 --- a/src/common/core-sorts.k +++ b/src/common/core-sorts.k @@ -98,14 +98,14 @@ syntax Signature ::= sig ( Id, Types ) syntax KResult ::= Signature -/*@ The member accessibility context of the current method - either static or instance.*/ +/*@ The member accessibility context of the current method --- either static or instance.*/ syntax ContextType ::= "staticCT" [latex(\terminal{static})] | "instanceCT" [latex(\terminal{instance})] syntax KResult ::= ContextType //@ \subsection{Values} -/* Represents a java value. May be either primitive - int, float, bool, of reference. The values nothing and undefined +/* Represents a java value. May be either primitive --- int, float, bool, of reference. The values nothing and undefined are special cases required by the semantics. The value nothing is associated with the return type void. The value undefined is the initial value of uninitialized local variables, before the first assignment. */ @@ -113,13 +113,13 @@ syntax RawVal ::= Int | Float | Bool | RawRefVal | "nothing" | "undefined" [latex(\bot)] -/*@ A reference value, in its four forms - as regular object, array, null or String. As mentioned previously +/*@ A reference value, in its four forms --- as regular object, array, null or String. As mentioned previously String values have special treatment in this semantics and are implemented as regular strings. The object closure has the following structure: \begin{itemize} -\item OL:Int -- the object location -\item List -- the object content, of the form +\item OL:Int --- the object location +\item List --- the object content, of the form \begin{verbatim} ListItem(layer( Class, @@ -138,9 +138,9 @@ syntax ObjectRef ::= objectRef ( /*@ The arrayRef has the following structure: \begin{itemize} -\item Type -- type of the array -\item Int -- location of the first element -\item Int -- array length +\item Type --- type of the array +\item Int --- location of the first element +\item Int --- array length \end{itemize} */ syntax ArrayRef ::= arrayRef ( @@ -190,7 +190,7 @@ syntax Types ::= types ( ) syntax KResult ::= Types -//Location type of each store location - either local variable or field +//@Location type of each store location --- either local variable or field syntax LocMetadata ::= "LocalLocMetadata" [latex(\terminal{Local})] | "FieldLocMetadata" [latex(\terminal{Field})] diff --git a/src/common/exp-syntax.k b/src/common/exp-syntax.k index e9aeaaa9..150eebeb 100644 --- a/src/common/exp-syntax.k +++ b/src/common/exp-syntax.k @@ -51,7 +51,7 @@ syntax Exp ::= "~" Exp [strict, klabel('Complement)] | "+" Exp [strict, klabel('Plus)] | "-" Exp [strict, klabel('Minus)] -//@ Operators with side effects - prefix, postfix ++/-- +//@ Operators with side effects --- prefix, postfix ++/-- syntax PrefixPostfixExp ::= "++" Exp [klabel('PreIncr)] | "--" Exp [klabel('PreDecr)] diff --git a/src/common/primitive-types.k b/src/common/primitive-types.k index 181742d2..f113b7a8 100644 --- a/src/common/primitive-types.k +++ b/src/common/primitive-types.k @@ -11,7 +11,7 @@ rule bitCount(int) => 32 rule bitCount(long) => 64 rule bitCount(char) => 16 -/*@ Symbolic execution limitation: this construct cannot be [function] +/* Symbolic execution limitation: this construct cannot be [function] When conditionals are needed, implementation have to use 'If - the symbolically processed version of if. */ syntax KItem ::= normalize ( TypedVal ) @@ -56,7 +56,7 @@ rule normalizeImpl(I:Int :: T:Type) +Int (1 < . -//@\subsection{Class literal - .class} +//@\subsection{Class literal --- .class} /*@ We need to synchronize access to class literals to avoid instantiation of the came .class by multiple threads. This is done by the term temp in . We cannot use 'Synchronized because it required an diff --git a/src/exec/api-threads.k b/src/exec/api-threads.k index 299522d9..b23077fd 100644 --- a/src/exec/api-threads.k +++ b/src/exec/api-threads.k @@ -293,13 +293,13 @@ module API-THREADS-SELECTION /*@ When \verb|object.wait()| is called the method call expression is replaced by \verb|waitImpl()| --- an auxiliary function that is used later to exit from the waiting state. +--- an auxiliary function that is used later to exit from the waiting state. The id of the current thread (\verb|TId|) has to be registered in the set inside \cellref[]{waitingThreads}. The cell \cellref[]{holds} attached to each thread stores the number of times the current thread acquired the lock on each object. Here we use it to make sure that the current thread acquired the lock at least once (see the side condition). Otherwise calling the method \verb|wait()| is illegal and we have to throw an exception, according to Java API. The exceptional case is covered by other rules. Another cell matched here is \cellref[]{busy}. It stores - the set of objects that serve as synchronization monitors -- arguments of blocks \verb|synchronized|. When + the set of objects that serve as synchronization monitors --- arguments of blocks \verb|synchronized|. When an object enters the waiting state it have to release the ownership of this monitor, this is reflected by deleting the entry \verb|OL| from the set. In this rule the cell \cellref[]{thread} is used solely for clarity, to separate the cells that are attached to a thread from global cells. In fact, if we would delete \cellref[]{thread} here and @@ -330,7 +330,7 @@ when When another thread calls \verb|notify()| we have to make sure that the thread holds the monitor on the target object (the side condition). Otherwise we have to throw an exception. The actual logic of \verb|notify()| is delegated to \verb|notifyImpl()|, in order to avoid duplication. The construct \verb|notifyImpl()| requires two rules for two - cases -- the case when there is at least one thread waiting on the target object, and the case when there is no one. + cases --- the case when there is at least one thread waiting on the target object, and the case when there is no one. */ rule [object-notify]: diff --git a/src/exec/configuration-exec.k b/src/exec/configuration-exec.k index 8e22323e..4960a26e 100644 --- a/src/exec/configuration-exec.k +++ b/src/exec/configuration-exec.k @@ -3,20 +3,20 @@ module CONFIGURATION-EXEC imports CORE-FUNCTIONS /*@ -The execution configuration consists from the top-level cell \cellref{T}, whose content is divided into three large cell groups. The group \cellref[]{threads} contains one or multiple cells \cellref[]{thread}. Here is included the data related to the execution of a thread, such as the computation, stack, local environment. The second group is contained inside \cellref[]{classes} that have multiple \cellref[]{class} cells -- all the content related to particular classes. The third group consists of the remaining top-level cells. +The execution configuration consists from the top-level cell \cellref{T}, whose content is divided into three large cell groups. The group \cellref[]{threads} contains one or multiple cells \cellref[]{thread}. Here is included the data related to the execution of a thread, such as the computation, stack, local environment. The second group is contained inside \cellref[]{classes} that have multiple \cellref[]{class} cells --- all the content related to particular classes. The third group consists of the remaining top-level cells. -\paragraph{Threads} Each execution thread has a corresponding \cellref{thread}. Inside a thread, \cellref[K]{k} is represents the actual computation - the sequence of tasks to be executed. Next cells are \cellref[List]{stack} -- the method call stack, and \cellref{methodContext}. The \cellref{methodContext} holds the local context of the executed method: +\paragraph{Threads} Each execution thread has a corresponding \cellref{thread}. Inside a thread, \cellref[K]{k} is represents the actual computation --- the sequence of tasks to be executed. Next cells are \cellref[List]{stack} --- the method call stack, and \cellref{methodContext}. The \cellref{methodContext} holds the local context of the executed method: \begin{itemize} - \item \cellref[Map{{[}}Id\mapsto{}Int{{]}}]{env} -- the map from local variable names to their location inside \cellref[]{store}. - \item \cellref[ClassType]{crntClass} -- the current class, the type of \verb|this| - \item \cellref[Int]{location} -- The location in memory store of the current object. + \item \cellref[Map{{[}}Id\mapsto{}Int{{]}}]{env} --- the map from local variable names to their location inside \cellref[]{store}. + \item \cellref[ClassType]{crntClass} --- the current class, the type of \verb|this| + \item \cellref[Int]{location} --- The location in memory store of the current object. \end{itemize} On the next line there are 3 cells related to multithreading: \begin{itemize} - \item \cellref{tid} -- the thread identified, generated when the thread is created. - \item \cellref[Map{{[}}Int\mapsto{}Int{{]}}]{holds} -- a map from Object locations to integer numbers. Map keys are monitor objects on which the current thread has the locks. Map values hold the number of times the lock was acquired. - \item \cellref[Bool]{interrupted} -- boolean value signaling whether the current thread was interrupted. + \item \cellref{tid} --- the thread identified, generated when the thread is created. + \item \cellref[Map{{[}}Int\mapsto{}Int{{]}}]{holds} --- a map from Object locations to integer numbers. Map keys are monitor objects on which the current thread has the locks. Map values hold the number of times the lock was acquired. + \item \cellref[Bool]{interrupted} --- boolean value signaling whether the current thread was interrupted. \end{itemize} \paragraph{Classes} The cell \cellref{classes} contains one \cellref{class} for each class in the program, both for supported JDK classes and for user-defined classes. Cell \cellref{class} has the following content: @@ -82,7 +82,7 @@ The next row contains global cells related to multithreading: \begin{itemize} \item \cellref[ Set{[} ObjLocation:Int {]} ]{busy} --- the set of busy objects. E.g. monitor objects for which there is a thread holding the monitor. \item \cellref[ Map{[} ThreadId:Int \mapsto OL:Int {]} ]{waitingThreads} --- The map from threads to monitor objects on which respective threads are blocked in a call to \verb|wait()|. Used by the methods \verb|Object.wait()|, \verb|Object.notify()|, \verb|Object.notifyAll()|. - \item \cellref[Set{[}ThreadId:Int{]}]{terminated} -- the set of identifiers of terminated threads. + \item \cellref[Set{[}ThreadId:Int{]}]{terminated} --- the set of identifiers of terminated threads. \end{itemize} The rest of the global cells are used for debugging purposes. diff --git a/src/exec/expressions.k b/src/exec/expressions.k index 50eedce9..3e238569 100644 --- a/src/exec/expressions.k +++ b/src/exec/expressions.k @@ -148,16 +148,18 @@ syntax LHS ::= TypedVal rule [Assign]: loc(L:Int) :: ResT:Type = V:RawVal :: ResT => store(L, V::ResT) ~> V::ResT -/*@ Desugars compound assign into the underlying operator + assign. - - Question: Why not during elaboration phase? +/*@ +\begin{markdown} +Desugars compound assign into the underlying operator + assign. Could probably be done during elaboration. Answer: - in the LHS of => location L is referred once - in the RHS of => it is referred twice - at elaboration phase we would have to rewrite the original expresion that produces L from one occurence to two occuences. - if operator LHS expression has side effects, we would end up with the side effect twice. - - Example: v[i++] += 1*/ + - Example: v[i++] += 1 +\end{markdown} +*/ rule loc(L:Int) :: T:Type *= Exp2:K => loc(L)::T = cast(T, lookup(L, T) * Exp2) rule loc(L:Int) :: T:Type /= Exp2:K => loc(L)::T = cast(T, lookup(L, T) / Exp2) diff --git a/src/exec/method-invoke.k b/src/exec/method-invoke.k index cf2b7a13..ff009830 100644 --- a/src/exec/method-invoke.k +++ b/src/exec/method-invoke.k @@ -110,7 +110,7 @@ The type after four dots (::) separator is the static type associated with that objectRef() are the address inside the store and the runtime type of the object. For the sake of simplicity we we will also - consider \dotCt{K} - the unit element of K to be KResult. The value \dotCt{K} is often + consider \dotCt{K} --- the unit element of K to be KResult. The value \dotCt{K} is often used in auxiliary functions as a placeholder until some actual value is computed. @@ -214,11 +214,11 @@ During the second step of the method invocation the second argument of the produ - Method signature Sig - Qualifying class QualC of the method invocation, e.g. the compile-time type of the qualifier. - - The meta type of QualC - MetaT. It may have one of the two values - class or interface. - - DecC - declaring class, the class where the method was actually declared, as observed by QualT. + - The meta type of QualC --- MetaT. It may have one of the two values - class or interface. + - DecC --- declaring class, the class where the method was actually declared, as observed by QualT. E.g. the most derived class in QualC hierarchy where there is a declaration of a method with signature Sig. - - ContextT - the context type of the method. Either static, for static methods, or instance for non-static methods. - - Acc - access modifier (private, package, protected or public). For the purpose of uniformity we use the modifier + - ContextT --- the context type of the method. Either static, for static methods, or instance for non-static methods. + - Acc --- access modifier (private, package, protected or public). For the purpose of uniformity we use the modifier package when no access modifier is provided. All the information stored in methodInfo() is static. In K-Java we already have @@ -242,7 +242,7 @@ syntax MethodName ::= methodInfo( The first rule from this step rewrites the method name into a methodInfo() term whose first argument is the method signature. The auxiliary function getTypes() computes the list of types from the list of parameter declarations. The second - argument of methodInfo() is also computed at this step - it is the type of the qualifier. The rest of the arguments + argument of methodInfo() is also computed at this step --- it is the type of the qualifier. The rest of the arguments are filled in with default values. They will be rewritten into actual values by the following rules. */ rule [Invoke-compute-methodInfo-Signature]: @@ -285,7 +285,7 @@ rule [Invoke-compute-methodInfo-DecC]: ... Sig |-> DecC:ClassType ... /*@ \begin{markdown} -There is one case that is not covered by the previous rule - the case when the cell \cellref[]{methods} does not have a key +There is one case that is not covered by the previous rule --- the case when the cell \cellref[]{methods} does not have a key equal to Sig. This is possible in one of the following situations: - Qualifying type is an interface. @@ -325,8 +325,8 @@ rule [Invoke-compute-methodInfo-ContextType]: In the third step of the method invocation algorithm, the actual method declaration is chosen. This step starts once all the fields of methodInfo() were filled in (where possible). The rules of this step rewrite methodInfo() into - methodRef() - another auxiliary data structure. -The production methodRef() is a reference to a method declaration. It contains two fields - Sig and DecC - the + methodRef() --- another auxiliary data structure. +The production methodRef() is a reference to a method declaration. It contains two fields --- Sig and DecC --- the signature and the declaration class. The implementation class is the class that contains the actual method declaration to be invoked. diff --git a/src/exec/new-instance.k b/src/exec/new-instance.k index e19359a2..a023304d 100644 --- a/src/exec/new-instance.k +++ b/src/exec/new-instance.k @@ -68,28 +68,28 @@ In this subsection we present the fragment of configuration used by runtime meth \vspace{3ex} -The cell \cellref[]{k} stores the current computation. Inside \cellref[]{env} we store the local environment -- a map +The cell \cellref[]{k} stores the current computation. Inside \cellref[]{env} we store the local environment --- a map from variable names to their locations in the store. The cell \cellref[]{methodContext} store information about the - current object -- the one accessible through the keyword this. Both \cellref[]{env} and \cellref[]{methodContext} play + current object --- the one accessible through the keyword this. Both \cellref[]{env} and \cellref[]{methodContext} play a special role in object instantiation. The cell \cellref[]{class} contains various sub-cells holding the content of that class. The first cell in \cellref[]{classType} of sort ClassType that holds the fully qualified class name. This cell is a unique identifier of a class, and is used as a key to access other cells inside a \cellref[]{class}. - Next relevant cells inside \cellref[]{class} are \cellref[]{enclosingClass} - the directly enclosing class in case + Next relevant cells inside \cellref[]{class} are \cellref[]{enclosingClass} --- the directly enclosing class in case this class is an inner class. The vase class is stored inside \cellref[]{extends} and the list of declarations of instance fields without identifiers is stored in \cellref[]{instanceFields}. -The next two cells are related to the store. The cell \cellref[]{store} has a central role in the semantics -- it is +The next two cells are related to the store. The cell \cellref[]{store} has a central role in the semantics --- it is the map from object locations (values in the cell \cellref[]{env}) to their actual typed values. The cell \cellref[]{nextLoc} is the counter of store locations. -The remaining big group of cells -- \cellref[]{objectStore} contains the inner structure of objects. +The remaining big group of cells --- \cellref[]{objectStore} contains the inner structure of objects. The \cellref[]{objectId} is an unique identifier of the object. Every reference to this object in the store is a reference to this id. Inside \cellref[]{objectType} is the actual runtime type of the object. Next we have a list of \cellref[]{layer} cells, each of them representing an inheritance layer of the object. Starting from class Object and ending with the actual object type. Inside each layer \cellref[]{layerClass} stores its - associated class, \cellref[]{layerEnv} -- the fields and \cellref[]{layerEnclosingObject} -- the enclosing object, + associated class, \cellref[]{layerEnv} --- the fields and \cellref[]{layerEnclosingObject} --- the enclosing object, in the case when \cellref[]{layerClass} is a non-static inner class. The complex rules for Java inner classes allow each layer to have its distinctive enclosing object, and we have tests that specifically target this requirement. @@ -117,11 +117,11 @@ When all the subexpressions of new have been evaluated, the main rule for new co First the current value of the counter inside \cellref[]{nextLoc} is used as the location of the newly created object. The counter is incremented for the next use. Inside \cellref[]{objectStore} a new cell \cellref[]{object} is created for the new object. For now it has just two - sub-cells specified -- \cellref[]{objectId} and \cellref[]{objectType}, and no layers. Curiously we don't have + sub-cells specified --- \cellref[]{objectId} and \cellref[]{objectType}, and no layers. Curiously we don't have to specify neither \cellref[]{object} nor \cellref[]{objectStore} cells explicitly here, we have to specify just the cells inside them that are modified. The capability to ignore surrounding cells when they can be automatically inferred is called configuration abstraction, another K feature\cite{k-jlap}. In the cell \cellref[]{store} - a new entry is created with key being L and value - a reference to the newly created object in \cellref[]{object}. + a new entry is created with key being L and value --- a reference to the newly created object in \cellref[]{object}. The content of \cellref[]{methodContext} is reset to a default state. This default state is required by rules that are applied next. diff --git a/src/exec/syntax-conversions.k b/src/exec/syntax-conversions.k index 8890bf34..4d1b8c94 100644 --- a/src/exec/syntax-conversions.k +++ b/src/exec/syntax-conversions.k @@ -26,6 +26,7 @@ rule typeOf('ParamImpl(T:Type,, _:Id)) => T /* General structure: +\begin{verbatim} 'Invoke( 'Method( 'MethodName( @@ -33,8 +34,9 @@ General structure: Name:Id ) ),, - [Args] - argument expressions + [Args] --- argument expressions ) +\end{verbatim} */ /* 'Method(Qual:K,, \_:K,, Name:Id) @@ -47,8 +49,6 @@ rule 'Invoke('Method( 'MethodName( Qual:K,, Name:Id ) ),, ArgList:KListWrap) => //somehow. //totest - if qualifier evaluates to null, NullPointerException should be thrown after //the evaluation of the arguments -/*@ Method invocation expression -*/ /*@ \subsection{Local variable declaration}*/ @@ -89,7 +89,7 @@ rule [NewInstance-to-QNewInstance-unpack]: new Class:ClassType(ArgExps:Exps) => noValue . new Class:ClassType(ArgExps:Exps) -/*@ \subsection{Syntactic lists - Exps, TypedVals, ClassTypes}*/ +/*@ \subsection{Syntactic lists --- Exps, TypedVals, ClassTypes}*/ /*@ A list of expressions, usually a list of arguments of a method or constructor. diff --git a/src/exec/var-lookup.k b/src/exec/var-lookup.k index 686a7b22..f9517e28 100644 --- a/src/exec/var-lookup.k +++ b/src/exec/var-lookup.k @@ -7,7 +7,7 @@ module VAR-LOOKUP //@ \subsection{Local variable access} /* Local variable access. At runtime may have one form: - - 'ExprName(X:Id) - local variable + - 'ExprName(X:Id) --- local variable */ @@ -21,7 +21,7 @@ rule [lvalue-ExprName-local]: lvalue('ExprName(X:Id)) => typedLoc(L) ... ... X |-> L:Int ... -/*@ \subsection{QThis - Self reference} */ +/*@ \subsection{QThis --- Self reference} */ // 'QThis(Class:ClassType) rule [QThis]: @@ -37,7 +37,7 @@ rule [QThis]: ... -//@ Search for the right value representing QThis(Class) - an expression of type Class.this +//@ Search for the right value representing QThis(Class) --- an expression of type Class.this syntax KItem ::= lookupQThis ( ClassType, //the type of this to look for, TypedVal //the objectRef where the type should be found @@ -67,8 +67,8 @@ when /*@ \subsection{Instance field access} */ /*@ Variable access. May have 2 forms: - - 'ExprName(Class, X:Id) - static field - - 'ExprName(Qual, X:Id) - instance field + - 'ExprName(Class, X:Id) --- static field + - 'ExprName(Qual, X:Id) --- instance field */ context 'Field(HOLE,, _) context lvalue('Field(HOLE,, _)) @@ -165,8 +165,8 @@ rule [lvalue-typedLoc]: /*@ \subsection{lookup} */ /*@ Retrieve a value from the store based on its location and the given compile-time type. - May be wrapped inside lvalue. If lookup is unwrapped, it evaluates to TypedVal - the store value, - of the type T - the second lookup argument. If lookup is wrapped into lvalue, it evaluates to loc(OL)::T. + May be wrapped inside lvalue. If lookup is unwrapped, it evaluates to TypedVal --- the store value, + of the type T --- the second lookup argument. If lookup is wrapped into lvalue, it evaluates to loc(OL)::T. */ syntax Exp ::= lookup ( Int, //OL - the store location to lookup diff --git a/src/prep/configuration-prep.k b/src/prep/configuration-prep.k index dcabae38..7e2cd064 100644 --- a/src/prep/configuration-prep.k +++ b/src/prep/configuration-prep.k @@ -52,11 +52,11 @@ Also during Process Type Names classes are first registered. Again, both top-lev \paragraph{Process Compilation Units} At the beginning of this phase computation is again initialized with the initial AST from \cellref{program}. The following new cells are filled in inside each \cellref{class}: \begin{itemize} - \item \cellref[ClassType]{enclosingClass} -- the directly enclosing class, for inner classes, or no value for top-level classes. - \item \cellref[K]{rawExtends} -- The extends clause of this class, in its raw (AST) form. - \item \cellref[K]{rawImplements} -- The implements clause, in AST form. - \item \cellref[K]{rawDeclarations} -- The class body, in AST form. - \item \cellref[Map{[}Id\mapsto{}ClassType{]}]{cuImports} -- A map from names accessible inside this class to fully qualified class names they represent. Only computed for top-level classes at this phase. For inner classes this cell remains empty. + \item \cellref[ClassType]{enclosingClass} --- the directly enclosing class, for inner classes, or no value for top-level classes. + \item \cellref[K]{rawExtends} --- The extends clause of this class, in its raw (AST) form. + \item \cellref[K]{rawImplements} --- The implements clause, in AST form. + \item \cellref[K]{rawDeclarations} --- The class body, in AST form. + \item \cellref[Map{[}Id\mapsto{}ClassType{]}]{cuImports} --- A map from names accessible inside this class to fully qualified class names they represent. Only computed for top-level classes at this phase. For inner classes this cell remains empty. \item \cellref[ContextType]{classContextType} --- Either static or instance, for inner classes. Always static for top-level classes. \end{itemize} @@ -72,15 +72,15 @@ Also during Process Compilation Units the following global cell is used: \paragraph{Process Class Declarations} Here each class passes through two more class phases: Bases Processed and Declarations Processed. First, for each class the semantics attempts to resolve its extends/implements clauses into fully qualified class names. The order in which dependencies are resolved depends on both class inheritance relationships as well as nesting relationships. Once the dependencies of a class are resolved, they are stored into a temporary cell: \begin{itemize} -\item \cellref[K]{unprocessedBases} -- Initialized with the list of fully qualified class names for classes mentioned in extends/implements clauses of this class. +\item \cellref[K]{unprocessedBases} --- Initialized with the list of fully qualified class names for classes mentioned in extends/implements clauses of this class. \end{itemize} Once the content of \cellref[K]{unprocessedBases} is created, the class enters into Bases Resolved phase. It then waits in this phase until all classes referred in extends/implements reach the phase Declarations Processed. The restrictions in JLS related to class dependencies guarantee that classes cannot have cyclic dependencies, thus a class cannot get locked in the waiting state. The cell \cellref[K]{unprocessedBases} is used to determine the moment when the class may exit the waiting state. Once a class reaches the phase Declarations Processed, is is deleted from cells \cellref[K]{unprocessedBases} of other classes. Thus, when all extends/implements dependencies of a class reach the phase Declarations Processed, the content of the its \cellref[K]{unprocessedBases} cell becomes empty. Once in this state, the class enters into the phase Declarations Processed itself and computes three more cells: \begin{itemize} -\item \cellref[ClassType]{extends} -- The base class, fully qualified. -\item \cellref[Set{[}ClassType{]}]{implements} -- The list of directly implemented interfaces, fully qualified. -\item \cellref[Map{[}Id\mapsto{}ClassType{]}]{imports} -- The map of classes accessible by simple name within the body of this class. The rules for computing this map are complex and include the following sources: +\item \cellref[ClassType]{extends} --- The base class, fully qualified. +\item \cellref[Set{[}ClassType{]}]{implements} --- The list of directly implemented interfaces, fully qualified. +\item \cellref[Map{[}Id\mapsto{}ClassType{]}]{imports} --- The map of classes accessible by simple name within the body of this class. The rules for computing this map are complex and include the following sources: \begin{itemize} \item Imports declarations of the current compilation unit. @@ -112,7 +112,7 @@ During Process Class Declarations the following global cell is first used: The following new class cells are produced: \begin{itemize} - \item \cellref[Set{[}ClassType{]}]{implTrans} -- The transitive closure of implemented interfaces. In the remaining phases this set is used by the subtyping relationship. + \item \cellref[Set{[}ClassType{]}]{implTrans} --- The transitive closure of implemented interfaces. In the remaining phases this set is used by the subtyping relationship. \item \cellref[ Map {[} Signature \mapsto ClassType {]} ]{methods} --- The map of accessible methods. Keys are method signatures, values are classes where methods are defined. Includes both methods declared within this class as well as methods inherited from base classes/ base interfaces. \item \cellref[Bag]{methodDecs} --- the collection of method declarations (\cellref{methodDec} cells)in the current class. This cell contains only a subset of methods from \cellref{methods}, as the set of accessible methods from \cellref{methods} also includes methods inherited from base classes/interfaces. Hence the need of two separate collections. Each \cellref[Bag]{methodDec} contains the following data: \begin{itemize} @@ -126,10 +126,10 @@ The following new class cells are produced: \item \cellref[MethodMetaType]{methodMetaType} --- either method or constructor \end{itemize} \item \cellref[K]{instanceFields} --- The list of instance field declarations, stored as a list of local variable declaration statements, without initializers. Used during object instantiation. - \item \cellref[K]{instanceInit} -- The list of instance initializers of the class combined into one big instance initializer. Instance field initializers are also concatenated into this cell in their textual order. + \item \cellref[K]{instanceInit} --- The list of instance initializers of the class combined into one big instance initializer. Instance field initializers are also concatenated into this cell in their textual order. \item \cellref[K]{staticFields} --- The list of static field declarations, in a similar format to \cellref{instanceFields} \item \cellref[K]{staticInit} --- The list of static initializers and static field initializers concatenated into one block. - \item \cellref[Map{[}Id \mapsto Value{]}]{constantEnv} -- The map from compile-time constants to their actual values. Constants in Java have a slightly different semantics compared to final static fields. In particular, accessing them don't trigger static initialization of the declaring class. + \item \cellref[Map{[}Id \mapsto Value{]}]{constantEnv} --- The map from compile-time constants to their actual values. Constants in Java have a slightly different semantics compared to final static fields. In particular, accessing them don't trigger static initialization of the declaring class. \end{itemize} Once all the cells above are computed the class proceeds into the phase Members Processed and the cell \cellref[]{rawDeclarations} is deleted. diff --git a/src/prep/elaboration-categories.k b/src/prep/elaboration-categories.k index feaa1280..0d43f300 100644 --- a/src/prep/elaboration-categories.k +++ b/src/prep/elaboration-categories.k @@ -227,12 +227,16 @@ rule isElabNaked('PackageOrTypeName(_)) => true rule isElabNaked('Id(_)) => true rule isElabNaked('Lit(InnerKL:KLabel(_))) => InnerKL =/=KLabel 'Class -/*@ Terms that should use custom elaboration rules. For those terms: - - They will not be automatically heated from their parents into the elab() state. - - They will not be automatically passed to elabDispose() state. Instead, those terms should have custom rules - for elaboration start (heating) and elaboration end (cooling). - Since all the automatic elaboration-related rules are an incredible mess, we have to put all the AST terms into this +/*@ +\begin{markdown} +Terms that should use custom elaboration rules. For those terms: + + - They will not be automatically heated from their parents into the elab() state. + - They will not be automatically passed to elabDispose() state. Instead, those terms should have custom rules for elaboration start (heating) and elaboration end (cooling). + +Since all the automatic elaboration-related rules are an incredible mess, we have to put all the AST terms into this cathegory one by one, and eliminate automatic elaboration heating/cooling rules altogether. +\end{markdown} */ syntax KItem ::= customElabChildren ( KLabel ) [function] rule customElabChildren(KL:KLabel) => diff --git a/src/prep/elaboration-core.k b/src/prep/elaboration-core.k index 7e640b34..d71927a2 100644 --- a/src/prep/elaboration-core.k +++ b/src/prep/elaboration-core.k @@ -5,21 +5,22 @@ module ELABORATION-CORE imports ELABORATION-EXPRESSIONS // for isExpressionLabel /*@ -Elaborate the composition of code blocks of a class - the last step of preprocessing. +\begin{markdown} +Elaborate the composition of code blocks of a class --- the last step of preprocessing (besides Folding). During this phase we inspect the contents of method bodies, instance initializers and static initializers of a class and perform the following transformations: \begin{itemize} \item each variable name x is resolved into either: \begin{itemize} - \item x - a local var - \item Class.x - a static var defined in the class Class - \item field(obj, Class, x) - a field of object obj declared in the class Class. + \item x --- a local var + \item Class.x --- a static var defined in the class Class + \item field(obj, Class, x) --- a field of object obj declared in the class Class. Term obj could also be 'This. \end{itemize} \item each method name is resolved into either: \begin{itemize} - \item Class.m - a static method defined in the class Class - \item method(obj, Class, x) - an instance method of object obj declared in the class Class. + \item Class.m --- a static method defined in the class Class + \item method(obj, Class, x) --- an instance method of object obj declared in the class Class. Term obj could also be 'This. The actual version of the method will be looked up at runtime. \end{itemize} \item each method signature is resolved into its appropriate overloaded version. To @@ -28,10 +29,11 @@ static initializers of a class and perform the following transformations: T being the compile-time type of the expression. \end{itemize} - /smallskip - During elaboration, elaborated members will be wrapped into elab(). +\smallskip +During elaboration, elaborated members will be wrapped into elab(). + +During elaboration an expression transition through 6 phases: - During elaboration an expression transition through 6 phases: 1. Elaboration heating: elab('CastRef(\_,, 'Minus('ExprName(x)))) => elab('Minus('ExprName(x)) ~> elab('CastRef(\_,, HOLE) @@ -55,9 +57,9 @@ static initializers of a class and perform the following transformations: compute the type of the current expression itself. When the expression is fully elaborated, it is wrapped into elabRes(). This is the step that requires custom rules for most AST terms. elabRes('Minus(cast(int,cast(int, localVar(X))))) ~> elab('CastRef(\_,, HOLE) - 7. Elaboration cooling. Once the top K Item was wrapped into elabRes, it is ready to be cooled back into its original - context: + 7. Elaboration cooling. Once the top K Item was wrapped into elabRes, it is ready to be cooled back into its original context: elab('CastRef(\_,, elabRes('Minus(cast(int,cast(int, localVar(X))))))) +\end{markdown} */ /*@Custom hole used for custom heating/cooling rules in the elaboration phase.*/ @@ -91,13 +93,17 @@ when ElabRes =/=K noValue rule [chainOfResponsibility-Result2]: noValue ~> (CHOLE ?? K:K) => K -/*@ Computes to true if the given argument is a list of elaboration results, false otherwise. - An elaborated result is either: - - KResult - - elabRes(...) +/*@ +\begin{markdown} +Computes to true if the given argument is a list of elaboration results, false otherwise. +An elaborated result is either: + + - KResult + - elabRes(...) It is notably NOT a cast() expression. This, together with the fact that cast() has no elaboration heatig rules, makes the whole elaboration phase non-reentrant. +\end{markdown} */ syntax KItem ::= isElabKList ( KListWrap ) [function] rule isElabKList([ElabKR:ElabKResult,, Ks:KList]) => isElabKList([Ks]) @@ -155,12 +161,17 @@ defaultElabHeating. The predicate definition is scattered across modules related to elaboration.*/ syntax KItem ::= customElabHeating ( KLabel, KListWrap ) [function] -/*@ The default algorithm of transforming the term from elab to elabRes, when the children were completely elaborated. +/*@ +\begin{markdown} +The default algorithm of transforming the term from elab to elabRes, when the children were completely elaborated. Deletes elabRes wrappers from children. This algorithm is activated when the following conditions apply: - - term is not customElabChildren - - term children are completely elaborated - isElab(children) - - term is not naked. This case should never be true, but there is some weird case that requires it. - When the default algorithm is not appropriate, the respective term should be in the cathegory customElabChildren + + - term is not customElabChildren + - term children are completely elaborated --- isElab(children) + - term is not naked. This case should never be true, but there is some weird case that requires it. + +When the default algorithm is not appropriate, the respective term should be in the cathegory customElabChildren +\end{markdown} */ syntax KItem ::= elabDispose ( K ) @@ -229,9 +240,9 @@ rule [elabEnd-findQualifierOfType-top-level]: rule [elabEnd-findQualifierOfType-static]: findQualifierOfType(noClass, K:K) => noValue -/*@ \subsection{Elaboration of statements - step elabEnd} */ +/*@ \subsection{Elaboration of statements --- step elabEnd} */ -/*@ Applies to all nodes that are not expressins - statements and non-expression auxiliary functions +/*@ Applies to all nodes that are not expressins --- statements and non-expression auxiliary functions */ rule [elabEnd-default-all-except-expressions]: elabEnd(KL:KLabel(Ks:KList)) => elabRes(KL(Ks)) @@ -248,7 +259,7 @@ rule elabEnd( stmtAndExp(Stmt:K, cast(T:Type, Exp:K)) ) #else elabRes(cast(T:Type, Exp:K)) #fi -/*@ \subsection{Elaboration of KListWrap - the list of terms} */ +/*@ \subsection{Elaboration of KListWrap --- the list of terms} */ //K bug: this section is a workaround t a serious K' bug that prevents [...] to be properly heated and cooled rule [elab-heat-KListWrap]: diff --git a/src/prep/elaboration-method-invoke.k b/src/prep/elaboration-method-invoke.k index e74f1c98..37930b07 100644 --- a/src/prep/elaboration-method-invoke.k +++ b/src/prep/elaboration-method-invoke.k @@ -117,7 +117,7 @@ rule isCastOfQThis(cast(_, 'QThis(_))) => true /*@ Lookup the right methodRef() based on supplied parameters. If the method is not found in the supplied class list, we should search for it in the class list corresponding to the enclosing class of the caller class. -First we search for the signature - lookupSignature construct. +First we search for the signature --- lookupSignature construct. Afterwards we cast the actual arguments to the types expected by the found method signature.*/ syntax KItem ::= lookupMethod ( ClassType,//target class, even for arrays. diff --git a/src/prep/elaboration-new-instance.k b/src/prep/elaboration-new-instance.k index 5bb06302..dbc336da 100644 --- a/src/prep/elaboration-new-instance.k +++ b/src/prep/elaboration-new-instance.k @@ -9,7 +9,7 @@ module ELABORATION-NEW-INSTANCE /*@ \subsubsection{Elaboration of 'NewInstance and 'QNewInstance} */ -/*@ elab('NewInstance()) is strict in arguments 2 and 3 - class name and constrctor arguments. +/*@ elab('NewInstance()) is strict in arguments 2 and 3 --- class name and constrctor arguments. Constrctor arguments have to be heated if this class is anonymous. */ rule customElabHeating('NewInstance, [Ks:KList]) => length([Ks]) in (SetItem(2) SetItem(3)) @@ -33,9 +33,13 @@ rule [elab-NewInstance]: EnclosingClass:ClassType CT:ContextType -/*@ elab('QNewInstance()) is strict in all its arguments except the class name (3) and anonymous body(6). +/*@ +\begin{markdown} +elab('QNewInstance()) is strict in all its arguments except the class name (3) and anonymous body(6): + - Argument (3) is heated if it is not a simple name but a precusros to a type - - Argument (6) is heated if it is 'None() - an empty body. + - Argument (6) is heated if it is 'None() --- an empty body. +\end{markdown} */ rule customElabHeating('QNewInstance, [Ks:KList,,KHole:K]) => length([Ks,,KHole]) in (SetItem(1) SetItem(2) SetItem(4) SetItem(5)) @@ -94,7 +98,7 @@ rule [elabEnd-QNewInstance-to-lookupMethod]: ) ~> elabEnd('QNewInstance(Qual:K,, Arg2:K,, Class:ClassType,, Arg4:K,, [Args:KList],, 'None(.KList))) -/*@ All new instance creation expressions are converted into qualified ones - 'QNewInstance, during elaboration phase. +/*@ All new instance creation expressions are converted into qualified ones --- 'QNewInstance, during elaboration phase. For instance inner classes, the qualifier will be a valid expression for the qualifier. For other classes qualifier will be noValue. At this stage 'QNewInstance is wrapped in elabEnd. */ diff --git a/src/prep/elaboration-statements.k b/src/prep/elaboration-statements.k index d88a84d2..b57868d1 100644 --- a/src/prep/elaboration-statements.k +++ b/src/prep/elaboration-statements.k @@ -4,7 +4,7 @@ module ELABORATION-STATEMENTS imports ELABORATION-METHOD-INVOKE //for lookupMethod imports PROCESS-LOCAL-CLASSES //for localClassGetExtraArgs -//@ Elaboration of 'KListWrap, 'Block, 'For or 'Catch - nodes that may contain variable declarations. +//@ Elaboration of 'KListWrap, 'Block, 'For or 'Catch --- nodes that may contain variable declarations. //K bug: support for KListWrap. This rule was replaced by a special section for elaboration of KListWrap. // See other K-bug-s. @@ -19,7 +19,7 @@ rule isVarDecHolderLabel('For) => true rule isVarDecHolderLabel('Catch) => true /*@ In addition to what defaul elab heating does, when we heat the first argument of 'Block, 'For of 'Catch -we need to save a copy of elaboration environment - e.g. the last entry of . +we need to save a copy of elaboration environment, e.g. the last entry of . This is because these statements are blocks that might declare local variables. */ rule [elab-Block-For-Catch-heat-FirstSubterm]: diff --git a/src/prep/elaboration-top-blocks.k b/src/prep/elaboration-top-blocks.k index 73dcb1b5..50f617a8 100644 --- a/src/prep/elaboration-top-blocks.k +++ b/src/prep/elaboration-top-blocks.k @@ -11,7 +11,7 @@ rule [ElaborationPhase-start]: ProcClassMembersPhase => ElaborationPhase /*@ Elaborate the blocks inside all classes. -Argument K = setWrap(Set) - the set of all classes. +Argument K = setWrap(Set) --- the set of all classes. */ syntax KItem ::= elaborateBlocks ( K ) [strict] @@ -37,7 +37,7 @@ rule [elaborateBlocks-discard]: elaborateBlocks(setWrap(.)) => . /*@ Elaborates the methods of the current class. The map contains the methods that were not elaborated yet. -When a class elaboration starts, the map is initialized with the contet of - all the methods accessible in +When a class elaboration starts, the map is initialized with the contet of --- all the methods accessible in the current class. Only methods declared in the current class are elaborated. The rest are discarded from the map. */ syntax KItem ::= elabMethods ( Map ) diff --git a/src/prep/process-anonymous-classes.k b/src/prep/process-anonymous-classes.k index fd3c2e6d..24266809 100644 --- a/src/prep/process-anonymous-classes.k +++ b/src/prep/process-anonymous-classes.k @@ -116,11 +116,15 @@ rule [processAnonymousClass]: ) ) -/*@ Build the part of the constructor of an anonymous class definition corresponding +/*@ +\begin{markdown} +Build the part of the constructor of an anonymous class definition corresponding to formal params, and arguments of the superclass constructor invocation, respectively -First KList - list of actual arguments -Second KList - the result -Third arg - a counter used to generate var names + + - First KList --- list of actual arguments + - Second KList --- the result + - Third arg --- a counter used to generate var names +\end{markdown} */ syntax KItem ::= buildConstructorFormalParams ( KListWrap, KListWrap, Int ) | buildConstructorFirstLineArgs ( KListWrap, KListWrap, Int ) diff --git a/src/prep/process-class-decs.k b/src/prep/process-class-decs.k index 158d7c6c..7e9d61ca 100644 --- a/src/prep/process-class-decs.k +++ b/src/prep/process-class-decs.k @@ -3,7 +3,7 @@ module PROCESS-CLASS-DECS imports CORE-PREPROCESSING imports PROCESS-TYPE-NAMES -/*@ \subsection{Third pass - processing class dependencies and imports} */ +/*@ \subsection{Third pass --- processing class dependencies and imports} */ rule [ProcClassDecsPhase-start]: . => processClassDecs(getTopLevelClasses) @@ -186,11 +186,15 @@ rule [saveImports-InheritTypes]: rule [saveImports-Discard-noClass]: saveImports(_,_, [(noClass => .KList),, _], _,_,_) -/*@ Compute the final result - the combined accessible classes map, with this components in order: +/*@ +\begin{markdown} +Compute the final result --- the combined accessible classes map, with this components in order: + - external names - local block names (for local classes only) - inherited names - inner names +\end{markdown} */ rule [saveImports-ComputeResult]: diff --git a/src/prep/process-class-members.k b/src/prep/process-class-members.k index 31241a1e..8482e2d3 100644 --- a/src/prep/process-class-members.k +++ b/src/prep/process-class-members.k @@ -3,7 +3,7 @@ module PROCESS-CLASS-MEMBERS imports CORE-CLASSES imports CORE-PREPROCESSING -/*@ \subsection{Third pass - processing class members} */ +/*@ \subsection{Third pass --- processing class members} */ /*@ We need to process Object first. Thus when we will process any interfaces, Object class will already be processed.*/ @@ -48,23 +48,27 @@ rule [processTypeWithDepends-Discard]: rule [processTypeWithDepends-Discard2]: processTypeWithDepends(noClass) => .K -syntax KItem ::= processType ( - ClassType //the class to be processed - ) +/*@ +\begin{markdown} +For each class computes the set of inherited interfaces, inherits all the members, +processes inner declarations. Computes the following class cells: -/*@ For each class compute the set of inherited interfaces, inherit all the members, -process inner declarations. Compute the following class cells: - - - - - - temporary cell, deleted after class body is processed. - - + - + - + - + - + - --- temporary cell, deleted after class body is processed. + - + - First we inherit methods from interfaces, then from the base class, and in the end we add methods declared in this class. Each new method overwrites previous methods with the same signature. +\end{markdown} */ +syntax KItem ::= processType ( + ClassType //the class to be processed + ) + rule [processType]: processType(Class:ClassType) => computeImplTrans(SetItem(BaseClass) ISet) @@ -102,7 +106,7 @@ rule [processType-discard]: Class MembersProcessedCPhase -//@ Compute cell - interfaces transitively implemented +//@ Compute cell --- interfaces transitively implemented syntax KItem ::= computeImplTrans ( Set ) rule [computeImplTrans]: diff --git a/src/prep/process-comp-units.k b/src/prep/process-comp-units.k index 2f1ece8a..f7cdca4b 100644 --- a/src/prep/process-comp-units.k +++ b/src/prep/process-comp-units.k @@ -5,11 +5,14 @@ module PROCESS-COMP-UNITS imports PROCESS-IMPORTS //for compUnitImportsStart() /*@ +\begin{markdown} ProcCompUnitsPhase: - For each CompUnit separately: + For each Compilation unit separately: + 1. Process import declarations. Build . For each class C in CompUnit separately: + 2. For each class save the cell with just the following: - - since we process CU content recursively, should be available - @@ -22,9 +25,10 @@ ProcCompUnitsPhase: This way we will have fast access to the declaration of a class, and will be able to process declarations in a less-restricted order. +\end{markdown} */ -/*@ \subsection{Second pass - processing declarations} */ +/*@ \subsection{Second pass --- processing declarations} */ rule [ProcCompUnitsPhase-start]: . => Program @@ -70,7 +74,8 @@ rule [processTypeDecsInPCUPhase-typeDec-ComputeFullName]: Pack:PackageId, _ ) [structural] -/* +/*@ +\begin{verbatim} 'ClassDec( 'ClassDecHead( [Modifiers],, @@ -79,8 +84,9 @@ rule [processTypeDecsInPCUPhase-typeDec-ComputeFullName]: 'Some('SuperDec( BaseClassRaw - extends declaration )),, 'Some('ImplementsDec([ ImplTypesRaw - implements declarations ])) ),, - 'ClassBody( [ Decls - member declarations ] ) + 'ClassBody( [ Decls --- member declarations ] ) ) +\end{verbatim} */ rule [ClassDec-NoExtendsDesugar]: diff --git a/src/prep/process-local-classes.k b/src/prep/process-local-classes.k index 6a138737..a82325da 100644 --- a/src/prep/process-local-classes.k +++ b/src/prep/process-local-classes.k @@ -132,9 +132,13 @@ when rule [localClassGetAccessibleOuterEnv-end]: localClassGetAccessibleOuterEnv( Class:ClassType, .Map, NewOuterEnv:Map, _, noValue ) => mapWrap(NewOuterEnv) -/*@ Convert the given local class into an equivalent inner class, with the following transformations: +/*@ +\begin{markdown} +Convert the given local class into an equivalent inner class, with the following transformations: + - Add a field to the class for each outer local variable - For each constructor add an argument for each outer local variable +\end{markdown} */ syntax KItem ::= localClassTransformIntoInner ( ClassType, //the local class @@ -155,7 +159,7 @@ rule [localClassTransformIntoInner]: #fi /*@ Same as localClassTransformIntoInner but AccessibleLocalEnv has one more entry - - the field LocaClass@LocalEnv\_obj that will be created later, a self reference required when a local class + --- the field LocaClass@LocalEnv\_obj that will be created later, a self reference required when a local class instantiates either itself or an enclosing local class. See tests 957, 958. */ syntax KItem ::= localClassTransformIntoInnerImpl ( @@ -326,7 +330,7 @@ rule [loadElabBuffer]: syntax KItem ::= localClassGetExtraArgs( ClassType ) /*@ When is not empty (only possible for certain local classes), - we add one more argument to the consturctor call - the local environment object. */ + we add one more argument to the consturctor call --- the local environment object. */ rule [elab-QNewInstance-local-augment-arguments]: localClassGetExtraArgs(Class:ClassType) diff --git a/src/prep/process-type-names.k b/src/prep/process-type-names.k index 0a5528c6..0ead2baa 100644 --- a/src/prep/process-type-names.k +++ b/src/prep/process-type-names.k @@ -72,9 +72,14 @@ rule [processTypeNames-AddPackage]: PackMap:Map => PackMap[mapWrap(.Map) / PackId] when notBool PackId in keys(PackMap) -/*@ A type name is either class or interface name. Anonymous labels will be one of: - - 'ClassDec('ClassDecHead(...)) - - 'InterfaceDec('InterfaceDecHead(...))*/ +/*@ +\begin{markdown} +A type name is either class or interface name. Anonymous labels will be one of: + + - 'ClassDec('ClassDecHead(...)) + - 'InterfaceDec('InterfaceDecHead(...)) +\end{markdown} +*/ rule [processTypeNames]: processTypeNames( From d9125dafd496b8b1c964cfda5b3cba7204b1f641 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Wed, 18 Feb 2015 20:23:37 +0200 Subject: [PATCH 02/43] Doc: Punctuation review. Wrap cell references, like into verb. --- .gitignore | 1 + src/common/core-classes.k | 2 +- src/common/core-sorts.k | 2 +- src/exec/api-core.k | 4 ++-- src/exec/api-threads.k | 8 ++++---- src/exec/arrays.k | 2 +- src/exec/core-exec.k | 2 +- src/exec/unfolding.k | 4 ++-- src/prep/core-preprocessing.k | 4 ++-- src/prep/elaboration-core.k | 4 ++-- src/prep/elaboration-statements.k | 4 ++-- src/prep/elaboration-top-blocks.k | 4 ++-- src/prep/folding.k | 2 +- src/prep/process-class-decs.k | 6 +++--- src/prep/process-class-members.k | 20 ++++++++++---------- src/prep/process-comp-units.k | 16 +++++++++------- src/prep/process-imports.k | 2 +- src/prep/process-local-classes.k | 4 ++-- src/prep/process-type-names.k | 6 +++--- 19 files changed, 50 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index ab6482c7..6c6405e5 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ /src/.latex /src/.modules /src/sty/.project +/src/sty/.texlipse /src/sty/*.pdf /src/sty/*.synctex /src/sty/.latex diff --git a/src/common/core-classes.k b/src/common/core-classes.k index f3ffc204..fb31c62d 100644 --- a/src/common/core-classes.k +++ b/src/common/core-classes.k @@ -77,7 +77,7 @@ rule [getTopLevel]: Class noClass -//@ Restore the content of with the given class +//@ Restore the content of \verb|| with the given class syntax KItem ::= restoreCrntClass ( ClassType //old content of ) diff --git a/src/common/core-sorts.k b/src/common/core-sorts.k index a7c83f08..6808b19d 100644 --- a/src/common/core-sorts.k +++ b/src/common/core-sorts.k @@ -123,7 +123,7 @@ The object closure has the following structure: \begin{verbatim} ListItem(layer( Class, - Env, + \verb||Env, enclosingObjClosure::T )) ... diff --git a/src/exec/api-core.k b/src/exec/api-core.k index cc25ad20..56072ce1 100644 --- a/src/exec/api-core.k +++ b/src/exec/api-core.k @@ -259,7 +259,7 @@ rule [storeCopy-discard]: //@\subsection{Class literal --- .class} /*@ We need to synchronize access to class literals to avoid instantiation of the came .class by multiple threads. - This is done by the term temp in . We cannot use 'Synchronized because it required an + This is done by the term temp in \verb||. We cannot use 'Synchronized because it required an objectRef as argument, and we might not have any objects instantiated at the moment. */ rule [Lit-Class-Instantiate]: @@ -287,7 +287,7 @@ rule [Lit-Class]: 'Lit('Class(T:Type)) => TV ... ... T |-> TV:TypedVal ... -//@Used inside only for synchronization purposes +//@Used inside \verb|| only for synchronization purposes syntax KItem ::= "temp" endmodule diff --git a/src/exec/api-threads.k b/src/exec/api-threads.k index b23077fd..523790ee 100644 --- a/src/exec/api-threads.k +++ b/src/exec/api-threads.k @@ -138,8 +138,8 @@ when ) andBool notBool OL in keys(Holds) -/*@Second part of a wait. Waiting was already registered to . -When the record in will be deleted, waiting itself shall end. +/*@Second part of a wait. Waiting was already registered to \verb||. +When the record in \verb|| will be deleted, waiting itself shall end. */ syntax KItem ::= waitImpl ( Int //Monitor object location @@ -272,8 +272,8 @@ rule [ThreadTermination]: //@ \subsection{Debug aids} -/*@ Dissolve all cells except for the purpose of model checking. We will avoid duplicates caused by the same - but different order of content in other cells.*/ +/*@ Dissolve all cells except \verb|| for the purpose of model checking. We will avoid duplicates caused by the same + \verb|| but different order of content in other cells.*/ rule [DissolveAllExceptOut]: Out:List diff --git a/src/exec/arrays.k b/src/exec/arrays.k index 6cdb7628..2139bbcd 100644 --- a/src/exec/arrays.k +++ b/src/exec/arrays.k @@ -121,7 +121,7 @@ rule [allocAndInitArray-MultiDim-desugar]: [structural] -/*@ The increment of by one is required to avoid problems with empty arrays. +/*@ The increment of \verb|| by one is required to avoid problems with empty arrays. Two empty arrays allocated one after another should have different starting locations, even if those starting locations are not used. This is required to identify them as two different objects. Their distinction could be tested by the operator ==. diff --git a/src/exec/core-exec.k b/src/exec/core-exec.k index e7b7bea7..31f07181 100644 --- a/src/exec/core-exec.k +++ b/src/exec/core-exec.k @@ -10,7 +10,7 @@ syntax KItem ::= sl ( //@ \subsection{Auxiliary methods} -//@ Restore the content of the cell +//@ Restore the content of the cell \verb|| syntax KItem ::= restoreMethContext ( Bag //The content of ) diff --git a/src/exec/unfolding.k b/src/exec/unfolding.k index 3f55b0bd..1ae468af 100644 --- a/src/exec/unfolding.k +++ b/src/exec/unfolding.k @@ -3,12 +3,12 @@ module UNFOLDING imports CORE-FUNCTIONS imports SYNTAX-CONVERSIONS -/*@At the beginning of execution semantics contains the term unfoldingPhase, is non-empty and the global phase is UnfoldingPhase. +/*@At the beginning of execution semantics \verb|| contains the term unfoldingPhase, \verb|| is non-empty and the global phase is UnfoldingPhase. */ syntax KItem ::= "unfoldingPhase" -//@In the initial configuration the cell is empty, global phase is UnfoldingPhase, is non-empty. +//@In the initial configuration the cell \verb|| is empty, global phase is UnfoldingPhase, \verb|| is non-empty. rule [UnfoldingPhase-start]: . => unfoldingPhase ... diff --git a/src/prep/core-preprocessing.k b/src/prep/core-preprocessing.k index a7af1cbc..5890686d 100644 --- a/src/prep/core-preprocessing.k +++ b/src/prep/core-preprocessing.k @@ -7,7 +7,7 @@ module CORE-PREPROCESSING //@ \subsection{Auxiliary constructs for retrieving a set of classes} /*@ Returns a setWrap(Set[ClassType]), containing all top level classes in the program. - Uses to compute the result. Used by the starting rule of several preprocessing phases. + Uses \verb|| to compute the result. Used by the starting rule of several preprocessing phases. */ syntax KItem ::= "getTopLevelClasses" | getTopLevelClasses ( Map, Set ) @@ -36,7 +36,7 @@ rule getTopLevelClasses(_ (_ |-> mapWrap(.Map) => .Map), _) rule getTopLevelClasses(.Map, ClassesSet:Set) => setWrap(ClassesSet) /*@ Returns a setWrap(Set[ClassType]), containing all direct inner classes of the given class. - Uses to compute the result. + Uses \verb|| to compute the result. */ syntax KItem ::= getInnerClasses ( ClassType ) | getInnerClasses ( Map, Set ) diff --git a/src/prep/elaboration-core.k b/src/prep/elaboration-core.k index d71927a2..3d278f2f 100644 --- a/src/prep/elaboration-core.k +++ b/src/prep/elaboration-core.k @@ -112,13 +112,13 @@ rule isElabKList([.KList]) => true //@ Elaborate parameter type, if not elaborated yet. For catch clause. context elab('Param(_:K,, HOLE,, _:Id)) -/*@Adds params to the . Used in both ELABORATION-TOP-BLOCKS and ELABORATION-BLOCKS +/*@Adds params to the \verb||. Used in both ELABORATION-TOP-BLOCKS and ELABORATION-BLOCKS */ rule [elab-Param]: elab('Param(K1:K,, T:Type,, X:Id)) => elabRes('Param(K1:K,, T:Type,, X:Id)) ... ListItem(mapWrap((. => X |-> T) _)) ... -//@Removes the last layer from +//@Removes the last layer from \verb|| syntax KItem ::= "removeLastElabEnv" rule [removeLastElabEnv]: removeLastElabEnv => . ... diff --git a/src/prep/elaboration-statements.k b/src/prep/elaboration-statements.k index b57868d1..94aae278 100644 --- a/src/prep/elaboration-statements.k +++ b/src/prep/elaboration-statements.k @@ -19,7 +19,7 @@ rule isVarDecHolderLabel('For) => true rule isVarDecHolderLabel('Catch) => true /*@ In addition to what defaul elab heating does, when we heat the first argument of 'Block, 'For of 'Catch -we need to save a copy of elaboration environment, e.g. the last entry of . +we need to save a copy of elaboration environment, e.g. the last entry of \verb|| \verb||. This is because these statements are blocks that might declare local variables. */ rule [elab-Block-For-Catch-heat-FirstSubterm]: @@ -49,7 +49,7 @@ rule [elab-LocalVarDecStm-desugar]: => 'LocalVarDec(Ks) ) [structural] -//@ Resolve the local var type, required to register the var in +//@ Resolve the local var type, required to register the var in \verb|| context elab('LocalVarDec(_:K,, HOLE,, _:K)) rule [elab-LocalVarDec-multi-desugar]: diff --git a/src/prep/elaboration-top-blocks.k b/src/prep/elaboration-top-blocks.k index 50f617a8..a9769708 100644 --- a/src/prep/elaboration-top-blocks.k +++ b/src/prep/elaboration-top-blocks.k @@ -37,7 +37,7 @@ rule [elaborateBlocks-discard]: elaborateBlocks(setWrap(.)) => . /*@ Elaborates the methods of the current class. The map contains the methods that were not elaborated yet. -When a class elaboration starts, the map is initialized with the contet of --- all the methods accessible in +When a class elaboration starts, the map is initialized with the contet of \verb|| --- all the methods accessible in the current class. Only methods declared in the current class are elaborated. The rest are discarded from the map. */ syntax KItem ::= elabMethods ( Map ) @@ -128,7 +128,7 @@ rule [elabStaticInit-End]: Class CHOLE => K -//@Adds a new empty layer to +//@Adds a new empty layer to \verb|| syntax KItem ::= "addElabEnv" rule [addElabEnv]: addElabEnv => . ... diff --git a/src/prep/folding.k b/src/prep/folding.k index e5a75d13..f45269a5 100644 --- a/src/prep/folding.k +++ b/src/prep/folding.k @@ -7,7 +7,7 @@ rule [FoldingPhase-start]: ElaborationPhase => FoldingPhase (.Bag => [.KList] ) -/*@ The sole content of cell during FoldingPhase +/*@ The sole content of \verb|| cell during FoldingPhase */ syntax KItem ::= "foldingPhase" diff --git a/src/prep/process-class-decs.k b/src/prep/process-class-decs.k index 7e9d61ca..05ab4aee 100644 --- a/src/prep/process-class-decs.k +++ b/src/prep/process-class-decs.k @@ -127,7 +127,7 @@ syntax KItem ::= kListToSet ( KListWrap, //a list of some K Terms rule kListToSet([(K:K => .KList),,_], (_ (.Set => SetItem(K) ))) rule kListToSet([.KList], TypeSet:Set) => setWrap(TypeSet) -//@ Receives a kListToSet term ans saves the resulting set into +//@ Receives a kListToSet term ans saves the resulting set into \verb|| syntax KItem ::= saveImplements ( ClassType, K ) [strict(2)] rule [saveImplements]: @@ -137,7 +137,7 @@ rule [saveImplements]: /*@ Computes the full names map used to resolve classes by simple name inside the class specified by the arg 4, - and stores them inside .*/ + and stores them inside \verb||.*/ syntax KItem ::= saveImports ( ClassType, //Class - the actual class ClassType, //The outer class of this class, if any, @@ -214,7 +214,7 @@ rule [saveImports-ComputeResult]: BaseClass:ClassType BaseClassMap:Map -//@ Save the computed Imports map into the cell of the given class +//@ Save the computed Imports map into the \verb|| cell of the given class rule [saveImports-end]: saveImports(Class:ClassType, _,_,_,_, mapWrap(Imports:Map)) => . diff --git a/src/prep/process-class-members.k b/src/prep/process-class-members.k index 8482e2d3..e4e588af 100644 --- a/src/prep/process-class-members.k +++ b/src/prep/process-class-members.k @@ -53,13 +53,13 @@ rule [processTypeWithDepends-Discard2]: For each class computes the set of inherited interfaces, inherits all the members, processes inner declarations. Computes the following class cells: - - - - - - - - - - --- temporary cell, deleted after class body is processed. - - - - + - \verb|| + - \verb|| + - \verb|| + - \verb|| + - \verb|| --- temporary cell, deleted after class body is processed. + - \verb|| + - \verb|| First we inherit methods from interfaces, then from the base class, and in the end we add methods declared in this class. Each new method overwrites previous methods with the same signature. @@ -106,7 +106,7 @@ rule [processType-discard]: Class MembersProcessedCPhase -//@ Compute cell --- interfaces transitively implemented +//@ Compute \verb|| cell --- interfaces transitively implemented syntax KItem ::= computeImplTrans ( Set ) rule [computeImplTrans]: @@ -198,7 +198,7 @@ rule isOverridden(BaseC:ClassType, package, SubC:ClassType) rule isOverridden(_, private, _) => false /*@ Inherit a method by the current class. The inherited method overwrites previous methods - with the same signature in + with the same signature in \verb|| */ syntax KItem ::= inherit ( MethodRef ) @@ -485,7 +485,7 @@ when andBool isFinalModifiers(Modifiers) /*@ Discard inner class declarations at this phase. They are processed when their - respective tag is encountered as part of processClasses. + respective \verb|| tag is encountered as part of processClasses. */ rule [ClassDec-discard]: 'ClassDec(_) => . rule [InterfaceDec-discard]: 'InterfaceDec(_) => . diff --git a/src/prep/process-comp-units.k b/src/prep/process-comp-units.k index f7cdca4b..7414d431 100644 --- a/src/prep/process-comp-units.k +++ b/src/prep/process-comp-units.k @@ -9,16 +9,16 @@ module PROCESS-COMP-UNITS ProcCompUnitsPhase: For each Compilation unit separately: -1. Process import declarations. Build . +1. Process import declarations. Build \verb||. For each class C in CompUnit separately: -2. For each class save the cell with just the following: - - - since we process CU content recursively, should be available - - - - - just for top-level classes, imports are taken from the . +2. For each class save the \verb|| cell with just the following: + - \verb|| --- since we process CU content recursively, should be available + - \verb|| + - \verb|| --- just for top-level classes, imports are taken from the \verb||. For inner classes this cell is still empty. - - - content of its 'ClassDec term. When this term is non-empty + - \verb|| --- content of its 'ClassDec term. When this term is non-empty then the class has not been preprocessed yet. 3. Process inner classes of C. @@ -75,6 +75,8 @@ rule [processTypeDecsInPCUPhase-typeDec-ComputeFullName]: ) [structural] /*@ +Structure of 'ClassDec: + \begin{verbatim} 'ClassDec( 'ClassDecHead( @@ -186,7 +188,7 @@ rule [processTypeDecsInPCUPhase-IInterfaceDec]: _ => [Decls] _ => staticCT -/*@ If the given type is top-level, then save from the cell. +/*@ If the given type is top-level, then save \verb|| from the \verb|| cell. Otherwise do nothing.*/ syntax KItem ::= saveImportsInPCUPhase ( K //is processed into TypeName diff --git a/src/prep/process-imports.k b/src/prep/process-imports.k index cfd64418..283f759e 100644 --- a/src/prep/process-imports.k +++ b/src/prep/process-imports.k @@ -35,7 +35,7 @@ rule [TypeImportOnDemandDec]: ... Pack |-> mapWrap(PackMap:Map) ... Imp:Map -//@ Imports to cell public classes from the given map. Classes with package access are ignored. +//@ Imports to \verb|| cell public classes from the given map. Classes with package access are ignored. syntax KItem ::= importOnDemandImpl ( Map //Map[X |-> Class] - classes to consider for importing. ) diff --git a/src/prep/process-local-classes.k b/src/prep/process-local-classes.k index a82325da..bbf3ee53 100644 --- a/src/prep/process-local-classes.k +++ b/src/prep/process-local-classes.k @@ -311,7 +311,7 @@ rule haveUnaugmentedConstructors(ConsName:Id, LocalEnvClass:ClassType, when notBool getLastKListElement([TList]) ==K LocalEnvClass -//@ Elaborates the given node and saves it to +//@ Elaborates the given node and saves it to \verb|| syntax KItem ::= appendToElabBuffer ( K ) //[strict, context(result(ElabKResult))] //K bug generalized strictness context appendToElabBuffer ( HOLE ) [result(ElabKResult)] @@ -329,7 +329,7 @@ rule [loadElabBuffer]: syntax KItem ::= localClassGetExtraArgs( ClassType ) -/*@ When is not empty (only possible for certain local classes), +/*@ When \verb|| is not empty (only possible for certain local classes), we add one more argument to the consturctor call --- the local environment object. */ rule [elab-QNewInstance-local-augment-arguments]: diff --git a/src/prep/process-type-names.k b/src/prep/process-type-names.k index 0ead2baa..dedebe1d 100644 --- a/src/prep/process-type-names.k +++ b/src/prep/process-type-names.k @@ -7,9 +7,9 @@ module PROCESS-TYPE-NAMES /*@ First pass - collecting globally accessible names in the program. This includes packages, top-level classes and inner classes. In each compilation unit just class declarations -(both global and inner) are processed. Results are stored in the cell . +(both global and inner) are processed. Results are stored in the cell \verb||. -The initial configuration contains the initial program in cells and , and global phase is ProcTypeNamesPhase. +The initial configuration contains the initial program in cells \verb|| and \verb||, and global phase is ProcTypeNamesPhase. */ /*@ \subsection{Compilation units}*/ @@ -109,7 +109,7 @@ rule [processTypeNames-ElemDiscard]: processTypeNames([(Label:KLabel(_) => .KList),, _], _) when notBool( (Label ==KLabel 'ClassDec) orBool (Label ==KLabel 'InterfaceDec) ) -//We match PackId in just to be sure that the package was added to the map. +//@We match PackId in \verb|| just to be sure that the package was added to the map. rule [processTypeNames-Discard]: processTypeNames([.KList], PackId:PackageId) => .K ... ... PackId |-> _ ... From a311ee71cf765bca730a8daa33e3588d29f7c2b5 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Wed, 18 Feb 2015 21:17:20 +0200 Subject: [PATCH 03/43] =?UTF-8?q?Doc:=20Punctuation=20review.=20Wrap=20met?= =?UTF-8?q?hod=20calls=20and=20smaller=20AST=20fragments=20inside=20doc=20?= =?UTF-8?q?into=20\verb|=E2=80=94|.=20Not=20all,=20just=20simpler=20AST=20?= =?UTF-8?q?forms=20captured.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/core-functions.k | 10 ++-- src/exec/api-core.k | 22 +++---- src/exec/api-threads.k | 16 +++--- src/exec/method-invoke.k | 86 ++++++++++++++-------------- src/exec/new-instance.k | 14 ++--- src/exec/statements.k | 2 +- src/exec/syntax-conversions.k | 2 +- src/exec/to-string.k | 2 +- src/exec/unfolding.k | 2 +- src/exec/var-lookup.k | 16 +++--- src/prep/core-preprocessing.k | 4 +- src/prep/elaboration-categories.k | 6 +- src/prep/elaboration-core.k | 50 ++++++++-------- src/prep/elaboration-expressions.k | 2 +- src/prep/elaboration-method-invoke.k | 2 +- src/prep/elaboration-top-blocks.k | 2 +- src/prep/process-class-decs.k | 2 +- 17 files changed, 119 insertions(+), 121 deletions(-) diff --git a/src/common/core-functions.k b/src/common/core-functions.k index 31b62efd..b37882a3 100644 --- a/src/common/core-functions.k +++ b/src/common/core-functions.k @@ -14,10 +14,10 @@ rule typeOf(null) => nullType rule typeOf(objectRef(_, Class:ClassType)) => Class rule typeOf(arrayRef( arrayOf T:Type, _, _)) => arrayOf T -/* Required by getTypes in elaboration phase, invoked by lookupMethod. */ +/*@ Required by \verb|getTypes()| in elaboration phase, invoked by \verb|lookupMethod()|. */ rule typeOf(cast(T:Type, _)) => T -// Required for getTypes() +//@ Required for \verb|getTypes()| rule typeOf('Param(_:K,, T:Type,, _:Id)) => T /*@The default value for all types. Used for field initializers.*/ @@ -90,7 +90,7 @@ rule plusAux(Str1:String :: _, Str2:String :: _) => (Str1 +String Str2) :: class */ syntax KResult ::= mapWrap ( Map ) -/*@ The union of two maps. Arguments are of the form mapWrap(Map). In this operation, elements of the second map +/*@ The union of two maps. Arguments are of the form \verb|mapWrap(Map)|. In this operation, elements of the second map overwrite elements of the first map if they collide. */ syntax KItem ::= mapUnion ( @@ -123,7 +123,7 @@ rule isEmpty(.Map) => true /*@A wrapper for sets, similar to the one for maps.*/ syntax KResult ::= setWrap ( Set ) -/*The union of two sets. Arguments are of the form setWrap(Set).*/ +/*@ The union of two sets. Arguments are of the form \verb|setWrap(Set)|.*/ syntax KItem ::= setUnion ( K, //setWrap(Set) K //setWrap(Set) @@ -166,8 +166,6 @@ rule getSimpleName(class ClassId:Id) /*@ \subsection{Identifiers}*/ -// 'Id(Str:String) - /*@Convert the AST representation of an Id into a K Id.*/ rule 'Id(Str:String) => String2Id(Str) [structural, anywhere] diff --git a/src/exec/api-core.k b/src/exec/api-core.k index 56072ce1..30d21082 100644 --- a/src/exec/api-core.k +++ b/src/exec/api-core.k @@ -4,7 +4,7 @@ module API-CORE imports ARRAYS // for allocAndInitArray() /*@ -All the methods defined in this module through invokeImpl are native, their body is 'NoMethodBody(\_), thus +All the methods defined in this module through invokeImpl are native, their body is \verb|'NoMethodBody(\_)|, thus they cannot be matched by rules in METHOD-INVOKE. */ @@ -20,7 +20,7 @@ context when Class ==K class String2Id("java.io.PrintWriter") andBool Id2String(MethodName) ==String "print" -//@ System.out.print(). For integers and strings, print their value. For classes, print class type. +//@ System.\verb|out.print()|. For integers and strings, print their value. For classes, print class type. rule [system-out-print-string]: @@ -49,7 +49,7 @@ when andBool (Id2String(MethodName) ==String "print") andBool notBool (isString(RV) ==K true) -/*@Scanner.nextInt(), used to read from the console.*/ +/*@\verb|Scanner.nextInt()|, used to read from the console.*/ rule [scanner-nextInt]: invokeImpl( methodRef(sig(MethodName:Id, _), Class:ClassType), _, @@ -78,7 +78,7 @@ rule [readString]: readString => Str :: classString ... ListItem(Str:String) => . ... -/*@ object.getClass()*/ +/*@ \verb|object.getClass()|*/ rule [object-getClass-on-object]: invokeImpl( @@ -113,7 +113,7 @@ rule [object-getClass-on-array]: when Class ==K classObject andBool Id2String(MethodName) ==String "getClass" -/*@ String.toString(). For Object.toString() the implementation is in the library java code.*/ +/*@ \verb|String.toString()|. For \verb|Object.toString()| the implementation is in the library java code.*/ rule [object-toString-on-String]: invokeImpl( methodRef(sig(MethodName:Id, _), Class:ClassType), Str:String::_, @@ -122,7 +122,7 @@ rule [object-toString-on-String]: when Class ==K classObject andBool Id2String(MethodName) ==String "toString" -/*@Object.hashCode(). Returns the canonical memory location of the objectRef. */ +/*@\verb|Object.hashCode()|. Returns the canonical memory location of the objectRef. */ rule [object-hashCode]: invokeImpl( @@ -141,7 +141,7 @@ when //@\subsection{String methods} -//@ int String.length() +//@ int \verb|String.length()| rule [String-length]: invokeImpl( methodRef(sig(MethodName:Id, _), Class:ClassType), @@ -162,7 +162,7 @@ rule [String-charAt]: when Class ==K classString andBool Id2String(MethodName) ==String "charAt" -//@static native String String.valueOf(int i); +//@static native String \verb|String.valueOf(int i)|; rule [String-valueOf]: invokeImpl( methodRef(sig(MethodName:Id, _), Class:ClassType), @@ -173,7 +173,7 @@ rule [String-valueOf]: when Class ==K classString andBool Id2String(MethodName) ==String "valueOf" -//@boolean String.equals(Object) +//@boolean \verb|String.equals(Object)| rule [String-equals]: invokeImpl( methodRef(sig(MethodName:Id, _), Class:ClassType), @@ -184,7 +184,7 @@ rule [String-equals]: when Class ==K classString andBool Id2String(MethodName) ==String "equals" -//@String.toString() +//@\verb|String.toString()| rule [String-toString]: invokeImpl( methodRef(sig(MethodName:Id, _), Class:ClassType), @@ -195,7 +195,7 @@ rule [String-toString]: when Class ==K classString andBool Id2String(MethodName) ==String "toString" -//@ int String.compareTo(Object another) +//@ int \verb|String.compareTo(Object another)| rule [String-compareTo]: invokeImpl( methodRef(sig(MethodName:Id, _), Class:ClassType), diff --git a/src/exec/api-threads.k b/src/exec/api-threads.k index 523790ee..628eff1a 100644 --- a/src/exec/api-threads.k +++ b/src/exec/api-threads.k @@ -6,7 +6,7 @@ module API-THREADS /*@Java API related to threads and locks. Just the core part.*/ -//@ \subsection{Method Thread.start()} +//@ \subsection{Method \texttt{Thread.start()}} rule [thread-start]: @@ -90,7 +90,7 @@ rule [monitor-completely-released]: ... (OL:Int |-> 0 => .) ... ... (SetItem(OL) => .) ... -//@ \subsection{Thread.join()} +//@ \subsection{\texttt{Thread.join()}} rule [thread-join]: @@ -120,7 +120,7 @@ when Class ==K class String2Id("java.lang.Thread") andBool Id2String(MethodName) ==String "joinImpl" [transition-threading, transition-sync] -//@ \subsection{Object.wait()} +//@ \subsection{\texttt{Object.wait()}} rule [object-wait-notify-notifyAll-without-sync]: @@ -157,9 +157,9 @@ when notBool OL in Busy [transition-threading, transition-sync] -//@ \subsection{Object.notify(), Object.notifyAll()} +//@ \subsection{\texttt{Object.notify()}, \texttt{Object.notifyAll()}} -/*@Implementation of Object.notify(), extracted here to avoid rule superfluousness*/ +/*@Implementation of \verb|Object.notify()|, extracted here to avoid rule superfluousness*/ syntax KItem ::= notifyImpl ( Int //store key of the monitor object ) @@ -194,7 +194,7 @@ when andBool Id2String(MethodName) ==String "notifyAll" andBool HoldLevel >=Int 1 -/*@Implementation of Object.notifyAll(), extracted here to avoid rule superfluousness*/ +/*@Implementation of \verb|Object.notifyAll()|, extracted here to avoid rule superfluousness*/ syntax KItem ::= objectNotifyAllImpl ( Int //store key of the monitor object ) @@ -217,7 +217,7 @@ when notBool OL in values(WT) [transition-threading] -//@ \subsection{Thread.interrupt()} +//@ \subsection{\texttt{Thread.interrupt()}} rule [thread-interrupt]: @@ -289,7 +289,7 @@ endmodule module API-THREADS-SELECTION imports API-THREADS -//@ \subsection{Methods wait() and notify()} +//@ \subsection{Methods \texttt{wait()} and \texttt{notify()}} /*@ When \verb|object.wait()| is called the method call expression is replaced by \verb|waitImpl()| diff --git a/src/exec/method-invoke.k b/src/exec/method-invoke.k index ff009830..ca63e42a 100644 --- a/src/exec/method-invoke.k +++ b/src/exec/method-invoke.k @@ -107,7 +107,7 @@ The first represents a class. Second is a typed value, the result of evaluation \end{syntaxBlock} The type after four dots (::) separator is the static type associated with that value. The values inside - objectRef() are the address inside the store and the runtime type of the object. + \verb|objectRef()| are the address inside the store and the runtime type of the object. For the sake of simplicity we we will also consider \dotCt{K} --- the unit element of K to be KResult. The value \dotCt{K} is often @@ -118,18 +118,18 @@ For the sake of simplicity we we will also \begin{markdown} An elaborated method invocation expression may have one of the following forms: - - An invocation of a static method qualified by its class: Class.f(args) + - An invocation of a static method qualified by its class: \verb|Class.f(args)| - An invocation of a static method qualified by an expression producing an object: - o.f(args). Even if the method is + \verb|o.f(args)|. Even if the method is static we cannot simply replace the qualifier with its compile-time type at elaboration phase, because the qualifier expression still has to be evaluated and might produce side effects. We cannot replace it with - o; class.f(args); either, because o; might be invalid. Not all expressions + o; \verb|class.f(args)|; either, because o; might be invalid. Not all expressions valid as qualifiers are valid as expression statements (JLS \S14.8). We wanted the elaboration result to be a valid Java program, thus we could not afford such a transformation. - - An invocation of an instance method qualified by a class reference: o.f(args) - - An invocation of an instance method qualified by an interface reference: i.f(args) + - An invocation of an instance method qualified by a class reference: \verb|o.f(args)| + - An invocation of an instance method qualified by an interface reference: \verb|i.f(args)| The evaluation of the method invocation expression consists from 5 steps outlined below. Those steps, unless otherwise specified, are common to all the method call forms @@ -209,8 +209,8 @@ Note that arguments have to be evaluated even in the case when the qualifier eva \begin{markdown} During the second step of the method invocation the second argument of the production is replaced with the auxiliary data - structure methodInfo(). This data structure contains the information required to choose the right method lookup - strategy at the next step. The production methodInfo() contains the following arguments: + structure \verb|methodInfo()|. This data structure contains the information required to choose the right method lookup + strategy at the next step. The production \verb|methodInfo()| contains the following arguments: - Method signature Sig - Qualifying class QualC of the method invocation, e.g. the compile-time type of the qualifier. @@ -221,10 +221,10 @@ During the second step of the method invocation the second argument of the produ - Acc --- access modifier (private, package, protected or public). For the purpose of uniformity we use the modifier package when no access modifier is provided. -All the information stored in methodInfo() is static. In K-Java we already have +All the information stored in \verb|methodInfo()| is static. In K-Java we already have this information computed, but it is stored in various cells inside \cellref[]{class} and \cellref[]{classDec}. The rules from step 3 simply load the relevant information from configuration - cells to methodInfo() arguments. + cells to \verb|methodInfo()| arguments. \end{markdown} */ syntax MethodName ::= methodInfo( Signature, //Sig - method signature @@ -239,10 +239,10 @@ syntax MethodName ::= methodInfo( ) /*@ -The first rule from this step rewrites the method name into a methodInfo() term whose first argument is the method +The first rule from this step rewrites the method name into a \verb|methodInfo()| term whose first argument is the method signature. - The auxiliary function getTypes() computes the list of types from the list of parameter declarations. The second - argument of methodInfo() is also computed at this step --- it is the type of the qualifier. The rest of the arguments + The auxiliary function \verb|getTypes()| computes the list of types from the list of parameter declarations. The second + argument of \verb|methodInfo()| is also computed at this step --- it is the type of the qualifier. The rest of the arguments are filled in with default values. They will be rewritten into actual values by the following rules. */ rule [Invoke-compute-methodInfo-Signature]: @@ -268,7 +268,7 @@ Note that in this rule variable Args is defined of type TypedVals instead of Exp Because TypedVal is subsorted to KResult, TypedVals being a list of KResult is implicitly subsorted to KResult. */ -/* Impl: We could combine this rule with the previous one by using getLookupTargetType(), but we'll keep it this way +/* Impl: We could combine this rule with the previous one by using \verb|getLookupTargetType()|, but we'll keep it this way to keep the core part of method invocation separate from the non object-related part. */ /*@ @@ -308,7 +308,7 @@ when notBool Sig in keys(Methods) /*@ -The last rule of step 3 loads ContextT and Acc. It requires DecC, so this rule may only match after the second rule for methodInfo(). +The last rule of step 3 loads ContextT and Acc. It requires DecC, so this rule may only match after the second rule for \verb|methodInfo()|. */ rule [Invoke-compute-methodInfo-ContextType]: @@ -324,9 +324,9 @@ rule [Invoke-compute-methodInfo-ContextType]: \subsection{Lookup method declaration} In the third step of the method invocation algorithm, the actual method declaration is chosen. This step starts once all - the fields of methodInfo() were filled in (where possible). The rules of this step rewrite methodInfo() into - methodRef() --- another auxiliary data structure. -The production methodRef() is a reference to a method declaration. It contains two fields --- Sig and DecC --- the + the fields of \verb|methodInfo()| were filled in (where possible). The rules of this step rewrite \verb|methodInfo()| into + \verb|methodRef()| --- another auxiliary data structure. +The production \verb|methodRef()| is a reference to a method declaration. It contains two fields --- Sig and DecC --- the signature and the declaration class. The implementation class is the class that contains the actual method declaration to be invoked. @@ -381,7 +381,7 @@ rule [Invoke-methodInfo-instance-private]: /*@ If the method is protected or public, then we should call the version of the method visible to the runtime type of the qualifying object (ObjC). Recall that the runtime type of an object is stored in the second argument of - objectRef(). + \verb|objectRef()|. This case also covers qualifying type interface, since interface methods are always public. The right method will always be the one referred by the signature Sig in the cell \cellref[]{methods} associated with the actual object class. This is because the unfolding phase populates \cellref[]{methods} with the union of methods inherited @@ -435,7 +435,7 @@ public class C extends B { protected void f(int a) { ... } } -((A) new C()).f(); +((A) new \verb|C()|).f(); \end{lstlisting} \end{minipage} @@ -462,11 +462,11 @@ In contrast, the K-Java algorithm starts the search with the qualifying type (e. derived class) that overrides the original one. The rule for package access mode delegates searching for the right method declaration to the auxiliary function - lookupPackageMethod(). The function takes 3 arguments: + \verb|lookupPackageMethod()|. The function takes 3 arguments: - method signature Sig - the list of classes in the inheritance chain between the qualifying class QualC and the actual object class ObjC. - This list is produced by classChain() + This list is produced by \verb|classChain()| - the third argument represents the declaring class of the best method found so far. It is initialized with \dotCt{K}. \end{markdown} @@ -484,10 +484,10 @@ rule [Invoke-methodInfo-instance-package]: ... Sig |-> _ ... /*@ -Before the evaluation of lookupPackageMethod() may begin, the term lookupPackageMethod() has to be heated to the top +Before the evaluation of \verb|lookupPackageMethod()| may begin, the term \verb|lookupPackageMethod()| has to be heated to the top of computation. The side condition in the context rule below ensured that the second argument of method call - expression is heated only if it contains a term lookupPackageMethod(). If it has other forms, - such as the method name or methodInfo(), it won't be heated. + expression is heated only if it contains a term \verb|lookupPackageMethod()|. If it has other forms, + such as the method name or \verb|methodInfo()|, it won't be heated. */ context _:K . HOLE (_) when @@ -520,7 +520,7 @@ syntax KItem ::= lookupPackageMethod ( /*@ \begin{markdown} -The rules for lookupPackageMethod() are based on the following two properties of the configuration: +The rules for \verb|lookupPackageMethod()| are based on the following two properties of the configuration: - if the cell \cellref[]{methods} for a particular class contains a key Sig, then \cellref[]{methods} for all classes derived from it will contain the key Sig. @@ -557,7 +557,7 @@ The second rule matches when we already found a declaring class (OldDecC) and th match $\mathrel{}\kall{class}{\kall{classType}{ CurrentC } \mathrel{}\kall{methods}{... Sig \mapsto CurrentC ...} }$, according to the definition of \cellref[]{methods}. -If the method in CurrentC directly overrides the method in OldDecC, the declaring class is updated to CurrentC. Otherwise the declaring class stays unchanged. The rules for direct overriding (case 1a above) are defined in the auxiliary function isOverridden(). The function takes three arguments: +If the method in CurrentC directly overrides the method in OldDecC, the declaring class is updated to CurrentC. Otherwise the declaring class stays unchanged. The rules for direct overriding (case 1a above) are defined in the auxiliary function \verb|isOverridden()|. The function takes three arguments: \begin{markdown} - The base class OldDecC - The derived class CurrentC @@ -629,13 +629,13 @@ when /*@ The last rule matches when the chain of classes stored in the first argument remains empty. It rewrites the whole - lookupPackageMethod() into a reference to the method that has to be invoked. + \verb|lookupPackageMethod()| into a reference to the method that has to be invoked. */ rule [lookupPackageMethod-end]: lookupPackageMethod( Sig:Signature, .ClassTypes, DecC:ClassType ) => methodRef(Sig, DecC) /*@ -For the code example above, the term lookupPackageMethod() will pass through the following forms during evaluation: +For the code example above, the term \verb|lookupPackageMethod()| will pass through the following forms during evaluation: \begin{tabular}{ | l | l | } \hline @@ -683,15 +683,15 @@ For the code example above, the term lookupPackageMethod() will pass through the \vspace{3ex} -When the term lookupPackageMethod() is first produced it takes as arguments the method signature (rendered here as f() +When the term \verb|lookupPackageMethod()| is first produced it takes as arguments the method signature (rendered here as \verb|f()| for convenience), the chain of classes from the qualifying class A to the runtime class C, and \dotCt{K} as the third argument. Since the third argument is \dotCt{K} only the third rule can match. This rule deletes A - from the class chain and updates the third argument to the class that defines the version of f() accessible to A. - That class is A. For classes B and C the second rule for lookupMethodM() matches. In both cases the method f() - defined in B and C overrides the previously found one. In the first case classes the method B.f() overrides A.f() - because the access mode is package and both A and B are in the same package. In the second case C.f() - overrides B.f() because B.f() has protected access mode, and is thus always overridden. The final result of - method lookup procedure is the version of method f() declared in the class C. + from the class chain and updates the third argument to the class that defines the version of \verb|f()| accessible to A. + That class is A. For classes B and C the second rule for \verb|lookupMethodM()| matches. In both cases the method \verb|f()| + defined in B and C overrides the previously found one. In the first case classes the method \verb|B.f()| overrides \verb|A.f()| + because the access mode is package and both A and B are in the same package. In the second case \verb|C.f()| + overrides \verb|B.f()| because \verb|B.f()| has protected access mode, and is thus always overridden. The final result of + method lookup procedure is the version of method \verb|f()| declared in the class C. */ /*@ @@ -699,7 +699,7 @@ When the term lookupPackageMethod() is first produced it takes as arguments the \begin{markdown} The central rule of method invocation is matched when the second argument of method call expression reaches the form - methodRef(). This rule performs the following operations: + \verb|methodRef()|. This rule performs the following operations: - saves the rest of computation (RestK) and the content of \cellref[]{methodContext} as a new entry of the cell \cellref[]{stack} This data is restored back by the rules for return statement. @@ -708,19 +708,19 @@ The central rule of method invocation is matched when the second argument of met - current class \cellref[]{crntClass} is initialized to the class declaring the method - object location \cellref[]{location} is initialized to the location of the qualifier object for instance methods, or \dotCt{K} for static methods. The extraction of the location from the qualifier value is performed by the - function getOId(). + function \verb|getOId()|. - Rewrites the method call expression into a sequence of four terms: - static initialization of the qualifying class - parameters initialization - actual method body - a return statement with no arguments after the method body. -The function staticInit() triggers static initialization of the qualifying class, if this class was not initialized yet. +The function \verb|staticInit()| triggers static initialization of the qualifying class, if this class was not initialized yet. Repeated calls of this function have no effect. Is required just for static methods and is described in JLS \S12.4. For an instance method call, the qualifying class will always be initialized already, - so staticInit() will have no effect. + so \verb|staticInit()| will have no effect. -The function initParams() rewrites each parameter declaration into two statements. First is a local variable +The function \verb|initParams()| rewrites each parameter declaration into two statements. First is a local variable declaration with that parameter name. The second is an assignment to that variable of the actual argument value. The return statement at the end ensures that there is a return statement on every execution path of the method. The @@ -851,7 +851,7 @@ rule [Invoke-QSuperMethod]: ),, _ ) -/* Elaboration result for super keyword in A.super.m() call. Have to be a typed expression. +/*@ Elaboration result for super keyword in A.\verb|super.m()| call. Have to be a typed expression. */ syntax MethodName ::= superMethodImpl ( K ) // is always equal to A.this - used to lookup the right qualifier closure. [strict] @@ -862,7 +862,7 @@ rule [superMethodImpl]: objectRef( OId:Int, //The layers above the layer where method should be searched - // should be discarded in order to implement super.m() functionality. + // should be discarded in order to implement \verb|super.m()| functionality. _ )::Class:ClassType //due to the way term superMethod() is first constructed, this is the upper search layer ) diff --git a/src/exec/new-instance.k b/src/exec/new-instance.k index a023304d..f01d23cc 100644 --- a/src/exec/new-instance.k +++ b/src/exec/new-instance.k @@ -126,22 +126,22 @@ When all the subexpressions of new have been evaluated, the main rule for new co by rules that are applied next. Inside \cellref[]{k} the new instance expression is rewritten into a sequence of computations that will be executed - by the following rules. The auxiliary function staticInit() triggers static initialization of the instantiated class, - in case it was not triggered earlier. Next, the function create() populates the layers of the object inside + by the following rules. The auxiliary function \verb|staticInit()| triggers static initialization of the instantiated class, + in case it was not triggered earlier. Next, the function \verb|create()| populates the layers of the object inside \cellref[]{object} This also includes allocation of all instance fields, and their initialization to the default value. - Field initializers are not executed yet. The function setEncloser() sets the enclosing object for the current class, + Field initializers are not executed yet. The function \verb|setEncloser()| sets the enclosing object for the current class, if the current class is an inner class. If some of the base classes are also inner classes, the encloser for their respective \cellref[]{layer} will be set as part of constructor invocation. -The next term in the computation (the one starting with typedLookup(L)) might look a bit weird, but it is in fact +The next term in the computation (the one starting with \verb|typedLookup(L)|) might look a bit weird, but it is in fact the invocation of the constructor. This term represents a mix of Java syntax for method invocation and auxiliary functions defined inside K-Java. It illustrates, among others, the power of K parser. Now, after all memory allocation procedures have been completed, it is the right time for it to be invoked. Preprocessing semantics - transforms all constructors into plain methods. The function typedLookup(L) is evaluated into the object stored - at the location L, that will serve as a qualifier for constructor invocation. The function getConsName() converts + transforms all constructors into plain methods. The function \verb|typedLookup(L)| is evaluated into the object stored + at the location L, that will serve as a qualifier for constructor invocation. The function \verb|getConsName()| converts the class name into the name of the constructor method. What remains is plain Java syntax for method invocation. -The last two terms bring computation to the state required to continue execution. Function restoreMethoContext() +The last two terms bring computation to the state required to continue execution. Function \verb|restoreMethoContext()| restores \cellref[]{methodContext} to the the state before object creation. The last term is the result value of the object instantiation expression. */ diff --git a/src/exec/statements.k b/src/exec/statements.k index cc7ea179..d149ed94 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -34,7 +34,7 @@ rule [Block]: Env [structural] -//@ \texttt{env} Restore the env cell content from env(...) statement argument +//@ \texttt{env} Restore the env cell content from \verb|env(...)| statement argument syntax KItem ::= env ( Map ) rule [env]: diff --git a/src/exec/syntax-conversions.k b/src/exec/syntax-conversions.k index 4d1b8c94..b03aad2b 100644 --- a/src/exec/syntax-conversions.k +++ b/src/exec/syntax-conversions.k @@ -18,7 +18,7 @@ rule toParams([KLParams:KList]) => toParams([KLParams], .Params) rule toParams([KLParams:KList,, 'Param(_,, K:K,, X:Id)], Params:Params) => toParams([KLParams], (K X,Params)) rule toParams([.KList], Params:Params) => Params -// Required for getTypes() +//@ Required for getTypes() rule typeOf('ParamImpl(T:Type,, _:Id)) => T /*@ \subsection{Method invocation}*/ diff --git a/src/exec/to-string.k b/src/exec/to-string.k index c66d3740..143f2276 100644 --- a/src/exec/to-string.k +++ b/src/exec/to-string.k @@ -18,7 +18,7 @@ rule toString(true::_) => "true" rule toString(false::_) => "false" rule toString(null::_) => "null" -//@ toString(arrayOf T) +//@ \verb|toString(arrayOf T)| rule toString(arrayOf byte) => "[B" rule toString(arrayOf short) => "[S" diff --git a/src/exec/unfolding.k b/src/exec/unfolding.k index 1ae468af..6561cccb 100644 --- a/src/exec/unfolding.k +++ b/src/exec/unfolding.k @@ -128,7 +128,7 @@ syntax KItem ::= getClassMetaType ( KLabel ) [function] rule getClassMetaType('ClassDec) => classCMT rule getClassMetaType('InterfaceDec) => interfaceCMT -// True if given KListWrap contains a 'MethodDec(\_) term +// True if given KListWrap contains a \verb|'MethodDec(\_)| term syntax KItem ::= containsMethodDecs( KListWrap ) [function] rule containsMethodDecs([_,, 'MethodDec(_),, _]) => true diff --git a/src/exec/var-lookup.k b/src/exec/var-lookup.k index f9517e28..fecb74f1 100644 --- a/src/exec/var-lookup.k +++ b/src/exec/var-lookup.k @@ -1,17 +1,17 @@ module VAR-LOOKUP imports CORE-SORTS imports SUBTYPING - imports STATIC-INIT //for staticInit() + imports STATIC-INIT //for \verb|staticInit()| imports EXPRESSIONS //@ \subsection{Local variable access} /* Local variable access. At runtime may have one form: - - 'ExprName(X:Id) --- local variable + - \verb|'ExprName(X:Id)| --- local variable */ -/*@ At execution phase 'ExprName(X) always represent a local variable. +/*@ At execution phase \verb|'ExprName(X)| always represents a local variable. */ rule [ExprName-local]: 'ExprName(X:Id) => typedLookup(L) ... @@ -37,7 +37,7 @@ rule [QThis]: ... -//@ Search for the right value representing QThis(Class) --- an expression of type Class.this +//@ Search for the right value representing \verb|QThis(Class)| --- an expression of type Class.this syntax KItem ::= lookupQThis ( ClassType, //the type of this to look for, TypedVal //the objectRef where the type should be found @@ -67,8 +67,8 @@ when /*@ \subsection{Instance field access} */ /*@ Variable access. May have 2 forms: - - 'ExprName(Class, X:Id) --- static field - - 'ExprName(Qual, X:Id) --- instance field + - \verb|'ExprName(Class, X:Id)| --- static field + - \verb|'ExprName(Qual, X:Id)| --- instance field */ context 'Field(HOLE,, _) context lvalue('Field(HOLE,, _)) @@ -112,7 +112,7 @@ rule [lvalue-Field-static]: => staticInit(TargetClass) ~> lvalue(staticFieldLookup(TargetClass, X)) /*@ The actual implementation of static field lookup. The distinction between this function and - 'Field(Class, X) term is that at the moment when this function is called the target clas is + \verb|'Field(Class, X)| term is that at the moment when this function is called the target clas is surely initialized. */ syntax KItem ::= staticFieldLookup ( ClassType , Id ) @@ -166,7 +166,7 @@ rule [lvalue-typedLoc]: /*@ Retrieve a value from the store based on its location and the given compile-time type. May be wrapped inside lvalue. If lookup is unwrapped, it evaluates to TypedVal --- the store value, - of the type T --- the second lookup argument. If lookup is wrapped into lvalue, it evaluates to loc(OL)::T. + of the type T --- the second lookup argument. If lookup is wrapped into lvalue, it evaluates to \verb|loc(OL)|::T. */ syntax Exp ::= lookup ( Int, //OL - the store location to lookup diff --git a/src/prep/core-preprocessing.k b/src/prep/core-preprocessing.k index 5890686d..84da59b3 100644 --- a/src/prep/core-preprocessing.k +++ b/src/prep/core-preprocessing.k @@ -6,7 +6,7 @@ module CORE-PREPROCESSING //@ \subsection{Auxiliary constructs for retrieving a set of classes} -/*@ Returns a setWrap(Set[ClassType]), containing all top level classes in the program. +/*@ Returns a \verb|setWrap(Set[ClassType])|, containing all top level classes in the program. Uses \verb|| to compute the result. Used by the starting rule of several preprocessing phases. */ syntax KItem ::= "getTopLevelClasses" @@ -35,7 +35,7 @@ rule [getTopLevelClasses-not-top-level]: rule getTopLevelClasses(_ (_ |-> mapWrap(.Map) => .Map), _) rule getTopLevelClasses(.Map, ClassesSet:Set) => setWrap(ClassesSet) -/*@ Returns a setWrap(Set[ClassType]), containing all direct inner classes of the given class. +/*@ Returns a \verb|setWrap(Set[ClassType])|, containing all direct inner classes of the given class. Uses \verb|| to compute the result. */ syntax KItem ::= getInnerClasses ( ClassType ) diff --git a/src/prep/elaboration-categories.k b/src/prep/elaboration-categories.k index 0d43f300..f895b1b8 100644 --- a/src/prep/elaboration-categories.k +++ b/src/prep/elaboration-categories.k @@ -210,7 +210,7 @@ rule defaultElabHeating('Id) => true*/ rule defaultElabHeating('stmtAndExp) => true /*@ Naked terms are those that should be computed directly into KResult during elaboration. - Those are literals, types and packages. They are heated "as is", without being wrapped into elab(). + Those are literals, types and packages. They are heated "as is", without being wrapped into \verb|elab()|. An exception is the class literal that is not executed during elaboration. Some auxiliary functions are also included in this cathegory in order to reduce the usage of elaboration wrappers. @@ -231,8 +231,8 @@ rule isElabNaked('Lit(InnerKL:KLabel(_))) => InnerKL =/=KLabel 'Class \begin{markdown} Terms that should use custom elaboration rules. For those terms: - - They will not be automatically heated from their parents into the elab() state. - - They will not be automatically passed to elabDispose() state. Instead, those terms should have custom rules for elaboration start (heating) and elaboration end (cooling). + - They will not be automatically heated from their parents into the \verb|elab()| state. + - They will not be automatically passed to \verb|elabDispose()| state. Instead, those terms should have custom rules for elaboration start (heating) and elaboration end (cooling). Since all the automatic elaboration-related rules are an incredible mess, we have to put all the AST terms into this cathegory one by one, and eliminate automatic elaboration heating/cooling rules altogether. diff --git a/src/prep/elaboration-core.k b/src/prep/elaboration-core.k index 3d278f2f..8a8059b4 100644 --- a/src/prep/elaboration-core.k +++ b/src/prep/elaboration-core.k @@ -14,23 +14,23 @@ static initializers of a class and perform the following transformations: \begin{itemize} \item x --- a local var \item Class.x --- a static var defined in the class Class - \item field(obj, Class, x) --- a field of object obj declared in the class Class. + \item \verb|field(obj, Class, x)| --- a field of object obj declared in the class Class. Term obj could also be 'This. \end{itemize} \item each method name is resolved into either: \begin{itemize} \item Class.m --- a static method defined in the class Class - \item method(obj, Class, x) --- an instance method of object obj declared in the class Class. + \item \verb|method(obj, Class, x)| --- an instance method of object obj declared in the class Class. Term obj could also be 'This. The actual version of the method will be looked up at runtime. \end{itemize} \item each method signature is resolved into its appropriate overloaded version. To denote the version, each actual parameter will be casted to the type of the actual parameter. - \item each expression Exp will be replaced with a corresponding typed expression cast(T, Exp), + \item each expression Exp will be replaced with a corresponding typed expression \verb|cast(T, Exp)|, T being the compile-time type of the expression. \end{itemize} \smallskip -During elaboration, elaborated members will be wrapped into elab(). +During elaboration, elaborated members will be wrapped into \verb|elab()|. During elaboration an expression transition through 6 phases: @@ -39,24 +39,24 @@ During elaboration an expression transition through 6 phases: => elab('Minus('ExprName(x)) ~> elab('CastRef(\_,, HOLE) Some AST terms, especially some statements require custom elaboration heating rules. If the heated expression should be always computed into a KResult, such as a type, package or certain literal expresssions, then - it is heated in the "naked" form, e.g. not wrapped into elab(). + it is heated in the "naked" form, e.g. not wrapped into \verb|elab()|. 2. Elaboration of children. All the children of the expression are elaborated. After this phase elaborated children - will be typed (if they are expressions) and wrapped into elabRes(). Typed expressions are cast expressions - - like cast(T, Exp). The whole initial term will be converted into: - elab('Minus(elabRes(cast(int, localVar(X))))) ~> elab('CastRef(\_,, HOLE) - 3. Initiation of the step elabDispose. When all children have been elaborated and are either KResult of elabRes(), - the wrapper is changed from elab() to elabDispose(). - elabDispose('Minus(elabRes(cast(int, localVar(X))))) ~> elab('CastRef(\_,, HOLE) - 4. Unwrapping of children. During elabDispose step elaborated children are unwrapped from their elabRes() wrapper. - elabDispose('Minus(cast(int, localVar(X)))) ~> elab('CastRef(\_,, HOLE) + will be typed (if they are expressions) and wrapped into \verb|elabRes()|. Typed expressions are cast expressions - + like \verb|cast(T, Exp)|. The whole initial term will be converted into: + elab('Minus(elabRes(cast(int, localVar(X))))) ~> elab(CastRef(\_,, HOLE) + 3. Initiation of the step elabDispose. When all children have been elaborated and are either KResult of \verb|elabRes()|, + the wrapper is changed from \verb|elab()| to \verb|elabDispose()|. + elabDispose('Minus(elabRes(cast(int, localVar(X))))) ~> elab(CastRef(\_,, HOLE) + 4. Unwrapping of children. During elabDispose step elaborated children are unwrapped from their \verb|elabRes()| wrapper. + elabDispose('Minus(cast(int, localVar(X)))) ~> elab(CastRef(\_,, HOLE) 5. End of the step elabDispose. When all children of the term wrapped into elabDispose have been unwrapped - from their elabRes() wrapper, the root wrapper is replaced from elabDispose to elabEnd. This contributes + from their \verb|elabRes()| wrapper, the root wrapper is replaced from elabDispose to elabEnd. This contributes to more simple rules for the following steps. - elabRes('Minus(cast(int, localVar(X)))) ~> elab('CastRef(\_,, HOLE) + elabRes('Minus(cast(int, localVar(X)))) ~> elab(CastRef(\_,, HOLE) 6. Computation of elaboration result. Now that all children have been elaborated and unwrapped, it is possible to compute the type of the current expression itself. When the expression is fully elaborated, it is wrapped into - elabRes(). This is the step that requires custom rules for most AST terms. - elabRes('Minus(cast(int,cast(int, localVar(X))))) ~> elab('CastRef(\_,, HOLE) + \verb|elabRes()|. This is the step that requires custom rules for most AST terms. + elabRes('Minus(cast(int,cast(int, localVar(X))))) ~> elab(CastRef(\_,, HOLE) 7. Elaboration cooling. Once the top K Item was wrapped into elabRes, it is ready to be cooled back into its original context: elab('CastRef(\_,, elabRes('Minus(cast(int,cast(int, localVar(X))))))) \end{markdown} @@ -75,7 +75,7 @@ rule isElabKResult(KR:KResult) => true /*@ \subsection{Operator ??}*/ /*@ Chain of responsibility pattern. -Evaluate the first argument. if it is KResult (except noValue) or elabRes(), the result of the ?? expression is +Evaluate the first argument. if it is KResult (except noValue) or \verb|elabRes()|, the result of the ?? expression is the result of the first argument. Otherwise, if the first argument evaluates to noValue, the result of the ?? expression is the result of the second argument. */ @@ -99,9 +99,9 @@ Computes to true if the given argument is a list of elaboration results, false o An elaborated result is either: - KResult - - elabRes(...) + - \verb|elabRes(...)| - It is notably NOT a cast() expression. This, together with the fact that cast() has no elaboration heatig rules, + It is notably NOT a \verb|cast()| expression. This, together with the fact that \verb|cast()| has no elaboration heatig rules, makes the whole elaboration phase non-reentrant. \end{markdown} */ @@ -132,7 +132,7 @@ The attribute [transition-strictness] is used as transition attribute for testin This is a rule that may lead to unexpected nondeterminism if it is wrongly implemented. In order to expose incorrect nondeterminism we need to model-check a program that exposes the nondeterminism. -Labels that are "naked" should be heated in their pure form. Other terms should be heated wrapped into elab(). +Labels that are "naked" should be heated in their pure form. Other terms should be heated wrapped into \verb|elab()|. */ rule [elab-heat-default]: (. => #if isElabNaked(K) ==K true @@ -150,7 +150,7 @@ rule [elab-cool-default]: (ElabK:ElabKResult => .) ~> elab(_:KLabel(_,, (CHOLE => ElabK),, _)) /*@ Must be true for AST nodes that require elaboration heating of their children. For the arguments KL, Ks, -the original node is of he form KL(KS,,\_) and the heated child is always the last element of Ks. +the original node is of he form \verb|KL(KS,,\_)| and the heated child is always the last element of Ks. Thus it is possible to decide whether the child is allowed to be heated based both on the position of the child in the list of arguments as well as based on the state of previous brothers. @@ -167,7 +167,7 @@ The default algorithm of transforming the term from elab to elabRes, when the ch Deletes elabRes wrappers from children. This algorithm is activated when the following conditions apply: - term is not customElabChildren - - term children are completely elaborated --- isElab(children) + - term children are completely elaborated --- \verb|isElab(children)| - term is not naked. This case should never be true, but there is some weird case that requires it. When the default algorithm is not appropriate, the respective term should be in the cathegory customElabChildren @@ -190,7 +190,7 @@ rule [elabDispose-to-elabEnd]: when notBool haveElabRes([Ks]) ==K true -//@ True if given KList has no terms of the form elabRes(...), false otherwise. +//@ True if given KList has no terms of the form \verb|elabRes(...)|, false otherwise. syntax KItem ::= haveElabRes ( KListWrap ) [function] rule haveElabRes([_,, elabRes(_),, _]) => true @@ -198,7 +198,7 @@ rule haveElabRes([_,, elabRes(_),, _]) => true rule haveElabRes([_,, KList2KLabel _,, elabRes(_),, _ (_),, _]) => true /*@ The 3rd elaboration-phase wrapper for expressions. Represents the case when children are completely elaborated and -unwrapped from elabRes(), but root node might not be elaborated yet. The implementation is scattered across all modules +unwrapped from \verb|elabRes()|, but root node might not be elaborated yet. The implementation is scattered across all modules that deal with the elaboration phase. */ syntax KItem ::= elabEnd ( K ) diff --git a/src/prep/elaboration-expressions.k b/src/prep/elaboration-expressions.k index fec53d0d..2e8761ae 100644 --- a/src/prep/elaboration-expressions.k +++ b/src/prep/elaboration-expressions.k @@ -6,7 +6,7 @@ module ELABORATION-EXPRESSIONS /*@ \subsection{Elaboration of numeric expressions} -Expression labels are not converted by the default rule in the phase elabDispose() => elabRes(...) +Expression labels are not converted by the default rule in the phase \verb|elabDispose()| => \verb|elabRes(...)| Each expression needs a specialized rule for disposing, that will compute, among others, the type of the expression. */ diff --git a/src/prep/elaboration-method-invoke.k b/src/prep/elaboration-method-invoke.k index 37930b07..61284896 100644 --- a/src/prep/elaboration-method-invoke.k +++ b/src/prep/elaboration-method-invoke.k @@ -60,7 +60,7 @@ rule [elabEnd-findQualifierForName-static]: rule customElabEnd('SuperMethod) => true -// super.X(_) +//@ \verb|super.X(_)| rule [SuperMethod-desugar]: elabEnd('SuperMethod(K:K,, Name:Id)) => elabEnd('QSuperMethod(Class,, K:K,, Name:Id)) diff --git a/src/prep/elaboration-top-blocks.k b/src/prep/elaboration-top-blocks.k index a9769708..7aafe20a 100644 --- a/src/prep/elaboration-top-blocks.k +++ b/src/prep/elaboration-top-blocks.k @@ -11,7 +11,7 @@ rule [ElaborationPhase-start]: ProcClassMembersPhase => ElaborationPhase /*@ Elaborate the blocks inside all classes. -Argument K = setWrap(Set) --- the set of all classes. +Argument K = \verb|setWrap(Set)| --- the set of all classes. */ syntax KItem ::= elaborateBlocks ( K ) [strict] diff --git a/src/prep/process-class-decs.k b/src/prep/process-class-decs.k index 05ab4aee..86dfd7ef 100644 --- a/src/prep/process-class-decs.k +++ b/src/prep/process-class-decs.k @@ -16,7 +16,7 @@ syntax KItem ::= processClassDecs ( [strict] /*@ Question: how do we know if bases were already resolved for this class or not? - Answer: When resolveBases(Class) is consumed by the rule [resolveBasesEnd], the class + Answer: When \verb|resolveBases(Class)| is consumed by the rule [resolveBasesEnd], the class changes its state: StoredCPhase => BasesResolvedCPhase */ rule [processClassDecs-resolveBases-TopLevel-Start]: From 25db3ebd826dc9f761fcf26a5247bb622a12d2e0 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Thu, 19 Feb 2015 10:50:58 +0200 Subject: [PATCH 04/43] Doc: Punctuation review. Wrap comments into \begin{markdown} ... \end{markdown} when itemizing is used inside. Fix line breaks and indentation to produce desired result. --- src/exec/expressions.k | 12 ++++++------ src/exec/method-invoke.k | 22 +++++++++++++++------- src/exec/var-lookup.k | 13 ++++--------- src/prep/process-comp-units.k | 22 +++++----------------- 4 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/exec/expressions.k b/src/exec/expressions.k index 3e238569..8ad6f2ee 100644 --- a/src/exec/expressions.k +++ b/src/exec/expressions.k @@ -149,16 +149,16 @@ rule [Assign]: loc(L:Int) :: ResT:Type = V:RawVal :: ResT => store(L, V::ResT) ~> V::ResT /*@ -\begin{markdown} -Desugars compound assign into the underlying operator + assign. Could probably be done during elaboration. - Answer: +Desugars compound assign into the underlying operator + assign. +*/ + +/*Could probably be done during elaboration, this way (not done this way currently!): + - in the LHS of => location L is referred once - in the RHS of => it is referred twice - - at elaboration phase we would have to rewrite the original expresion that produces L - from one occurence to two occuences. + - at elaboration phase we would have to rewrite the original expresion that produces L from one occurence to two occuences. - if operator LHS expression has side effects, we would end up with the side effect twice. - Example: v[i++] += 1 -\end{markdown} */ rule loc(L:Int) :: T:Type *= Exp2:K => loc(L)::T = cast(T, lookup(L, T) * Exp2) diff --git a/src/exec/method-invoke.k b/src/exec/method-invoke.k index ca63e42a..60073570 100644 --- a/src/exec/method-invoke.k +++ b/src/exec/method-invoke.k @@ -164,14 +164,17 @@ Generally the rules of K-Java do not follow directly the wording of JLS. The rea /*@ \subsection{Evaluation of the qualifier and the arguments} +\begin{markdown} The first two parts of method invocation logic are evaluation of the qualifier expression and evaluation of the arguments. JLS enforces the following conditions on the order of subexpressions evaluation: + - Arguments have to be evaluated after the qualifier was evaluated. This is ensured by checking that the qualifier is of sort KResult at the moment when arguments are heated. - Arguments are evaluated left to right. To ensure this we add a side condition that checks that all the arguments before the one being heated (if any) are already of the sort KResult. +\end{markdown} While there are two sections dedicated to this logic (\S15.12.4.1, \S15.12.4.2), we don't need any K rules for it. Instead, subexpressions evaluation ensured by strictness annotations @@ -196,6 +199,7 @@ The annotation {\kattribute{seqstrict}(1,3)} on the first definition ensures tha qualifier is evaluated. The qualifier term might be either an expression or a Class. If it is expression, it will be heated and evaluated. If it is a class (for certain static methods), then it is already a KResult strictness rule will have no effect on it. + Note that arguments have to be evaluated even in the case when the qualifier evaluated to null. At the same time that if evaluation of the qualifier or any of the arguments completes abruptly, the whole method invocation expression completes abruptly for the @@ -493,7 +497,7 @@ context _:K . HOLE (_) when getKLabel(HOLE) ==KLabel 'lookupPackageMethod -/* +/*@ Returns the list of classes representing the layer of the given object (by OId), located between MostBaseClass (exclusively) and MostDerivedClass (inclusively). */ @@ -502,7 +506,7 @@ syntax KItem ::= getClassChain( ClassType, //MostBaseClass //the list of classes ) -/* [Skip] The right signature is already found. +/*@ The right signature is already found. Search for the right implementation is performed from the compile-time type of the target to more derived types, up to the object type of the target. This is required in order to respect the rules of inheritance in the presence of access modes. @@ -554,7 +558,7 @@ rule [lookupPackageMethod-layer-first-dec-found]: /*@ The second rule matches when we already found a declaring class (OldDecC) and the current class CurrentC has another method declaration with the right signature. The presence of a declaration with signature Sig inside CurrentC is identified by the - match $\mathrel{}\kall{class}{\kall{classType}{ CurrentC } \mathrel{}\kall{methods}{... Sig \mapsto CurrentC ...} }$, + match $\kall{class}{\kall{classType}{ CurrentC } \mathrel{} \kmiddle{methods}{ Sig \mapsto CurrentC } }$, according to the definition of \cellref[]{methods}. If the method in CurrentC directly overrides the method in OldDecC, the declaring class is updated to CurrentC. Otherwise the declaring class stays unchanged. The rules for direct overriding (case 1a above) are defined in the auxiliary function \verb|isOverridden()|. The function takes three arguments: @@ -585,13 +589,17 @@ rule [lookupPackageMethod-new-method]: ... -/* +/*@ +\begin{markdown} Tests if a method declared in class BaseC with access mode Acc is overridden by a method with the same signature declared in a subclass SubC. The method is overridden if either: + - Acc is protected or public - Acc is package and BaseC and SubC are declared in the same package (JLS \S6.6) + +\end{markdown} */ syntax KItem ::= isOverridden ( ClassType, //BaseC @@ -754,7 +762,7 @@ syntax KItem ::= getOId( K ) [function] rule getOId( objectRef(OId:Int,_)::_ ) => OId rule getOId( noValue ) => noValue -/* Binds a list of formal parameters to their values. Used by method calls and try-catch. +/*@ Binds a list of formal parameters to their values. Used by method calls and try-catch. */ syntax KItem ::= initParams ( Params, // {T:Type X:Id},... - parameter declarations TypedVals // values @@ -825,7 +833,7 @@ module METHOD-INVOKE-REST imports SYNTAX-CONVERSIONS imports METHOD-INVOKE -/* [Skip] +/*@ The next rule for method invocation is applied when the qualifier type is array. This array type is rewritten into the auxiliary class ArrayImpl, that is used in K-Java to simulate method invocations over array objects. This rule is required in order to minimize the number of particular cases involving arrays in the rules that follow. @@ -900,7 +908,7 @@ when notBool ((DecC ==K classObject) andBool (Name ==K String2Id("wait") orBool Name ==K String2Id("notify") orBool Name ==K String2Id("notifyAll"))) -/* [Skip] Auxiliary function for methods that need implementation in the semantics. The implementation +/*@ Auxiliary function for methods that need implementation in the semantics. The implementation of this production is given in api-core.k and api-threads.k. */ syntax KItem ::= invokeImpl ( diff --git a/src/exec/var-lookup.k b/src/exec/var-lookup.k index fecb74f1..7074d98a 100644 --- a/src/exec/var-lookup.k +++ b/src/exec/var-lookup.k @@ -6,11 +6,6 @@ module VAR-LOOKUP //@ \subsection{Local variable access} -/* Local variable access. At runtime may have one form: - - \verb|'ExprName(X:Id)| --- local variable -*/ - - /*@ At execution phase \verb|'ExprName(X)| always represents a local variable. */ rule [ExprName-local]: @@ -66,10 +61,9 @@ when /*@ \subsection{Instance field access} */ -/*@ Variable access. May have 2 forms: - - \verb|'ExprName(Class, X:Id)| --- static field - - \verb|'ExprName(Qual, X:Id)| --- instance field +/*@ Has the following form: \verb|'ExprName(Qual, X:Id)|. */ + context 'Field(HOLE,, _) context lvalue('Field(HOLE,, _)) @@ -102,7 +96,8 @@ rule [Field-instance-OfNull]: [anywhere] /*@ \subsection{Static field access} */ - +/*@ Has the following form: \verb|'ExprName(Class, X:Id)|. +*/ rule [Field-static]: 'Field( TargetClass:ClassType,, X:Id ) => staticInit(TargetClass) ~> staticFieldLookup(TargetClass, X) diff --git a/src/prep/process-comp-units.k b/src/prep/process-comp-units.k index 7414d431..abb5f960 100644 --- a/src/prep/process-comp-units.k +++ b/src/prep/process-comp-units.k @@ -6,30 +6,18 @@ module PROCESS-COMP-UNITS /*@ \begin{markdown} -ProcCompUnitsPhase: - For each Compilation unit separately: +\paragraph{Module Overview} For each Compilation unit: -1. Process import declarations. Build \verb||. + - Process import declarations. Build \verb||. - For each class C in CompUnit separately: +For each class C in CompUnit: -2. For each class save the \verb|| cell with just the following: - - \verb|| --- since we process CU content recursively, should be available - - \verb|| - - \verb|| --- just for top-level classes, imports are taken from the \verb||. - For inner classes this cell is still empty. - - \verb|| --- content of its 'ClassDec term. When this term is non-empty - then the class has not been preprocessed yet. + - Add to \verb|| containing C the cells mentioned in configuration doc. + - Process inner classes of C. -3. Process inner classes of C. - - This way we will have fast access to the declaration of a class, and will be able to -process declarations in a less-restricted order. \end{markdown} */ -/*@ \subsection{Second pass --- processing declarations} */ - rule [ProcCompUnitsPhase-start]: . => Program ( Program:K => .) From 40afe5c63d1e5212cc666ec5c1978144337109b1 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Thu, 19 Feb 2015 15:42:19 +0200 Subject: [PATCH 05/43] Latex tools: Elliminate {kblock} environment from tex output --- src/prep/elaboration-core.k | 2 +- src/sty/custom-commands.tex | 4 ++-- tools/kjkompile.sh | 32 ++++++-------------------------- tools/remove-kblock.sh | 13 +++++++++++++ 4 files changed, 22 insertions(+), 29 deletions(-) create mode 100644 tools/remove-kblock.sh diff --git a/src/prep/elaboration-core.k b/src/prep/elaboration-core.k index 8a8059b4..ee7a50e9 100644 --- a/src/prep/elaboration-core.k +++ b/src/prep/elaboration-core.k @@ -242,7 +242,7 @@ rule [elabEnd-findQualifierOfType-static]: /*@ \subsection{Elaboration of statements --- step elabEnd} */ -/*@ Applies to all nodes that are not expressins --- statements and non-expression auxiliary functions +/*@ Applies to all nodes that are not expressions --- statements and non-expression auxiliary functions */ rule [elabEnd-default-all-except-expressions]: elabEnd(KL:KLabel(Ks:KList)) => elabRes(KL(Ks)) diff --git a/src/sty/custom-commands.tex b/src/sty/custom-commands.tex index f2affcc4..a5729b46 100644 --- a/src/sty/custom-commands.tex +++ b/src/sty/custom-commands.tex @@ -31,10 +31,10 @@ } %Wraps a group of cells and properly aligns them. -\newcommand{\kwrap}[1]{% +\newcommand{\kwrap}[1]{{%Additional braces to confine the scope of setkeys to this macro \setkeys{k}{ruleHangindent=0pt,StartVspace=0ex,EndVspace=0ex}% \ksentence[]{}{}{#1}{}{}{}% -} +}} % Environment "kdefinition" have effect only in poster style, thus in math style may be safely deleted. diff --git a/tools/kjkompile.sh b/tools/kjkompile.sh index 2468827a..1541839f 100755 --- a/tools/kjkompile.sh +++ b/tools/kjkompile.sh @@ -198,48 +198,28 @@ case "$OPTION" in ;; "--prep-latex") $KOMPILE_CMD -d prep --backend latex --doc-style "style=math,modulesAsSections" prep/java-prep.k - mv prep/java-prep.tex . - mv prep/k.sty . - ;; -"--prep-pdf") - $KOMPILE_CMD -d prep --backend pdf --doc-style "style=math,modulesAsSections" prep/java-prep.k - mv prep/java-prep.tex . + remove-kblock.sh prep/java-prep.tex > java-prep.tex + rm prep/java-prep.tex . mv prep/k.sty . ;; "--exec-latex") $KOMPILE_CMD -d exec --backend latex --doc-style "style=math,modulesAsSections" exec/java-exec.k - mv exec/java-exec.tex . - mv exec/k.sty . - ;; -"--exec-pdf") - $KOMPILE_CMD -d exec --backend pdf --doc-style "style=math,modulesAsSections" exec/java-exec.k - mv exec/java-exec.tex . + remove-kblock.sh exec/java-exec.tex > java-exec.tex + rm exec/java-exec.tex mv exec/k.sty . ;; "--methods-latex") - $KOMPILE_CMD -d exec --backend latex --doc-style "style=math,modulesAsSections" exec/java-exec.k + kjkompile.sh $EXTRA_OPTS --exec-latex extract-module.sh -m METHOD-INVOKE -o method-invoke.tex java-exec.tex mv exec/java-exec.tex . mv exec/k.sty . ;; -"--methods-pdf") - kjkompile.sh $EXTRA_OPTS --methods-latex - mkdir -p .latex - pdflatex -synctex=-1 -max-print-line=120 -interaction=nonstopmode -shell-escape \ - --aux-directory=.latex method-invoke.tex - ;; "--new-latex") - $KOMPILE_CMD -d exec --backend latex --doc-style "style=math,modulesAsSections" exec/java-exec.k + kjkompile.sh $EXTRA_OPTS --exec-latex extract-module.sh -m NEW-INSTANCE -o new-instance.tex java-exec.tex mv exec/java-exec.tex . mv exec/k.sty . ;; -"--new-pdf") - kjkompile.sh $EXTRA_OPTS --new-latex - mkdir -p .latex - pdflatex -synctex=-1 -max-print-line=120 -interaction=nonstopmode -shell-escape \ - --aux-directory=.latex new-instance.tex - ;; "--modules-latex") echo "Preprocessing semantics:" # "&> file" redirects both stdin and stderr to the given file diff --git a/tools/remove-kblock.sh b/tools/remove-kblock.sh new file mode 100644 index 00000000..a19c1764 --- /dev/null +++ b/tools/remove-kblock.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +#removes \begin{kblock}, \end{kblock} from the given file +if [ $# == 0 ]; then + echo "Usage: `basename $0` " + exit 1 +fi + +# http://www.cyberciti.biz/faq/howto-delete-word-using-sed-under-unix-linux-bsd-appleosx/ +# http://stackoverflow.com/questions/2369314/why-does-sed-require-3-backslashes-for-a-regular-backslash +# http://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n + +sed -e ':a;N;$!ba; s/\\begin{kblock}\[text\]\s*\n*\s*//g; s/\\end{kblock}\n//g' $1 From b6c9dbc7fd56877eb614e44bfa340aeb72d749a3 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Fri, 20 Feb 2015 11:07:03 +0200 Subject: [PATCH 06/43] Doc: Punctuation review. Reviewed \verb|...|, delete those visible in the output. --- src/common/core-sorts.k | 2 +- src/exec/method-invoke.k | 2 +- tools/kjkompile.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/core-sorts.k b/src/common/core-sorts.k index 6808b19d..a7c83f08 100644 --- a/src/common/core-sorts.k +++ b/src/common/core-sorts.k @@ -123,7 +123,7 @@ The object closure has the following structure: \begin{verbatim} ListItem(layer( Class, - \verb||Env, + Env, enclosingObjClosure::T )) ... diff --git a/src/exec/method-invoke.k b/src/exec/method-invoke.k index 60073570..b88970e7 100644 --- a/src/exec/method-invoke.k +++ b/src/exec/method-invoke.k @@ -439,7 +439,7 @@ public class C extends B { protected void f(int a) { ... } } -((A) new \verb|C()|).f(); +((A) new C()).f(); \end{lstlisting} \end{minipage} diff --git a/tools/kjkompile.sh b/tools/kjkompile.sh index 1541839f..3e935d15 100755 --- a/tools/kjkompile.sh +++ b/tools/kjkompile.sh @@ -199,7 +199,7 @@ case "$OPTION" in "--prep-latex") $KOMPILE_CMD -d prep --backend latex --doc-style "style=math,modulesAsSections" prep/java-prep.k remove-kblock.sh prep/java-prep.tex > java-prep.tex - rm prep/java-prep.tex . + rm prep/java-prep.tex mv prep/k.sty . ;; "--exec-latex") From b3b6e85a3456b8b441c5c0979fdd26c387c8b8c6 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Fri, 20 Feb 2015 11:39:21 +0200 Subject: [PATCH 07/43] Doc: Punctuation review. Uppercase at the beginning of sentences ad list items, just in configuration docs. Spell checking, just configuration docs. Some common misspellings corrected throughout hte semantics. --- src/common/core-sorts.k | 2 +- src/common/shared-syntax.k | 2 +- src/exec/api-core.k | 8 ++--- src/exec/configuration-exec.k | 48 ++++++++++++++-------------- src/prep/configuration-prep.k | 44 ++++++++++++------------- src/prep/elaboration-categories.k | 4 +-- src/prep/elaboration-core.k | 2 +- src/prep/elaboration-method-invoke.k | 2 +- src/prep/elaboration-vars.k | 2 +- src/prep/literals.k | 2 +- 10 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/common/core-sorts.k b/src/common/core-sorts.k index a7c83f08..2365fcdc 100644 --- a/src/common/core-sorts.k +++ b/src/common/core-sorts.k @@ -105,7 +105,7 @@ syntax KResult ::= ContextType //@ \subsection{Values} -/* Represents a java value. May be either primitive --- int, float, bool, of reference. The values nothing and undefined +/* Represents a Java value. May be either primitive --- int, float, bool, of reference. The values nothing and undefined are special cases required by the semantics. The value nothing is associated with the return type void. The value undefined is the initial value of uninitialized local variables, before the first assignment. */ diff --git a/src/common/shared-syntax.k b/src/common/shared-syntax.k index dddcb088..3283780f 100644 --- a/src/common/shared-syntax.k +++ b/src/common/shared-syntax.k @@ -1,5 +1,5 @@ module SHARED-SYNTAX -/*previously defined elsewhere for ltl-support, now these syntax are also used for java, +/*previously defined elsewhere for ltl-support, now these syntax are also used for Java, although we don't incorporate ltl for now, let's keep this independent like this */ syntax Exp ::= Exp "<=" Exp [seqstrict, klabel('LtEq)] diff --git a/src/exec/api-core.k b/src/exec/api-core.k index 30d21082..bf89e717 100644 --- a/src/exec/api-core.k +++ b/src/exec/api-core.k @@ -8,7 +8,7 @@ All the methods defined in this module through invokeImpl are native, their body they cannot be matched by rules in METHOD-INVOKE. */ -/*@ This module contains the minimal part of java API required to perform console read/write operations, +/*@ This module contains the minimal part of Java API required to perform console read/write operations, as well as a few other API functions mentioned in JLS.*/ //@system-out-print-convert heat argument @@ -35,10 +35,10 @@ when Class ==K class String2Id("java.io.PrintWriter") andBool Id2String(MethodName) ==String "print" //With [transition-threading], the time to produce 2 solutions for the test threads_11_two_th_msg is 14s. - //But with [transition-strictness], the same test takes 3m52s, with java heap = 16GB. + //But with [transition-strictness], the same test takes 3m52s, with Java heap = 16GB. [transition-threading] -//@Is only used for primitive type arguments. Object arguments are converted by java code inside the class PrintWriter. +//@Is only used for primitive type arguments. Object arguments are converted by Java code inside the class PrintWriter. rule [system-out-print-convert]: invokeImpl( methodRef(sig(MethodName:Id, _), Class:ClassType), _, @@ -113,7 +113,7 @@ rule [object-getClass-on-array]: when Class ==K classObject andBool Id2String(MethodName) ==String "getClass" -/*@ \verb|String.toString()|. For \verb|Object.toString()| the implementation is in the library java code.*/ +/*@ \verb|String.toString()|. For \verb|Object.toString()| the implementation is in the library Java code.*/ rule [object-toString-on-String]: invokeImpl( methodRef(sig(MethodName:Id, _), Class:ClassType), Str:String::_, diff --git a/src/exec/configuration-exec.k b/src/exec/configuration-exec.k index 4960a26e..09657f77 100644 --- a/src/exec/configuration-exec.k +++ b/src/exec/configuration-exec.k @@ -7,41 +7,41 @@ The execution configuration consists from the top-level cell \cellref{T}, whose \paragraph{Threads} Each execution thread has a corresponding \cellref{thread}. Inside a thread, \cellref[K]{k} is represents the actual computation --- the sequence of tasks to be executed. Next cells are \cellref[List]{stack} --- the method call stack, and \cellref{methodContext}. The \cellref{methodContext} holds the local context of the executed method: \begin{itemize} - \item \cellref[Map{{[}}Id\mapsto{}Int{{]}}]{env} --- the map from local variable names to their location inside \cellref[]{store}. - \item \cellref[ClassType]{crntClass} --- the current class, the type of \verb|this| + \item \cellref[Map{{[}}Id \mapsto Int{{]}}]{env} --- The map from local variable names to their location inside \cellref[]{store}. + \item \cellref[ClassType]{crntClass} --- The current class, the type of \verb|this|. \item \cellref[Int]{location} --- The location in memory store of the current object. \end{itemize} On the next line there are 3 cells related to multithreading: \begin{itemize} - \item \cellref{tid} --- the thread identified, generated when the thread is created. - \item \cellref[Map{{[}}Int\mapsto{}Int{{]}}]{holds} --- a map from Object locations to integer numbers. Map keys are monitor objects on which the current thread has the locks. Map values hold the number of times the lock was acquired. - \item \cellref[Bool]{interrupted} --- boolean value signaling whether the current thread was interrupted. + \item \cellref{tid} --- The thread identified, generated when the thread is created. + \item \cellref[Map{{[}}Int \mapsto Int{{]}}]{holds} --- A map from Object locations to integer numbers. Map keys are monitor objects on which the current thread has the locks. Map values hold the number of times the lock was acquired. + \item \cellref[Bool]{interrupted} --- A boolean value signaling whether the current thread was interrupted. \end{itemize} \paragraph{Classes} The cell \cellref{classes} contains one \cellref{class} for each class in the program, both for supported JDK classes and for user-defined classes. Cell \cellref{class} has the following content: \begin{itemize} - \item \cellref[ClassType]{classType} --- the fully qualified class name. This cell serves as identifier for the whole \cellref{class}, thus \cellref{classes} may be seen as a map from class name to \cellref{class} content. - \item \cellref[ClassMetaType]{classMetaType} --- Whether this type is class or interface. Both are referred hereafter as "classes", making the distinctions only when necessary. + \item \cellref[ClassType]{classType} --- The fully qualified class name. This cell serves as identifier for the whole \cellref{class}, thus \cellref{classes} may be seen as a map from class name to \cellref{class} content. + \item \cellref[ClassMetaType]{classMetaType} --- Indicates whether this type is class or interface. Both are referred hereafter as "classes", making the distinctions only when necessary. \item \cellref[ClassPhase]{classPhase} --- Used during unfolding global phase (see below). \item \cellref[ClassType]{enclosingClass} --- For inner classes, the direct lexically enclosing class of this class. For top-level classes --- no value. \item \cellref[ClassType]{extends} --- The base class. - \item \cellref[Set {[} ClassType {]} ]{implTrans} --- the transitive closure of implemented interfaces. + \item \cellref[Set {[} ClassType {]} ]{implTrans} --- The transitive closure of implemented interfaces. \item \cellref[ Map {[} Signature \mapsto ClassType {]} ]{methods} --- The map of accessible methods. Keys are method signatures, values are classes where methods are defined. Includes both methods declared within this class as well as methods inherited from base classes/ base interfaces. - \item \cellref[Bag]{methodDecs} --- the collection of method declarations (\cellref{methodDec} cells)in the current class. This cell contains only a subset of methods from \cellref{methods}, as the set of accessible methods from \cellref{methods} also includes methods inherited from base classes/interfaces. Hence the need of two separate collections. Each \cellref[Bag]{methodDec} contains the following data: + \item \cellref[Bag]{methodDecs} --- The collection of method declarations (\cellref{methodDec} cells)in the current class. This cell contains only a subset of methods from \cellref{methods}, as the set of accessible methods from \cellref{methods} also includes methods inherited from base classes/interfaces. Hence the need of two separate collections. Each \cellref[Bag]{methodDec} contains the following data: \begin{itemize} \item \cellref[Signature]{methodSignature} --- The method signature, acting as identifier of the \cellref{methodDec} - \item \cellref[ List{[} Param {]} ]{methodParams} --- method parameters + \item \cellref[ List{[} Param {]} ]{methodParams} --- The method parameters. \item \cellref[K]{methodBody} --- method body - \item \cellref[AccessMode]{methodAccessMode} --- method access mode - \item \cellref[ContextType]{methodContextType} --- either static or instance + \item \cellref[AccessMode]{methodAccessMode} --- The method access mode. + \item \cellref[ContextType]{methodContextType} --- May be either static or instance. \end{itemize} \item \cellref[K]{instanceFields} --- The list of instance field declarations, stored as a list of local variable declaration statements, without initializers. Used during object instantiation. \item \cellref[K]{staticFields} --- The list of static field declarations, in a similar format as \cellref{instanceFields} \item \cellref[K]{staticInit} --- The list of static initializers and static field initializers concatenated into one block. The content of \cellref{staticFields} and \cellref{staticInit} is executed during class static initialization. - \item \cellref[K]{folded} --- the initial representation of the class in AST format, during unfolding phase (see below). - \item \cellref[StaticInitStatus]{staticInitStatus} --- the static initialization status of the class. May be either uninitialized, initializing or initialized. The content of this class is used to trigger static initialization of the class on first use. + \item \cellref[K]{folded} --- The initial representation of the class in AST format, during unfolding phase (see below). + \item \cellref[StaticInitStatus]{staticInitStatus} --- The static initialization status of the class. May be either uninitialized, initializing or initialized. The content of this class is used to trigger static initialization of the class on first use. \item \cellref[ Map{[} Id \mapsto Location {]} ]{staticEnv} --- The map from static fields declared in this class to their locations in the store. Populated during static initialization. This cell along with \cellref{staticInitStatus} are the only two cells of \cellref{class} altered during program execution, during static initialization. The rest of the cells are populated before the execution. \end{itemize} @@ -49,13 +49,13 @@ On the next line there are 3 cells related to multithreading: The first three cells after \cellref{classes} are important at the beginning of computation: \begin{itemize} \item \cellref[K]{program} --- The initial AST representation of the program, containing both core classes from JDK and user-defined classes. - \item \cellref[K]{mainClass} --- The class containing the method \verb|main()| --- the starting point of execution. Loaded froma command line argument. - \item \cellref[K]{globalPhase} --- Computation in the execution semantics may be in one of two global phases: Unfolding and Execution. The role of hte unfolding phase is to convert the AST representation of the program stored in \cellref{program} into the collection of cells \cellref{classes}. When this operation is complete, execution phase follows. + \item \cellref[K]{mainClass} --- The class containing the method \verb|main()| --- the starting point of execution. Loaded from a command line argument. + \item \cellref[K]{globalPhase} --- Computation in the execution semantics may be in one of two global phases: Unfolding and Execution. The role of the unfolding phase is to convert the AST representation of the program stored in \cellref{program} into the collection of cells \cellref{classes}. When this operation is complete, execution phase follows. \end{itemize} The next 4 cells represent the memory model of K-Java: \begin{itemize} - \item \cellref[Map{[}Location:Int \mapsto Value:TypedVal{]}]{store} --- the program memory. Map from memory locations to actual values. For reference types only the reference is stored in this cell. + \item \cellref[Map{[}Location:Int \mapsto Value:TypedVal{]}]{store} --- The program memory. Map from memory locations to actual values. For reference types only the reference is stored in this cell. \item \cellref[ Map{[} Location:Int \mapsto LocMetadata {]} ]{storeMetadata} --- For each location in \cellref{store}, information whether that location is a local variable or field. Used for performance optimization of multi-threaded model-checking. \item \cellref[Int]{nextLoc} --- the next available memory location. Incremmented after each allocation. \item \cellref[ Map{[} Type \mapsto TypedVal {]} ]{classLiteralsMap} --- A map from types T to objects that represent the value of the expression \verb|T.class| . @@ -63,10 +63,10 @@ The next 4 cells represent the memory model of K-Java: \begin{itemize} \item \cellref[Int]{objectId} --- A unique object identifier, pointed by each reference in \cellref{store} \item \cellref[ClassType]{objectType} --- The runtime type of the object. - \item \cellref[Bag]{layer} --- There could be multiple layer cells inside an \cellref{object}. Each layer represents a concrete class in the inheritance hierarchy, starting from \verb|java.lang.Object| and finishing with \cellref{objectType}. An object layer stores the follosing information: + \item \cellref[Bag]{layer} --- There could be multiple layer cells inside an \cellref{object}. Each layer represents a concrete class in the inheritance hierarchy, starting from \verb|Java.lang.Object| and finishing with \cellref{objectType}. An object layer stores the following information: \begin{itemize} \item \cellref[ClassType]{layerClass} --- The class represented by this layer. - \item \cellref[Map{[}Id \mapsto Int{]}]{layerEnv} --- A map from instante fields to their loations in the store. + \item \cellref[Map{[}Id \mapsto Int{]}]{layerEnv} --- A map from instance fields to their locations in the store. \item \cellref[TypedVal]{layerEnclosingObject} --- A reference to the directly enclosing object if this object represents an instance inner class, or empty for other types of objects (top-level and static inner). \end{itemize} \end{itemize} @@ -74,15 +74,15 @@ The next 4 cells represent the memory model of K-Java: The following cells represent program I/O: \begin{itemize} - \item \cellref[List]{in} --- the standard input, represented as pre-parsed list of elements of type Int or String. - \item \cellref[List]{out} --- the standard output. + \item \cellref[List]{in} --- The standard input, represented as pre-parsed list of elements of type Int or String. + \item \cellref[List]{out} --- The standard output. \end{itemize} The next row contains global cells related to multithreading: \begin{itemize} - \item \cellref[ Set{[} ObjLocation:Int {]} ]{busy} --- the set of busy objects. E.g. monitor objects for which there is a thread holding the monitor. + \item \cellref[ Set{[} ObjLocation:Int {]} ]{busy} --- The set of busy objects. E.g. monitor objects for which there is a thread holding the monitor. \item \cellref[ Map{[} ThreadId:Int \mapsto OL:Int {]} ]{waitingThreads} --- The map from threads to monitor objects on which respective threads are blocked in a call to \verb|wait()|. Used by the methods \verb|Object.wait()|, \verb|Object.notify()|, \verb|Object.notifyAll()|. - \item \cellref[Set{[}ThreadId:Int{]}]{terminated} --- the set of identifiers of terminated threads. + \item \cellref[Set{[}ThreadId:Int{]}]{terminated} --- The set of identifiers of terminated threads. \end{itemize} The rest of the global cells are used for debugging purposes. @@ -233,7 +233,7 @@ configuration //Initial cells, loaded by krun and initial configuration. //The initial program loaded by krun. For full mode and preprocessing this is - //the initial java program, for execution mode it is the folded java program. + //the initial Java program, for execution mode it is the folded Java program. $PGM:K //Main class, passed as krun argument. We need it from the outside, just like JDK Java. diff --git a/src/prep/configuration-prep.k b/src/prep/configuration-prep.k index 7e2cd064..3ee65be8 100644 --- a/src/prep/configuration-prep.k +++ b/src/prep/configuration-prep.k @@ -3,7 +3,7 @@ module CONFIGURATION-PREP imports CORE-FUNCTIONS /*@ -The Static semantics consists of several phases that analyze the input program, distribute it from the AST form to a set of cells and finally assembles it back to an AST, this time containing just a subset of features of Java. Each phase digs deeper into a program strucutre, and most phases also store their result into new cells. Below is the list of global phases, in their execution order: +The Static semantics consists of several phases that analyze the input program, distribute it from the AST form to a set of cells and finally assembles it back to an AST, this time containing just a subset of features of Java. Each phase digs deeper into a program structure, and most phases also store their result into new cells. Below is the list of global phases, in their execution order: \begin{itemize} \item Process Type Names @@ -27,19 +27,19 @@ In the remaining of this section are documented all cells of the configuration, \paragraph{Process Type Names} During this phase, one global cell is computed: \begin{itemize} - \item \cellref[Map{[}PackageId\mapsto{}Map{[}Id\mapsto{}ClassType{]}{]}]{namesToClasses} A two-level map. First level is a map from package names to second-level maps. Second-level maps are from simple class names to fully qualified class names within the package. This cell is extensively used through the semantics. The map contains both top-level and inner classes. For inner classes, their enclosing package is the fully qualified class name of the directly enclosing class. + \item \cellref[Map{[}PackageId \mapsto Map{[}Id\mapsto{}ClassType{]}{]}]{namesToClasses} --- A two-level map. First level is a map from package names to second-level maps. Second-level maps are from simple class names to fully qualified class names within the package. This cell is extensively used through the semantics. The map contains both top-level and inner classes. For inner classes, their enclosing package is the fully qualified class name of the directly enclosing class. \end{itemize} Also during Process Type Names classes are first registered. Again, both top-level and inner classes are covered. In a newly created \cellref[]{class} just a few sub-cells are initialized with data: \begin{itemize} \item \cellref[ClassType]{classType} --- The fully qualified class name. The identifier of the class. - \item \cellref[ClassMetaType]{classMetaType} --- Whether the type stored in this cell is class or interface. To avoid terminology superfluousness, we will refer hereafter to both classes and interfaces as "classes", making distinctions only when necessary. + \item \cellref[ClassMetaType]{classMetaType} --- Represents whether the type stored in this cell is class or interface. To avoid terminology superfluousness, we will refer hereafter to both classes and interfaces as "classes", making distinctions only when necessary. \item \cellref[ClassAccessMode]{classAccessMode} --- The access modifier of the class, either public or package. - \item \cellref[ClassPhase]{classPhase} --- represents the state of this class. In addition to the global computation phase, each class has its own lifecycle phase. Class phases are required to keep track which classes were processed in the current global phase and which were not. During each global phase all classes should transition to a certain class phase. However, as we shall see, not all global phases change the state of the class. The class phases are: + \item \cellref[ClassPhase]{classPhase} --- Represents the state of this class. In addition to the global computation phase, each class has its own lifecycle phase. Class phases are required to keep track which classes were processed in the current global phase and which were not. During each global phase all classes should transition to a certain class phase. However, as we shall see, not all global phases change the state of the class. The class phases are: \begin{itemize} - \item Discovered --- the initial phase. At the end of Process Type Names all classes are in the state "Discovered". + \item Discovered --- The initial phase. At the end of Process Type Names all classes are in the state "Discovered". \item Stored \item Bases Resolved \item Declaration Processed @@ -52,11 +52,11 @@ Also during Process Type Names classes are first registered. Again, both top-lev \paragraph{Process Compilation Units} At the beginning of this phase computation is again initialized with the initial AST from \cellref{program}. The following new cells are filled in inside each \cellref{class}: \begin{itemize} - \item \cellref[ClassType]{enclosingClass} --- the directly enclosing class, for inner classes, or no value for top-level classes. + \item \cellref[ClassType]{enclosingClass} --- The directly enclosing class, for inner classes, or no value for top-level classes. \item \cellref[K]{rawExtends} --- The extends clause of this class, in its raw (AST) form. \item \cellref[K]{rawImplements} --- The implements clause, in AST form. \item \cellref[K]{rawDeclarations} --- The class body, in AST form. - \item \cellref[Map{[}Id\mapsto{}ClassType{]}]{cuImports} --- A map from names accessible inside this class to fully qualified class names they represent. Only computed for top-level classes at this phase. For inner classes this cell remains empty. + \item \cellref[Map{[}Id \mapsto ClassType{]}]{cuImports} --- A map from names accessible inside this class to fully qualified class names they represent. Only computed for top-level classes at this phase. For inner classes this cell remains empty. \item \cellref[ContextType]{classContextType} --- Either static or instance, for inner classes. Always static for top-level classes. \end{itemize} @@ -66,7 +66,7 @@ The class phase changes from Discovered to Stored. As we can see, the cells comp Also during Process Compilation Units the following global cell is used: \begin{itemize} - \item \cellref[Map{[}Id\mapsto{}ClassType{]}]{compUnitImports} A map from all type names accessible in the current compilation unit (Java file) to their respective fully qualified class names. This includes both classes accessible through imports declarations and classes declared in the package of the current compilation unit. Used to compute \cellref{cuImports} of top-level classes. + \item \cellref[Map{[}Id \mapsto ClassType{]}]{compUnitImports} --- A map from all type names accessible in the current compilation unit (Java file) to their respective fully qualified class names. This includes both classes accessible through imports declarations and classes declared in the package of the current compilation unit. Used to compute \cellref{cuImports} of top-level classes. \end{itemize} \paragraph{Process Class Declarations} Here each class passes through two more class phases: Bases Processed and Declarations Processed. First, for each class the semantics attempts to resolve its extends/implements clauses into fully qualified class names. The order in which dependencies are resolved depends on both class inheritance relationships as well as nesting relationships. Once the dependencies of a class are resolved, they are stored into a temporary cell: @@ -80,7 +80,7 @@ Once the content of \cellref[K]{unprocessedBases} is created, the class enters i \begin{itemize} \item \cellref[ClassType]{extends} --- The base class, fully qualified. \item \cellref[Set{[}ClassType{]}]{implements} --- The list of directly implemented interfaces, fully qualified. -\item \cellref[Map{[}Id\mapsto{}ClassType{]}]{imports} --- The map of classes accessible by simple name within the body of this class. The rules for computing this map are complex and include the following sources: +\item \cellref[Map{[}Id \mapsto ClassType{]}]{imports} --- The map of classes accessible by simple name within the body of this class. The rules for computing this map are complex and include the following sources: \begin{itemize} \item Imports declarations of the current compilation unit. @@ -114,16 +114,16 @@ The following new class cells are produced: \begin{itemize} \item \cellref[Set{[}ClassType{]}]{implTrans} --- The transitive closure of implemented interfaces. In the remaining phases this set is used by the subtyping relationship. \item \cellref[ Map {[} Signature \mapsto ClassType {]} ]{methods} --- The map of accessible methods. Keys are method signatures, values are classes where methods are defined. Includes both methods declared within this class as well as methods inherited from base classes/ base interfaces. - \item \cellref[Bag]{methodDecs} --- the collection of method declarations (\cellref{methodDec} cells)in the current class. This cell contains only a subset of methods from \cellref{methods}, as the set of accessible methods from \cellref{methods} also includes methods inherited from base classes/interfaces. Hence the need of two separate collections. Each \cellref[Bag]{methodDec} contains the following data: + \item \cellref[Bag]{methodDecs} --- The collection of method declarations (\cellref{methodDec} cells)in the current class. This cell contains only a subset of methods from \cellref{methods}, as the set of accessible methods from \cellref{methods} also includes methods inherited from base classes/interfaces. Hence the need of two separate collections. Each \cellref[Bag]{methodDec} contains the following data: \begin{itemize} - \item \cellref[Signature]{methodSignature} --- The method signature, acting as identifier of the \cellref{methodDec} - \item \cellref[Type]{methodReturnType} --- Method return type - \item \cellref[ List{[} Param {]} ]{methodParams} --- method parameters + \item \cellref[Signature]{methodSignature} --- The method signature, acting as identifier of the \cellref{methodDec}. + \item \cellref[Type]{methodReturnType} --- The method return type. + \item \cellref[ List{[} Param {]} ]{methodParams} --- The method parameters. \item \cellref[K]{methodConstrFirstLine} --- the first line of a constructor (if this method is indeed a constructor, for other classes than \verb|Object|). It contains a call to another constructor: either \verb|super()| or \verb|this()|. - \item \cellref[K]{methodBody} --- method body - \item \cellref[AccessMode]{methodAccessMode} --- method access mode - \item \cellref[ContextType]{methodContextType} --- either static or instance - \item \cellref[MethodMetaType]{methodMetaType} --- either method or constructor + \item \cellref[K]{methodBody} --- The method body. + \item \cellref[AccessMode]{methodAccessMode} --- The method access mode. + \item \cellref[ContextType]{methodContextType} --- May be either static or instance. + \item \cellref[MethodMetaType]{methodMetaType} --- May be either method or constructor. \end{itemize} \item \cellref[K]{instanceFields} --- The list of instance field declarations, stored as a list of local variable declaration statements, without initializers. Used during object instantiation. \item \cellref[K]{instanceInit} --- The list of instance initializers of the class combined into one big instance initializer. Instance field initializers are also concatenated into this cell in their textual order. @@ -137,7 +137,7 @@ Once all the cells above are computed the class proceeds into the phase Members \paragraph{Elaboration} Here all the code blocks are processed --- method and constructor bodies, static and instance initializers. Most of the information traditionally inferred by the compiler is computed at this phase. More precisely the elaboration performs the following transformations: \begin{itemize} -\item Each name is resolved into local variable, field, method, class or package. While a method may be distinguished from other cathegories purely syntactically, resolving to other categories requires knowledge of the names existing in the current context. +\item Each name is resolved into local variable, field, method, class or package. While a method may be distinguished from other categories purely syntactically, resolving to other categories requires knowledge of the names existing in the current context. \item Simple class names are resolved into fully qualified class names. Hereafter all the class names in the code are fully qualified. \item The compile-time type of each expression is inferred. Thus, when the code reaches execution phase, expressions are no longer in their initial form. The expressions are annotated with their types. \item For each method call the precise signature in inferred. @@ -156,13 +156,13 @@ Among global cells the following new cells are added: \item \cellref[List[mapWrap(Map[Id \mapsto Type])]]{elabEnv} --- A stack where each layer is a map of local variables. Each layer of the stack represents a code block, in the blocks nesting order. Inside each layer, the map is from local variables accessible in that layer to variable types. \item \cellref[Int]{contextType} --- The context type of the currently elaborated class. Either static or instance. \item \cellref[List[mapWrap(Map[Id \mapsto ClassType])]]{localTypes} --- A cell similar in structure to \cellref{elabEnv}. This time it contains stack layers which are maps from local class names to local class types. - \item \cellref[Int]{nextLocalId} --- a number used to generate unique fully-qualified class names for local classes. - \item \cellref[K]{elabBuffer} --- a temporary cell used during elaboration of local classes. + \item \cellref[Int]{nextLocalId} --- A number used to generate unique fully-qualified class names for local classes. + \item \cellref[K]{elabBuffer} --- A temporary cell used during elaboration of local classes. \end{itemize} During the elaboration phase no cells are consumed. Instead, the code blocks stored inside \cellref[]{methodDecs}, \cellref[]{instanceInit}, \cellref[]{staticInit} are processed and stored back into the same cell. After elaboration the classes remain in the same state --- Members Processed. The state Members Processed is in fact the final state of the cell \cellref[]{class}. -\paragraph{Folding} During the last phase of static semantics the program is assembled from \cellref{classes} back into the AST form. First the content of each class is assembled into \cellref[K]{folded} of the respective class, and the class phase changes to Folded. Second, the AST representation of each class is appended into \cellref{program}. When this phase ends, the content of \cellref{program} is printed to the standart output. +\paragraph{Folding} During the last phase of static semantics the program is assembled from \cellref{classes} back into the AST form. First the content of each class is assembled into \cellref[K]{folded} of the respective class, and the class phase changes to Folded. Second, the AST representation of each class is appended into \cellref{program}. When this phase ends, the content of \cellref{program} is printed to the standard output. */ configuration @@ -172,7 +172,7 @@ configuration $PGM:K //The initial program loaded by krun. For full mode and preprocessing this is - //the initial java program, for execution mode it is the folded java program. + //the initial Java program, for execution mode it is the folded Java program. $PGM:K ProcTypeNamesPhase diff --git a/src/prep/elaboration-categories.k b/src/prep/elaboration-categories.k index f895b1b8..6351fa2f 100644 --- a/src/prep/elaboration-categories.k +++ b/src/prep/elaboration-categories.k @@ -213,7 +213,7 @@ rule defaultElabHeating('stmtAndExp) => true Those are literals, types and packages. They are heated "as is", without being wrapped into \verb|elab()|. An exception is the class literal that is not executed during elaboration. - Some auxiliary functions are also included in this cathegory in order to reduce the usage of elaboration wrappers. + Some auxiliary functions are also included in this category in order to reduce the usage of elaboration wrappers. */ syntax KItem ::= isElabNaked ( K ) [function] rule isElabNaked(RV:RawVal) => true @@ -235,7 +235,7 @@ Terms that should use custom elaboration rules. For those terms: - They will not be automatically passed to \verb|elabDispose()| state. Instead, those terms should have custom rules for elaboration start (heating) and elaboration end (cooling). Since all the automatic elaboration-related rules are an incredible mess, we have to put all the AST terms into this - cathegory one by one, and eliminate automatic elaboration heating/cooling rules altogether. + category one by one, and eliminate automatic elaboration heating/cooling rules altogether. \end{markdown} */ syntax KItem ::= customElabChildren ( KLabel ) [function] diff --git a/src/prep/elaboration-core.k b/src/prep/elaboration-core.k index ee7a50e9..7508d010 100644 --- a/src/prep/elaboration-core.k +++ b/src/prep/elaboration-core.k @@ -170,7 +170,7 @@ The default algorithm of transforming the term from elab to elabRes, when the ch - term children are completely elaborated --- \verb|isElab(children)| - term is not naked. This case should never be true, but there is some weird case that requires it. -When the default algorithm is not appropriate, the respective term should be in the cathegory customElabChildren +When the default algorithm is not appropriate, the respective term should be in the category customElabChildren \end{markdown} */ syntax KItem ::= elabDispose ( K ) diff --git a/src/prep/elaboration-method-invoke.k b/src/prep/elaboration-method-invoke.k index 61284896..41dea0c5 100644 --- a/src/prep/elaboration-method-invoke.k +++ b/src/prep/elaboration-method-invoke.k @@ -217,7 +217,7 @@ syntax KItem ::= methodLookupResult ( /*@ In the past implementation, the non-empty qualifier of a static method call was moved to a separate statement in front of a method call using stmtAndExp(). - But since stmtAndExp() is incompatible with java intermediate form, we keep the non-empty qualifier + But since stmtAndExp() is incompatible with Java intermediate form, we keep the non-empty qualifier as is even for static methods. */ rule [methodProcessArguments-Invoke-end]: diff --git a/src/prep/elaboration-vars.k b/src/prep/elaboration-vars.k index 1ea19db9..66839003 100644 --- a/src/prep/elaboration-vars.k +++ b/src/prep/elaboration-vars.k @@ -2,7 +2,7 @@ module ELABORATION-VARS imports CORE-SORTS imports ELABORATION-CORE -//@ Elaboration of rules in java-var-lookup +//@ Elaboration of terms defined in var-lookup.k //@ Both unqualified and qualified AmbName. rule [elabEnd-AmbName]: elabEnd('AmbName(Ks:KList)) => elabEnd('ExprName(Ks)) ?? 'TypeName(Ks) ?? 'PackageName([Ks]) diff --git a/src/prep/literals.k b/src/prep/literals.k index 596bea84..834f2014 100644 --- a/src/prep/literals.k +++ b/src/prep/literals.k @@ -117,7 +117,7 @@ rule 'Lit('Bool('True(.KList))) => true rule 'Lit('Bool('False(.KList))) => false //@ \subsection{char literals} -//@ Chars are represented as int values, as described in java specification. +//@ Chars are represented as int values, as described in Java specification. // 'Lit('Char('Single( I:Int ))) rule 'Lit('Char('Single( I:Int ))) => I :: char From 5faac14792608e0d249f6fdfa429e5c43b429864 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Fri, 20 Feb 2015 12:00:32 +0200 Subject: [PATCH 08/43] Doc: Punctuation review. Review \vspace throughout the document. --- src/exec/method-invoke.k | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/exec/method-invoke.k b/src/exec/method-invoke.k index b88970e7..efacbfbf 100644 --- a/src/exec/method-invoke.k +++ b/src/exec/method-invoke.k @@ -88,8 +88,6 @@ The cell \cellref[]{methodDec} represents a method declared inside the current c In order for strictness and context rules to work we have to define some K productions as KResult. The most common forms of KResult in Java are the following: -\vspace{3ex} - \begin{syntaxBlock}{\nonTerminal{\sort{KResult}}} \syntax{{\nonTerminal{\sort{ClassType}}}}{} \syntaxCont{{\nonTerminal{\sort{TypedVal}}}}{} @@ -98,8 +96,6 @@ In order for strictness and context rules to work we have to define some K produ The first represents a class. Second is a typed value, the result of evaluation of any expression. The forms of typed values relevant for method invocation are object reference and null: -\vspace{3ex} - \begin{syntaxBlock}{\nonTerminal{\sort{TypedVal}}}\syntax{{}\terminal{objectRef} ({{\nonTerminal{\sort{Int}}}},{{\nonTerminal{\sort{ClassType}}}}){} \terminal{::}{{\nonTerminal{\sort{ClassType}}}}}{}\syntaxCont{{}\terminal{null} @@ -180,8 +176,6 @@ While there are two sections dedicated to this logic (\S15.12.4.1, \S15.12.4.2), for it. Instead, subexpressions evaluation ensured by strictness annotations that accompany the following syntax definitions: -\vspace{3ex} - \begin{syntaxBlock}{ \nonTerminal{\sort{Exp}}}\syntax{{{\nonTerminal{\sort{K}}}}\terminal{.}{{\nonTerminal{\sort{MethodName}}}} ({{\nonTerminal{\sort{Exps}}}})}{\kattribute{seqstrict}(1,3)} @@ -259,8 +253,6 @@ Note that in this rule variable Args is defined of type TypedVals instead of Exp arguments (and consequently the qualifier) are already evaluated at the moment when this rule is invoked. The sort TypedVals represents a list of typed values, the evaluation result of Exps. It is defined as following: -\vspace{3ex} - \begin{syntaxBlock}{ \nonTerminal{\sort{TypedVals}}}\syntax{List\{{\nonTerminal{\sort{TypedVal}}}, \mbox{``},\mbox{''}\}}{} \end{syntaxBlock} @@ -334,8 +326,6 @@ The production \verb|methodRef()| is a reference to a method declaration. It con signature and the declaration class. The implementation class is the class that contains the actual method declaration to be invoked. -\vspace{3ex} - \begin{syntaxBlock}{ \nonTerminal{\sort{MethodName}}}\syntax{{}\terminal{methodRef}({{\nonTerminal{\sort{Signature}}}},{{\nonTerminal{\sort{RefType}}}})}{} \end{syntaxBlock} @@ -645,6 +635,7 @@ rule [lookupPackageMethod-end]: /*@ For the code example above, the term \verb|lookupPackageMethod()| will pass through the following forms during evaluation: +\vspace{3ex} \begin{tabular}{ | l | l | } \hline $\mathrel{}\kall{k}{ lookupPackageMethod(f(), (a.A, a.B, b.C), \dotCt{K}) ...}$ &\\ From 712757024487ddbf109d8608004e18c983eddd3c Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Fri, 20 Feb 2015 12:28:18 +0200 Subject: [PATCH 09/43] Doc: Punctuation review. Write with \verb|...| style rule variables from method-invoke. No need for other modules. --- src/exec/method-invoke.k | 86 ++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/exec/method-invoke.k b/src/exec/method-invoke.k index efacbfbf..426bf926 100644 --- a/src/exec/method-invoke.k +++ b/src/exec/method-invoke.k @@ -210,13 +210,13 @@ During the second step of the method invocation the second argument of the produ structure \verb|methodInfo()|. This data structure contains the information required to choose the right method lookup strategy at the next step. The production \verb|methodInfo()| contains the following arguments: - - Method signature Sig - - Qualifying class QualC of the method invocation, e.g. the compile-time type of the qualifier. - - The meta type of QualC --- MetaT. It may have one of the two values - class or interface. - - DecC --- declaring class, the class where the method was actually declared, as observed by QualT. - E.g. the most derived class in QualC hierarchy where there is a declaration of a method with signature Sig. - - ContextT --- the context type of the method. Either static, for static methods, or instance for non-static methods. - - Acc --- access modifier (private, package, protected or public). For the purpose of uniformity we use the modifier + - Method signature \verb|Sig| + - Qualifying class \verb|QualC| of the method invocation, e.g. the compile-time type of the qualifier. + - The meta type of \verb|QualC| --- \verb|MetaT|. It may have one of the two values - class or interface. + - \verb|DecC| --- declaring class, the class where the method was actually declared, as observed by \verb|QualT|. + E.g. the most derived class in \verb|QualC| hierarchy where there is a declaration of a method with signature \verb|Sig|. + - \verb|ContextT| --- the context type of the method. Either static, for static methods, or instance for non-static methods. + - \verb|Acc| --- access modifier (private, package, protected or public). For the purpose of uniformity we use the modifier package when no access modifier is provided. All the information stored in \verb|methodInfo()| is static. In K-Java we already have @@ -268,7 +268,7 @@ Because TypedVal is subsorted to KResult, TypedVals being a list of KResult is i to keep the core part of method invocation separate from the non object-related part. */ /*@ -The second rule for method invocation loads MetaT and DecC. It requires Sig and QualC computed by the previous rule. +The second rule for method invocation loads \verb|MetaT| and \verb|DecC|. It requires \verb|Sig| and \verb|QualC| computed by the previous rule. */ rule [Invoke-compute-methodInfo-DecC]: @@ -282,14 +282,14 @@ rule [Invoke-compute-methodInfo-DecC]: /*@ \begin{markdown} There is one case that is not covered by the previous rule --- the case when the cell \cellref[]{methods} does not have a key - equal to Sig. This is possible in one of the following situations: + equal to \verb|Sig|. This is possible in one of the following situations: - Qualifying type is an interface. - Qualifying type is an abstract class. The called method is inherited from an interface but is not declared neither in this class nor in its base classes. -In both cases the method is an abstract method in the class QualT. For this case DecC cannot be computed, but we know - for sure that ContextT for an abstract method is instance. Also, because the method was declared in an interface, +In both cases the method is an abstract method in the class \verb|QualT|. For this case \verb|DecC| cannot be computed, but we know + for sure that \verb|ContextT| for an abstract method is instance. Also, because the method was declared in an interface, it is certainly public. \end{markdown} */ rule [Invoke-compute-methodInfo-unmapped-method-ContextType]: @@ -304,7 +304,7 @@ when notBool Sig in keys(Methods) /*@ -The last rule of step 3 loads ContextT and Acc. It requires DecC, so this rule may only match after the second rule for \verb|methodInfo()|. +The last rule of step 3 loads \verb|ContextT| and \verb|Acc|. It requires \verb|DecC|, so this rule may only match after the second rule for \verb|methodInfo()|. */ rule [Invoke-compute-methodInfo-ContextType]: @@ -322,7 +322,7 @@ rule [Invoke-compute-methodInfo-ContextType]: In the third step of the method invocation algorithm, the actual method declaration is chosen. This step starts once all the fields of \verb|methodInfo()| were filled in (where possible). The rules of this step rewrite \verb|methodInfo()| into \verb|methodRef()| --- another auxiliary data structure. -The production \verb|methodRef()| is a reference to a method declaration. It contains two fields --- Sig and DecC --- the +The production \verb|methodRef()| is a reference to a method declaration. It contains two fields --- \verb|Sig| and \verb|DecC| --- the signature and the declaration class. The implementation class is the class that contains the actual method declaration to be invoked. @@ -331,7 +331,7 @@ The production \verb|methodRef()| is a reference to a method declaration. It con \end{syntaxBlock} \begin{markdown} -Since we already know the signature, this phase amounts to computing DecC. This step contains different rules for the following cases: +Since we already know the signature, this phase amounts to computing \verb|DecC|. This step contains different rules for the following cases: - Static method (JLS \S15.12.4.4 paragraph 2) - Instance method with target being null (JLS \S15.12.4.4 paragraph 3) @@ -342,7 +342,7 @@ Since we already know the signature, this phase amounts to computing DecC. This -The method below is for the first case. If the method is static, then the declaring type DecC is the qualifying type. +The method below is for the first case. If the method is static, then the declaring type \verb|DecC| is the qualifying type. The qualifier is discarded by rewriting it into \dotCt{K} . \end{markdown} */ @@ -352,9 +352,9 @@ rule [Invoke-methodInfo-static]: (_) /*@ -If the qualifier value is null and ContextT is instance, then NullPointerException is thrown and method invocation +If the qualifier value is null and \verb|ContextT| is instance, then NullPointerException is thrown and method invocation expression is discarded. It is only at this point that we should check the qualifier whether it is null or not. - If ContextT is static, then the previous rule will match, and no exception will be thrown. + If \verb|ContextT| is static, then the previous rule will match, and no exception will be thrown. */ rule [Invoke-methodInfo-instance-on-null]: /* [Impl] Qualifier type could be either object or array. @@ -374,13 +374,13 @@ rule [Invoke-methodInfo-instance-private]: /*@ If the method is protected or public, then we should call the version of the method visible to the runtime type of - the qualifying object (ObjC). Recall that the runtime type of an object is stored in the second argument of + the qualifying object (\verb|ObjC|). Recall that the runtime type of an object is stored in the second argument of \verb|objectRef()|. This case also covers qualifying type interface, since interface methods are always public. - The right method will always be the one referred by the signature Sig in the cell \cellref[]{methods} associated with the + The right method will always be the one referred by the signature \verb|Sig| in the cell \cellref[]{methods} associated with the actual object class. This is because the unfolding phase populates \cellref[]{methods} with the union of methods inherited from the base class and methods declared in the current class, the latter overriding the former. - The variable DecC is the class where the right method version is declared. + The variable \verb|DecC| is the class where the right method version is declared. */ rule [Invoke-methodInfo-instance-protected-or-public]: @@ -458,8 +458,8 @@ In contrast, the K-Java algorithm starts the search with the qualifying type (e. The rule for package access mode delegates searching for the right method declaration to the auxiliary function \verb|lookupPackageMethod()|. The function takes 3 arguments: - - method signature Sig - - the list of classes in the inheritance chain between the qualifying class QualC and the actual object class ObjC. + - method signature \verb|Sig| + - the list of classes in the inheritance chain between the qualifying class \verb|QualC| and the actual object class \verb|ObjC|. This list is produced by \verb|classChain()| - the third argument represents the declaring class of the best method found so far. It is initialized with \dotCt{K}. @@ -516,11 +516,11 @@ syntax KItem ::= lookupPackageMethod ( \begin{markdown} The rules for \verb|lookupPackageMethod()| are based on the following two properties of the configuration: - - if the cell \cellref[]{methods} for a particular class contains a key Sig, then \cellref[]{methods} for all classes derived from it - will contain the key Sig. - - if a particular class contain a method declaration with signature Sig access mode Acc, then all declarations - of Sig in derived classes (that are not necessarily overriding!) will have the access mode equal to either Acc or a - value wider than Acc. + - if the cell \cellref[]{methods} for a particular class contains a key \verb|Sig|, then \cellref[]{methods} for all classes derived from it + will contain the key \verb|Sig|. + - if a particular class contain a method declaration with signature \verb|Sig| access mode \verb|Acc|, then all declarations + of \verb|Sig| in derived classes (that are not necessarily overriding!) will have the access mode equal to either \verb|Acc| or a + value wider than \verb|Acc|. The first property is ensured by the unfolding algorithm. Because \cellref[]{methods} of a derived class inherit all the \cellref[]{methods} of the direct base class, the map \cellref[]{methods} may only grow from base classes to derived. The second property is ensured @@ -528,7 +528,7 @@ The first property is ensured by the unfolding algorithm. Because \cellref[]{met method must provide at least as much access as the overridden or hidden method". The search for the right package method declaration is performed from the base-most class in the chain (the left-most - one) to the most derived one. Every rule matches and deletes the leftmost class in the class chain (CurrentC), + one) to the most derived one. Every rule matches and deletes the leftmost class in the class chain (\verb|CurrentC|), and possibly rewrites the third argument into the current class. The first rule matches when there is no declaring class yet (third argument is \dotCt{K}, the initial case). \end{markdown} @@ -546,16 +546,16 @@ rule [lookupPackageMethod-layer-first-dec-found]: ... Sig |-> DecC:ClassType ... /*@ -The second rule matches when we already found a declaring class (OldDecC) and the current class CurrentC has another - method declaration with the right signature. The presence of a declaration with signature Sig inside CurrentC is identified by the +The second rule matches when we already found a declaring class (\verb|OldDecC|) and the current class \verb|CurrentC| has another + method declaration with the right signature. The presence of a declaration with signature \verb|Sig| inside \verb|CurrentC| is identified by the match $\kall{class}{\kall{classType}{ CurrentC } \mathrel{} \kmiddle{methods}{ Sig \mapsto CurrentC } }$, according to the definition of \cellref[]{methods}. -If the method in CurrentC directly overrides the method in OldDecC, the declaring class is updated to CurrentC. Otherwise the declaring class stays unchanged. The rules for direct overriding (case 1a above) are defined in the auxiliary function \verb|isOverridden()|. The function takes three arguments: +If the method in \verb|CurrentC| directly overrides the method in \verb|OldDecC|, the declaring class is updated to \verb|CurrentC|. Otherwise the declaring class stays unchanged. The rules for direct overriding (case 1a above) are defined in the auxiliary function \verb|isOverridden()|. The function takes three arguments: \begin{markdown} - - The base class OldDecC - - The derived class CurrentC - - The access mode Acc of the definition of Sig in OldDecC. + - The base class \verb|OldDecC| + - The derived class \verb|CurrentC| + - The access mode \verb|Acc| of the definition of \verb|Sig| in \verb|OldDecC|. \end{markdown} */ rule [lookupPackageMethod-new-method]: @@ -581,13 +581,13 @@ rule [lookupPackageMethod-new-method]: /*@ \begin{markdown} -Tests if a method declared in class BaseC with access mode Acc is overridden by a method - with the same signature declared in a subclass SubC. +Tests if a method declared in class \verb|BaseC| with access mode \verb|Acc| is overridden by a method + with the same signature declared in a subclass \verb|SubC|. The method is overridden if either: - - Acc is protected or public - - Acc is package and BaseC and SubC are declared in the same package (JLS \S6.6) + - \verb|Acc| is protected or public + - \verb|Acc| is package and \verb|BaseC| and \verb|SubC| are declared in the same package (JLS \S6.6) \end{markdown} */ @@ -607,9 +607,9 @@ rule isOverridden(BaseC:ClassType, package, SubC:ClassType) rule isOverridden(_, private, _) => false /*@ -The third rule represents the case when CurrentC chain does not contain method declarations with signature - Sig. This case is identified by the side condition CurrentC =/=K DecC. Indeed, the two classes are different only - when the entry Sig $\mapsto$ DecC in \cellref[]{methods} was inherited rather than produced by a method in CurrentC. +The third rule represents the case when \verb|CurrentC| chain does not contain method declarations with signature + \verb|Sig|. This case is identified by the side condition \verb|CurrentC| =/=K \verb|DecC|. Indeed, the two classes are different only + when the entry \verb|Sig| $\mapsto$ \verb|DecC| in \cellref[]{methods} was inherited rather than produced by a method in \verb|CurrentC|. */ rule [lookupPackageMethod-no-new-method]: @@ -700,7 +700,7 @@ When the term \verb|lookupPackageMethod()| is first produced it takes as argumen The central rule of method invocation is matched when the second argument of method call expression reaches the form \verb|methodRef()|. This rule performs the following operations: - - saves the rest of computation (RestK) and the content of \cellref[]{methodContext} as a new entry of the cell \cellref[]{stack} + - saves the rest of computation (\verb|RestK|) and the content of \cellref[]{methodContext} as a new entry of the cell \cellref[]{stack} This data is restored back by the rules for return statement. - Initializes the new method context. - The local variable environment \cellref[]{env} is emptied @@ -826,7 +826,7 @@ module METHOD-INVOKE-REST /*@ The next rule for method invocation is applied when the qualifier type is array. This array type is rewritten - into the auxiliary class ArrayImpl, that is used in K-Java to simulate method invocations over array objects. + into the auxiliary class \verb|ArrayImpl|, that is used in K-Java to simulate method invocations over array objects. This rule is required in order to minimize the number of particular cases involving arrays in the rules that follow. */ rule [Invoke-compute-methodInfo-arrays]: From 1af90f76a3ff6426fa40f74522acfc21fe59fc5e Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Fri, 20 Feb 2015 18:07:30 +0200 Subject: [PATCH 10/43] Doc: Put configuration docs after the configuration, not in front of it. Also some page filling adjustments. --- src/exec/configuration-exec.k | 172 ++++++++++---------- src/prep/configuration-prep.k | 296 +++++++++++++++++----------------- src/sty/custom-commands.tex | 7 + 3 files changed, 242 insertions(+), 233 deletions(-) diff --git a/src/exec/configuration-exec.k b/src/exec/configuration-exec.k index 09657f77..0b8c6b51 100644 --- a/src/exec/configuration-exec.k +++ b/src/exec/configuration-exec.k @@ -2,92 +2,6 @@ module CONFIGURATION-EXEC imports CORE-SORTS imports CORE-FUNCTIONS -/*@ -The execution configuration consists from the top-level cell \cellref{T}, whose content is divided into three large cell groups. The group \cellref[]{threads} contains one or multiple cells \cellref[]{thread}. Here is included the data related to the execution of a thread, such as the computation, stack, local environment. The second group is contained inside \cellref[]{classes} that have multiple \cellref[]{class} cells --- all the content related to particular classes. The third group consists of the remaining top-level cells. - -\paragraph{Threads} Each execution thread has a corresponding \cellref{thread}. Inside a thread, \cellref[K]{k} is represents the actual computation --- the sequence of tasks to be executed. Next cells are \cellref[List]{stack} --- the method call stack, and \cellref{methodContext}. The \cellref{methodContext} holds the local context of the executed method: -\begin{itemize} - \item \cellref[Map{{[}}Id \mapsto Int{{]}}]{env} --- The map from local variable names to their location inside \cellref[]{store}. - \item \cellref[ClassType]{crntClass} --- The current class, the type of \verb|this|. - \item \cellref[Int]{location} --- The location in memory store of the current object. -\end{itemize} - -On the next line there are 3 cells related to multithreading: -\begin{itemize} - \item \cellref{tid} --- The thread identified, generated when the thread is created. - \item \cellref[Map{{[}}Int \mapsto Int{{]}}]{holds} --- A map from Object locations to integer numbers. Map keys are monitor objects on which the current thread has the locks. Map values hold the number of times the lock was acquired. - \item \cellref[Bool]{interrupted} --- A boolean value signaling whether the current thread was interrupted. -\end{itemize} - -\paragraph{Classes} The cell \cellref{classes} contains one \cellref{class} for each class in the program, both for supported JDK classes and for user-defined classes. Cell \cellref{class} has the following content: - -\begin{itemize} - \item \cellref[ClassType]{classType} --- The fully qualified class name. This cell serves as identifier for the whole \cellref{class}, thus \cellref{classes} may be seen as a map from class name to \cellref{class} content. - \item \cellref[ClassMetaType]{classMetaType} --- Indicates whether this type is class or interface. Both are referred hereafter as "classes", making the distinctions only when necessary. - \item \cellref[ClassPhase]{classPhase} --- Used during unfolding global phase (see below). - \item \cellref[ClassType]{enclosingClass} --- For inner classes, the direct lexically enclosing class of this class. For top-level classes --- no value. - \item \cellref[ClassType]{extends} --- The base class. - \item \cellref[Set {[} ClassType {]} ]{implTrans} --- The transitive closure of implemented interfaces. - \item \cellref[ Map {[} Signature \mapsto ClassType {]} ]{methods} --- The map of accessible methods. Keys are method signatures, values are classes where methods are defined. Includes both methods declared within this class as well as methods inherited from base classes/ base interfaces. - \item \cellref[Bag]{methodDecs} --- The collection of method declarations (\cellref{methodDec} cells)in the current class. This cell contains only a subset of methods from \cellref{methods}, as the set of accessible methods from \cellref{methods} also includes methods inherited from base classes/interfaces. Hence the need of two separate collections. Each \cellref[Bag]{methodDec} contains the following data: - \begin{itemize} - \item \cellref[Signature]{methodSignature} --- The method signature, acting as identifier of the \cellref{methodDec} - \item \cellref[ List{[} Param {]} ]{methodParams} --- The method parameters. - \item \cellref[K]{methodBody} --- method body - \item \cellref[AccessMode]{methodAccessMode} --- The method access mode. - \item \cellref[ContextType]{methodContextType} --- May be either static or instance. - \end{itemize} - \item \cellref[K]{instanceFields} --- The list of instance field declarations, stored as a list of local variable declaration statements, without initializers. Used during object instantiation. - \item \cellref[K]{staticFields} --- The list of static field declarations, in a similar format as \cellref{instanceFields} - \item \cellref[K]{staticInit} --- The list of static initializers and static field initializers concatenated into one block. The content of \cellref{staticFields} and \cellref{staticInit} is executed during class static initialization. - \item \cellref[K]{folded} --- The initial representation of the class in AST format, during unfolding phase (see below). - \item \cellref[StaticInitStatus]{staticInitStatus} --- The static initialization status of the class. May be either uninitialized, initializing or initialized. The content of this class is used to trigger static initialization of the class on first use. - \item \cellref[ Map{[} Id \mapsto Location {]} ]{staticEnv} --- The map from static fields declared in this class to their locations in the store. Populated during static initialization. This cell along with \cellref{staticInitStatus} are the only two cells of \cellref{class} altered during program execution, during static initialization. The rest of the cells are populated before the execution. -\end{itemize} - -\paragraph{The remaining cells} -The first three cells after \cellref{classes} are important at the beginning of computation: -\begin{itemize} - \item \cellref[K]{program} --- The initial AST representation of the program, containing both core classes from JDK and user-defined classes. - \item \cellref[K]{mainClass} --- The class containing the method \verb|main()| --- the starting point of execution. Loaded from a command line argument. - \item \cellref[K]{globalPhase} --- Computation in the execution semantics may be in one of two global phases: Unfolding and Execution. The role of the unfolding phase is to convert the AST representation of the program stored in \cellref{program} into the collection of cells \cellref{classes}. When this operation is complete, execution phase follows. -\end{itemize} - -The next 4 cells represent the memory model of K-Java: -\begin{itemize} - \item \cellref[Map{[}Location:Int \mapsto Value:TypedVal{]}]{store} --- The program memory. Map from memory locations to actual values. For reference types only the reference is stored in this cell. - \item \cellref[ Map{[} Location:Int \mapsto LocMetadata {]} ]{storeMetadata} --- For each location in \cellref{store}, information whether that location is a local variable or field. Used for performance optimization of multi-threaded model-checking. - \item \cellref[Int]{nextLoc} --- the next available memory location. Incremmented after each allocation. - \item \cellref[ Map{[} Type \mapsto TypedVal {]} ]{classLiteralsMap} --- A map from types T to objects that represent the value of the expression \verb|T.class| . - \item \cellref[Bag]{objectStore} --- Represents runtime state of all the instantiated objects. Multiple references to the same object are modeled through multiple entries in \cellref{store} pointing to the same entry in \cellref{objectStore}. The cell contains multiple \cellref{object} cells, each with the following content: - \begin{itemize} - \item \cellref[Int]{objectId} --- A unique object identifier, pointed by each reference in \cellref{store} - \item \cellref[ClassType]{objectType} --- The runtime type of the object. - \item \cellref[Bag]{layer} --- There could be multiple layer cells inside an \cellref{object}. Each layer represents a concrete class in the inheritance hierarchy, starting from \verb|Java.lang.Object| and finishing with \cellref{objectType}. An object layer stores the following information: - \begin{itemize} - \item \cellref[ClassType]{layerClass} --- The class represented by this layer. - \item \cellref[Map{[}Id \mapsto Int{]}]{layerEnv} --- A map from instance fields to their locations in the store. - \item \cellref[TypedVal]{layerEnclosingObject} --- A reference to the directly enclosing object if this object represents an instance inner class, or empty for other types of objects (top-level and static inner). - \end{itemize} - \end{itemize} -\end{itemize} - -The following cells represent program I/O: -\begin{itemize} - \item \cellref[List]{in} --- The standard input, represented as pre-parsed list of elements of type Int or String. - \item \cellref[List]{out} --- The standard output. -\end{itemize} - -The next row contains global cells related to multithreading: -\begin{itemize} - \item \cellref[ Set{[} ObjLocation:Int {]} ]{busy} --- The set of busy objects. E.g. monitor objects for which there is a thread holding the monitor. - \item \cellref[ Map{[} ThreadId:Int \mapsto OL:Int {]} ]{waitingThreads} --- The map from threads to monitor objects on which respective threads are blocked in a call to \verb|wait()|. Used by the methods \verb|Object.wait()|, \verb|Object.notify()|, \verb|Object.notifyAll()|. - \item \cellref[Set{[}ThreadId:Int{]}]{terminated} --- The set of identifiers of terminated threads. -\end{itemize} - -The rest of the global cells are used for debugging purposes. -*/ - configuration //Configuration part 1: threads @@ -330,4 +244,90 @@ configuration +/*@ +The execution configuration consists from the top-level cell \cellref{T}, whose content is divided into three large cell groups. The group \cellref[]{threads} contains one or multiple cells \cellref[]{thread}. Here is included the data related to the execution of a thread, such as the computation, stack, local environment. The second group is contained inside \cellref[]{classes} that have multiple \cellref[]{class} cells --- all the content related to particular classes. The third group consists of the remaining top-level cells. + +\paragraph{Threads} Each execution thread has a corresponding \cellref{thread}. Inside a thread, \cellref[K]{k} is represents the actual computation --- the sequence of tasks to be executed. Next cells are \cellref[List]{stack} --- the method call stack, and \cellref{methodContext}. The \cellref{methodContext} holds the local context of the executed method: +\begin{itemize} + \item \cellref[Map{{[}}Id \mapsto Int{{]}}]{env} --- The map from local variable names to their location inside \cellref[]{store}. + \item \cellref[ClassType]{crntClass} --- The current class, the type of \verb|this|. + \item \cellref[Int]{location} --- The location in memory store of the current object. +\end{itemize} + +On the next line there are 3 cells related to multithreading: +\begin{itemize} + \item \cellref{tid} --- The thread identified, generated when the thread is created. + \item \cellref[Map{{[}}Int \mapsto Int{{]}}]{holds} --- A map from Object locations to integer numbers. Map keys are monitor objects on which the current thread has the locks. Map values hold the number of times the lock was acquired. + \item \cellref[Bool]{interrupted} --- A boolean value signaling whether the current thread was interrupted. +\end{itemize} + +\paragraph{Classes} The cell \cellref{classes} contains one \cellref{class} for each class in the program, both for supported JDK classes and for user-defined classes. Cell \cellref{class} has the following content: + +\begin{itemize} + \item \cellref[ClassType]{classType} --- The fully qualified class name. This cell serves as identifier for the whole \cellref{class}, thus \cellref{classes} may be seen as a map from class name to \cellref{class} content. + \item \cellref[ClassMetaType]{classMetaType} --- Indicates whether this type is class or interface. Both are referred hereafter as "classes", making the distinctions only when necessary. + \item \cellref[ClassPhase]{classPhase} --- Used during unfolding global phase (see below). + \item \cellref[ClassType]{enclosingClass} --- For inner classes, the direct lexically enclosing class of this class. For top-level classes --- no value. + \item \cellref[ClassType]{extends} --- The base class. + \item \cellref[Set {[} ClassType {]} ]{implTrans} --- The transitive closure of implemented interfaces. + \item \cellref[ Map {[} Signature \mapsto ClassType {]} ]{methods} --- The map of accessible methods. Keys are method signatures, values are classes where methods are defined. Includes both methods declared within this class as well as methods inherited from base classes/ base interfaces. + \item \cellref[Bag]{methodDecs} --- The collection of method declarations (\cellref{methodDec} cells)in the current class. This cell contains only a subset of methods from \cellref{methods}, as the set of accessible methods from \cellref{methods} also includes methods inherited from base classes/interfaces. Hence the need of two separate collections. Each \cellref[Bag]{methodDec} contains the following data: + \begin{itemize} + \item \cellref[Signature]{methodSignature} --- The method signature, acting as identifier of the \cellref{methodDec} + \item \cellref[ List{[} Param {]} ]{methodParams} --- The method parameters. + \item \cellref[K]{methodBody} --- method body + \item \cellref[AccessMode]{methodAccessMode} --- The method access mode. + \item \cellref[ContextType]{methodContextType} --- May be either static or instance. + \end{itemize} + \item \cellref[K]{instanceFields} --- The list of instance field declarations, stored as a list of local variable declaration statements, without initializers. Used during object instantiation. + \item \cellref[K]{staticFields} --- The list of static field declarations, in a similar format as \cellref{instanceFields} + \item \cellref[K]{staticInit} --- The list of static initializers and static field initializers concatenated into one block. The content of \cellref{staticFields} and \cellref{staticInit} is executed during class static initialization. + \item \cellref[K]{folded} --- The initial representation of the class in AST format, during unfolding phase (see below). + \item \cellref[StaticInitStatus]{staticInitStatus} --- The static initialization status of the class. May be either uninitialized, initializing or initialized. The content of this class is used to trigger static initialization of the class on first use. + \item \cellref[ Map{[} Id \mapsto Location {]} ]{staticEnv} --- The map from static fields declared in this class to their locations in the store. Populated during static initialization. This cell along with \cellref{staticInitStatus} are the only two cells of \cellref{class} altered during program execution, during static initialization. The rest of the cells are populated before the execution. +\end{itemize} + +\paragraph{The remaining cells} +The first three cells after \cellref{classes} are important at the beginning of computation: +\begin{itemize} + \item \cellref[K]{program} --- The initial AST representation of the program, containing both core classes from JDK and user-defined classes. + \item \cellref[K]{mainClass} --- The class containing the method \verb|main()| --- the starting point of execution. Loaded from a command line argument. + \item \cellref[K]{globalPhase} --- Computation in the execution semantics may be in one of two global phases: Unfolding and Execution. The role of the unfolding phase is to convert the AST representation of the program stored in \cellref{program} into the collection of cells \cellref{classes}. When this operation is complete, execution phase follows. +\end{itemize} + +The next 4 cells represent the memory model of K-Java: +\begin{itemize} + \item \cellref[Map{[}Location:Int \mapsto Value:TypedVal{]}]{store} --- The program memory. Map from memory locations to actual values. For reference types only the reference is stored in this cell. + \item \cellref[ Map{[} Location:Int \mapsto LocMetadata {]} ]{storeMetadata} --- For each location in \cellref{store}, information whether that location is a local variable or field. Used for performance optimization of multi-threaded model-checking. + \item \cellref[Int]{nextLoc} --- the next available memory location. Incremmented after each allocation. + \item \cellref[ Map{[} Type \mapsto TypedVal {]} ]{classLiteralsMap} --- A map from types T to objects that represent the value of the expression \verb|T.class| . + \item \cellref[Bag]{objectStore} --- Represents runtime state of all the instantiated objects. Multiple references to the same object are modeled through multiple entries in \cellref{store} pointing to the same entry in \cellref{objectStore}. The cell contains multiple \cellref{object} cells, each with the following content: + \begin{itemize} + \item \cellref[Int]{objectId} --- A unique object identifier, pointed by each reference in \cellref{store} + \item \cellref[ClassType]{objectType} --- The runtime type of the object. + \item \cellref[Bag]{layer} --- There could be multiple layer cells inside an \cellref{object}. Each layer represents a concrete class in the inheritance hierarchy, starting from \verb|Java.lang.Object| and finishing with \cellref{objectType}. An object layer stores the following information: + \begin{itemize} + \item \cellref[ClassType]{layerClass} --- The class represented by this layer. + \item \cellref[Map{[}Id \mapsto Int{]}]{layerEnv} --- A map from instance fields to their locations in the store. + \item \cellref[TypedVal]{layerEnclosingObject} --- A reference to the directly enclosing object if this object represents an instance inner class, or empty for other types of objects (top-level and static inner). + \end{itemize} + \end{itemize} +\end{itemize} + +The following cells represent program I/O: +\begin{itemize} + \item \cellref[List]{in} --- The standard input, represented as pre-parsed list of elements of type Int or String. + \item \cellref[List]{out} --- The standard output. +\end{itemize} + +The next row contains global cells related to multithreading: +\begin{itemize} + \item \cellref[ Set{[} ObjLocation:Int {]} ]{busy} --- The set of busy objects. E.g. monitor objects for which there is a thread holding the monitor. + \item \cellref[ Map{[} ThreadId:Int \mapsto OL:Int {]} ]{waitingThreads} --- The map from threads to monitor objects on which respective threads are blocked in a call to \verb|wait()|. Used by the methods \verb|Object.wait()|, \verb|Object.notify()|, \verb|Object.notifyAll()|. + \item \cellref[Set{[}ThreadId:Int{]}]{terminated} --- The set of identifiers of terminated threads. +\end{itemize} + +The rest of the global cells are used for debugging purposes. +*/ + endmodule diff --git a/src/prep/configuration-prep.k b/src/prep/configuration-prep.k index 3ee65be8..7beba519 100644 --- a/src/prep/configuration-prep.k +++ b/src/prep/configuration-prep.k @@ -16,153 +16,7 @@ The Static semantics consists of several phases that analyze the input program, The configuration cells may be divided into 2 categories: cells directly placed inside the all-enclosing cell \cellref{T} (top-level cells), and cells inside \cellref{classes}. The cell \cellref{classes} is a collection of \cellref{class} cells, each representing a Java class (both supported classes from JDK and classes defined by the developer). A \cellref{class} contains all components of a class --- such as extends/implements clauses, imports, fields, methods, etc, each distributed into a separate class, in order to be conveniently accessed when needed. -In the remaining of this section are documented all cells of the configuration, ordered by the global phase in which they are first used. - -\paragraph{Initial state} The first row contains three cells most relevant to computation initial state: -\begin{itemize} - \item \cellref[K]{k} --- Holds the current computation in all phases of the semantics. Initializes with the AST representation of the program. - \item \cellref[K]{program} --- A backup of program AST. Required because the initial AST is needed in both 1st ans 2nd phase of static K-Java, but the first phase destroys the content inside \cellref{k}. Also used in the last phase (Folding) to assemble the preprocessed program. - \item \cellref[GlobalPhase]{globalPhase} --- The current computation global phase. -\end{itemize} - -\paragraph{Process Type Names} During this phase, one global cell is computed: -\begin{itemize} - \item \cellref[Map{[}PackageId \mapsto Map{[}Id\mapsto{}ClassType{]}{]}]{namesToClasses} --- A two-level map. First level is a map from package names to second-level maps. Second-level maps are from simple class names to fully qualified class names within the package. This cell is extensively used through the semantics. The map contains both top-level and inner classes. For inner classes, their enclosing package is the fully qualified class name of the directly enclosing class. -\end{itemize} - -Also during Process Type Names classes are first registered. Again, both top-level and inner classes are covered. In a newly created \cellref[]{class} just a few sub-cells are initialized with data: - -\begin{itemize} - \item \cellref[ClassType]{classType} --- The fully qualified class name. The identifier of the class. - \item \cellref[ClassMetaType]{classMetaType} --- Represents whether the type stored in this cell is class or interface. To avoid terminology superfluousness, we will refer hereafter to both classes and interfaces as "classes", making distinctions only when necessary. - \item \cellref[ClassAccessMode]{classAccessMode} --- The access modifier of the class, either public or package. - \item \cellref[ClassPhase]{classPhase} --- Represents the state of this class. In addition to the global computation phase, each class has its own lifecycle phase. Class phases are required to keep track which classes were processed in the current global phase and which were not. During each global phase all classes should transition to a certain class phase. However, as we shall see, not all global phases change the state of the class. The class phases are: - - \begin{itemize} - \item Discovered --- The initial phase. At the end of Process Type Names all classes are in the state "Discovered". - \item Stored - \item Bases Resolved - \item Declaration Processed - \item Members Processed - \item Folded - \end{itemize} - -\end{itemize} - -\paragraph{Process Compilation Units} At the beginning of this phase computation is again initialized with the initial AST from \cellref{program}. The following new cells are filled in inside each \cellref{class}: - -\begin{itemize} - \item \cellref[ClassType]{enclosingClass} --- The directly enclosing class, for inner classes, or no value for top-level classes. - \item \cellref[K]{rawExtends} --- The extends clause of this class, in its raw (AST) form. - \item \cellref[K]{rawImplements} --- The implements clause, in AST form. - \item \cellref[K]{rawDeclarations} --- The class body, in AST form. - \item \cellref[Map{[}Id \mapsto ClassType{]}]{cuImports} --- A map from names accessible inside this class to fully qualified class names they represent. Only computed for top-level classes at this phase. For inner classes this cell remains empty. - \item \cellref[ContextType]{classContextType} --- Either static or instance, for inner classes. Always static for top-level classes. -\end{itemize} - -The class phase changes from Discovered to Stored. As we can see, the cells computed so far contain all the data of the original program. Thus, initial AST representation of the program is no longer needed. In fact, the cell \cellref[]{program} is discarded at the end of Process Compilation Units. The remaining preprocessing phases will use class data in this initial form to compute other cells within \cellref[]{class}, finally used for execution. - - -Also during Process Compilation Units the following global cell is used: - -\begin{itemize} - \item \cellref[Map{[}Id \mapsto ClassType{]}]{compUnitImports} --- A map from all type names accessible in the current compilation unit (Java file) to their respective fully qualified class names. This includes both classes accessible through imports declarations and classes declared in the package of the current compilation unit. Used to compute \cellref{cuImports} of top-level classes. -\end{itemize} - -\paragraph{Process Class Declarations} Here each class passes through two more class phases: Bases Processed and Declarations Processed. First, for each class the semantics attempts to resolve its extends/implements clauses into fully qualified class names. The order in which dependencies are resolved depends on both class inheritance relationships as well as nesting relationships. Once the dependencies of a class are resolved, they are stored into a temporary cell: - -\begin{itemize} -\item \cellref[K]{unprocessedBases} --- Initialized with the list of fully qualified class names for classes mentioned in extends/implements clauses of this class. -\end{itemize} - -Once the content of \cellref[K]{unprocessedBases} is created, the class enters into Bases Resolved phase. It then waits in this phase until all classes referred in extends/implements reach the phase Declarations Processed. The restrictions in JLS related to class dependencies guarantee that classes cannot have cyclic dependencies, thus a class cannot get locked in the waiting state. The cell \cellref[K]{unprocessedBases} is used to determine the moment when the class may exit the waiting state. Once a class reaches the phase Declarations Processed, is is deleted from cells \cellref[K]{unprocessedBases} of other classes. Thus, when all extends/implements dependencies of a class reach the phase Declarations Processed, the content of the its \cellref[K]{unprocessedBases} cell becomes empty. Once in this state, the class enters into the phase Declarations Processed itself and computes three more cells: - -\begin{itemize} -\item \cellref[ClassType]{extends} --- The base class, fully qualified. -\item \cellref[Set{[}ClassType{]}]{implements} --- The list of directly implemented interfaces, fully qualified. -\item \cellref[Map{[}Id \mapsto ClassType{]}]{imports} --- The map of classes accessible by simple name within the body of this class. The rules for computing this map are complex and include the following sources: - -\begin{itemize} -\item Imports declarations of the current compilation unit. -\item Classes declared within the package of the current compilation unit. -\item Classes accessible within the body of the directly enclosing class, if the current class is inner class. -\item Inner classes inherited from base classes, e.g. from extends/implements clauses. -\item Inner classes of this class itself. -\end{itemize} - -The need to cover all these cases leads to the intricate order in which class dependencies have to be be resolved. -\end{itemize} - -When a class enters the phase Declarations Processed, the cells \cellref[]{rawExtends}, \cellref[]{rawImplements} and \cellref[K]{unprocessedBases} are no longer needed and are discarded. Once all classes reach this phase the computation proceeds to the next global phase. - -During Process Class Declarations the following global cell is first used: -\begin{itemize} - \item \cellref[ClassType]{crntClass} --- The current class. Used in multiple phases starting from Process Class Declarations. -\end{itemize} - -\paragraph{Process Class Members} During this phase each class processes its members and reaches the state Members Processes. Until then, the class body is stored in \cellref[]{rawDeclarations}. A class member could be one of: - -\begin{itemize} - \item field - \item method - \item constructor - \item static or instance initializer -\end{itemize} - -The following new class cells are produced: - -\begin{itemize} - \item \cellref[Set{[}ClassType{]}]{implTrans} --- The transitive closure of implemented interfaces. In the remaining phases this set is used by the subtyping relationship. - \item \cellref[ Map {[} Signature \mapsto ClassType {]} ]{methods} --- The map of accessible methods. Keys are method signatures, values are classes where methods are defined. Includes both methods declared within this class as well as methods inherited from base classes/ base interfaces. - \item \cellref[Bag]{methodDecs} --- The collection of method declarations (\cellref{methodDec} cells)in the current class. This cell contains only a subset of methods from \cellref{methods}, as the set of accessible methods from \cellref{methods} also includes methods inherited from base classes/interfaces. Hence the need of two separate collections. Each \cellref[Bag]{methodDec} contains the following data: - \begin{itemize} - \item \cellref[Signature]{methodSignature} --- The method signature, acting as identifier of the \cellref{methodDec}. - \item \cellref[Type]{methodReturnType} --- The method return type. - \item \cellref[ List{[} Param {]} ]{methodParams} --- The method parameters. - \item \cellref[K]{methodConstrFirstLine} --- the first line of a constructor (if this method is indeed a constructor, for other classes than \verb|Object|). It contains a call to another constructor: either \verb|super()| or \verb|this()|. - \item \cellref[K]{methodBody} --- The method body. - \item \cellref[AccessMode]{methodAccessMode} --- The method access mode. - \item \cellref[ContextType]{methodContextType} --- May be either static or instance. - \item \cellref[MethodMetaType]{methodMetaType} --- May be either method or constructor. - \end{itemize} - \item \cellref[K]{instanceFields} --- The list of instance field declarations, stored as a list of local variable declaration statements, without initializers. Used during object instantiation. - \item \cellref[K]{instanceInit} --- The list of instance initializers of the class combined into one big instance initializer. Instance field initializers are also concatenated into this cell in their textual order. - \item \cellref[K]{staticFields} --- The list of static field declarations, in a similar format to \cellref{instanceFields} - \item \cellref[K]{staticInit} --- The list of static initializers and static field initializers concatenated into one block. - \item \cellref[Map{[}Id \mapsto Value{]}]{constantEnv} --- The map from compile-time constants to their actual values. Constants in Java have a slightly different semantics compared to final static fields. In particular, accessing them don't trigger static initialization of the declaring class. -\end{itemize} - -Once all the cells above are computed the class proceeds into the phase Members Processed and the cell \cellref[]{rawDeclarations} is deleted. - -\paragraph{Elaboration} Here all the code blocks are processed --- method and constructor bodies, static and instance initializers. Most of the information traditionally inferred by the compiler is computed at this phase. More precisely the elaboration performs the following transformations: - -\begin{itemize} -\item Each name is resolved into local variable, field, method, class or package. While a method may be distinguished from other categories purely syntactically, resolving to other categories requires knowledge of the names existing in the current context. -\item Simple class names are resolved into fully qualified class names. Hereafter all the class names in the code are fully qualified. -\item The compile-time type of each expression is inferred. Thus, when the code reaches execution phase, expressions are no longer in their initial form. The expressions are annotated with their types. -\item For each method call the precise signature in inferred. -\item Local and anonymous classes are processed. The earliest phase where local classes could be discovered is elaboration. Still, local classes have all the features of other classes. Thus they need to be passed through all the preprocessing steps. The whole preprocessing for local classes is performed during the global phase elaboration. -\end{itemize} - -Despite this phase being the most complex preprocessing phase of all, it introduces few new cells. Most of them are related to local classes. Inside \cellref[]{class} just one new cell is introduced: - -\begin{itemize} -\item \cellref[Map{[}Id \mapsto Type{]}]{enclosingLocalEnv} --- The map from local variables of the current block to their types. Used during local classes processing. -\end{itemize} - -Among global cells the following new cells are added: - -\begin{itemize} - \item \cellref[List[mapWrap(Map[Id \mapsto Type])]]{elabEnv} --- A stack where each layer is a map of local variables. Each layer of the stack represents a code block, in the blocks nesting order. Inside each layer, the map is from local variables accessible in that layer to variable types. - \item \cellref[Int]{contextType} --- The context type of the currently elaborated class. Either static or instance. - \item \cellref[List[mapWrap(Map[Id \mapsto ClassType])]]{localTypes} --- A cell similar in structure to \cellref{elabEnv}. This time it contains stack layers which are maps from local class names to local class types. - \item \cellref[Int]{nextLocalId} --- A number used to generate unique fully-qualified class names for local classes. - \item \cellref[K]{elabBuffer} --- A temporary cell used during elaboration of local classes. -\end{itemize} - -During the elaboration phase no cells are consumed. Instead, the code blocks stored inside \cellref[]{methodDecs}, \cellref[]{instanceInit}, \cellref[]{staticInit} are processed and stored back into the same cell. After elaboration the classes remain in the same state --- Members Processed. The state Members Processed is in fact the final state of the cell \cellref[]{class}. - -\paragraph{Folding} During the last phase of static semantics the program is assembled from \cellref{classes} back into the AST form. First the content of each class is assembled into \cellref[K]{folded} of the respective class, and the class phase changes to Folded. Second, the AST representation of each class is appended into \cellref{program}. When this phase ends, the content of \cellref{program} is printed to the standard output. +In the remaining of this section are documented all the cells of the configuration, ordered by the global phase in which they are first used. */ configuration @@ -391,4 +245,152 @@ configuration +/*@ +\paragraph{Initial state} The first row contains three cells most relevant to computation initial state: +\begin{itemize} + \item \cellref[K]{k} --- Holds the current computation in all phases of the semantics. Initializes with the AST representation of the program. + \item \cellref[K]{program} --- A backup of program AST. Required because the initial AST is needed in both 1st ans 2nd phase of static K-Java, but the first phase destroys the content inside \cellref{k}. Also used in the last phase (Folding) to assemble the preprocessed program. + \item \cellref[GlobalPhase]{globalPhase} --- The current computation global phase. +\end{itemize} + +\paragraph{Process Type Names} During this phase, one global cell is computed: +\begin{itemize} + \item \cellref[Map{[}PackageId \mapsto Map{[}Id\mapsto{}ClassType{]}{]}]{namesToClasses} --- A two-level map. First level is a map from package names to second-level maps. Second-level maps are from simple class names to fully qualified class names within the package. This cell is extensively used through the semantics. The map contains both top-level and inner classes. For inner classes, their enclosing package is the fully qualified class name of the directly enclosing class. +\end{itemize} + +Also during Process Type Names classes are first registered. Again, both top-level and inner classes are covered. In a newly created \cellref[]{class} just a few sub-cells are initialized with data: + +\begin{itemize} + \item \cellref[ClassType]{classType} --- The fully qualified class name. The identifier of the class. + \item \cellref[ClassMetaType]{classMetaType} --- Represents whether the type stored in this cell is class or interface. To avoid terminology superfluousness, we will refer hereafter to both classes and interfaces as "classes", making distinctions only when necessary. + \item \cellref[ClassAccessMode]{classAccessMode} --- The access modifier of the class, either public or package. + \item \cellref[ClassPhase]{classPhase} --- Represents the state of this class. In addition to the global computation phase, each class has its own lifecycle phase. Class phases are required to keep track which classes were processed in the current global phase and which were not. During each global phase all classes should transition to a certain class phase. However, as we shall see, not all global phases change the state of the class. The class phases are: + + \begin{itemize} + \item Discovered --- The initial phase. At the end of Process Type Names all classes are in the state "Discovered". + \item Stored + \item Bases Resolved + \item Declaration Processed + \item Members Processed + \item Folded + \end{itemize} + +\end{itemize} + +\paragraph{Process Compilation Units} At the beginning of this phase computation is again initialized with the initial AST from \cellref{program}. The following new cells are filled in inside each \cellref{class}: + +\begin{itemize} + \item \cellref[ClassType]{enclosingClass} --- The directly enclosing class, for inner classes, or no value for top-level classes. + \item \cellref[K]{rawExtends} --- The extends clause of this class, in its raw (AST) form. + \item \cellref[K]{rawImplements} --- The implements clause, in AST form. + \item \cellref[K]{rawDeclarations} --- The class body, in AST form. + \item \cellref[Map{[}Id \mapsto ClassType{]}]{cuImports} --- A map from names accessible inside this class to fully qualified class names they represent. Only computed for top-level classes at this phase. For inner classes this cell remains empty. + \item \cellref[ContextType]{classContextType} --- Either static or instance, for inner classes. Always static for top-level classes. +\end{itemize} + +The class phase changes from Discovered to Stored. As we can see, the cells computed so far contain all the data of the original program. Thus, initial AST representation of the program is no longer needed. In fact, the cell \cellref[]{program} is discarded at the end of Process Compilation Units. The remaining preprocessing phases will use class data in this initial form to compute other cells within \cellref[]{class}, finally used for execution. + + +Also during Process Compilation Units the following global cell is used: + +\begin{itemize} + \item \cellref[Map{[}Id \mapsto ClassType{]}]{compUnitImports} --- A map from all type names accessible in the current compilation unit (Java file) to their respective fully qualified class names. This includes both classes accessible through imports declarations and classes declared in the package of the current compilation unit. Used to compute \cellref{cuImports} of top-level classes. +\end{itemize} + +\paragraph{Process Class Declarations} Here each class passes through two more class phases: Bases Processed and Declarations Processed. First, for each class the semantics attempts to resolve its extends/implements clauses into fully qualified class names. The order in which dependencies are resolved depends on both class inheritance relationships as well as nesting relationships. Once the dependencies of a class are resolved, they are stored into a temporary cell: + +\begin{itemize} +\item \cellref[K]{unprocessedBases} --- Initialized with the list of fully qualified class names for classes mentioned in extends/implements clauses of this class. +\end{itemize} + +Once the content of \cellref[K]{unprocessedBases} is created, the class enters into Bases Resolved phase. It then waits in this phase until all classes referred in extends/implements reach the phase Declarations Processed. The restrictions in JLS related to class dependencies guarantee that classes cannot have cyclic dependencies, thus a class cannot get locked in the waiting state. The cell \cellref[K]{unprocessedBases} is used to determine the moment when the class may exit the waiting state. Once a class reaches the phase Declarations Processed, is is deleted from cells \cellref[K]{unprocessedBases} of other classes. Thus, when all extends/implements dependencies of a class reach the phase Declarations Processed, the content of the its \cellref[K]{unprocessedBases} cell becomes empty. Once in this state, the class enters into the phase Declarations Processed itself and computes three more cells: + +\begin{itemize} +\item \cellref[ClassType]{extends} --- The base class, fully qualified. +\item \cellref[Set{[}ClassType{]}]{implements} --- The list of directly implemented interfaces, fully qualified. +\item \cellref[Map{[}Id \mapsto ClassType{]}]{imports} --- The map of classes accessible by simple name within the body of this class. The rules for computing this map are complex and include the following sources: + +\begin{itemize} +\item Imports declarations of the current compilation unit. +\item Classes declared within the package of the current compilation unit. +\item Classes accessible within the body of the directly enclosing class, if the current class is inner class. +\item Inner classes inherited from base classes, e.g. from extends/implements clauses. +\item Inner classes of this class itself. +\end{itemize} + +The need to cover all these cases leads to the intricate order in which class dependencies have to be be resolved. +\end{itemize} + +When a class enters the phase Declarations Processed, the cells \cellref[]{rawExtends}, \cellref[]{rawImplements} and \cellref[K]{unprocessedBases} are no longer needed and are discarded. Once all classes reach this phase the computation proceeds to the next global phase. + +During Process Class Declarations the following global cell is first used: +\begin{itemize} + \item \cellref[ClassType]{crntClass} --- The current class. Used in multiple phases starting from Process Class Declarations. +\end{itemize} + +\paragraph{Process Class Members} During this phase each class processes its members and reaches the state Members Processes. Until then, the class body is stored in \cellref[]{rawDeclarations}. A class member could be one of: + +\begin{itemize} + \item field + \item method + \item constructor + \item static or instance initializer +\end{itemize} + +The following new class cells are produced: + +\begin{itemize} + \item \cellref[Set{[}ClassType{]}]{implTrans} --- The transitive closure of implemented interfaces. In the remaining phases this set is used by the subtyping relationship. + \item \cellref[ Map {[} Signature \mapsto ClassType {]} ]{methods} --- The map of accessible methods. Keys are method signatures, values are classes where methods are defined. Includes both methods declared within this class as well as methods inherited from base classes/ base interfaces. + \item \cellref[Bag]{methodDecs} --- The collection of method declarations (\cellref{methodDec} cells)in the current class. This cell contains only a subset of methods from \cellref{methods}, as the set of accessible methods from \cellref{methods} also includes methods inherited from base classes/interfaces. Hence the need of two separate collections. Each \cellref[Bag]{methodDec} contains the following data: + \begin{itemize} + \item \cellref[Signature]{methodSignature} --- The method signature, acting as identifier of the \cellref{methodDec}. + \item \cellref[Type]{methodReturnType} --- The method return type. + \item \cellref[ List{[} Param {]} ]{methodParams} --- The method parameters. + \item \cellref[K]{methodConstrFirstLine} --- the first line of a constructor (if this method is indeed a constructor, for other classes than \verb|Object|). It contains a call to another constructor: either \verb|super()| or \verb|this()|. + \item \cellref[K]{methodBody} --- The method body. + \item \cellref[AccessMode]{methodAccessMode} --- The method access mode. + \item \cellref[ContextType]{methodContextType} --- May be either static or instance. + \item \cellref[MethodMetaType]{methodMetaType} --- May be either method or constructor. + \end{itemize} + \item \cellref[K]{instanceFields} --- The list of instance field declarations, stored as a list of local variable declaration statements, without initializers. Used during object instantiation. + \item \cellref[K]{instanceInit} --- The list of instance initializers of the class combined into one big instance initializer. Instance field initializers are also concatenated into this cell in their textual order. + \item \cellref[K]{staticFields} --- The list of static field declarations, in a similar format to \cellref{instanceFields} + \item \cellref[K]{staticInit} --- The list of static initializers and static field initializers concatenated into one block. + \item \cellref[Map{[}Id \mapsto Value{]}]{constantEnv} --- The map from compile-time constants to their actual values. Constants in Java have a slightly different semantics compared to final static fields. In particular, accessing them don't trigger static initialization of the declaring class. +\end{itemize} + +Once all the cells above are computed the class proceeds into the phase Members Processed and the cell \cellref[]{rawDeclarations} is deleted. + +\paragraph{Elaboration} Here all the code blocks are processed --- method and constructor bodies, static and instance initializers. Most of the information traditionally inferred by the compiler is computed at this phase. More precisely the elaboration performs the following transformations: + +\begin{itemize} +\item Each name is resolved into local variable, field, method, class or package. While a method may be distinguished from other categories purely syntactically, resolving to other categories requires knowledge of the names existing in the current context. +\item Simple class names are resolved into fully qualified class names. Hereafter all the class names in the code are fully qualified. +\item The compile-time type of each expression is inferred. Thus, when the code reaches execution phase, expressions are no longer in their initial form. The expressions are annotated with their types. +\item For each method call the precise signature in inferred. +\item Local and anonymous classes are processed. The earliest phase where local classes could be discovered is elaboration. Still, local classes have all the features of other classes. Thus they need to be passed through all the preprocessing steps. The whole preprocessing for local classes is performed during the global phase elaboration. +\end{itemize} + +Despite this phase being the most complex preprocessing phase of all, it introduces few new cells. Most of them are related to local classes. Inside \cellref[]{class} just one new cell is introduced: + +\begin{itemize} +\item \cellref[Map{[}Id \mapsto Type{]}]{enclosingLocalEnv} --- The map from local variables of the current block to their types. Used during local classes processing. +\end{itemize} + +Among global cells the following new cells are added: + +\begin{itemize} + \item \cellref[List[mapWrap(Map[Id \mapsto Type])]]{elabEnv} --- A stack where each layer is a map of local variables. Each layer of the stack represents a code block, in the blocks nesting order. Inside each layer, the map is from local variables accessible in that layer to variable types. + \item \cellref[Int]{contextType} --- The context type of the currently elaborated class. Either static or instance. + \item \cellref[List[mapWrap(Map[Id \mapsto ClassType])]]{localTypes} --- A cell similar in structure to \cellref{elabEnv}. This time it contains stack layers which are maps from local class names to local class types. + \item \cellref[Int]{nextLocalId} --- A number used to generate unique fully-qualified class names for local classes. + \item \cellref[K]{elabBuffer} --- A temporary cell used during elaboration of local classes. +\end{itemize} + +During the elaboration phase no cells are consumed. Instead, the code blocks stored inside \cellref[]{methodDecs}, \cellref[]{instanceInit}, \cellref[]{staticInit} are processed and stored back into the same cell. After elaboration the classes remain in the same state --- Members Processed. The state Members Processed is in fact the final state of the cell \cellref[]{class}. + +\paragraph{Folding} During the last phase of static semantics the program is assembled from \cellref{classes} back into the AST form. First the content of each class is assembled into \cellref[K]{folded} of the respective class, and the class phase changes to Folded. Second, the AST representation of each class is appended into \cellref{program}. When this phase ends, the content of \cellref{program} is printed to the standard output. +*/ + endmodule diff --git a/src/sty/custom-commands.tex b/src/sty/custom-commands.tex index a5729b46..e7864997 100644 --- a/src/sty/custom-commands.tex +++ b/src/sty/custom-commands.tex @@ -21,6 +21,13 @@ breaklines=true,showstringspaces=false,emph={label}, basicstyle=\ttfamily} +\makeatletter +% Call this in front of a \begin{itemize} to prevent page break before the list +% Doesn't work. +% http://tex.stackexchange.com/questions/2644/how-to-prevent-a-page-break-before-an-itemize-list +\newcommand{\nolisttopbreak}{\vspace{\topsep}\nobreak\@afterheading} +\makeatother + % #1 = sort, #2 = name \newcommand{\cellref}[2][]{% %\kall{#2}{\ifthenelse{\isempty{#1}}{}{$\sortName{#1}$}}%doesn't work From 58672063756983d46a0e1885646df6eb52dd612c Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Fri, 20 Feb 2015 18:58:39 +0200 Subject: [PATCH 11/43] Doc: Combined hard-wrapped lines, now that we have soft wrap in Intellij. Only configuration docs and well documented modules. --- src/exec/method-invoke.k | 331 ++++++++++------------------------ src/exec/new-instance.k | 35 +--- src/prep/configuration-prep.k | 134 +++++++------- 3 files changed, 168 insertions(+), 332 deletions(-) diff --git a/src/exec/method-invoke.k b/src/exec/method-invoke.k index 426bf926..de9fa71a 100644 --- a/src/exec/method-invoke.k +++ b/src/exec/method-invoke.k @@ -7,8 +7,7 @@ module METHOD-INVOKE /*@ \subsection{Background} -In this section we present the fragment of configuration used by runtime method - invocation. The figure below contains the cells and their sorts\footnote{$AM^{***}$ = \sortName{AccessMode}, $CT^{***}$ = \sortName{ContextType}}. +In this section we present the fragment of configuration used by runtime method invocation. The figure below contains the cells and their sorts\footnote{$AM^{***}$ = \sortName{AccessMode}, $CT^{***}$ = \sortName{ContextType}}. \vspace{3ex} @@ -60,54 +59,32 @@ In this section we present the fragment of configuration used by runtime method \vspace{3ex} -The cell \cellref[]{k} stores the current computation. The cell \cellref[]{stack} is a list of pairs of the - form (K, Bag), and represents the standard method call stack. The first element - represents the remaining computation at the moment the method was called. The second - element of sort Bag represents the content of cell \cellref[]{methodContext} at the moment - of method call. - -The cell \cellref[]{class} contains various sub-cells holding the content of that class. The - first cell in \cellref[]{classType} of sort ClassType that holds the fully qualified class name. - This cell serves as a key in all rules that match a fragment of a \cellref[]{class}. The value - in the cell \cellref[]{classMetaType} is either "class" or "interface". From now on we will - refer to both meta types as classes, referring to metatype value when distinction - is necessary. The next cell is \cellref[]{methods}. This is a map from method signatures to - classes where the respective signatures are declared. It contains not only the methods - declared in this class, but also those inherited from the base class, but not from the - base interfaces. By "inherited" here we mean all the methods contained in the cell - \cellref[]{methods} of the base class that were not overridden by a method declaration with - the same signature in the current class. This definition is different from the - inheritance rules in JLS \S8.4.6, although the difference is only relevant at the - elaboration time. - -The cell \cellref[]{methodDec} represents a method declared inside the current class. The subcell - \cellref[]{methodSignature} is the key for accessing other cells for this declaration. The other - cells are the parameters, the body, the access mode (private, public etc.) and the - context type (either instance or static). - -In order for strictness and context rules to work we have to define some K productions - as KResult. The most common forms of KResult in Java are the following: - -\begin{syntaxBlock}{\nonTerminal{\sort{KResult}}} -\syntax{{\nonTerminal{\sort{ClassType}}}}{} -\syntaxCont{{\nonTerminal{\sort{TypedVal}}}}{} +The cell \cellref[]{k} stores the current computation. The cell \cellref[]{stack} is a list of pairs of the form (K, Bag), and represents the standard method call stack. The first element represents the remaining computation at the moment the method was called. The second element of sort Bag represents the content of cell \cellref[]{methodContext} at the moment of method call. + +The cell \cellref[]{class} contains various sub-cells holding the content of that class. The first cell in \cellref[]{classType} of sort ClassType that holds the fully qualified class name. This cell serves as a key in all rules that match a fragment of a \cellref[]{class}. The value in the cell \cellref[]{classMetaType} is either "class" or "interface". From now on we will refer to both meta types as classes, referring to metatype value when distinction is necessary. The next cell is \cellref[]{methods}. This is a map from method signatures to classes where the respective signatures are declared. It contains not only the methods declared in this class, but also those inherited from the base class, but not from the base interfaces. By "inherited" here we mean all the methods contained in the cell \cellref[]{methods} of the base class that were not overridden by a method declaration with the same signature in the current class. This definition is different from the inheritance rules in JLS \S8.4.6, although the difference is only relevant at the elaboration time. + +The cell \cellref[]{methodDec} represents a method declared inside the current class. The subcell \cellref[]{methodSignature} is the key for accessing other cells for this declaration. The other cells are the parameters, the body, the access mode (private, public etc.) and the context type (either instance or static). + +In order for strictness and context rules to work we have to define some K productions as KResult. The most common forms of KResult in Java are the following: + +\begin{syntaxBlock}{KResult} + \syntax{{\nonTerminal{\sort{ClassType}}}}{} + \syntaxCont{{\nonTerminal{\sort{TypedVal}}}}{} \end{syntaxBlock} The first represents a class. Second is a typed value, the result of evaluation of any expression. The forms of typed values relevant for method invocation are object reference and null: -\begin{syntaxBlock}{\nonTerminal{\sort{TypedVal}}}\syntax{{}\terminal{objectRef} - ({{\nonTerminal{\sort{Int}}}},{{\nonTerminal{\sort{ClassType}}}}){} - \terminal{::}{{\nonTerminal{\sort{ClassType}}}}}{}\syntaxCont{{}\terminal{null} - {}\terminal{::}{{\nonTerminal{\sort{ClassType}}}}}{} +\begin{syntaxBlock}{TypedVal} + \syntax{\terminal{objectRef} + ({{\nonTerminal{\sort{Int}}}},{{\nonTerminal{\sort{ClassType}}}}){} + \terminal{::}{{\nonTerminal{\sort{ClassType}}}}}{}\syntaxCont{{}\terminal{null} + {}\terminal{::}{{\nonTerminal{\sort{ClassType}}}}}{} \end{syntaxBlock} -The type after four dots (::) separator is the static type associated with that value. The values inside - \verb|objectRef()| are the address inside the store and the runtime type of the object. +The type after four dots (::) separator is the static type associated with that value. The values inside \verb|objectRef()| are the address inside the store and the runtime type of the object. -For the sake of simplicity we we will also - consider \dotCt{K} --- the unit element of K to be KResult. The value \dotCt{K} is often - used in auxiliary functions as a placeholder until some actual value is computed. +For the sake of simplicity we we will also consider \dotCt{K} --- the unit element of K to be KResult. The value \dotCt{K} is often used in auxiliary functions as a placeholder until some actual value is computed. \subsection{Introduction} @@ -115,21 +92,12 @@ For the sake of simplicity we we will also An elaborated method invocation expression may have one of the following forms: - An invocation of a static method qualified by its class: \verb|Class.f(args)| - - An invocation of a static method qualified by an expression producing an object: - \verb|o.f(args)|. Even if the method is - static we cannot simply replace the qualifier with its compile-time type at - elaboration phase, because the qualifier - expression still has to be evaluated and might produce side effects. We cannot replace it with - o; \verb|class.f(args)|; either, because o; might be invalid. Not all expressions - valid as qualifiers are valid as expression statements (JLS \S14.8). We wanted the elaboration - result to be a valid Java program, thus we could not afford such a transformation. + - An invocation of a static method qualified by an expression producing an object: \verb|o.f(args)|. Even if the method is static we cannot simply replace the qualifier with its compile-time type at elaboration phase, because the qualifier expression still has to be evaluated and might produce side effects. We cannot replace it with \verb|o; class.f(args);| either, because \verb|o;| might be invalid. Not all expressions valid as qualifiers are valid as expression statements (JLS \S14.8). We wanted the elaboration result to be a valid Java program, thus we could not afford such a transformation. - An invocation of an instance method qualified by a class reference: \verb|o.f(args)| - An invocation of an instance method qualified by an interface reference: \verb|i.f(args)| -The evaluation of the method invocation expression consists from 5 steps outlined below. - Those steps, unless otherwise specified, are common to all the method call forms - enumerated above. +The evaluation of the method invocation expression consists from 5 steps outlined below. Those steps, unless otherwise specified, are common to all the method call forms enumerated above. 1. Evaluation of the qualifier expression 2. Evaluation of method arguments @@ -137,11 +105,7 @@ The evaluation of the method invocation expression consists from 5 steps outline 4. Locating the actual method declaration to be invoked 5. Actual method invocation. -In JLS runtime semantics of method invocation is described in \S15.2.4. Although there - is some correspondence between the steps in our semantics and the steps in JLS, it is - generally not one-to-one. JLS description of method invocation consists of the - following 5 steps. For each step we give the relevant chapter of the JLS and the step - in our semantics. +In JLS runtime semantics of method invocation is described in \S15.2.4. Although there is some correspondence between the steps in our semantics and the steps in JLS, it is generally not one-to-one. JLS description of method invocation consists of the following 5 steps. For each step we give the relevant chapter of the JLS and the step in our semantics. 1. Compute the target reference (\S15.12.4.1), semantics step 1 2. Evaluate arguments (\S15.12.4.2), semantics step 1 @@ -149,11 +113,7 @@ In JLS runtime semantics of method invocation is described in \S15.2.4. Although 4. Locate the actual method code to invoke (\S15.12.4.4), semantics step 3 5. Actual method invocation, semantics step 4. -Generally the rules of K-Java do not follow directly the wording of JLS. The reasons - for this will choice will be given at the end of the section. - The details related to each step are described in the semantics below, above each - rule and auxiliary construct. For each rule we will also refer to the respective - JLS page, if there is a correspondence. +Generally the rules of K-Java do not follow directly the wording of JLS. The reasons for this will choice will be given at the end of the section. The details related to each step are described in the semantics below, above each rule and auxiliary construct. For each rule we will also refer to the respective JLS page, if there is a correspondence. \end{markdown} */ @@ -161,68 +121,46 @@ Generally the rules of K-Java do not follow directly the wording of JLS. The rea \subsection{Evaluation of the qualifier and the arguments} \begin{markdown} -The first two parts of method invocation logic are evaluation of the qualifier expression and evaluation of the - arguments. JLS enforces the following conditions on the order of subexpressions evaluation: - - - Arguments have to be evaluated after the qualifier was evaluated. This is ensured - by checking that the qualifier is of sort KResult at the moment when arguments are - heated. - - Arguments are evaluated left to right. To ensure this we add a side condition that - checks that all the arguments before the one being heated (if any) are already of the - sort KResult. +The first two parts of method invocation logic are evaluation of the qualifier expression and evaluation of the arguments. JLS enforces the following conditions on the order of subexpressions evaluation: + + - Arguments have to be evaluated after the qualifier was evaluated. This is ensured by checking that the qualifier is of sort KResult at the moment when arguments are heated. + - Arguments are evaluated left to right. To ensure this we add a side condition that checks that all the arguments before the one being heated (if any) are already of the sort KResult. \end{markdown} -While there are two sections dedicated to this logic (\S15.12.4.1, \S15.12.4.2), we don't need any K rules - for it. Instead, subexpressions evaluation ensured by strictness annotations - that accompany the following syntax definitions: +While there are two sections dedicated to this logic (\S15.12.4.1, \S15.12.4.2), we don't need any K rules for it. Instead, subexpressions evaluation ensured by strictness annotations that accompany the following syntax definitions: -\begin{syntaxBlock}{ - \nonTerminal{\sort{Exp}}}\syntax{{{\nonTerminal{\sort{K}}}}\terminal{.}{{\nonTerminal{\sort{MethodName}}}} - ({{\nonTerminal{\sort{Exps}}}})}{\kattribute{seqstrict}(1,3)} +\begin{syntaxBlock}{Exp} + \syntax{{{\nonTerminal{\sort{K}}}}\terminal{.}{{\nonTerminal{\sort{MethodName}}}} + ({{\nonTerminal{\sort{Exps}}}})}{\kattribute{seqstrict}(1,3)} \end{syntaxBlock} -\begin{syntaxBlock}{ - \nonTerminal{\sort{MethodName}}}\syntax{{\nonTerminal{\sort{Id}}}}{} +\begin{syntaxBlock}{MethodName} + \syntax{{\nonTerminal{\sort{Id}}}}{} \end{syntaxBlock} -\begin{syntaxBlock}{ - \nonTerminal{\sort{Exps}}}\syntax{List\{{\nonTerminal{\sort{Exp}}}, \mbox{``},\mbox{''}\}}{\kattribute{seqstrict}} +\begin{syntaxBlock}{Exps} + \syntax{List\{{\nonTerminal{\sort{Exp}}}, \mbox{``},\mbox{''}\}}{\kattribute{seqstrict}} \end{syntaxBlock} -The annotation {\kattribute{seqstrict}(1,3)} on the first definition ensures that arguments are evaluated after the - qualifier is evaluated. The qualifier term might be either an expression or a Class. If it is expression, - it will be heated and evaluated. If it is a class (for certain static methods), then it is already a KResult - strictness rule will have no effect on it. +The annotation {\kattribute{seqstrict}(1,3)} on the first definition ensures that arguments are evaluated after the qualifier is evaluated. The qualifier term might be either an expression or a Class. If it is expression, it will be heated and evaluated. If it is a class (for certain static methods), then it is already a KResult strictness rule will have no effect on it. -Note that arguments have to be evaluated even in the case when the qualifier evaluated to null. At the same time - that if evaluation of the qualifier or any of the arguments - completes abruptly, the whole method invocation expression completes abruptly for the - same reason. K-Java does not need any special rules to cover those cases. The semantics has a fixed number of rules - for throw statement that ensure the correct propagation of exceptions from any context. +Note that arguments have to be evaluated even in the case when the qualifier evaluated to null. At the same time that if evaluation of the qualifier or any of the arguments completes abruptly, the whole method invocation expression completes abruptly for the same reason. K-Java does not need any special rules to cover those cases. The semantics has a fixed number of rules for throw statement that ensure the correct propagation of exceptions from any context. */ /*@ \subsection{Loading method information} \begin{markdown} -During the second step of the method invocation the second argument of the production is replaced with the - auxiliary data - structure \verb|methodInfo()|. This data structure contains the information required to choose the right method lookup - strategy at the next step. The production \verb|methodInfo()| contains the following arguments: +During the second step of the method invocation the second argument of the production is replaced with the auxiliary data structure \verb|methodInfo()|. This data structure contains the information required to choose the right method lookup strategy at the next step. The production \verb|methodInfo()| contains the following arguments: - Method signature \verb|Sig| - Qualifying class \verb|QualC| of the method invocation, e.g. the compile-time type of the qualifier. - The meta type of \verb|QualC| --- \verb|MetaT|. It may have one of the two values - class or interface. - - \verb|DecC| --- declaring class, the class where the method was actually declared, as observed by \verb|QualT|. - E.g. the most derived class in \verb|QualC| hierarchy where there is a declaration of a method with signature \verb|Sig|. + - \verb|DecC| --- declaring class, the class where the method was actually declared, as observed by \verb|QualT|. E.g. the most derived class in \verb|QualC| hierarchy where there is a declaration of a method with signature \verb|Sig|. - \verb|ContextT| --- the context type of the method. Either static, for static methods, or instance for non-static methods. - - \verb|Acc| --- access modifier (private, package, protected or public). For the purpose of uniformity we use the modifier - package when no access modifier is provided. + - \verb|Acc| --- access modifier (private, package, protected or public). For the purpose of uniformity we use the modifier package when no access modifier is provided. -All the information stored in \verb|methodInfo()| is static. In K-Java we already have - this information computed, but it is stored in various cells inside \cellref[]{class} and \cellref[]{classDec}. - The rules from step 3 simply load the relevant information from configuration - cells to \verb|methodInfo()| arguments. +All the information stored in \verb|methodInfo()| is static. In K-Java we already have this information computed, but it is stored in various cells inside \cellref[]{class} and \cellref[]{classDec}. The rules from step 3 simply load the relevant information from configuration cells to \verb|methodInfo()| arguments. \end{markdown} */ syntax MethodName ::= methodInfo( Signature, //Sig - method signature @@ -237,11 +175,7 @@ syntax MethodName ::= methodInfo( ) /*@ -The first rule from this step rewrites the method name into a \verb|methodInfo()| term whose first argument is the method -signature. - The auxiliary function \verb|getTypes()| computes the list of types from the list of parameter declarations. The second - argument of \verb|methodInfo()| is also computed at this step --- it is the type of the qualifier. The rest of the arguments - are filled in with default values. They will be rewritten into actual values by the following rules. +The first rule from this step rewrites the method name into a \verb|methodInfo()| term whose first argument is the method signature. The auxiliary function \verb|getTypes()| computes the list of types from the list of parameter declarations. The second argument of \verb|methodInfo()| is also computed at this step --- it is the type of the qualifier. The rest of the arguments are filled in with default values. They will be rewritten into actual values by the following rules. */ rule [Invoke-compute-methodInfo-Signature]: Qual:KResult @@ -249,27 +183,23 @@ rule [Invoke-compute-methodInfo-Signature]: (Args:TypedVals) /*@ -Note that in this rule variable Args is defined of type TypedVals instead of Exps. This restriction ensures that - arguments (and consequently the qualifier) are already evaluated at the moment when this rule is invoked. - The sort TypedVals represents a list of typed values, the evaluation result of Exps. It is defined as following: +Note that in this rule variable Args is defined of type TypedVals instead of Exps. This restriction ensures that arguments (and consequently the qualifier) are already evaluated at the moment when this rule is invoked. The sort TypedVals represents a list of typed values, the evaluation result of Exps. It is defined as following: -\begin{syntaxBlock}{ - \nonTerminal{\sort{TypedVals}}}\syntax{List\{{\nonTerminal{\sort{TypedVal}}}, \mbox{``},\mbox{''}\}}{} +\begin{syntaxBlock}{TypedVals} + \syntax{List\{{\nonTerminal{\sort{TypedVal}}}, \mbox{``},\mbox{''}\}}{} \end{syntaxBlock} -\begin{syntaxBlock}{ - \nonTerminal{\sort{Exps}}}\syntax{{\nonTerminal{\sort{TypedVals}}}}{} +\begin{syntaxBlock}{Exps} + \syntax{{\nonTerminal{\sort{TypedVals}}}}{} \end{syntaxBlock} Because TypedVal is subsorted to KResult, TypedVals being a list of KResult is implicitly subsorted to KResult. */ -/* Impl: We could combine this rule with the previous one by using \verb|getLookupTargetType()|, but we'll keep it this way - to keep the core part of method invocation separate from the non object-related part. */ +/* Impl: We could combine this rule with the previous one by using \verb|getLookupTargetType()|, but we'll keep it this way to keep the core part of method invocation separate from the non object-related part. */ /*@ The second rule for method invocation loads \verb|MetaT| and \verb|DecC|. It requires \verb|Sig| and \verb|QualC| computed by the previous rule. - */ rule [Invoke-compute-methodInfo-DecC]: @@ -281,16 +211,12 @@ rule [Invoke-compute-methodInfo-DecC]: ... Sig |-> DecC:ClassType ... /*@ \begin{markdown} -There is one case that is not covered by the previous rule --- the case when the cell \cellref[]{methods} does not have a key - equal to \verb|Sig|. This is possible in one of the following situations: +There is one case that is not covered by the previous rule --- the case when the cell \cellref[]{methods} does not have a key equal to \verb|Sig|. This is possible in one of the following situations: - Qualifying type is an interface. - - Qualifying type is an abstract class. The called method is inherited from an interface but is not declared neither - in this class nor in its base classes. + - Qualifying type is an abstract class. The called method is inherited from an interface but is not declared neither in this class nor in its base classes. -In both cases the method is an abstract method in the class \verb|QualT|. For this case \verb|DecC| cannot be computed, but we know - for sure that \verb|ContextT| for an abstract method is instance. Also, because the method was declared in an interface, - it is certainly public. +In both cases the method is an abstract method in the class \verb|QualT|. For this case \verb|DecC| cannot be computed, but we know for sure that \verb|ContextT| for an abstract method is instance. Also, because the method was declared in an interface, it is certainly public. \end{markdown} */ rule [Invoke-compute-methodInfo-unmapped-method-ContextType]: @@ -319,15 +245,11 @@ rule [Invoke-compute-methodInfo-ContextType]: /*@ \subsection{Lookup method declaration} -In the third step of the method invocation algorithm, the actual method declaration is chosen. This step starts once all - the fields of \verb|methodInfo()| were filled in (where possible). The rules of this step rewrite \verb|methodInfo()| into - \verb|methodRef()| --- another auxiliary data structure. -The production \verb|methodRef()| is a reference to a method declaration. It contains two fields --- \verb|Sig| and \verb|DecC| --- the - signature and the declaration class. The implementation class is the class that contains the actual method - declaration to be invoked. +In the third step of the method invocation algorithm, the actual method declaration is chosen. This step starts once all the fields of \verb|methodInfo()| were filled in (where possible). The rules of this step rewrite \verb|methodInfo()| into \verb|methodRef()| --- another auxiliary data structure. +The production \verb|methodRef()| is a reference to a method declaration. It contains two fields --- \verb|Sig| and \verb|DecC| --- the signature and the declaration class. The implementation class is the class that contains the actual method declaration to be invoked. -\begin{syntaxBlock}{ - \nonTerminal{\sort{MethodName}}}\syntax{{}\terminal{methodRef}({{\nonTerminal{\sort{Signature}}}},{{\nonTerminal{\sort{RefType}}}})}{} +\begin{syntaxBlock}{MethodName} + \syntax{{}\terminal{methodRef}({{\nonTerminal{\sort{Signature}}}},{{\nonTerminal{\sort{RefType}}}})}{} \end{syntaxBlock} \begin{markdown} @@ -336,14 +258,12 @@ Since we already know the signature, this phase amounts to computing \verb|DecC| - Static method (JLS \S15.12.4.4 paragraph 2) - Instance method with target being null (JLS \S15.12.4.4 paragraph 3) - Instance method with non-null target, private method (JLS \S15.12.4.4 paragraph 4) - - Instance method with non-null target, access mode is protected or public. This also includes qualifying type - being interface. (JLS \S15.12.4.4 paragraph 6 and point 1) + - Instance method with non-null target, access mode is protected or public. This also includes qualifying type being interface. (JLS \S15.12.4.4 paragraph 6 and point 1) - Instance method with non-null target, access mode is package (no dedicated mention in JLS \S15.12.4.4) -The method below is for the first case. If the method is static, then the declaring type \verb|DecC| is the qualifying type. - The qualifier is discarded by rewriting it into \dotCt{K} . +The method below is for the first case. If the method is static, then the declaring type \verb|DecC| is the qualifying type. The qualifier is discarded by rewriting it into \dotCt{K} . \end{markdown} */ rule [Invoke-methodInfo-static]: @@ -352,9 +272,7 @@ rule [Invoke-methodInfo-static]: (_) /*@ -If the qualifier value is null and \verb|ContextT| is instance, then NullPointerException is thrown and method invocation - expression is discarded. It is only at this point that we should check the qualifier whether it is null or not. - If \verb|ContextT| is static, then the previous rule will match, and no exception will be thrown. +If the qualifier value is null and \verb|ContextT| is instance, then NullPointerException is thrown and method invocation expression is discarded. It is only at this point that we should check the qualifier whether it is null or not. If \verb|ContextT| is static, then the previous rule will match, and no exception will be thrown. */ rule [Invoke-methodInfo-instance-on-null]: /* [Impl] Qualifier type could be either object or array. @@ -373,14 +291,7 @@ rule [Invoke-methodInfo-instance-private]: (_) /*@ -If the method is protected or public, then we should call the version of the method visible to the runtime type of - the qualifying object (\verb|ObjC|). Recall that the runtime type of an object is stored in the second argument of - \verb|objectRef()|. - This case also covers qualifying type interface, since interface methods are always public. - The right method will always be the one referred by the signature \verb|Sig| in the cell \cellref[]{methods} associated with the - actual object class. This is because the unfolding phase populates \cellref[]{methods} with the union of methods inherited - from the base class and methods declared in the current class, the latter overriding the former. - The variable \verb|DecC| is the class where the right method version is declared. +If the method is protected or public, then we should call the version of the method visible to the runtime type of the qualifying object (\verb|ObjC|). Recall that the runtime type of an object is stored in the second argument of \verb|objectRef()|. This case also covers qualifying type interface, since interface methods are always public. The right method will always be the one referred by the signature \verb|Sig| in the cell \cellref[]{methods} associated with the actual object class. This is because the unfolding phase populates \cellref[]{methods} with the union of methods inherited from the base class and methods declared in the current class, the latter overriding the former. The variable \verb|DecC| is the class where the right method version is declared. */ rule [Invoke-methodInfo-instance-protected-or-public]: @@ -396,17 +307,14 @@ when /*@ \begin{markdown} -The most complex case is for instance methods with package access mode. The precise semantics of overriding for all - access modes is defined in JLS \S8.4.6.1: +The most complex case is for instance methods with package access mode. The precise semantics of overriding for all access modes is defined in JLS \S8.4.6.1: -An instance method derivedM declared in a class Derived overrides another method with the - same signature, baseM, declared in class Base iff both: +An instance method derivedM declared in a class Derived overrides another method with the same signature, baseM, declared in class Base iff both: 1. Derived is a subclass of Base. 2. Either - a. baseM is public, protected, or declared with package access in the same package as derivedM - b. derivedM overrides a method middleM, middleM distinct from baseM and derivedM, - such that middleM overrides baseM + a. baseM is public, protected, or declared with package access in the same package as derivedM. + b. derivedM overrides a method middleM, middleM distinct from baseM and derivedM, such that middleM overrides baseM. The transitive rule for overriding relation (2b) is required specifically for package access mode. Consider the following example: \end{markdown} @@ -435,29 +343,17 @@ public class C extends B { \medskip -The method in class C overrides the method in class A transitively through the method in B. There is no direct - overriding between A and C, because the method is declared with default (package) access mode in A, and class C is - in a different package. Note that if the access mode in B would have been package instead of protected, - there would be no overriding. +The method in class C overrides the method in class A transitively through the method in B. There is no direct overriding between A and C, because the method is declared with default (package) access mode in A, and class C is in a different package. Note that if the access mode in B would have been package instead of protected, there would be no overriding. -\begin{markdown} -In order to correctly handle such cases we have to analyse all the classes in the inheritance chain between the - qualifying type and the qualifier runtime type. +In order to correctly handle such cases we have to analyse all the classes in the inheritance chain between the qualifying type and the qualifier runtime type. -The algorithm employed in K-Java is significantly different from the one in JLS, but it is much simpler to implement. - Yet it yields the correct behaviour and was extensively tested by our test suite. The JLS algorithm involves starting - the search from the runtime type of the qualifier and moving upwards in the inheritance tree until we find the FIRST - method that overrides the originally called method (or is the originally called method itself). This apparently - simple algorithm leads to multiple particular cases when we consider the transitive rule (2b above) for overriding. +The algorithm employed in K-Java is significantly different from the one in JLS, but it is much simpler to implement. Yet it yields the correct behaviour and was extensively tested by our test suite. The JLS algorithm involves starting the search from the runtime type of the qualifier and moving upwards in the inheritance tree until we find the FIRST method that overrides the originally called method (or is the originally called method itself). This apparently simple algorithm leads to multiple particular cases when we consider the transitive rule (2b above) for overriding. -In contrast, the K-Java algorithm starts the search with the qualifying type (e.g. static type of the qualifier - expression) and moves downwards in the inheritance chain until it reaches the runtime type of the qualifier. - When all classes in the chain were traversed the algorithm returns the LAST found method (e.g. defined in the most - derived class) that overrides the original one. +In contrast, the K-Java algorithm starts the search with the qualifying type (e.g. static type of the qualifier expression) and moves downwards in the inheritance chain until it reaches the runtime type of the qualifier. When all classes in the chain were traversed the algorithm returns the LAST found method (e.g. defined in the most derived class) that overrides the original one. -The rule for package access mode delegates searching for the right method declaration to the auxiliary function - \verb|lookupPackageMethod()|. The function takes 3 arguments: +The rule for package access mode delegates searching for the right method declaration to the auxiliary function \verb|lookupPackageMethod()|. The function takes 3 arguments: +\begin{markdown} - method signature \verb|Sig| - the list of classes in the inheritance chain between the qualifying class \verb|QualC| and the actual object class \verb|ObjC|. This list is produced by \verb|classChain()| @@ -478,29 +374,23 @@ rule [Invoke-methodInfo-instance-package]: ... Sig |-> _ ... /*@ -Before the evaluation of \verb|lookupPackageMethod()| may begin, the term \verb|lookupPackageMethod()| has to be heated to the top - of computation. The side condition in the context rule below ensured that the second argument of method call - expression is heated only if it contains a term \verb|lookupPackageMethod()|. If it has other forms, - such as the method name or \verb|methodInfo()|, it won't be heated. +Before the evaluation of \verb|lookupPackageMethod()| may begin, the term \verb|lookupPackageMethod()| has to be heated to the top of computation. The side condition in the context rule below ensured that the second argument of method call expression is heated only if it contains a term \verb|lookupPackageMethod()|. If it has other forms, such as the method name or \verb|methodInfo()|, it won't be heated. */ context _:K . HOLE (_) when getKLabel(HOLE) ==KLabel 'lookupPackageMethod /*@ -Returns the list of classes representing the layer of the given object (by OId), - located between MostBaseClass (exclusively) and MostDerivedClass (inclusively). +Returns the list of classes representing the layer of the given object (by OId), located between MostBaseClass (exclusively) and MostDerivedClass (inclusively). */ syntax KItem ::= getClassChain( ClassType, //MostBaseClass ClassTypes //MostDerivedClass at beginning, gradually accumulates //the list of classes ) -/*@ The right signature is already found. -Search for the right implementation is performed from the compile-time type of the target -to more derived types, up to the object type of the target. -This is required in order to respect the rules of inheritance in the presence of access modes. -Evaluates into typed method closure.*/ +/*@ +The right signature is already found. Search for the right implementation is performed from the compile-time type of the target to more derived types, up to the object type of the target. This is required in order to respect the rules of inheritance in the presence of access modes. Evaluates into typed method closure. +*/ syntax KItem ::= lookupPackageMethod ( Signature, //sig(Name, SigTL) - Method signature ClassTypes, //computes Class,... , list of elements of type ClassType, @@ -516,20 +406,12 @@ syntax KItem ::= lookupPackageMethod ( \begin{markdown} The rules for \verb|lookupPackageMethod()| are based on the following two properties of the configuration: - - if the cell \cellref[]{methods} for a particular class contains a key \verb|Sig|, then \cellref[]{methods} for all classes derived from it - will contain the key \verb|Sig|. - - if a particular class contain a method declaration with signature \verb|Sig| access mode \verb|Acc|, then all declarations - of \verb|Sig| in derived classes (that are not necessarily overriding!) will have the access mode equal to either \verb|Acc| or a - value wider than \verb|Acc|. + - if the cell \cellref[]{methods} for a particular class contains a key \verb|Sig|, then \cellref[]{methods} for all classes derived from it will contain the key \verb|Sig|. + - if a particular class contain a method declaration with signature \verb|Sig| access mode \verb|Acc|, then all declarations of \verb|Sig| in derived classes (that are not necessarily overriding!) will have the access mode equal to either \verb|Acc| or a value wider than \verb|Acc|. -The first property is ensured by the unfolding algorithm. Because \cellref[]{methods} of a derived class inherit all the \cellref[]{methods} - of the direct base class, the map \cellref[]{methods} may only grow from base classes to derived. The second property is ensured - by restrictions on overriding specified in JLS \S8.4.8.3: "The access modifier (\S6.6) of an overriding or hiding - method must provide at least as much access as the overridden or hidden method". +The first property is ensured by the unfolding algorithm. Because \cellref[]{methods} of a derived class inherit all the \cellref[]{methods} of the direct base class, the map \cellref[]{methods} may only grow from base classes to derived. The second property is ensured by restrictions on overriding specified in JLS \S8.4.8.3: "The access modifier (\S6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method". -The search for the right package method declaration is performed from the base-most class in the chain (the left-most - one) to the most derived one. Every rule matches and deletes the leftmost class in the class chain (\verb|CurrentC|), - and possibly rewrites the third argument into the current class. +The search for the right package method declaration is performed from the base-most class in the chain (the left-most one) to the most derived one. Every rule matches and deletes the leftmost class in the class chain (\verb|CurrentC|), and possibly rewrites the third argument into the current class. The first rule matches when there is no declaring class yet (third argument is \dotCt{K}, the initial case). \end{markdown} */ @@ -546,12 +428,10 @@ rule [lookupPackageMethod-layer-first-dec-found]: ... Sig |-> DecC:ClassType ... /*@ -The second rule matches when we already found a declaring class (\verb|OldDecC|) and the current class \verb|CurrentC| has another - method declaration with the right signature. The presence of a declaration with signature \verb|Sig| inside \verb|CurrentC| is identified by the - match $\kall{class}{\kall{classType}{ CurrentC } \mathrel{} \kmiddle{methods}{ Sig \mapsto CurrentC } }$, - according to the definition of \cellref[]{methods}. +The second rule matches when we already found a declaring class (\verb|OldDecC|) and the current class \verb|CurrentC| has another method declaration with the right signature. The presence of a declaration with signature \verb|Sig| inside \verb|CurrentC| is identified by the match $\kall{class}{\kall{classType}{ CurrentC } \mathrel{} \kmiddle{methods}{ Sig \mapsto CurrentC } }$, according to the definition of \cellref[]{methods}. + +If the method in \verb|CurrentC| directly overrides the method in \verb|OldDecC|, the declaring class is updated to \verb|CurrentC|. Otherwise the declaring class stays unchanged. The rules for direct overriding (case 1a above) are defined in the auxiliary function \verb|isOverridden()|. The function takes 3 arguments: -If the method in \verb|CurrentC| directly overrides the method in \verb|OldDecC|, the declaring class is updated to \verb|CurrentC|. Otherwise the declaring class stays unchanged. The rules for direct overriding (case 1a above) are defined in the auxiliary function \verb|isOverridden()|. The function takes three arguments: \begin{markdown} - The base class \verb|OldDecC| - The derived class \verb|CurrentC| @@ -581,8 +461,7 @@ rule [lookupPackageMethod-new-method]: /*@ \begin{markdown} -Tests if a method declared in class \verb|BaseC| with access mode \verb|Acc| is overridden by a method - with the same signature declared in a subclass \verb|SubC|. +Tests if a method declared in class \verb|BaseC| with access mode \verb|Acc| is overridden by a method with the same signature declared in a subclass \verb|SubC|. The method is overridden if either: @@ -607,9 +486,7 @@ rule isOverridden(BaseC:ClassType, package, SubC:ClassType) rule isOverridden(_, private, _) => false /*@ -The third rule represents the case when \verb|CurrentC| chain does not contain method declarations with signature - \verb|Sig|. This case is identified by the side condition \verb|CurrentC| =/=K \verb|DecC|. Indeed, the two classes are different only - when the entry \verb|Sig| $\mapsto$ \verb|DecC| in \cellref[]{methods} was inherited rather than produced by a method in \verb|CurrentC|. +The third rule represents the case when \verb|CurrentC| chain does not contain method declarations with signature \verb|Sig|. This case is identified by the side condition \verb|CurrentC| =/=K \verb|DecC|. Indeed, the two classes are different only when the entry \verb|Sig| $\mapsto$ \verb|DecC| in \cellref[]{methods} was inherited rather than produced by a method in \verb|CurrentC|. */ rule [lookupPackageMethod-no-new-method]: @@ -626,8 +503,7 @@ when CurrentC =/=K DecC /*@ -The last rule matches when the chain of classes stored in the first argument remains empty. It rewrites the whole - \verb|lookupPackageMethod()| into a reference to the method that has to be invoked. +The last rule matches when the chain of classes stored in the first argument remains empty. It rewrites the whole \verb|lookupPackageMethod()| into a reference to the method that has to be invoked. */ rule [lookupPackageMethod-end]: lookupPackageMethod( Sig:Signature, .ClassTypes, DecC:ClassType ) => methodRef(Sig, DecC) @@ -682,49 +558,31 @@ For the code example above, the term \verb|lookupPackageMethod()| will pass thro \vspace{3ex} -When the term \verb|lookupPackageMethod()| is first produced it takes as arguments the method signature (rendered here as \verb|f()| - for convenience), the chain of classes from the qualifying class A to the runtime class C, - and \dotCt{K} as the third argument. Since the third argument is \dotCt{K} only the third rule can match. This rule deletes A - from the class chain and updates the third argument to the class that defines the version of \verb|f()| accessible to A. - That class is A. For classes B and C the second rule for \verb|lookupMethodM()| matches. In both cases the method \verb|f()| - defined in B and C overrides the previously found one. In the first case classes the method \verb|B.f()| overrides \verb|A.f()| - because the access mode is package and both A and B are in the same package. In the second case \verb|C.f()| - overrides \verb|B.f()| because \verb|B.f()| has protected access mode, and is thus always overridden. The final result of - method lookup procedure is the version of method \verb|f()| declared in the class C. +When the term \verb|lookupPackageMethod()| is first produced it takes as arguments the method signature (rendered here as \verb|f()| for convenience), the chain of classes from the qualifying class A to the runtime class C, and \dotCt{K} as the third argument. Since the third argument is \dotCt{K} only the third rule can match. This rule deletes A from the class chain and updates the third argument to the class that defines the version of \verb|f()| accessible to A. That class is A. For classes B and C the second rule for \verb|lookupMethodM()| matches. In both cases the method \verb|f()| defined in B and C overrides the previously found one. In the first case classes the method \verb|B.f()| overrides \verb|A.f()| because the access mode is package and both A and B are in the same package. In the second case \verb|C.f()| overrides \verb|B.f()| because \verb|B.f()| has protected access mode, and is thus always overridden. The final result of method lookup procedure is the version of method \verb|f()| declared in the class C. */ /*@ \subsection{Actual method invocation} \begin{markdown} -The central rule of method invocation is matched when the second argument of method call expression reaches the form - \verb|methodRef()|. This rule performs the following operations: +The central rule of method invocation is matched when the second argument of method call expression reaches the form \verb|methodRef()|. This rule performs the following operations: - - saves the rest of computation (\verb|RestK|) and the content of \cellref[]{methodContext} as a new entry of the cell \cellref[]{stack} - This data is restored back by the rules for return statement. + - saves the rest of computation (\verb|RestK|) and the content of \cellref[]{methodContext} as a new entry of the cell \cellref[]{stack} This data is restored back by the rules for return statement. - Initializes the new method context. - The local variable environment \cellref[]{env} is emptied - current class \cellref[]{crntClass} is initialized to the class declaring the method - - object location \cellref[]{location} is initialized to the location of the qualifier object for instance methods, - or \dotCt{K} for static methods. The extraction of the location from the qualifier value is performed by the - function \verb|getOId()|. + - object location \cellref[]{location} is initialized to the location of the qualifier object for instance methods, or \dotCt{K} for static methods. The extraction of the location from the qualifier value is performed by the function \verb|getOId()|. - Rewrites the method call expression into a sequence of four terms: - static initialization of the qualifying class - parameters initialization - actual method body - a return statement with no arguments after the method body. -The function \verb|staticInit()| triggers static initialization of the qualifying class, if this class was not initialized yet. - Repeated calls of this function have no effect. Is required just for static methods and is described in JLS \S12.4. - For an instance method call, the qualifying class will always be initialized already, - so \verb|staticInit()| will have no effect. +The function \verb|staticInit()| triggers static initialization of the qualifying class, if this class was not initialized yet. Repeated calls of this function have no effect. Is required just for static methods and is described in JLS \S12.4. For an instance method call, the qualifying class will always be initialized already, so \verb|staticInit()| will have no effect. -The function \verb|initParams()| rewrites each parameter declaration into two statements. First is a local variable - declaration with that parameter name. The second is an assignment to that variable of the actual argument value. +The function \verb|initParams()| rewrites each parameter declaration into two statements. First is a local variable declaration with that parameter name. The second is an assignment to that variable of the actual argument value. -The return statement at the end ensures that there is a return statement on every execution path of the method. The - statement will only be useful for methods with return type void, as methods returning a value are required by JLS - to have an appropriate return statement on every return path. +The return statement at the end ensures that there is a return statement on every execution path of the method. The statement will only be useful for methods with return type void, as methods returning a value are required by JLS to have an appropriate return statement on every return path. \end{markdown} */ rule [Invoke-methodRef]: @@ -825,9 +683,7 @@ module METHOD-INVOKE-REST imports METHOD-INVOKE /*@ -The next rule for method invocation is applied when the qualifier type is array. This array type is rewritten - into the auxiliary class \verb|ArrayImpl|, that is used in K-Java to simulate method invocations over array objects. - This rule is required in order to minimize the number of particular cases involving arrays in the rules that follow. +The next rule for method invocation is applied when the qualifier type is array. This array type is rewritten into the auxiliary class \verb|ArrayImpl|, that is used in K-Java to simulate method invocations over array objects. This rule is required in order to minimize the number of particular cases involving arrays in the rules that follow. */ rule [Invoke-compute-methodInfo-arrays]: QualRV:RawVal :: (arrayOf T:Type => classArrayImpl) @@ -899,8 +755,7 @@ when notBool ((DecC ==K classObject) andBool (Name ==K String2Id("wait") orBool Name ==K String2Id("notify") orBool Name ==K String2Id("notifyAll"))) -/*@ Auxiliary function for methods that need implementation in the semantics. The implementation - of this production is given in api-core.k and api-threads.k. +/*@ Auxiliary function for methods that need implementation in the semantics. The implementation of this production is given in api-core.k and api-threads.k. */ syntax KItem ::= invokeImpl ( MethodRef, //the method reference diff --git a/src/exec/new-instance.k b/src/exec/new-instance.k index f01d23cc..27988fdb 100644 --- a/src/exec/new-instance.k +++ b/src/exec/new-instance.k @@ -8,8 +8,7 @@ module NEW-INSTANCE /*@ \subsection{Background} -In this subsection we present the fragment of configuration used by runtime method - invocation. The figure below contains the cells and their sorts. +In this subsection we present the fragment of configuration used by runtime method invocation. The figure below contains the cells and their sorts. \vspace{3ex} @@ -68,31 +67,13 @@ In this subsection we present the fragment of configuration used by runtime meth \vspace{3ex} -The cell \cellref[]{k} stores the current computation. Inside \cellref[]{env} we store the local environment --- a map - from variable names to their locations in the store. The cell \cellref[]{methodContext} store information about the - current object --- the one accessible through the keyword this. Both \cellref[]{env} and \cellref[]{methodContext} play - a special role in object instantiation. - -The cell \cellref[]{class} contains various sub-cells holding the content of that class. The - first cell in \cellref[]{classType} of sort ClassType that holds the fully qualified class name. - This cell is a unique identifier of a class, and is used as a key to access other cells inside a \cellref[]{class}. - Next relevant cells inside \cellref[]{class} are \cellref[]{enclosingClass} --- the directly enclosing class in case - this class is an inner class. The vase class is stored inside \cellref[]{extends} and the list of declarations of - instance fields without identifiers is stored in \cellref[]{instanceFields}. - -The next two cells are related to the store. The cell \cellref[]{store} has a central role in the semantics --- it is - the map from object locations (values in the cell \cellref[]{env}) to their actual typed values. - The cell \cellref[]{nextLoc} is the counter of store locations. - -The remaining big group of cells --- \cellref[]{objectStore} contains the inner structure of objects. - The \cellref[]{objectId} is an unique identifier of the object. Every reference to this object in the store is - a reference to this id. Inside \cellref[]{objectType} is the actual runtime type of the object. Next we have a list - of \cellref[]{layer} cells, each of them representing an inheritance layer of the object. Starting from class - Object and ending with the actual object type. Inside each layer \cellref[]{layerClass} stores its - associated class, \cellref[]{layerEnv} --- the fields and \cellref[]{layerEnclosingObject} --- the enclosing object, - in the case when \cellref[]{layerClass} is a non-static inner class. The complex rules for Java inner classes - allow each layer to have its distinctive enclosing object, and we have tests that specifically target this - requirement. +The cell \cellref[]{k} stores the current computation. Inside \cellref[]{env} we store the local environment --- a map from variable names to their locations in the store. The cell \cellref[]{methodContext} store information about the current object --- the one accessible through the keyword this. Both \cellref[]{env} and \cellref[]{methodContext} play a special role in object instantiation. + +The cell \cellref[]{class} contains various sub-cells holding the content of that class. The first cell in \cellref[]{classType} of sort ClassType that holds the fully qualified class name. This cell is a unique identifier of a class, and is used as a key to access other cells inside a \cellref[]{class}. Next relevant cells inside \cellref[]{class} are \cellref[]{enclosingClass} --- the directly enclosing class in case this class is an inner class. The vase class is stored inside \cellref[]{extends} and the list of declarations of instance fields without identifiers is stored in \cellref[]{instanceFields}. + +The next two cells are related to the store. The cell \cellref[]{store} has a central role in the semantics --- it is the map from object locations (values in the cell \cellref[]{env}) to their actual typed values. The cell \cellref[]{nextLoc} is the counter of store locations. + +The remaining big group of cells --- \cellref[]{objectStore} contains the inner structure of objects. The \cellref[]{objectId} is an unique identifier of the object. Every reference to this object in the store is a reference to this id. Inside \cellref[]{objectType} is the actual runtime type of the object. Next we have a list of \cellref[]{layer} cells, each of them representing an inheritance layer of the object. Starting from class Object and ending with the actual object type. Inside each layer \cellref[]{layerClass} stores its associated class, \cellref[]{layerEnv} --- the fields and \cellref[]{layerEnclosingObject} --- the enclosing object, in the case when \cellref[]{layerClass} is a non-static inner class. The complex rules for Java inner classes allow each layer to have its distinctive enclosing object, and we have tests that specifically target this requirement. */ /*@ \subsection{New instance creation}*/ diff --git a/src/prep/configuration-prep.k b/src/prep/configuration-prep.k index 7beba519..6fb0808b 100644 --- a/src/prep/configuration-prep.k +++ b/src/prep/configuration-prep.k @@ -6,12 +6,12 @@ module CONFIGURATION-PREP The Static semantics consists of several phases that analyze the input program, distribute it from the AST form to a set of cells and finally assembles it back to an AST, this time containing just a subset of features of Java. Each phase digs deeper into a program structure, and most phases also store their result into new cells. Below is the list of global phases, in their execution order: \begin{itemize} - \item Process Type Names - \item Process Compilation Units - \item Process Class Declarations - \item Process Class Members - \item Elaboration - \item Folding + \item Process Type Names + \item Process Compilation Units + \item Process Class Declarations + \item Process Class Members + \item Elaboration + \item Folding \end{itemize} The configuration cells may be divided into 2 categories: cells directly placed inside the all-enclosing cell \cellref{T} (top-level cells), and cells inside \cellref{classes}. The cell \cellref{classes} is a collection of \cellref{class} cells, each representing a Java class (both supported classes from JDK and classes defined by the developer). A \cellref{class} contains all components of a class --- such as extends/implements clauses, imports, fields, methods, etc, each distributed into a separate class, in order to be conveniently accessed when needed. @@ -248,44 +248,44 @@ configuration /*@ \paragraph{Initial state} The first row contains three cells most relevant to computation initial state: \begin{itemize} - \item \cellref[K]{k} --- Holds the current computation in all phases of the semantics. Initializes with the AST representation of the program. - \item \cellref[K]{program} --- A backup of program AST. Required because the initial AST is needed in both 1st ans 2nd phase of static K-Java, but the first phase destroys the content inside \cellref{k}. Also used in the last phase (Folding) to assemble the preprocessed program. - \item \cellref[GlobalPhase]{globalPhase} --- The current computation global phase. + \item \cellref[K]{k} --- Holds the current computation in all phases of the semantics. Initializes with the AST representation of the program. + \item \cellref[K]{program} --- A backup of program AST. Required because the initial AST is needed in both 1st ans 2nd phase of static K-Java, but the first phase destroys the content inside \cellref{k}. Also used in the last phase (Folding) to assemble the preprocessed program. + \item \cellref[GlobalPhase]{globalPhase} --- The current computation global phase. \end{itemize} \paragraph{Process Type Names} During this phase, one global cell is computed: \begin{itemize} - \item \cellref[Map{[}PackageId \mapsto Map{[}Id\mapsto{}ClassType{]}{]}]{namesToClasses} --- A two-level map. First level is a map from package names to second-level maps. Second-level maps are from simple class names to fully qualified class names within the package. This cell is extensively used through the semantics. The map contains both top-level and inner classes. For inner classes, their enclosing package is the fully qualified class name of the directly enclosing class. + \item \cellref[Map{[}PackageId \mapsto Map{[}Id\mapsto{}ClassType{]}{]}]{namesToClasses} --- A two-level map. First level is a map from package names to second-level maps. Second-level maps are from simple class names to fully qualified class names within the package. This cell is extensively used through the semantics. The map contains both top-level and inner classes. For inner classes, their enclosing package is the fully qualified class name of the directly enclosing class. \end{itemize} Also during Process Type Names classes are first registered. Again, both top-level and inner classes are covered. In a newly created \cellref[]{class} just a few sub-cells are initialized with data: \begin{itemize} - \item \cellref[ClassType]{classType} --- The fully qualified class name. The identifier of the class. - \item \cellref[ClassMetaType]{classMetaType} --- Represents whether the type stored in this cell is class or interface. To avoid terminology superfluousness, we will refer hereafter to both classes and interfaces as "classes", making distinctions only when necessary. - \item \cellref[ClassAccessMode]{classAccessMode} --- The access modifier of the class, either public or package. - \item \cellref[ClassPhase]{classPhase} --- Represents the state of this class. In addition to the global computation phase, each class has its own lifecycle phase. Class phases are required to keep track which classes were processed in the current global phase and which were not. During each global phase all classes should transition to a certain class phase. However, as we shall see, not all global phases change the state of the class. The class phases are: - - \begin{itemize} - \item Discovered --- The initial phase. At the end of Process Type Names all classes are in the state "Discovered". - \item Stored - \item Bases Resolved - \item Declaration Processed - \item Members Processed - \item Folded - \end{itemize} + \item \cellref[ClassType]{classType} --- The fully qualified class name. The identifier of the class. + \item \cellref[ClassMetaType]{classMetaType} --- Represents whether the type stored in this cell is class or interface. To avoid terminology superfluousness, we will refer hereafter to both classes and interfaces as "classes", making distinctions only when necessary. + \item \cellref[ClassAccessMode]{classAccessMode} --- The access modifier of the class, either public or package. + \item \cellref[ClassPhase]{classPhase} --- Represents the state of this class. In addition to the global computation phase, each class has its own lifecycle phase. Class phases are required to keep track which classes were processed in the current global phase and which were not. During each global phase all classes should transition to a certain class phase. However, as we shall see, not all global phases change the state of the class. The class phases are: + + \begin{itemize} + \item Discovered --- The initial phase. At the end of Process Type Names all classes are in the state "Discovered". + \item Stored + \item Bases Resolved + \item Declaration Processed + \item Members Processed + \item Folded + \end{itemize} \end{itemize} \paragraph{Process Compilation Units} At the beginning of this phase computation is again initialized with the initial AST from \cellref{program}. The following new cells are filled in inside each \cellref{class}: \begin{itemize} - \item \cellref[ClassType]{enclosingClass} --- The directly enclosing class, for inner classes, or no value for top-level classes. - \item \cellref[K]{rawExtends} --- The extends clause of this class, in its raw (AST) form. - \item \cellref[K]{rawImplements} --- The implements clause, in AST form. - \item \cellref[K]{rawDeclarations} --- The class body, in AST form. - \item \cellref[Map{[}Id \mapsto ClassType{]}]{cuImports} --- A map from names accessible inside this class to fully qualified class names they represent. Only computed for top-level classes at this phase. For inner classes this cell remains empty. - \item \cellref[ContextType]{classContextType} --- Either static or instance, for inner classes. Always static for top-level classes. + \item \cellref[ClassType]{enclosingClass} --- The directly enclosing class, for inner classes, or no value for top-level classes. + \item \cellref[K]{rawExtends} --- The extends clause of this class, in its raw (AST) form. + \item \cellref[K]{rawImplements} --- The implements clause, in AST form. + \item \cellref[K]{rawDeclarations} --- The class body, in AST form. + \item \cellref[Map{[}Id \mapsto ClassType{]}]{cuImports} --- A map from names accessible inside this class to fully qualified class names they represent. Only computed for top-level classes at this phase. For inner classes this cell remains empty. + \item \cellref[ContextType]{classContextType} --- Either static or instance, for inner classes. Always static for top-level classes. \end{itemize} The class phase changes from Discovered to Stored. As we can see, the cells computed so far contain all the data of the original program. Thus, initial AST representation of the program is no longer needed. In fact, the cell \cellref[]{program} is discarded at the end of Process Compilation Units. The remaining preprocessing phases will use class data in this initial form to compute other cells within \cellref[]{class}, finally used for execution. @@ -294,70 +294,70 @@ The class phase changes from Discovered to Stored. As we can see, the cells comp Also during Process Compilation Units the following global cell is used: \begin{itemize} - \item \cellref[Map{[}Id \mapsto ClassType{]}]{compUnitImports} --- A map from all type names accessible in the current compilation unit (Java file) to their respective fully qualified class names. This includes both classes accessible through imports declarations and classes declared in the package of the current compilation unit. Used to compute \cellref{cuImports} of top-level classes. + \item \cellref[Map{[}Id \mapsto ClassType{]}]{compUnitImports} --- A map from all type names accessible in the current compilation unit (Java file) to their respective fully qualified class names. This includes both classes accessible through imports declarations and classes declared in the package of the current compilation unit. Used to compute \cellref{cuImports} of top-level classes. \end{itemize} \paragraph{Process Class Declarations} Here each class passes through two more class phases: Bases Processed and Declarations Processed. First, for each class the semantics attempts to resolve its extends/implements clauses into fully qualified class names. The order in which dependencies are resolved depends on both class inheritance relationships as well as nesting relationships. Once the dependencies of a class are resolved, they are stored into a temporary cell: \begin{itemize} -\item \cellref[K]{unprocessedBases} --- Initialized with the list of fully qualified class names for classes mentioned in extends/implements clauses of this class. + \item \cellref[K]{unprocessedBases} --- Initialized with the list of fully qualified class names for classes mentioned in extends/implements clauses of this class. \end{itemize} -Once the content of \cellref[K]{unprocessedBases} is created, the class enters into Bases Resolved phase. It then waits in this phase until all classes referred in extends/implements reach the phase Declarations Processed. The restrictions in JLS related to class dependencies guarantee that classes cannot have cyclic dependencies, thus a class cannot get locked in the waiting state. The cell \cellref[K]{unprocessedBases} is used to determine the moment when the class may exit the waiting state. Once a class reaches the phase Declarations Processed, is is deleted from cells \cellref[K]{unprocessedBases} of other classes. Thus, when all extends/implements dependencies of a class reach the phase Declarations Processed, the content of the its \cellref[K]{unprocessedBases} cell becomes empty. Once in this state, the class enters into the phase Declarations Processed itself and computes three more cells: +Once the content of \cellref[]{unprocessedBases} is created, the class enters into Bases Resolved phase. It then waits in this phase until all classes referred in extends/implements reach the phase Declarations Processed. The restrictions in JLS related to class dependencies guarantee that classes cannot have cyclic dependencies, thus a class cannot get locked in the waiting state. The cell \cellref[]{unprocessedBases} is used to determine the moment when the class may exit the waiting state. Once a class reaches the phase Declarations Processed, is is deleted from cells \cellref[]{unprocessedBases} of other classes. Thus, when all extends/implements dependencies of a class reach the phase Declarations Processed, the content of the its \cellref[]{unprocessedBases} cell becomes empty. Once in this state, the class enters into the phase Declarations Processed itself and computes three more cells: \begin{itemize} -\item \cellref[ClassType]{extends} --- The base class, fully qualified. -\item \cellref[Set{[}ClassType{]}]{implements} --- The list of directly implemented interfaces, fully qualified. -\item \cellref[Map{[}Id \mapsto ClassType{]}]{imports} --- The map of classes accessible by simple name within the body of this class. The rules for computing this map are complex and include the following sources: + \item \cellref[ClassType]{extends} --- The base class, fully qualified. + \item \cellref[Set{[}ClassType{]}]{implements} --- The list of directly implemented interfaces, fully qualified. + \item \cellref[Map{[}Id \mapsto ClassType{]}]{imports} --- The map of classes accessible by simple name within the body of this class. The rules for computing this map are complex and include the following sources: -\begin{itemize} -\item Imports declarations of the current compilation unit. -\item Classes declared within the package of the current compilation unit. -\item Classes accessible within the body of the directly enclosing class, if the current class is inner class. -\item Inner classes inherited from base classes, e.g. from extends/implements clauses. -\item Inner classes of this class itself. -\end{itemize} + \begin{itemize} + \item Imports declarations of the current compilation unit. + \item Classes declared within the package of the current compilation unit. + \item Classes accessible within the body of the directly enclosing class, if the current class is inner class. + \item Inner classes inherited from base classes, e.g. from extends/implements clauses. + \item Inner classes of this class itself. + \end{itemize} -The need to cover all these cases leads to the intricate order in which class dependencies have to be be resolved. + The need to cover all these cases leads to the intricate order in which class dependencies have to be be resolved. \end{itemize} -When a class enters the phase Declarations Processed, the cells \cellref[]{rawExtends}, \cellref[]{rawImplements} and \cellref[K]{unprocessedBases} are no longer needed and are discarded. Once all classes reach this phase the computation proceeds to the next global phase. +When a class enters the phase Declarations Processed, the cells \cellref[]{rawExtends}, \cellref[]{rawImplements} and \cellref[]{unprocessedBases} are no longer needed and are discarded. Once all classes reach this phase the computation proceeds to the next global phase. During Process Class Declarations the following global cell is first used: \begin{itemize} - \item \cellref[ClassType]{crntClass} --- The current class. Used in multiple phases starting from Process Class Declarations. + \item \cellref[ClassType]{crntClass} --- The current class. Used in multiple phases starting from Process Class Declarations. \end{itemize} \paragraph{Process Class Members} During this phase each class processes its members and reaches the state Members Processes. Until then, the class body is stored in \cellref[]{rawDeclarations}. A class member could be one of: \begin{itemize} - \item field - \item method - \item constructor - \item static or instance initializer + \item field + \item method + \item constructor + \item static or instance initializer \end{itemize} The following new class cells are produced: \begin{itemize} - \item \cellref[Set{[}ClassType{]}]{implTrans} --- The transitive closure of implemented interfaces. In the remaining phases this set is used by the subtyping relationship. + \item \cellref[Set{[}ClassType{]}]{implTrans} --- The transitive closure of implemented interfaces. In the remaining phases this set is used by the subtyping relationship. \item \cellref[ Map {[} Signature \mapsto ClassType {]} ]{methods} --- The map of accessible methods. Keys are method signatures, values are classes where methods are defined. Includes both methods declared within this class as well as methods inherited from base classes/ base interfaces. \item \cellref[Bag]{methodDecs} --- The collection of method declarations (\cellref{methodDec} cells)in the current class. This cell contains only a subset of methods from \cellref{methods}, as the set of accessible methods from \cellref{methods} also includes methods inherited from base classes/interfaces. Hence the need of two separate collections. Each \cellref[Bag]{methodDec} contains the following data: \begin{itemize} \item \cellref[Signature]{methodSignature} --- The method signature, acting as identifier of the \cellref{methodDec}. - \item \cellref[Type]{methodReturnType} --- The method return type. + \item \cellref[Type]{methodReturnType} --- The method return type. \item \cellref[ List{[} Param {]} ]{methodParams} --- The method parameters. \item \cellref[K]{methodConstrFirstLine} --- the first line of a constructor (if this method is indeed a constructor, for other classes than \verb|Object|). It contains a call to another constructor: either \verb|super()| or \verb|this()|. - \item \cellref[K]{methodBody} --- The method body. + \item \cellref[K]{methodBody} --- The method body. \item \cellref[AccessMode]{methodAccessMode} --- The method access mode. \item \cellref[ContextType]{methodContextType} --- May be either static or instance. - \item \cellref[MethodMetaType]{methodMetaType} --- May be either method or constructor. + \item \cellref[MethodMetaType]{methodMetaType} --- May be either method or constructor. \end{itemize} \item \cellref[K]{instanceFields} --- The list of instance field declarations, stored as a list of local variable declaration statements, without initializers. Used during object instantiation. - \item \cellref[K]{instanceInit} --- The list of instance initializers of the class combined into one big instance initializer. Instance field initializers are also concatenated into this cell in their textual order. + \item \cellref[K]{instanceInit} --- The list of instance initializers of the class combined into one big instance initializer. Instance field initializers are also concatenated into this cell in their textual order. \item \cellref[K]{staticFields} --- The list of static field declarations, in a similar format to \cellref{instanceFields} - \item \cellref[K]{staticInit} --- The list of static initializers and static field initializers concatenated into one block. - \item \cellref[Map{[}Id \mapsto Value{]}]{constantEnv} --- The map from compile-time constants to their actual values. Constants in Java have a slightly different semantics compared to final static fields. In particular, accessing them don't trigger static initialization of the declaring class. + \item \cellref[K]{staticInit} --- The list of static initializers and static field initializers concatenated into one block. + \item \cellref[Map{[}Id \mapsto Value{]}]{constantEnv} --- The map from compile-time constants to their actual values. Constants in Java have a slightly different semantics compared to final static fields. In particular, accessing them don't trigger static initialization of the declaring class. \end{itemize} Once all the cells above are computed the class proceeds into the phase Members Processed and the cell \cellref[]{rawDeclarations} is deleted. @@ -365,27 +365,27 @@ Once all the cells above are computed the class proceeds into the phase Members \paragraph{Elaboration} Here all the code blocks are processed --- method and constructor bodies, static and instance initializers. Most of the information traditionally inferred by the compiler is computed at this phase. More precisely the elaboration performs the following transformations: \begin{itemize} -\item Each name is resolved into local variable, field, method, class or package. While a method may be distinguished from other categories purely syntactically, resolving to other categories requires knowledge of the names existing in the current context. -\item Simple class names are resolved into fully qualified class names. Hereafter all the class names in the code are fully qualified. -\item The compile-time type of each expression is inferred. Thus, when the code reaches execution phase, expressions are no longer in their initial form. The expressions are annotated with their types. -\item For each method call the precise signature in inferred. -\item Local and anonymous classes are processed. The earliest phase where local classes could be discovered is elaboration. Still, local classes have all the features of other classes. Thus they need to be passed through all the preprocessing steps. The whole preprocessing for local classes is performed during the global phase elaboration. + \item Each name is resolved into local variable, field, method, class or package. While a method may be distinguished from other categories purely syntactically, resolving to other categories requires knowledge of the names existing in the current context. + \item Simple class names are resolved into fully qualified class names. Hereafter all the class names in the code are fully qualified. + \item The compile-time type of each expression is inferred. Thus, when the code reaches execution phase, expressions are no longer in their initial form. The expressions are annotated with their types. + \item For each method call the precise signature in inferred. + \item Local and anonymous classes are processed. The earliest phase where local classes could be discovered is elaboration. Still, local classes have all the features of other classes. Thus they need to be passed through all the preprocessing steps. The whole preprocessing for local classes is performed during the global phase elaboration. \end{itemize} Despite this phase being the most complex preprocessing phase of all, it introduces few new cells. Most of them are related to local classes. Inside \cellref[]{class} just one new cell is introduced: \begin{itemize} -\item \cellref[Map{[}Id \mapsto Type{]}]{enclosingLocalEnv} --- The map from local variables of the current block to their types. Used during local classes processing. + \item \cellref[Map{[}Id \mapsto Type{]}]{enclosingLocalEnv} --- The map from local variables of the current block to their types. Used during local classes processing. \end{itemize} Among global cells the following new cells are added: \begin{itemize} - \item \cellref[List[mapWrap(Map[Id \mapsto Type])]]{elabEnv} --- A stack where each layer is a map of local variables. Each layer of the stack represents a code block, in the blocks nesting order. Inside each layer, the map is from local variables accessible in that layer to variable types. - \item \cellref[Int]{contextType} --- The context type of the currently elaborated class. Either static or instance. - \item \cellref[List[mapWrap(Map[Id \mapsto ClassType])]]{localTypes} --- A cell similar in structure to \cellref{elabEnv}. This time it contains stack layers which are maps from local class names to local class types. - \item \cellref[Int]{nextLocalId} --- A number used to generate unique fully-qualified class names for local classes. - \item \cellref[K]{elabBuffer} --- A temporary cell used during elaboration of local classes. + \item \cellref[List[mapWrap(Map[Id \mapsto Type])]]{elabEnv} --- A stack where each layer is a map of local variables. Each layer of the stack represents a code block, in the blocks nesting order. Inside each layer, the map is from local variables accessible in that layer to variable types. + \item \cellref[Int]{contextType} --- The context type of the currently elaborated class. Either static or instance. + \item \cellref[List[mapWrap(Map[Id \mapsto ClassType])]]{localTypes} --- A cell similar in structure to \cellref{elabEnv}. This time it contains stack layers which are maps from local class names to local class types. + \item \cellref[Int]{nextLocalId} --- A number used to generate unique fully-qualified class names for local classes. + \item \cellref[K]{elabBuffer} --- A temporary cell used during elaboration of local classes. \end{itemize} During the elaboration phase no cells are consumed. Instead, the code blocks stored inside \cellref[]{methodDecs}, \cellref[]{instanceInit}, \cellref[]{staticInit} are processed and stored back into the same cell. After elaboration the classes remain in the same state --- Members Processed. The state Members Processed is in fact the final state of the cell \cellref[]{class}. From 4bc59673bfa6e8db7f6e79ce7c1edcd3aa3eb340 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Thu, 5 Mar 2015 17:33:48 +0200 Subject: [PATCH 12/43] Latex: Added generation of unique file names for each markdown env. Benefit: reverse search inside markdown env. --- src/sty/custom-commands.tex | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/sty/custom-commands.tex b/src/sty/custom-commands.tex index e7864997..2d150907 100644 --- a/src/sty/custom-commands.tex +++ b/src/sty/custom-commands.tex @@ -9,12 +9,19 @@ %Font set latin modern is not compatible with large angular brackets (package yhmath), so we cannot use it. %\usepackage{lmodern} +%%% MARKDOWN ENV + +\newcounter{MarkdownId} + %Required package fancyvrb already imported by k.sty \newenvironment{markdown}% - {\VerbatimEnvironment\begin{VerbatimOut}{tmp.markdown}}% + {\stepcounter{MarkdownId}% + \VerbatimEnvironment\begin{VerbatimOut}{tmp\theMarkdownId.markdown}% + }% {\end{VerbatimOut}% - \immediate\write18{pandoc .latex\string\\tmp.markdown -t latex -o .latex\string\\tmp.tex}% - \input{.latex\string\\tmp.tex}} + \immediate\write18{pandoc .latex\string\\tmp\theMarkdownId.markdown -t latex -o .latex\string\\tmp\theMarkdownId.tex}% + \input{.latex\string\\tmp\theMarkdownId.tex}% + } \lstset{language=Java,captionpos=t,tabsize=3,frame=no,keywordstyle=\color{blue}, commentstyle=\color{gray},stringstyle=\color{red}, From 38e2a237f0d23d438e787285ca9a2560d6c550c9 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Mon, 9 Mar 2015 10:47:01 +0200 Subject: [PATCH 13/43] Doc: Review doc output of STATIC-INIT (in particular double-slashes). --- src/exec/static-init.k | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/exec/static-init.k b/src/exec/static-init.k index 73bcaff0..cf7c6f67 100644 --- a/src/exec/static-init.k +++ b/src/exec/static-init.k @@ -3,21 +3,23 @@ module STATIC-INIT imports CORE-CLASSES //for objectClass imports CORE-EXEC //for restoreMethContext -/*@ Triggers static initialization of a class. - -Detailed initialization procedure is described in JLS \$12.4.2. Here we implement an approximation of that algorithm, -that does not use the traditional Java synchronization mechanism, but instead relies on term rewriting +/*@ +Triggers the static initialization of a class. +The detailed initialization procedure is described in JLS \$12.4.2. Here we implement an approximation of that algorithm, +one that does not use the traditional Java synchronization mechanism, but relies instead on term rewriting capabilities to implement locks. This algorithm is required to avoid multithreaded issues during static initialization. This may happen when two threads access an uninitialized class at the same time. -Initialization status of a class may have 3 states: StaticUninitialized, StaticInitializing(TId), StaticInitialized. -//Here TId is the id of the thread that initiated the initializing process. -//Now when we reach staticInit(Class), depending on the initialization status of class we should do the following: -1. status = StaticUninitialized => perform the initialization -2. status = StaticInitializing(TId), TId = this thread => this is a recursive initialization request, discard the term. -3. status = StaticInitializing(TId), IID = another thread => we should wait until the initialization is completed - by another thread. Do not match this case. -4. status = StaticInitialized => the class has already been initialized. Discard the term. +Initialization status of a class may have one of the following 3 states: StaticUninitialized, StaticInitializing(TId), StaticInitialized. +Here TId is the identifier of the thread that initiated the initialization process. +When we reach staticInit(Class), depending on the initialization status of the class (stored in \cellref{staticInitStatus}), we should do one of the following: + +\begin{markdown} + - \verb|status = StaticUninitialized| --- Perform the initialization. + - \verb|status = StaticInitializing(TId), TId = this thread| --- This is a recursive initialization request, discard the term. + - \verb|status = StaticInitializing(TId), TId = another thread| --- We should wait until the initialization is completed by another thread. Do not match this case. + - \verb|status = StaticInitialized| --- The class has already been initialized. Discard the term. +\end{markdown} */ syntax KItem ::= staticInit ( ClassType // Class - the ClassType to be initialized, From 4feaecd8745c909443c2545e2fb8c4b81e9a6928 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Mon, 9 Mar 2015 12:26:28 +0200 Subject: [PATCH 14/43] Doc: Reviewed comments in syntax modules. Also moved around some syntax. --- src/common/class-syntax.k | 14 +++--- src/common/core-sorts.k | 2 + src/common/exp-syntax.k | 23 +++++----- src/common/interface-syntax.k | 10 ++--- src/common/lexical-syntax.k | 83 ++--------------------------------- src/common/literal-syntax.k | 25 ++++++----- src/common/package-syntax.k | 6 +-- src/common/stmt-syntax.k | 6 +-- src/common/type-syntax.k | 11 +++-- src/sty/custom-commands.tex | 17 +++++-- src/sty/k-java.tex | 3 +- 11 files changed, 67 insertions(+), 133 deletions(-) diff --git a/src/common/class-syntax.k b/src/common/class-syntax.k index 582256a7..098982d8 100644 --- a/src/common/class-syntax.k +++ b/src/common/class-syntax.k @@ -1,7 +1,7 @@ module CLASS-SYNTAX imports EXP-SYNTAX -//@ \subsection{ClassDeclarations.sdf} +//@ \paragraph{ClassDeclarations} syntax ClassDecHead ::= AnnoClassModList "class" Id OptionalTypeParams OptionalSuper OptionalInterfaces [klabel('ClassDecHead)] @@ -34,7 +34,7 @@ syntax InterfaceDec syntax SemiColon ::= ";" [klabel('SemiColon)] -//@ \subsection{ConstructorDeclarations.sdf} +//@ \paragraph{ConstructorDeclarations} syntax ConstrHead ::= AnnoConstrModList OptionalTypeParams Type Id "(" Params ")" OptionalThrows [klabel('ConstrDecHead)] @@ -53,7 +53,7 @@ syntax ConstrMod ::= Public syntax AnnoConstrMod ::= Anno | ConstrMod -//@ \subsection{EnumDeclarations.sdf} +//@ \paragraph{EnumDeclarations} syntax EnumDecHead ::= AnnoClassModList "enum" Id OptionalInterfaces [klabel('EnumDecHead)] /* Java allows , at the end of List. @@ -71,7 +71,7 @@ syntax EnumConstArgs ::= "(" Exps ")" [bracket syntax EnumBodyDecs ::= ";" ClassBodyDecList [klabel('EnumBodyDecs)] -//@ \subsection{FieldDeclarations.sdf} +//@ \paragraph{FieldDeclarations} syntax FieldDec ::= AnnoFieldModList Type VarDecList ";" [klabel('FieldDec)] syntax VarDec ::= VarDecId [klabel('VarDec)] @@ -92,7 +92,7 @@ syntax FieldMod ::= Public syntax AnnoFieldMod ::= Anno | FieldMod -//@ \subsection{MethodDeclarations.sdf} +//@ \paragraph{MethodDeclarations} syntax MethodDecHead ::= AnnoMethodModList OptionalTypeParams Type Id "(" Params ")" OptionalThrows [klabel('MethodDecHead)] @@ -123,11 +123,11 @@ syntax VarMod ::= Final syntax AnnoVarMod ::= Anno | VarMod -//@ \subsection{InstanceInitializers.sdf} +//@ \paragraph{InstanceInitializers} syntax InstanceInit ::= Block [klabel('InstanceInit)] -//@ \subsection{StaticInitializers.sdf} +//@ \paragraph{StaticInitializers} syntax StaticInit ::= "static" Block [klabel('StaticInit)] syntax Block diff --git a/src/common/core-sorts.k b/src/common/core-sorts.k index 2365fcdc..a6ea9382 100644 --- a/src/common/core-sorts.k +++ b/src/common/core-sorts.k @@ -203,6 +203,8 @@ syntax ClassInstanceCreationExp ::= "new" ClassType "(" Exps ")" //Denis' syntax syntax ClassOrName ::= Id | ClassType //Denis' syntax + +/*@ A fully qualified class name, or noClass where no valid class exists in the current context.*/ syntax ClassType ::= "class" Id | "noClass" [latex({\dotCt{K}})] //Denis' syntax syntax Param ::= Type Id [klabel('ParamImpl)] diff --git a/src/common/exp-syntax.k b/src/common/exp-syntax.k index 150eebeb..8afcebff 100644 --- a/src/common/exp-syntax.k +++ b/src/common/exp-syntax.k @@ -5,7 +5,7 @@ module EXP-SYNTAX syntax Exp ::= StmtExp syntax StmtExp ::= PrefixPostfixExp | AssignExp | MethodInvokeExp | ClassInstanceCreationExp -//@ \subsection{MethodInvocation.sdf} +//@ \paragraph{MethodInvocation} syntax MethodInvokeExp ::= MethodSpec "(" Exps ")" [klabel('Invoke)] syntax MethodSpec ::= MethodName [klabel('Method)] | Exp "." OptionalTypeArgs Id [klabel('Method)] @@ -14,7 +14,7 @@ syntax MethodSpec ::= MethodName [klabel( | AmbName "." TypeArgs Id [klabel('GenericMethod)] -//@ \subsection{ClassInstanceCreation.sdf} +//@ \paragraph{ClassInstanceCreation} syntax ClassInstanceCreationExp ::= "new" OptionalTypeArgs ClassOrInterfaceType "(" Exps ")" OptionalClassBody [klabel('NewInstance)] @@ -23,7 +23,7 @@ syntax ClassInstanceCreationExp ::= [klabel('QNewInstance)] -//@ \subsection{AssignmentOperators.sdf} +//@ \paragraph{AssignmentOperators} syntax LHS ::= ExprName | FieldAccess | ArrayAccess syntax AssignExp ::= LHS "=" Exp [klabel('Assign)] @@ -42,7 +42,7 @@ syntax CompoundAssignExp ::= LHS "*=" Exp [klabel(' | LHS "|=" Exp [klabel('AssignOr)] -//@ \subsection{UnaryOperators.sdf} +//@ \paragraph{UnaryOperators} syntax Exp ::= "(" PrimType ")" Exp [klabel('CastPrim)] syntax Exp ::= "(" RefType ")" Exp [klabel('CastRef)] @@ -51,17 +51,16 @@ syntax Exp ::= "~" Exp [strict, klabel('Complement)] | "+" Exp [strict, klabel('Plus)] | "-" Exp [strict, klabel('Minus)] -//@ Operators with side effects --- prefix, postfix ++/-- syntax PrefixPostfixExp ::= "++" Exp [klabel('PreIncr)] | "--" Exp [klabel('PreDecr)] -//@ \subsection{Postfix.sdf} +//@ \paragraph{Postfix} syntax PrefixPostfixExp ::= Exp "++" [klabel('PostIncr)] | Exp "--" [klabel('PostDecr)] -//@ \subsection{BinaryOperators.sdf} +//@ \paragraph{BinaryOperators} syntax Exp ::= Exp "*" Exp [seqstrict, klabel('Mul)] | Exp "/" Exp [seqstrict, klabel('Div)] | Exp "%" Exp [seqstrict, klabel('Remain)] @@ -87,20 +86,20 @@ syntax Exp ::= Exp "?" Exp ":" Exp [klabel('Cond)] syntax Exp ::= Exp "instanceof" RefType [strict, klabel('InstanceOf)] -//@ \subsection{FieldAccess.sdf} +//@ \paragraph{FieldAccess} syntax Exp ::= FieldAccess syntax FieldAccess ::= Exp "." Id [klabel('Field)] | "super" "." Id [klabel('SuperField)] | TypeName "." "super" "." Id [klabel('QSuperField)] -//@ \subsection{ArrayAccess.sdf} +//@ \paragraph{ArrayAccess} syntax Exp ::= ArrayAccess //syntax ArraySubscript ::= "[" Exp "]" [bracket] syntax ArrayAccess ::= Exp "[" Exp "]" [seqstrict, klabel('ArrayAccess)] -//@ \subsection{ArrayCreation.sdf} +//@ \paragraph{ArrayCreation} /* Either 'NewArray( T:ElemType,, ['Dim(N1),,'Dim('N2),, ...],, [...,, 'Dim(.KList),, ...] ) Or 'NewArray( T:ElemType,, [...,, 'Dim(.KList),, ...],, 'ArrayInit(_) ) */ @@ -118,12 +117,12 @@ syntax Dim ::= "[" "]" [klabel('Dim syntax DimExp ::= "[" Exp "]" [strict, hybrid, klabel('Dim)] -//@ \subsection{ArrayInitializers.sdf} +//@ \paragraph{ArrayInitializers} syntax ArrayInit ::= "{" VarInits "}" [klabel('ArrayInit)] syntax ArrayInit ::= "{" VarInits "," "}" [klabel('ArrayInit)] -//@ \subsection{Primary.sdf} +//@ \paragraph{Primary} syntax Exp ::= Literal [klabel('Lit)] syntax Literal ::= IntLiteral | FloatLiteral diff --git a/src/common/interface-syntax.k b/src/common/interface-syntax.k index a8de4608..4bdb6a3c 100644 --- a/src/common/interface-syntax.k +++ b/src/common/interface-syntax.k @@ -1,7 +1,7 @@ module INTERFACE-SYNTAX imports CLASS-SYNTAX -//@ \subsection{AbstractMethodDeclarations.sdf} +//@ \paragraph{AbstractMethodDeclarations} syntax AbstractMethodDec ::= AnnoAbstractMethodModList OptionalTypeParams Type Id "(" Params ")" OptionalThrows ";" [klabel('AbstractMethodDec)] @@ -10,7 +10,7 @@ syntax AbstractMethodMod ::= Public | Abstract syntax AnnoAbstractMethodMod ::= Anno | AbstractMethodMod -//@ \subsection{Annotations.sdf} +//@ \paragraph{Annotations} syntax Anno ::= "@" TypeName "(" ElemValPairList ")" [klabel('Anno)] | "@" TypeName "(" ElemVal ")" [klabel('SingleElemAnno)] | "@" TypeName [klabel('MarkerAnno)] @@ -23,7 +23,7 @@ syntax ElemVal ::= Exp syntax ElemValPair ::= Id "=" ElemVal [klabel('ElemValPair)] -//@ \subsection{AnnotationTypes.sdf} +//@ \paragraph{AnnotationTypes} syntax AnnoDecHead ::= AnnoInterfaceModList "@" "interface" Id [klabel('AnnoDecHead)] syntax AnnoDec ::= AnnoDecHead "{" AnnoElemDecList "}" [klabel('AnnoDec)] @@ -35,7 +35,7 @@ syntax AnnoElemDec ::= AbstractMethodModList Type Id "(" ")" OptionalDefaultVal syntax DefaultVal ::= "default" ElemVal [klabel('DefaultVal)] -//@ \subsection{ConstantDeclarations.sdf} +//@ \paragraph{ConstantDeclarations} syntax ConstantDec ::= AnnoConstantModList Type VarDecList ";" [klabel('ConstantDec)] syntax ConstantMod ::= Public @@ -45,7 +45,7 @@ syntax ConstantMod ::= Public syntax AnnoConstantMod ::= Anno | ConstantMod -//@ \subsection{InterfaceDeclarations.sdf} +//@ \paragraph{InterfaceDeclarations} syntax InterfaceDecHead ::= AnnoInterfaceModList "interface" Id OptionalTypeParams OptionalExtendsInterfaces [klabel('InterfaceDecHead)] diff --git a/src/common/lexical-syntax.k b/src/common/lexical-syntax.k index 21c813b7..238361c9 100644 --- a/src/common/lexical-syntax.k +++ b/src/common/lexical-syntax.k @@ -1,75 +1,18 @@ module LEXICAL-SYNTAX -//@ \subsection{Comments.sdf} -//no need to define because K provides fixed layout -//@ \subsection{Identifiers.sdf} +//@ \paragraph{Identifiers} syntax Id ::= ID [klabel('Id)] syntax ID ::= Token{[A-Za-z\_\$][A-Za-z0-9\_\$]*} [onlyLabel] -//@ \subsection{KeyWord.sdf(not needed?)} -/* -syntax Keyword ::= "abstract" - | "assert" - | "boolean" - | "break" - | "byte" - | "case" - | "catch" - | "char" - | "class" - | "const" - | "continue" - | "default" - | "do" - | "double" - | "else" - | "enum" - | "extends" - | "final" - | "finally" - | "float" - | "for" - | "goto" - | "if" - | "implements" - | "import" - | "instanceof" - | "int" - | "interface" - | "long" - | "native" - | "new" - | "package" - | "private" - | "protected" - | "public" - | "return" - | "short" - | "static" - | "strictfp" - | "super" - | "switch" - | "synchronized" - | "this" - | "throw" - | "throws" - | "transient" - | "try" - | "void" - | "volatile" - | "while" -*/ +//@ \paragraph{LineTerminators} -//@ \subsection{LineTerminators.sdf} -syntax EndOfFile syntax CarriageReturn ::= Token{[\r]} [onlyLabel] syntax LineTerminator ::= EndOfFile | CarriageReturn | Token{[\n]} [onlyLabel] | Token{[\r][\n]} [onlyLabel] - -//@ \subsection{Modifiers.sdf} +//@ \paragraph{Modifiers} syntax Public ::= "public" [klabel('Public)] syntax Private ::= "private" [klabel('Private)] syntax Protected ::= "protected" [klabel('Protected)] @@ -82,22 +25,4 @@ syntax Volatile ::= "volatile" [klabel('Volatile)] syntax StrictFP ::= "strictfp" [klabel('StrictFP)] syntax Synchronized ::= "synchronized" [klabel('Synchronized)] -syntax Modifier ::= Public - | Private - | Protected - | Abstract - | Final - | Static - | Native - | Transient - | Volatile - | StrictFP - | Synchronized - -//@ \subsection{UnicodeEscape.sdf} -syntax UnicodeEscape ::= Token {[\\][u]+ [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]} - [onlyLabel, klabel('UnicodeEscape)] - -//@ \subsection{WhiteSpace.sdf} -//no need to define because K provides fixed layout -endmodule \ No newline at end of file +endmodule diff --git a/src/common/literal-syntax.k b/src/common/literal-syntax.k index 0cf2e03e..dce416ad 100644 --- a/src/common/literal-syntax.k +++ b/src/common/literal-syntax.k @@ -2,23 +2,19 @@ module LITERAL-SYNTAX imports LEXICAL-SYNTAX imports LIST-SYNTAX -//@ \subsection{BooleanLiterals.sdf} +//@ \paragraph{BooleanLiterals} syntax BoolLiteral ::= Boolean [klabel('Bool)] syntax Boolean ::= "true" [onlyLabel, klabel('True)] syntax Boolean ::= "false" [onlyLabel, klabel('False)] -//@ \subsection{CharacterLiterals.sdf} todo -syntax SingleChar// ::= Token{[\r\n\'\\]}//don't understand ^? +//@ \paragraph{CharacterLiterals} syntax CharContent ::= SingleChar [klabel('Single)] | UnicodeEscape | EscapeSeq -//Problem: Multiple lookahead not fully supported (does not appear when tested in small language) -syntax CharLiteral //::= "'" CharContent "'" [klabel('Char)] - -//@ \subsection{EscapeSequences.sdf} +//@ \paragraph{EscapeSequences} syntax EscapeSeq ::= OctaEscape | NamedEscape syntax NamedEscape ::= Token{"\\" [btnfr\"\'\\]} [onlyLabel, klabel('NamedEscape)] @@ -28,11 +24,11 @@ syntax OctaEscape ::= Token{"\\" [0-7]} [onlyLabel, klabel('Oct | Token{"\\" [0-3][0-7][0-7]} [onlyLabel, klabel('OctaEscape3)] -//@ \subsection{FloatingPointLiterals.sdf} todo +//@ \paragraph{FloatingPointLiterals} syntax FloatLiteral ::= Float [klabel('Float)] -//@ \subsection{IntegerLiterals.sdf} +//@ \paragraph{IntegerLiterals} syntax DeciLiteral ::= Token{[1-9][0-9]* [lL]?} [onlyLabel] syntax HexaLiteral ::= Token{[0][xX][0-9a-fA-F]+ [lL]?} [onlyLabel] syntax OctaLiteral ::= Token{[0][0-7]+ [lL]?} [onlyLabel] @@ -42,11 +38,11 @@ syntax IntLiteral ::= DeciLiteral [klabel('Deci)] | OctaLiteral [klabel('Octa)] -//@ \subsection{NullLiteral.sdf} +//@ \paragraph{NullLiteral} syntax NullLiteral ::= "null" [klabel('Null)] -//@ \subsection{StringLiterals.sdf} todo +//@ \paragraph{StringLiterals} syntax StringLiteral ::= "\"" StringPartList "\"" [klabel('String)] syntax StringPart ::= StringChars [klabel('Chars)] @@ -55,4 +51,9 @@ syntax StringPart ::= StringChars [klabel('Chars)] syntax StringChars //::= Token {~[\"\\\n\13]} -endmodule \ No newline at end of file + +//@ \subsection{UnicodeEscape.sdf} +syntax UnicodeEscape ::= Token {[\\][u]+ [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]} + [onlyLabel, klabel('UnicodeEscape)] + +endmodule diff --git a/src/common/package-syntax.k b/src/common/package-syntax.k index ce487e9b..71acf3aa 100644 --- a/src/common/package-syntax.k +++ b/src/common/package-syntax.k @@ -1,19 +1,15 @@ module PACKAGE-SYNTAX imports CLASS-SYNTAX -//@ \subsection{CompilationUnits.sdf} syntax CompilationUnit ::= OptionalPackageDec ImportDecList TypeDecList [klabel('CompilationUnit)] -//@ \subsection{TypeDeclarations.sdf} syntax TypeDec ::= ClassDec | InterfaceDec | SemiColon -//@ \subsection{ImportDeclarations.sdf} syntax ImportDec ::= "import" TypeName ";" [klabel('TypeImportDec)] | "import" PackageName "." "*" ";" [klabel('TypeImportOnDemandDec)] | "import" "static" TypeName "." Id ";" [klabel('StaticImportDec)] | "import" "static" TypeName "." "*" ";" [klabel('StaticImportOnDemandDec)] -//@ \subsection{PackageDeclarations.sdf} syntax PackageDec ::= AnnoList "package" PackageName ";" [klabel('PackageDec)] -endmodule \ No newline at end of file +endmodule diff --git a/src/common/stmt-syntax.k b/src/common/stmt-syntax.k index 9365bb50..bc50d186 100644 --- a/src/common/stmt-syntax.k +++ b/src/common/stmt-syntax.k @@ -1,17 +1,17 @@ module STMT-SYNTAX imports CLASS-SYNTAX -//@ \subsection{Blocks.sdf} +//@ \paragraph{Blocks} syntax BlockStmt ::= Stmt | LocalVarDecStmt | ClassDec [klabel('ClassDecStm)] syntax Block ::= "{" BlockStmList "}" [klabel('Block)] -//@ \subsection{LocalVariableDeclaraions.sdf} +//@ \paragraph{LocalVariableDeclaraions} syntax LocalVarDecStmt ::= LocalVarDec ";" [prefer, klabel('LocalVarDecStm)] syntax LocalVarDec ::= AnnoVarModList Type VarDecList [prefer, klabel('LocalVarDec)] -//@ \subsection{Statements.sdf} +//@ \paragraph{Statements} syntax Stmt ::= StmtWithoutTrailing | LabeledStmt | IfThenElseStmt diff --git a/src/common/type-syntax.k b/src/common/type-syntax.k index 3c8542d9..ea5f0edb 100644 --- a/src/common/type-syntax.k +++ b/src/common/type-syntax.k @@ -2,14 +2,13 @@ module TYPE-SYNTAX imports NAME-SYNTAX imports OPTIONAL-SYNTAX -//@ \subsection{Main.sdf} syntax Type ::= PrimType | RefType /*Denis' syntax: actually in sdf "void" together with Type compose ResultType, since now "void" is Type, there is no need for another syntax of ResultType.*/ | "void" [klabel('Void)] -//@ \subsection{ParameterizedTypes.sdf} +//@ \paragraph{ParameterizedTypes} syntax TypeArgs ::= "<" ActualTypeArgList ">" [klabel('TypeArgs)] syntax ActualTypeArg ::= Type @@ -19,7 +18,7 @@ syntax WildcardBound ::= "extends" RefType [klabel('WildcardUpperBo | "super" RefType [klabel('WildcardLowerBound)] -//@ \subsection{PrimitiveTypes.sdf} +//@ \paragraph{PrimitiveTypes} syntax IntOrLongType ::= "int" [klabel('Int)] | "long" [klabel('Long)] syntax IntType ::= "byte" [klabel('Byte)] @@ -34,8 +33,8 @@ syntax NumericType ::= IntType | FloatType syntax PrimType ::= NumericType | "bool" [klabel('Boolean)] //sdf "boolean" -//@ \subsection{ReferenceTypes.sdf} - /*@ A fully qualified class name, or noClass where no valid class could be computed.*/ +//@ \paragraph{ReferenceTypes} + syntax ClassOrInterfaceType ::= TypeDecSpec OptionalTypeArgs [klabel('ClassOrInterfaceType)] syntax InterfaceType ::= TypeDecSpec OptionalTypeArgs [klabel('InterfaceType)] @@ -51,7 +50,7 @@ syntax ArrayType ::= Type "[" "]" [strict, klabel( syntax RefType ::= ClassOrInterfaceType | ArrayType -//@ \subsection{TypeVariables.sdf} +//@ \paragraph{TypeVariables} syntax TypeVarId ::= Id syntax TypeBound ::= "extends" ClassOrInterfaceTypeList [klabel('TypeBound)] diff --git a/src/sty/custom-commands.tex b/src/sty/custom-commands.tex index 2d150907..6497e9d1 100644 --- a/src/sty/custom-commands.tex +++ b/src/sty/custom-commands.tex @@ -2,13 +2,23 @@ %\documentclass[a4paper, landscape]{article} %\usepackage[style=bubble, tight]{k} -% Reduces page borders, now we can put more characters in one line -%\usepackage{fullpage} - %Font set latin modern is not compatible with large angular brackets (package yhmath), so we cannot use it. %\usepackage{lmodern} +%For TOC fix +\usepackage{etoolbox} + +%%% Adding TOC to PDF bookmarks. +% Source: http://tex.stackexchange.com/questions/1820/contents-in-pdf-bookmarks +\makeatletter +\pretocmd{\tableofcontents}{% + \if@openright\cleardoublepage\else\clearpage\fi + \pdfbookmark[0]{\contentsname}{toc}% +}{}{}% +\makeatother + + %%% MARKDOWN ENV \newcounter{MarkdownId} @@ -23,6 +33,7 @@ \input{.latex\string\\tmp\theMarkdownId.tex}% } +%%% JAVA LSTLISTINGS SETUP \lstset{language=Java,captionpos=t,tabsize=3,frame=no,keywordstyle=\color{blue}, commentstyle=\color{gray},stringstyle=\color{red}, breaklines=true,showstringspaces=false,emph={label}, diff --git a/src/sty/k-java.tex b/src/sty/k-java.tex index e819593f..45c1e2af 100644 --- a/src/sty/k-java.tex +++ b/src/sty/k-java.tex @@ -10,9 +10,10 @@ \usepackage{fullpage} -\title{JAVA-EXEC} \begin{document} +\tableofcontents + \chapter{K-Java Common modules} \input{../.modules/core-sorts.tex} From 7609e58c1888a983e89673c1e5a364963ce5d177 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Mon, 9 Mar 2015 12:40:09 +0200 Subject: [PATCH 15/43] Syntax: minor fix of kompile error. --- src/common/lexical-syntax.k | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/common/lexical-syntax.k b/src/common/lexical-syntax.k index 238361c9..7d640b40 100644 --- a/src/common/lexical-syntax.k +++ b/src/common/lexical-syntax.k @@ -6,9 +6,7 @@ syntax ID ::= Token{[A-Za-z\_\$][A-Za-z0-9\_\$]*} [onlyLabel] //@ \paragraph{LineTerminators} -syntax CarriageReturn ::= Token{[\r]} [onlyLabel] -syntax LineTerminator ::= EndOfFile - | CarriageReturn +syntax LineTerminator ::= Token{[\r]} [onlyLabel] | Token{[\n]} [onlyLabel] | Token{[\r][\n]} [onlyLabel] From 937f377d2a4531fc43206604c5cf4ef26cc4fcae Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Mon, 9 Mar 2015 12:41:14 +0200 Subject: [PATCH 16/43] Syntax: minor fix of kompile error. --- src/common/literal-syntax.k | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/literal-syntax.k b/src/common/literal-syntax.k index dce416ad..daea9b40 100644 --- a/src/common/literal-syntax.k +++ b/src/common/literal-syntax.k @@ -14,6 +14,8 @@ syntax CharContent ::= SingleChar [klabel('Single)] | UnicodeEscape | EscapeSeq +syntax SingleChar + //@ \paragraph{EscapeSequences} syntax EscapeSeq ::= OctaEscape | NamedEscape From e7be6e5c32e643edffe055d944860aed71602e1f Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Mon, 9 Mar 2015 12:45:13 +0200 Subject: [PATCH 17/43] Syntax: minor fix of kompile error. --- src/common/literal-syntax.k | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/literal-syntax.k b/src/common/literal-syntax.k index daea9b40..bff6fa04 100644 --- a/src/common/literal-syntax.k +++ b/src/common/literal-syntax.k @@ -15,6 +15,7 @@ syntax CharContent ::= SingleChar [klabel('Single)] | EscapeSeq syntax SingleChar +syntax CharLiteral //::= "'" CharContent "'" [klabel('Char)] //@ \paragraph{EscapeSequences} syntax EscapeSeq ::= OctaEscape | NamedEscape From a25abc0f5631642f62504a0854c3fa7f7eeb5863 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Mon, 9 Mar 2015 15:04:17 +0200 Subject: [PATCH 18/43] Doc: Syntax chapter acknowledgement: mentioned that this syntax is developed by Shijiao, and the present status: how it was developed and how it is used. --- src/sty/k-java.tex | 1 + src/sty/syntax-intro.tex | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 src/sty/syntax-intro.tex diff --git a/src/sty/k-java.tex b/src/sty/k-java.tex index 45c1e2af..cd2c4f50 100644 --- a/src/sty/k-java.tex +++ b/src/sty/k-java.tex @@ -69,6 +69,7 @@ \chapter{K-Java Static semantics} \input{../.modules/folding.tex} \chapter{K-Java Syntax} +\input{syntax-intro.tex} \input{../.modules/exp-syntax.tex} \input{../.modules/stmt-syntax.tex} diff --git a/src/sty/syntax-intro.tex b/src/sty/syntax-intro.tex new file mode 100644 index 00000000..d6d33a3b --- /dev/null +++ b/src/sty/syntax-intro.tex @@ -0,0 +1,10 @@ +This chapter contains the entire semantics of Java 5. +This syntax was developed by Shijiao Yuwen from Formal Systems Laboratory of UIUC. +It is an adaptation of Java-Front~\cite{java-front}, the same syntax definition used to produce the external parser for K-Java. +Although the syntax is fairly complete, it might still contain errors. +This is because at the moment of writing it was not yet used to produce a parser for Java, consequently it was not yet used to parse programs. +Also, only a small part of K-Java is now defined over Java syntax. +The rest of the semantics is still in AST form. +Thus, most of this syntax was not put to use yet. +Yet, the part of this syntax that \textit{is} used is expressions, statements, and for the rest of the syntax, the attributes (strictness and \texttt{klabel}). +Syntax definition was added to K-Java at a later stage of development, when the semantics for Java 1.4 was already complete. From 4cb87e75dae36c6a21d02c5cf852f57a2023be10 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Mon, 9 Mar 2015 19:28:05 +0200 Subject: [PATCH 19/43] Doc: Make all section names uppercase. --- src/exec/core-exec.k | 2 +- src/exec/expressions-classes.k | 4 ++-- src/exec/expressions.k | 10 ++++++---- src/exec/new-instance.k | 2 ++ src/exec/var-lookup.k | 4 ++-- src/prep/literals.k | 6 +++--- src/prep/process-class-decs.k | 2 -- src/prep/process-class-members.k | 8 +++++--- src/prep/process-local-classes.k | 4 +++- 9 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/exec/core-exec.k b/src/exec/core-exec.k index 31f07181..82185d95 100644 --- a/src/exec/core-exec.k +++ b/src/exec/core-exec.k @@ -19,7 +19,7 @@ rule [restoreMethContext]: restoreMethContext(MethContext:Bag) => . ... _ => MethContext -/*@ \subsection{lvalue and loc syntax} */ +/*@ \subsection{Syntax for lvalue and loc} */ syntax KItem ::= lvalue ( K ) syntax RawVal ::= loc ( Int ) diff --git a/src/exec/expressions-classes.k b/src/exec/expressions-classes.k index c18b376f..0d42ed5f 100644 --- a/src/exec/expressions-classes.k +++ b/src/exec/expressions-classes.k @@ -8,13 +8,13 @@ module EXPRESSIONS-CLASSES /*@ Expressions that operate over objects. */ -/*@ \subsection{Instance Of} */ +/*@ \subsection{Operator instanceof} */ rule [InstanceOf]: V:RawVal::_ instanceof RT2:RefType => (V =/=K null) && subtype(typeOf(V), RT2) -/*@ \subsection{Cast} */ +/*@ \subsection{Cast for references} */ rule [cast-RefType]: cast(RT1:RefType, V:RawVal :: RT2:RefType) => ifAux ( subtype(typeOf(V), RT1) , diff --git a/src/exec/expressions.k b/src/exec/expressions.k index 8ad6f2ee..4d21f110 100644 --- a/src/exec/expressions.k +++ b/src/exec/expressions.k @@ -173,21 +173,21 @@ rule loc(L:Int) :: T:Type &= Exp2:K => loc(L)::T = cast(T, lookup(L, T) & Exp2) rule loc(L:Int) :: T:Type ^= Exp2:K => loc(L)::T = cast(T, lookup(L, T) ^ Exp2) rule loc(L:Int) :: T:Type |= Exp2:K => loc(L)::T = cast(T, lookup(L, T) | Exp2) -/*@ \subsection{primitive types cast} */ +/*@ \subsection{Cast expression --- primitive types} */ //@ The type of RV could either be NumericType or tempType. This rule matches both. rule [cast-Number]: cast(NT:NumericType, RV:RawVal::_) => normalize(RV::NT) rule [cast-Bool]: cast(bool, B:Bool::bool) => B::bool -/*@ \subsubsection{artificial cases of cast, arised during semantics separation} */ +/*@ \subsubsection{Artificial cases of cast, arised during semantics separation} */ rule [cast-void]: cast(void, RV:RawVal::void) => RV::void //Happens for the qualifier of a static method call rule [cast-noValue]: cast(_, noValue) => noValue -/*@ \subsection{lvalue semantics} */ +/*@ \subsection{Heating/cooling rules for lvalue} */ /* We cannot use context rules here because of wrapper-related limitations. If a term is wrapped into lvalue during heating by a context rule, it will be cooled also from lvalue by the cooling rule. This is unacceptable @@ -245,6 +245,8 @@ rule [lvalue-Throw-desugar]: lvalue( throw E:Exp; ) => throw E; [structural] +/*@ \subsection{Auxiliary functions for store} */ + syntax KItem ::= store ( Int, //OL - the store location K //evaluates to TypedVal - the value to be stored @@ -263,7 +265,7 @@ rule [storeImpl]: storeImpl(L:Int, V:RawVal :: T:Type) => . ... ... L |-> (_ => V) :: T ... -/*@ \subsection{auxiliary terms produced during elaboration} */ +/*@ \subsection{Auxiliary constructs produced during elaboration} */ rule stmtAndExp(Stmt:K, Exp:K) => Stmt ~> Exp diff --git a/src/exec/new-instance.k b/src/exec/new-instance.k index 27988fdb..d7c5e2b1 100644 --- a/src/exec/new-instance.k +++ b/src/exec/new-instance.k @@ -229,6 +229,8 @@ module NEW-INSTANCE-REST imports VAR-LOOKUP //for typedLookup() imports NEW-INSTANCE +/*@Additional cases of new instance creation. */ + //@\subsection{Instance field declarations} rule [FieldDec-instance]: diff --git a/src/exec/var-lookup.k b/src/exec/var-lookup.k index 7074d98a..54a4f897 100644 --- a/src/exec/var-lookup.k +++ b/src/exec/var-lookup.k @@ -136,7 +136,7 @@ rule [lvalue-Field-static]: TargetClass ... X |-> L:Int ... -/*@ \subsection{lvalue and loc} */ +/*@ \subsection{Functions typedLookup and typedLoc} */ //@ Typed version of lookup and loc syntax KItem ::= typedLookup ( Int ) @@ -157,7 +157,7 @@ rule [typedLoc]: rule [lvalue-typedLoc]: lvalue(typedLoc(L:Int)) => typedLoc(L) -/*@ \subsection{lookup} */ +/*@ \subsection{Function lookup} */ /*@ Retrieve a value from the store based on its location and the given compile-time type. May be wrapped inside lvalue. If lookup is unwrapped, it evaluates to TypedVal --- the store value, diff --git a/src/prep/literals.k b/src/prep/literals.k index 834f2014..1489fb73 100644 --- a/src/prep/literals.k +++ b/src/prep/literals.k @@ -94,7 +94,7 @@ rule [Lit-Octa]: #else normalize(octaToInt(trimHead(Str, 1)) :: int ) #fi -//@ \subsection{float literals} +//@ \subsection{Float literals} rule [Lit-FFloat]: 'Lit('Float(Str:String)) @@ -106,7 +106,7 @@ rule [Lit-FFloat]: #fi #fi -//@ \subsection{bool literals} +//@ \subsection{Boolean literals} /* 'Lit('Bool('True(.KList))) 'Lit('Bool('False(.KList))) @@ -116,7 +116,7 @@ rule 'Lit('Bool('True(.KList))) => true rule 'Lit('Bool('False(.KList))) => false -//@ \subsection{char literals} +//@ \subsection{Char literals} //@ Chars are represented as int values, as described in Java specification. // 'Lit('Char('Single( I:Int ))) diff --git a/src/prep/process-class-decs.k b/src/prep/process-class-decs.k index 86dfd7ef..201fef3d 100644 --- a/src/prep/process-class-decs.k +++ b/src/prep/process-class-decs.k @@ -3,8 +3,6 @@ module PROCESS-CLASS-DECS imports CORE-PREPROCESSING imports PROCESS-TYPE-NAMES -/*@ \subsection{Third pass --- processing class dependencies and imports} */ - rule [ProcClassDecsPhase-start]: . => processClassDecs(getTopLevelClasses) ProcCompUnitsPhase => ProcClassDecsPhase diff --git a/src/prep/process-class-members.k b/src/prep/process-class-members.k index e4e588af..d377c1fe 100644 --- a/src/prep/process-class-members.k +++ b/src/prep/process-class-members.k @@ -3,7 +3,7 @@ module PROCESS-CLASS-MEMBERS imports CORE-CLASSES imports CORE-PREPROCESSING -/*@ \subsection{Third pass --- processing class members} */ +/*@ \subsection{General rules} */ /*@ We need to process Object first. Thus when we will process any interfaces, Object class will already be processed.*/ @@ -208,7 +208,7 @@ rule [inherit]: Class Env:Map => Env[DecClass/Sig] -/*@ \subsection{Method declaration} +/*@ \subsection{Method declarations} Methods are now typed and we need to store their types in their closures, so that their type contract can be checked at invocation time. The rule below is conceptually similar to that of untyped KOOL; @@ -385,6 +385,8 @@ rule [ConstrDec]: Class:ClassType when paramTypesResolved([Params]) +//@ \subsection{Fields and initializers} + // 'FieldDec(Modifiers:K,, T:Type,, ['VarDec(X:Id,, InitExp:K),, _]) //resolve field declaration type @@ -463,7 +465,7 @@ rule [ConstantDec-Desugar]: TypeK,, VarDecs ) -/*@Subsection compile-time constants*/ +/*@\subsection{Compile-time constants}*/ //compute the value of a compile-time constant context 'FieldDec(Modifiers:K,, T:Type,, ['VarDec(X:Id,, HOLE) ]) diff --git a/src/prep/process-local-classes.k b/src/prep/process-local-classes.k index bbf3ee53..c85900ac 100644 --- a/src/prep/process-local-classes.k +++ b/src/prep/process-local-classes.k @@ -6,6 +6,8 @@ module PROCESS-LOCAL-CLASSES imports PROCESS-CLASS-MEMBERS //for processTypeWithDepends imports ELABORATION-VARS //for elabLookup +//@\subsection{Main rules} + // ClassDecStm('ClassDec(...)) rule [elab-ClassDecStm]: @@ -325,7 +327,7 @@ rule [loadElabBuffer]: loadElabBuffer => elabRes(ElabBuffer) ... ElabBuffer:K => [.KList] -//@\subsection{Utility functions for other modules} +//@\subsection{Auxiliary functions for other modules} syntax KItem ::= localClassGetExtraArgs( ClassType ) From 8ed958a2cfd29fb26376b8e925bce82a849a7e17 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 11:38:13 +0200 Subject: [PATCH 20/43] Doc: Make all section names uppercase. This time rendered and verified. --- src/common/literal-syntax.k | 1 - src/exec/statements.k | 6 ------ 2 files changed, 7 deletions(-) diff --git a/src/common/literal-syntax.k b/src/common/literal-syntax.k index bff6fa04..0882c8cd 100644 --- a/src/common/literal-syntax.k +++ b/src/common/literal-syntax.k @@ -55,7 +55,6 @@ syntax StringPart ::= StringChars [klabel('Chars)] syntax StringChars //::= Token {~[\"\\\n\13]} -//@ \subsection{UnicodeEscape.sdf} syntax UnicodeEscape ::= Token {[\\][u]+ [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]} [onlyLabel, klabel('UnicodeEscape)] diff --git a/src/exec/statements.k b/src/exec/statements.k index d149ed94..4a328458 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -6,11 +6,6 @@ module STATEMENTS imports METHOD-INVOKE // for initParams imports STMT-SYNTAX -//@ \subsection{isStmt} -rule isStmt('For(_)) => true -rule isStmt('Switch(_)) => true -rule isStmt('Block(_)) => true - //@ \subsection{Call of main method} //For now main class may only be placed in the default package. @@ -114,7 +109,6 @@ rule [AssertStm-FirstFalse]: //@ \subsection{Switch statement} - syntax KItem ::= switchImpl ( TypedVal, // TV - switch argument KListWrap, // switch body - list of 'SwitchGroup labels From 4aed4df4d98ef19f5496bc084ecdd5349e35b049 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 12:14:06 +0200 Subject: [PATCH 21/43] Tools: jenkins script for branch kj-with-syntax. --- tools/jenkins/k-java-latex-test.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tools/jenkins/k-java-latex-test.sh diff --git a/tools/jenkins/k-java-latex-test.sh b/tools/jenkins/k-java-latex-test.sh new file mode 100644 index 00000000..bf66f352 --- /dev/null +++ b/tools/jenkins/k-java-latex-test.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +export TOOLS_DIR=$WORKSPACE/tools +export PATH=/home/denis.bogdanas/k-framework-stable/bin:\ +$TOOLS_DIR:\ +$PATH + +echo "Using K Framework version:" +krun --version +echo "krun command:" +cat /home/denis.bogdanas/k-framework-stable/bin/krun + +rm -rf $WORKSPACE/* +cp -rf $WORKSPACE/../k-java-latex/* $WORKSPACE + +cd $WORKSPACE/src +aux-kjtest.sh -mode run -threads 12 -timeout 120 -encodeXML true -clean true ../tests From 1d7659b98c5cf5d9485595e671c950616dde6561 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 16:26:59 +0200 Subject: [PATCH 22/43] Semantics: fixes to statements, soft-sorting rather than hard-sorting variables of type Stmt. --- src/exec/statements.k | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/exec/statements.k b/src/exec/statements.k index 4a328458..bc8f94e5 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -59,7 +59,7 @@ rule [Empty]: //@ \subsection{Labeled statements} JLS \$14.7 rule [Labeled]: - X:Id : S:Stmt => S ~> labeledImpl(X) + X:Id : S<:Stmt => S ~> labeledImpl(X) //@ Processed version of the labeled statement syntax KItem ::= labeledImpl ( Id ) @@ -73,19 +73,19 @@ rule _:TypedVal; => .K //@ \subsection{If statement} rule [If-True]: - if (true::bool) S:Stmt else _:Stmt => S + if (true::bool) S<:Stmt else _<:Stmt => S [symbolic-rule] rule [If-False]: - if (false::bool) _:Stmt else S:Stmt => S + if (false::bool) _<:Stmt else S<:Stmt => S [symbolic-rule] rule [If-True]: - if (true::bool) S:Stmt => S + if (true::bool) S<:Stmt => S [symbolic-rule] rule [If-False]: - if (false::bool) _:Stmt => . + if (false::bool) _<:Stmt => . [symbolic-rule] //@ \subsection{Assert statement} @@ -155,7 +155,7 @@ rule [switchEnd-Discard]: //@ \subsection{While statement} and loop infrastructure. rule [while]: - while(E:Exp)S:Stmt => whileImpl(E, S) [structural] + while (E:Exp) S<:Stmt => whileImpl(E, S) [structural] syntax KItem ::= whileImpl ( K, // E - test expression. In For loop, it is UpdClause ~> testExp @@ -167,7 +167,7 @@ rule [whileImpl]: //@ \subsection{Do statement} rule [do-while]: - do S:Stmt while(E:Exp); => S ~> whileImpl(E, S) [structural] + do S<:Stmt while(E:Exp); => S ~> whileImpl(E, S) [structural] //@ \subsection{For statement} //wrapper of certain clauses of for statement From 0a326a8de643582b1a11c1c6b1a128175325c577 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 16:59:11 +0200 Subject: [PATCH 23/43] Removed isSort predicates for Stmt and some unused expression sort. --- src/common/core-classes.k | 34 ++++++---------------------------- src/common/core-sorts.k | 3 +++ src/common/exp-syntax.k | 3 +-- 3 files changed, 10 insertions(+), 30 deletions(-) diff --git a/src/common/core-classes.k b/src/common/core-classes.k index fb31c62d..e4708184 100644 --- a/src/common/core-classes.k +++ b/src/common/core-classes.k @@ -5,10 +5,12 @@ module CORE-CLASSES imports EXP-SYNTAX //for definitions of sort Exp imports STMT-SYNTAX //for definitions of sort Stmt -/*@ Auxiliary functions related to classes and packages. +/*@ This module is a collection of auxiliary functions related to classes and packages. */ -//@ \subsection{Shortcuts for the most frequently used classes within the semantics} +//@ \subsection{Shortcuts for frequently used classes} + +//@Shortcuts for the most frequently used classes that need special treatment within the semantics. syntax KItem ::= "classObject" [function, latex(\terminal{Object})] @@ -25,7 +27,7 @@ rule classNullPointerException => class String2Id("java.lang.NullPointerExceptio syntax KItem ::= "classArrayImpl" [function] rule classArrayImpl => class String2Id("java.lang.ArrayImpl") -//@ \subsection{Packages} +//@ \subsection{Auxiliary functions for packages} /*@A Java package.*/ syntax PackageId ::= packageId ( Id ) @@ -45,7 +47,7 @@ rule getPackage(class ClassId:Id) rfindString(Id2String(ClassId), ".", lengthString(Id2String(ClassId))) )) ) -//@ \subsection{Classes} +//@ \subsection{Auxiliary functions for classes} //@ Converts a pair of PackagId, Id into a fully qualified class name syntax ClassType ::= getClassType ( @@ -90,30 +92,6 @@ rule [restoreAfterProcessLocalClass]: syntax KItem ::= getConsName ( ClassType ) [function] rule getConsName(class ClassId:Id) => String2Id("$cons$" +String Id2String(ClassId)) -//@ \subsection{Expressions and their subsorts} -syntax Exp ::= NonNumericExp -syntax NonNumericExp ::= "dummyNonNumericExp" - -rule isNonNumericExp('ArrayAccess(_)) => true -rule isNonNumericExp('NewInstance(_)) => true // also in customElabChildren -rule isNonNumericExp('QNewInstance(_)) => true // also in customElabChildren -rule isNonNumericExp('InstanceOf(_)) => true -rule isNonNumericExp('Invoke(_)) => true -rule isNonNumericExp('This(_)) => true -rule isNonNumericExp('QThis(_)) => true -rule isNonNumericExp('AmbName(_)) => true -rule isNonNumericExp('ExprName(_)) => true -rule isNonNumericExp('Field(_)) => true -rule isNonNumericExp('SuperField(_)) => true -rule isNonNumericExp('QSuperField(_)) => true -rule isNonNumericExp('NewArray(_)) => true -rule isNonNumericExp('CastPrim(_)) => true -rule isNonNumericExp('CastRef(_)) => true - - -//@ Since RawVal terms can easily be converted into TypedVal, they are also of sort Exp. -syntax Exp ::= TypedVal | RawVal - //@ \subsubsection{Computation terms produced during elaboration} /*@ These auxiliary terms functions that should be threated as expressions in the elaboration phase. diff --git a/src/common/core-sorts.k b/src/common/core-sorts.k index a6ea9382..d04bbba6 100644 --- a/src/common/core-sorts.k +++ b/src/common/core-sorts.k @@ -156,6 +156,9 @@ syntax RawRefVal ::= ObjectRef | ArrayRef | String | NullLiteral */ syntax TypedVal ::= RawVal "::" Type +//@ Since RawVal terms can easily be converted into TypedVal, they are also of sort Exp. +syntax Exp ::= TypedVal | RawVal + /*@ The three most common forms of computation result are Typed value or Type. Those are most common results we will encounter during elaboration. Other result types are more context-specific. */ diff --git a/src/common/exp-syntax.k b/src/common/exp-syntax.k index 8afcebff..1549fc31 100644 --- a/src/common/exp-syntax.k +++ b/src/common/exp-syntax.k @@ -25,6 +25,7 @@ syntax ClassInstanceCreationExp ::= //@ \paragraph{AssignmentOperators} syntax LHS ::= ExprName | FieldAccess | ArrayAccess +syntax Exp ::= LHS syntax AssignExp ::= LHS "=" Exp [klabel('Assign)] syntax AssignExp ::= CompoundAssignExp @@ -87,14 +88,12 @@ syntax Exp ::= Exp "instanceof" RefType [strict, klabel('Instanc //@ \paragraph{FieldAccess} -syntax Exp ::= FieldAccess syntax FieldAccess ::= Exp "." Id [klabel('Field)] | "super" "." Id [klabel('SuperField)] | TypeName "." "super" "." Id [klabel('QSuperField)] //@ \paragraph{ArrayAccess} -syntax Exp ::= ArrayAccess //syntax ArraySubscript ::= "[" Exp "]" [bracket] syntax ArrayAccess ::= Exp "[" Exp "]" [seqstrict, klabel('ArrayAccess)] From 06a878582f372dd0184e2c72fab95109164b1b76 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 17:15:47 +0200 Subject: [PATCH 24/43] Cleaned up the definition of ResultOrParam. --- src/exec/statements.k | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/exec/statements.k b/src/exec/statements.k index bc8f94e5..b04521e8 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -404,20 +404,16 @@ context try _:K HOLE syntax CatchClause ::= "catch" "(" K ")" K [klabel('Catch)] //resolve 'Param term of the catch clause -context catch(HOLE)_ [result(ExtKResult)] +context catch(HOLE) _ [result(ResultOrParam)] rule 'Param(_,, K:Type,, X:Id) => K X [structural] -rule catch(KR:ExtKResult)S:K => catchImpl(KR,S) +rule catch(KR:ResultOrParam) S:K => catchImpl(KR,S) /*@ Extended K Result. Represents KLabels that should be treated as KResult during execution phase, but not during elaboration phase. */ -syntax ExtKResult ::= "dummy" - -rule isExtKResult(KR:KResult) => true - -rule isExtKResult('ParamImpl(T:Type,, _:Id)) => true +syntax ResultOrParam ::= KResult | Param //@ Internal representation of a preprocessed catch clause syntax CatchImpl ::= catchImpl ( From 55ff4fb20235a242fb22ac3ef974746cc6cb51bb Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 17:28:29 +0200 Subject: [PATCH 25/43] ResultOrParam: fixed compile-time error. --- src/exec/statements.k | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/exec/statements.k b/src/exec/statements.k index b04521e8..690dad6d 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -25,7 +25,7 @@ rule [ExecutionPhase-Start]: //@ \subsection{Blocks} JLS \$14.2 rule [Block]: - 'Block(S:K) => S ~> env(Env:Map) ... + { S<:BlockStmtList } => S ~> env(Env:Map) ... Env [structural] @@ -413,7 +413,8 @@ rule catch(KR:ResultOrParam) S:K => catchImpl(KR,S) /*@ Extended K Result. Represents KLabels that should be treated as KResult during execution phase, but not during elaboration phase. */ -syntax ResultOrParam ::= KResult | Param +syntax ResultOrParam ::= Param //| KResult - not allowed +rule isResultOrParam(_:KResult) => true // Because KResult cannot be used in a sort definition above. //@ Internal representation of a preprocessed catch clause syntax CatchImpl ::= catchImpl ( From 432d44e06f3f85f344b7596b13c4e836f1352015 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 17:33:06 +0200 Subject: [PATCH 26/43] ResultOrParam: fixed compile-time error. --- src/exec/statements.k | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exec/statements.k b/src/exec/statements.k index 690dad6d..d0b6e3da 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -25,7 +25,7 @@ rule [ExecutionPhase-Start]: //@ \subsection{Blocks} JLS \$14.2 rule [Block]: - { S<:BlockStmtList } => S ~> env(Env:Map) ... + { S<:BlockStmList } => S ~> env(Env:Map) ... Env [structural] From b3fb9be68d9c6ba9a6b7b78998f4294012472cc7 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 17:57:55 +0200 Subject: [PATCH 27/43] Statements: experiments with syntactic block. --- src/common/stmt-syntax.k | 2 +- src/exec/statements.k | 22 ++++++++++------------ src/exec/syntax-conversions.k | 10 +++++++--- src/exec/unfolding.k | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/common/stmt-syntax.k b/src/common/stmt-syntax.k index bc50d186..644fd607 100644 --- a/src/common/stmt-syntax.k +++ b/src/common/stmt-syntax.k @@ -32,7 +32,7 @@ syntax StmtWithoutTrailing ::= Block syntax StackConsumerStmt ::= ThrowStmt | ContinueStmt | BreakStmt | ReturnStmt syntax IfThenElseStmt ::= "if" "(" Exp ")" Stmt "else" Stmt [strict(1), klabel('If)] -syntax IfThenStmt ::= "if" "(" Exp ")" Stmt [prefer, strict(1), klabel('If)] +syntax IfThenStmt ::= "if" "(" Exp ")" Stmt [prefer, klabel('If)] syntax WhileStmt ::= "while" "(" Exp ")" Stmt [strict(1),klabel('While)] diff --git a/src/exec/statements.k b/src/exec/statements.k index d0b6e3da..a76ddfcf 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -25,10 +25,13 @@ rule [ExecutionPhase-Start]: //@ \subsection{Blocks} JLS \$14.2 rule [Block]: - { S<:BlockStmList } => S ~> env(Env:Map) ... + { S:BlockStmList } => S ~> env(Env:Map) ... Env [structural] +rule [BlockStmList]: + S:Stmt SL:BlockStmList => S ~> SL + //@ \texttt{env} Restore the env cell content from \verb|env(...)| statement argument syntax KItem ::= env ( Map ) @@ -72,6 +75,9 @@ rule [labeledImpl-Discard]: rule _:TypedVal; => .K //@ \subsection{If statement} +rule [If-Then-Desugar]: + if (E<:Exp) S<:Stmt => if (E) S else {} + rule [If-True]: if (true::bool) S<:Stmt else _<:Stmt => S [symbolic-rule] @@ -80,14 +86,6 @@ rule [If-False]: if (false::bool) _<:Stmt else S<:Stmt => S [symbolic-rule] -rule [If-True]: - if (true::bool) S<:Stmt => S - [symbolic-rule] - -rule [If-False]: - if (false::bool) _<:Stmt => . - [symbolic-rule] - //@ \subsection{Assert statement} //short version: assert exp1; rule [AssertStm-True-OneArg]: @@ -157,13 +155,13 @@ rule [switchEnd-Discard]: rule [while]: while (E:Exp) S<:Stmt => whileImpl(E, S) [structural] -syntax KItem ::= whileImpl ( +syntax Stmt ::= whileImpl ( K, // E - test expression. In For loop, it is UpdClause ~> testExp K // S - while body ) rule [whileImpl]: - whileImpl(E:K, S:K) => ifAux(E, S ~> whileImpl(E, S), .K) [structural] + whileImpl(E:K, S:K) => if(E) {S whileImpl(E, S)} [structural] //@ \subsection{Do statement} rule [do-while]: @@ -171,7 +169,7 @@ rule [do-while]: //@ \subsection{For statement} //wrapper of certain clauses of for statement -syntax KItem ::= stm ( KListWrap ) +syntax Stmt ::= stm ( KListWrap ) rule [stm-KListWrap-empty]: stm([.KList]) => . [structural] diff --git a/src/exec/syntax-conversions.k b/src/exec/syntax-conversions.k index b03aad2b..afa3d903 100644 --- a/src/exec/syntax-conversions.k +++ b/src/exec/syntax-conversions.k @@ -11,13 +11,17 @@ module SYNTAX-CONVERSIONS // 'Param(\_:K,, T:Type,, X:Id). Consumed by initParams(). -syntax KItem ::= toParams( KListWrap ) [function] - | toParams( KListWrap , Params ) [function] +syntax KItem ::= toParams( KListWrap , Params ) [function] -rule toParams([KLParams:KList]) => toParams([KLParams], .Params) rule toParams([KLParams:KList,, 'Param(_,, K:K,, X:Id)], Params:Params) => toParams([KLParams], (K X,Params)) rule toParams([.KList], Params:Params) => Params +rule 'Block([Ks:KList]) => toBlockStmList(.BlockStmList, [Ks]) +syntax KItem ::= toBlockStmList( KListWrap , BlockStmList ) [function] + +rule toBlockStmList([KL:KList,, S<:BlockStmt], L:BlockStmList) => toBlockStmList([KL], (S L)) +rule toBlockStmList([.KList], S<:BlockStmt) => S + //@ Required for getTypes() rule typeOf('ParamImpl(T:Type,, _:Id)) => T diff --git a/src/exec/unfolding.k b/src/exec/unfolding.k index 6561cccb..8d2ec809 100644 --- a/src/exec/unfolding.k +++ b/src/exec/unfolding.k @@ -153,7 +153,7 @@ rule [unfolding-MethodDec]: (.Bag => sig(Name:Id, getTypes([Params])) - toParams([Params:KList]) + toParams([Params:KList], .Params) MethodBody:K Acc:AccessMode CT:ContextType From d214afc55a24417d437b8f4f7383b88d8748fd7f Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 18:12:13 +0200 Subject: [PATCH 28/43] Statements: experiments with syntactic block. --- src/exec/syntax-conversions.k | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exec/syntax-conversions.k b/src/exec/syntax-conversions.k index afa3d903..270ebda9 100644 --- a/src/exec/syntax-conversions.k +++ b/src/exec/syntax-conversions.k @@ -16,7 +16,7 @@ syntax KItem ::= toParams( KListWrap , Params ) [function] rule toParams([KLParams:KList,, 'Param(_,, K:K,, X:Id)], Params:Params) => toParams([KLParams], (K X,Params)) rule toParams([.KList], Params:Params) => Params -rule 'Block([Ks:KList]) => toBlockStmList(.BlockStmList, [Ks]) +rule 'Block([Ks:KList]) => toBlockStmList([Ks], .BlockStmList) syntax KItem ::= toBlockStmList( KListWrap , BlockStmList ) [function] rule toBlockStmList([KL:KList,, S<:BlockStmt], L:BlockStmList) => toBlockStmList([KL], (S L)) From faaf649cc6968dab0cf21557a37a614d4078b2f9 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 20:23:17 +0200 Subject: [PATCH 29/43] Statements: an attempt to define 'Block syntactically. Syntax of block extended for this purpose. --- src/common/stmt-syntax.k | 2 +- src/exec/statements.k | 9 +++------ src/exec/static-init.k | 26 ++++++++++---------------- src/exec/syntax-conversions.k | 10 ++-------- 4 files changed, 16 insertions(+), 31 deletions(-) diff --git a/src/common/stmt-syntax.k b/src/common/stmt-syntax.k index 644fd607..8061638d 100644 --- a/src/common/stmt-syntax.k +++ b/src/common/stmt-syntax.k @@ -3,7 +3,7 @@ module STMT-SYNTAX //@ \paragraph{Blocks} syntax BlockStmt ::= Stmt | LocalVarDecStmt | ClassDec [klabel('ClassDecStm)] -syntax Block ::= "{" BlockStmList "}" [klabel('Block)] +syntax Block ::= "{" K "}" [klabel('Block)] //was BlockStmList before //@ \paragraph{LocalVariableDeclaraions} diff --git a/src/exec/statements.k b/src/exec/statements.k index a76ddfcf..5e6a14d5 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -25,13 +25,10 @@ rule [ExecutionPhase-Start]: //@ \subsection{Blocks} JLS \$14.2 rule [Block]: - { S:BlockStmList } => S ~> env(Env:Map) ... + { S:K } => S ~> env(Env:Map) ... Env [structural] -rule [BlockStmList]: - S:Stmt SL:BlockStmList => S ~> SL - //@ \texttt{env} Restore the env cell content from \verb|env(...)| statement argument syntax KItem ::= env ( Map ) @@ -76,7 +73,7 @@ rule _:TypedVal; => .K //@ \subsection{If statement} rule [If-Then-Desugar]: - if (E<:Exp) S<:Stmt => if (E) S else {} + if (E<:Exp) S<:Stmt => if (E) S else { .K }<:Block rule [If-True]: if (true::bool) S<:Stmt else _<:Stmt => S @@ -381,7 +378,7 @@ rule [Throw-CausesThreadTermination]: rule [Try-Catch-Finally-Desugar]: try TryS:K (K:CatchClause Ks:CatchClauses) finally FinallyS:K - => try 'Block(try TryS (K Ks)) .CatchClauses finally FinallyS + => try { try TryS (K Ks) } .CatchClauses finally FinallyS [structural] /*@ \subsubsection{Execution of try-catch} JLS \$14.20.1 diff --git a/src/exec/static-init.k b/src/exec/static-init.k index cf7c6f67..37c27df1 100644 --- a/src/exec/static-init.k +++ b/src/exec/static-init.k @@ -33,23 +33,17 @@ rule [staticInit]: StaticFields,, //Static fields have to be allocated before base class is statically initialized, // because during base class initialization those fields might be accessed. staticInit(BaseClass),, - 'Try( - StaticInit,, + try + { StaticInit } - //catch clause of 'Try - [ - 'Catch('ParamImpl(classObject,, String2Id("e") ),, - 'Block(throw new class String2Id("java.lang.ExceptionInInitializerError") - (((classObject) String2Id("e")));)) - ] - ,, + catch ( 'ParamImpl(classObject,, String2Id("e")) ) { + throw new class String2Id("java.lang.ExceptionInInitializerError") + (((classObject) String2Id("e"))); + } - //finally clause of 'Try - [ - restoreMethContext(MethContext),, - staticInitDone(Class) - ] - ) + finally { + [restoreMethContext(MethContext),, staticInitDone(Class)] + } //end of try ] ... @@ -65,7 +59,7 @@ rule [staticInit]: Class BaseClass:ClassType StaticFields:KListWrap - StaticInit:KListWrap + StaticInit StaticUninitialized => StaticInitializing(TId) rule [staticInit-already-initialized-discard]: diff --git a/src/exec/syntax-conversions.k b/src/exec/syntax-conversions.k index 270ebda9..d211cab4 100644 --- a/src/exec/syntax-conversions.k +++ b/src/exec/syntax-conversions.k @@ -16,12 +16,6 @@ syntax KItem ::= toParams( KListWrap , Params ) [function] rule toParams([KLParams:KList,, 'Param(_,, K:K,, X:Id)], Params:Params) => toParams([KLParams], (K X,Params)) rule toParams([.KList], Params:Params) => Params -rule 'Block([Ks:KList]) => toBlockStmList([Ks], .BlockStmList) -syntax KItem ::= toBlockStmList( KListWrap , BlockStmList ) [function] - -rule toBlockStmList([KL:KList,, S<:BlockStmt], L:BlockStmList) => toBlockStmList([KL], (S L)) -rule toBlockStmList([.KList], S<:BlockStmt) => S - //@ Required for getTypes() rule typeOf('ParamImpl(T:Type,, _:Id)) => T @@ -103,8 +97,8 @@ syntax KItem ::= toExps( KListWrap ) [function] | toExps( KListWrap , Exps ) [function] rule toExps([Args:KList]) => toExps([Args], .Exps) -rule toExps([Args:KList,, Arg:Exp], Es:Exps) => toExps([Args], (Arg,Es)) -rule toExps([.KList], Es:Exps) => Es +rule toExps([Args:KList,, Arg<:Exp], Es<:Exps) => toExps([Args], (Arg,Es)) +rule toExps([.KList], Es<:Exps) => Es syntax KItem ::= toKListWrap( Exps ) [function] | toKListWrap( KListWrap , Exps ) [function] From 36f15f54e38325a362e21419ad279ee4dbe93858 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 21:12:49 +0200 Subject: [PATCH 30/43] Statements: exception on windows, kompile error on linux. --- src/exec/statements.k | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exec/statements.k b/src/exec/statements.k index 5e6a14d5..120357a4 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -158,7 +158,7 @@ syntax Stmt ::= whileImpl ( ) rule [whileImpl]: - whileImpl(E:K, S:K) => if(E) {S whileImpl(E, S)} [structural] + whileImpl(E:K, S:K) => if (E) {S ~> whileImpl(E, S)} [structural] //@ \subsection{Do statement} rule [do-while]: From 8609f9966175286ce32d6cf12219a9bb6df115f2 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Tue, 10 Mar 2015 23:07:41 +0200 Subject: [PATCH 31/43] Statements: finally found the error, rolled back the changes in static-init.k --- src/exec/statements.k | 4 ++-- src/exec/static-init.k | 27 ++++++++++++++++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/exec/statements.k b/src/exec/statements.k index 120357a4..5ed9c35d 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -73,7 +73,7 @@ rule _:TypedVal; => .K //@ \subsection{If statement} rule [If-Then-Desugar]: - if (E<:Exp) S<:Stmt => if (E) S else { .K }<:Block + if (E<:Exp) S<:Stmt => if (E) S else ( .K )<:Stmt rule [If-True]: if (true::bool) S<:Stmt else _<:Stmt => S @@ -158,7 +158,7 @@ syntax Stmt ::= whileImpl ( ) rule [whileImpl]: - whileImpl(E:K, S:K) => if (E) {S ~> whileImpl(E, S)} [structural] + whileImpl(E:K, S:K) => if (E) (S ~> whileImpl(E, S))<:Stmt [structural] //@ \subsection{Do statement} rule [do-while]: diff --git a/src/exec/static-init.k b/src/exec/static-init.k index 37c27df1..5cafdf85 100644 --- a/src/exec/static-init.k +++ b/src/exec/static-init.k @@ -33,17 +33,26 @@ rule [staticInit]: StaticFields,, //Static fields have to be allocated before base class is statically initialized, // because during base class initialization those fields might be accessed. staticInit(BaseClass),, - try - { StaticInit } - catch ( 'ParamImpl(classObject,, String2Id("e")) ) { - throw new class String2Id("java.lang.ExceptionInInitializerError") - (((classObject) String2Id("e"))); - } + //Cannot write this statement syntactically, + // because the body of the finally clause cannot be a block. + 'Try( + StaticInit,, - finally { - [restoreMethContext(MethContext),, staticInitDone(Class)] - } //end of try + //catch clause of 'Try + [ + 'Catch('ParamImpl(classObject,, String2Id("e") ),, + 'Block(throw new class String2Id("java.lang.ExceptionInInitializerError") + (((classObject) String2Id("e")));)) + ] + ,, + + //finally clause of 'Try + [ + restoreMethContext(MethContext),, + staticInitDone(Class) + ] + ) ] ... From 71d55cfaee69f864dc2a95274b43a9be0218b449 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Wed, 11 Mar 2015 11:37:09 +0200 Subject: [PATCH 32/43] Statements: Figured out the problem. Separated the solution to a separate module. --- src/common/sort-predicate-hacks.k | 36 +++++++++++++++++++++++++++++++ src/exec/java-exec.k | 2 ++ src/prep/java-prep.k | 2 ++ 3 files changed, 40 insertions(+) create mode 100644 src/common/sort-predicate-hacks.k diff --git a/src/common/sort-predicate-hacks.k b/src/common/sort-predicate-hacks.k new file mode 100644 index 00000000..07eab6e7 --- /dev/null +++ b/src/common/sort-predicate-hacks.k @@ -0,0 +1,36 @@ +module SORT-PREDICATE-HACKS + +/*@ + The rules in this module are designed to extend the predicates for basic syntactic sorts like Exp or Stmt, and to + ease the restrictions imposed by those predicates. + For example, the syntactic definition of plus : syntax Exp ::= Exp + Exp, will return true for + isExp('Plus(K1,,K2)) only when both K1 and K2 are valid Exp terms, while a rule isExp('Plus(_)) => true + will produce true for any term whose root node has the label 'Plus. This allows us to use variable subsorting inside + rules, to define more rules syntactically. +*/ + +/* + Workaround: in a correct semantics these rules should not be needed, as all the labels below + are associated with expression syntax. Yet, the predicate isExp generated for sort Exp checks not only the + root label, but also the content of child nodes recursively, and child nodes are sometimes not valid children + of an expression. + + The predicate isExp() is used in elaboration phase by the rule [elabEnd-default-all-except-expressions]. +*/ +rule isExp('ArrayAccess(_)) => true +rule isExp('NewInstance(_)) => true // also in customElabChildren +rule isExp('QNewInstance(_)) => true // also in customElabChildren +rule isExp('InstanceOf(_)) => true +rule isExp('Invoke(_)) => true +rule isExp('This(_)) => true +rule isExp('QThis(_)) => true +rule isExp('AmbName(_)) => true +rule isExp('ExprName(_)) => true +rule isExp('Field(_)) => true +rule isExp('SuperField(_)) => true +rule isExp('QSuperField(_)) => true +rule isExp('NewArray(_)) => true +rule isExp('CastPrim(_)) => true +rule isExp('CastRef(_)) => true + +endmodule diff --git a/src/exec/java-exec.k b/src/exec/java-exec.k index 4f40acb9..0815e382 100644 --- a/src/exec/java-exec.k +++ b/src/exec/java-exec.k @@ -7,6 +7,7 @@ require "../common/core-functions.k" require "../common/primitive-types.k" require "../common/subtyping.k" require "../common/java-syntax.k" +require "../common/sort-predicate-hacks.k" require "core-exec.k" require "syntax-conversions.k" require "to-string.k" @@ -44,5 +45,6 @@ module JAVA-EXEC imports API-THREADS // imports LTL-SUPPORT imports JAVA-SYNTAX + imports SORT-PREDICATE-HACKS endmodule diff --git a/src/prep/java-prep.k b/src/prep/java-prep.k index 13a8caa8..64a5c720 100644 --- a/src/prep/java-prep.k +++ b/src/prep/java-prep.k @@ -7,6 +7,7 @@ require "../common/aux-strings.k" require "../common/primitive-types.k" require "../common/subtyping.k" require "../common/java-syntax.k" +require "../common/sort-predicate-hacks.k" require "core-preprocessing.k" require "process-type-names.k" require "process-comp-units.k" @@ -54,6 +55,7 @@ module JAVA-PREP imports JAVA-SYNTAX imports LIST-MACRO + imports SORT-PREDICATE-HACKS endmodule From 066ffb651da4bd9d6340e6c1f9cf23fc518a5b42 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Wed, 11 Mar 2015 12:29:43 +0200 Subject: [PATCH 33/43] Statements: Some experiments moving syntax around and hacking isStm() predicate. Needs kompilation on linux. --- src/common/exp-syntax.k | 8 +++- src/common/java-syntax.k | 1 - src/common/shared-syntax.k | 9 ---- src/common/sort-predicate-hacks.k | 27 ++++++++++++ src/exec/ltl-support.k | 2 +- src/exec/statements.k | 71 +++++++------------------------ src/exec/syntax-conversions.k | 36 ++++++++++++++++ 7 files changed, 86 insertions(+), 68 deletions(-) delete mode 100644 src/common/shared-syntax.k diff --git a/src/common/exp-syntax.k b/src/common/exp-syntax.k index 1549fc31..814c15b7 100644 --- a/src/common/exp-syntax.k +++ b/src/common/exp-syntax.k @@ -1,6 +1,5 @@ module EXP-SYNTAX imports TYPE-SYNTAX - imports SHARED-SYNTAX syntax Exp ::= StmtExp syntax StmtExp ::= PrefixPostfixExp | AssignExp | MethodInvokeExp | ClassInstanceCreationExp @@ -139,4 +138,11 @@ syntax Exp ::= "this" [klabel('Thi syntax Exp ::= "(" Exp ")" [bracket] +/*previously defined elsewhere for ltl-support, now these syntax are also used for Java, +although we don't incorporate ltl for now, let's keep this independent like this +*/ +syntax Exp ::= Exp "<=" Exp [seqstrict, klabel('LtEq)] + | Exp "==" Exp [seqstrict, klabel('Eq)] + | Exp "!=" Exp [klabel('NotEq)] + endmodule diff --git a/src/common/java-syntax.k b/src/common/java-syntax.k index d511c216..8cad49da 100644 --- a/src/common/java-syntax.k +++ b/src/common/java-syntax.k @@ -22,5 +22,4 @@ module JAVA-SYNTAX imports PACKAGE-SYNTAX imports OPTIONAL-SYNTAX imports TYPE-SYNTAX - imports SHARED-SYNTAX endmodule diff --git a/src/common/shared-syntax.k b/src/common/shared-syntax.k deleted file mode 100644 index 3283780f..00000000 --- a/src/common/shared-syntax.k +++ /dev/null @@ -1,9 +0,0 @@ -module SHARED-SYNTAX -/*previously defined elsewhere for ltl-support, now these syntax are also used for Java, -although we don't incorporate ltl for now, let's keep this independent like this -*/ -syntax Exp ::= Exp "<=" Exp [seqstrict, klabel('LtEq)] - | Exp "==" Exp [seqstrict, klabel('Eq)] - | Exp "!=" Exp [klabel('NotEq)] - -endmodule diff --git a/src/common/sort-predicate-hacks.k b/src/common/sort-predicate-hacks.k index 07eab6e7..1c9b67d9 100644 --- a/src/common/sort-predicate-hacks.k +++ b/src/common/sort-predicate-hacks.k @@ -33,4 +33,31 @@ rule isExp('NewArray(_)) => true rule isExp('CastPrim(_)) => true rule isExp('CastRef(_)) => true + +//@ Used to define statements syntactically +rule isStmt(_:K) => true +//rule isStmt('ClassDecStm(_)) => true +//rule isStmt('Block(_)) => true +//rule isStmt('LocalVarDecStm(_)) => true +//rule isStmt('LocalVarDec(_)) => true +//rule isStmt('If(_)) => true +//rule isStmt('While(_)) => true +//rule isStmt('For(_)) => true +//rule isStmt('ForEach(_)) => true +//rule isStmt('Labeled(_)) => true +//rule isStmt('Empty(_)) => true +//rule isStmt('ExprStm(_)) => true +//rule isStmt('AssertStm(_)) => true +//rule isStmt('Switch(_)) => true +//rule isStmt('DoWhile(_)) => true +//rule isStmt('Try(_)) => true +//rule isStmt('Throw(_)) => true +//rule isStmt('Continue(_)) => true +//rule isStmt('Break(_)) => true +//rule isStmt('Return(_)) => true +//rule isStmt('Synchronized(_)) => true +// +//// Special case, a sequence of statements. Might not be needed, we'll better add it to be sure. +//rule isStmt('ListWrap(_)) => true + endmodule diff --git a/src/exec/ltl-support.k b/src/exec/ltl-support.k index fb519405..ecf488e8 100644 --- a/src/exec/ltl-support.k +++ b/src/exec/ltl-support.k @@ -3,7 +3,7 @@ require "../common/shared-syntax.k" module LTL-SUPPORT-SYNTAX imports SYNTAX-CONVERSIONS - imports SHARED-SYNTAX + imports JAVA-SYNTAX syntax Prop ::= Exp diff --git a/src/exec/statements.k b/src/exec/statements.k index 5ed9c35d..85074a41 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -54,12 +54,12 @@ rule [LocalVarDec]: //@ \subsection{Empty statement} JLS \$14.6 rule [Empty]: - ;<:EmptyStmt => . + ; :EmptyStmt => . //@ \subsection{Labeled statements} JLS \$14.7 rule [Labeled]: - X:Id : S<:Stmt => S ~> labeledImpl(X) + X:Id : S:Stmt => S ~> labeledImpl(X) //@ Processed version of the labeled statement syntax KItem ::= labeledImpl ( Id ) @@ -73,34 +73,34 @@ rule _:TypedVal; => .K //@ \subsection{If statement} rule [If-Then-Desugar]: - if (E<:Exp) S<:Stmt => if (E) S else ( .K )<:Stmt + if (E:Exp) S:Stmt => if (E) S else ( ; ) rule [If-True]: - if (true::bool) S<:Stmt else _<:Stmt => S + if (true::bool) S:Stmt else _:Stmt => S [symbolic-rule] rule [If-False]: - if (false::bool) _<:Stmt else S<:Stmt => S + if (false::bool) _:Stmt else S:Stmt => S [symbolic-rule] //@ \subsection{Assert statement} //short version: assert exp1; rule [AssertStm-True-OneArg]: - assert true::bool; => . + assert true::bool; => . rule [AssertStm-False-OneArg]: - assert false::bool; - => throw new class String2Id("java.lang.AssertionError") (null::classString); + assert false::bool; + => throw new class String2Id("java.lang.AssertionError") (null::classString); //full version: assert exp1:exp2; rule [AssertStm-FirstTrue-SecondDiscarded]: - assert true::bool : _ ; => . + assert true::bool : _ ; => . context assert false::bool : HOLE; rule [AssertStm-FirstFalse]: - assert (false::bool) : (TV:TypedVal); - => throw new class String2Id("java.lang.AssertionError") (toString(TV)); + assert (false::bool) : (TV:TypedVal); + => throw new class String2Id("java.lang.AssertionError") (toString(TV)); //@ \subsection{Switch statement} @@ -150,7 +150,7 @@ rule [switchEnd-Discard]: //@ \subsection{While statement} and loop infrastructure. rule [while]: - while (E:Exp) S<:Stmt => whileImpl(E, S) [structural] + while (E:Exp) S:Stmt => whileImpl(E, S) [structural] syntax Stmt ::= whileImpl ( K, // E - test expression. In For loop, it is UpdClause ~> testExp @@ -158,11 +158,11 @@ syntax Stmt ::= whileImpl ( ) rule [whileImpl]: - whileImpl(E:K, S:K) => if (E) (S ~> whileImpl(E, S))<:Stmt [structural] + whileImpl(E:K, S:K) => if (E) {S ~> whileImpl(E, S)} [structural] //@ \subsection{Do statement} rule [do-while]: - do S<:Stmt while(E:Exp); => S ~> whileImpl(E, S) [structural] + do S:Stmt while(E:Exp); => S ~> whileImpl(E, S) [structural] //@ \subsection{For statement} //wrapper of certain clauses of for statement @@ -333,10 +333,7 @@ rule [Throw-checkCatch-True]: // ~> 'Throw(TV:TypedVal) ~> throw TV:TypedVal; ~> catchBlocks(catchImpl(Param:Param, CatchS:K) _:CatchClauses) - => 'Block([ - initParams(Param, TV),, - CatchS - ]) + => { initParams(Param, TV) ~> CatchS } rule [Throw-checkCatch-False]: (checkCatch(false::bool) => .) @@ -381,44 +378,6 @@ rule [Try-Catch-Finally-Desugar]: => try { try TryS (K Ks) } .CatchClauses finally FinallyS [structural] -/*@ \subsubsection{Execution of try-catch} JLS \$14.20.1 -*/ -//macro -rule 'Try(Trys:K,,([Catches:KList] => toCatchClauses([Catches])),,FinallyS:K) [anywhere] -rule 'Try(Trys:K,,([Catches:KList] => toCatchClauses([Catches]))) [anywhere] - -syntax CatchClauses ::= toCatchClauses( KListWrap ) [function] - | toCatchClauses( KListWrap , CatchClauses ) [function] - -rule toCatchClauses([KLCatchClauses:KList]) => toCatchClauses([KLCatchClauses],.CatchClauses) -rule toCatchClauses([KLCatchClauses:KList,, C:CatchClause], CatchClauses:CatchClauses) => toCatchClauses([KLCatchClauses], (C CatchClauses)) -rule toCatchClauses([.KList], CatchClauses:CatchClauses) => CatchClauses - -//resolve the catch clauses of try statement -context try _:K HOLE - -syntax CatchClause ::= "catch" "(" K ")" K [klabel('Catch)] -//resolve 'Param term of the catch clause -context catch(HOLE) _ [result(ResultOrParam)] - -rule 'Param(_,, K:Type,, X:Id) => K X [structural] - -rule catch(KR:ResultOrParam) S:K => catchImpl(KR,S) - -/*@ Extended K Result. - Represents KLabels that should be treated as KResult during execution phase, but not during elaboration phase. -*/ -syntax ResultOrParam ::= Param //| KResult - not allowed -rule isResultOrParam(_:KResult) => true // Because KResult cannot be used in a sort definition above. - -//@ Internal representation of a preprocessed catch clause -syntax CatchImpl ::= catchImpl ( - K, //'Param(...), - K //the code block - ) -syntax KResult ::= CatchImpl -syntax CatchClause ::= CatchImpl - rule [Try-Catch]: (try TryS:K KRs:CatchClauses => TryS ~> catchBlocks(KRs)) when isKResult(KRs) diff --git a/src/exec/syntax-conversions.k b/src/exec/syntax-conversions.k index d211cab4..6d622db2 100644 --- a/src/exec/syntax-conversions.k +++ b/src/exec/syntax-conversions.k @@ -124,4 +124,40 @@ rule getTypes(types(Ts:KList), .TypedVals) => types(Ts) syntax KResult ::= ClassTypes syntax ClassTypes ::= List{ClassType, ","} +//@ /subsubsection{Try -- syntax conversion macros} +rule 'Try(Trys:K,, ([Catches:KList] => toCatchClauses([Catches])),, _:KList) [anywhere] + +syntax CatchClauses ::= toCatchClauses( KListWrap ) [function] + | toCatchClauses( KListWrap , CatchClauses ) [function] + +rule toCatchClauses([KLCatchClauses:KList]) => toCatchClauses([KLCatchClauses],.CatchClauses) +rule toCatchClauses([KLCatchClauses:KList,, C:CatchClause], CatchClauses:CatchClauses) + => toCatchClauses([KLCatchClauses], (C CatchClauses)) +rule toCatchClauses([.KList], CatchClauses:CatchClauses) => CatchClauses + +//resolve the catch clauses of try statement +context try _:K HOLE + +syntax CatchClause ::= "catch" "(" K ")" K [klabel('Catch)] +//resolve 'Param term of the catch clause +context catch(HOLE) _ [result(ResultOrParam)] + +rule 'Param(_,, K:Type,, X:Id) => K X [structural] + +rule catch(KR:ResultOrParam) S:K => catchImpl(KR,S) + +/*@ Extended K Result. + Represents KLabels that should be treated as KResult during execution phase, but not during elaboration phase. +*/ +syntax ResultOrParam ::= Param //| KResult - not allowed +rule isResultOrParam(_:KResult) => true // Because KResult cannot be used in a sort definition above. + +//@ Internal representation of a preprocessed catch clause +syntax CatchImpl ::= catchImpl ( + K, //'Param(...), + K //the code block + ) +syntax KResult ::= CatchImpl +syntax CatchClause ::= CatchImpl + endmodule From 914478abb630c14c10538ed4242ec2bb9af851d4 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Wed, 11 Mar 2015 12:33:36 +0200 Subject: [PATCH 34/43] Statements: Some experiments moving syntax around and hacking isStm() predicate. Needs kompilation on linux. --- src/common/java-syntax.k | 2 +- src/exec/ltl-support.k | 2 +- src/sty/k-java.tex | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/java-syntax.k b/src/common/java-syntax.k index 8cad49da..c493aeac 100644 --- a/src/common/java-syntax.k +++ b/src/common/java-syntax.k @@ -9,7 +9,7 @@ require "interface-syntax.k" require "package-syntax.k" require "optional-syntax.k" require "type-syntax.k" -require "shared-syntax.k" + module JAVA-SYNTAX imports LIST-SYNTAX imports STMT-SYNTAX diff --git a/src/exec/ltl-support.k b/src/exec/ltl-support.k index ecf488e8..48eccf48 100644 --- a/src/exec/ltl-support.k +++ b/src/exec/ltl-support.k @@ -1,5 +1,5 @@ require "builtins/model-checker.k" -require "../common/shared-syntax.k" +require "../common/java-syntax.k" module LTL-SUPPORT-SYNTAX imports SYNTAX-CONVERSIONS diff --git a/src/sty/k-java.tex b/src/sty/k-java.tex index cd2c4f50..e91d3361 100644 --- a/src/sty/k-java.tex +++ b/src/sty/k-java.tex @@ -82,7 +82,6 @@ \chapter{K-Java Syntax} \input{../.modules/lexical-syntax.tex} \input{../.modules/literal-syntax.tex} \input{../.modules/optional-syntax.tex} -\input{../.modules/shared-syntax.tex} \end{document} @@ -91,3 +90,4 @@ \chapter{K-Java Syntax} % \input{../.modules/java-prep.tex} % \input{../.modules/java-syntax.tex} % \input{../.modules/list-macro.tex} +% \input{../.modules/sort-predicate-hacks.tex} From 45410f022a8cbfdd95745f2f8beccd44d997ffb7 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Wed, 11 Mar 2015 14:54:09 +0200 Subject: [PATCH 35/43] Statements: Fixed the bugs introduced in previous commit. Waiting for jenkins to test. --- src/common/stmt-syntax.k | 2 +- src/exec/statements.k | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/common/stmt-syntax.k b/src/common/stmt-syntax.k index 8061638d..4eb2a20f 100644 --- a/src/common/stmt-syntax.k +++ b/src/common/stmt-syntax.k @@ -34,7 +34,7 @@ syntax StackConsumerStmt ::= ThrowStmt | ContinueStmt | BreakStmt | ReturnStmt syntax IfThenElseStmt ::= "if" "(" Exp ")" Stmt "else" Stmt [strict(1), klabel('If)] syntax IfThenStmt ::= "if" "(" Exp ")" Stmt [prefer, klabel('If)] -syntax WhileStmt ::= "while" "(" Exp ")" Stmt [strict(1),klabel('While)] +syntax WhileStmt ::= "while" "(" Exp ")" Stmt [klabel('While)] syntax ForStmt ::= "for" "(" LocalVarDec ";" OptionalExp ";" Exps ")" Stmt [klabel('For)] syntax ForStmt ::= "for" "(" Exps ";" OptionalExp ";" Exps ")" Stmt [klabel('For)] diff --git a/src/exec/statements.k b/src/exec/statements.k index 85074a41..19b6956d 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -73,7 +73,7 @@ rule _:TypedVal; => .K //@ \subsection{If statement} rule [If-Then-Desugar]: - if (E:Exp) S:Stmt => if (E) S else ( ; ) + if (E<:Exp) S:Stmt => if (E) S else ( ; ) rule [If-True]: if (true::bool) S:Stmt else _:Stmt => S @@ -212,7 +212,6 @@ rule [StackConsumerStmt-RestoreEnv]: //@ \subsection{Break statement} rule [Break-UnlabeledPropagate]: - // 'Break('None(_)) ~> (KL:KLabel(_) => .) break 'None(_); ~> (KL:KLabel(_) => .) when KL =/=KLabel 'env @@ -221,7 +220,6 @@ when andBool KL =/=KLabel 'switchEnd rule [Break-Unlabeled]: - //'Break('None(_)) ~> KL:KLabel(_) => . break 'None(_); ~> KL:KLabel(_) => . when KL ==KLabel 'whileImpl From 6dd8494b0ae9b4db14ea86b0bb450d96a29f6276 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Wed, 11 Mar 2015 15:40:33 +0200 Subject: [PATCH 36/43] Statements: replaced one context with strictness. The last change to semantics rules. --- src/exec/statements.k | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/exec/statements.k b/src/exec/statements.k index 19b6956d..d46e0666 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -211,6 +211,11 @@ rule [StackConsumerStmt-RestoreEnv]: //@ \subsection{Break statement} +/*K limitation: Looks like neither 'None nor 'Some can be expressed syntactically. + Attempts to replace them with syntax, in rules for break, give either compile-time or runtime errors. + This is definitely a K limitation, as such syntax was not used in K before. +*/ + rule [Break-UnlabeledPropagate]: break 'None(_); ~> (KL:KLabel(_) => .) when @@ -323,8 +328,7 @@ rule [Throw]: ~> throw TV:TypedVal; ~> catchBlocks(catchImpl('ParamImpl(T:Type,, X:Id),_) _:CatchClauses) -syntax KItem ::= checkCatch ( K ) -context checkCatch(HOLE) +syntax KItem ::= checkCatch ( K ) [strict] rule [Throw-checkCatch-True]: checkCatch(true::bool) From a6b7f976844d63d17d18a9e6b2713cad6a2c1b61 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Wed, 11 Mar 2015 16:08:38 +0200 Subject: [PATCH 37/43] Doc: commented some unused doc that produces latex errors. --- src/common/sort-predicate-hacks.k | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/common/sort-predicate-hacks.k b/src/common/sort-predicate-hacks.k index 1c9b67d9..f162b26b 100644 --- a/src/common/sort-predicate-hacks.k +++ b/src/common/sort-predicate-hacks.k @@ -1,12 +1,12 @@ module SORT-PREDICATE-HACKS -/*@ - The rules in this module are designed to extend the predicates for basic syntactic sorts like Exp or Stmt, and to - ease the restrictions imposed by those predicates. - For example, the syntactic definition of plus : syntax Exp ::= Exp + Exp, will return true for - isExp('Plus(K1,,K2)) only when both K1 and K2 are valid Exp terms, while a rule isExp('Plus(_)) => true - will produce true for any term whose root node has the label 'Plus. This allows us to use variable subsorting inside - rules, to define more rules syntactically. +/* +The rules in this module are designed to extend the predicates for basic syntactic sorts like Exp or Stmt, and to +ease the restrictions imposed by those predicates. +For example, the syntactic definition of plus : syntax Exp ::= Exp + Exp, will return true for +isExp('Plus(K1,,K2)) only when both K1 and K2 are valid Exp terms, while a rule isExp('Plus(_)) => true +will produce true for any term whose root node has the label 'Plus. This allows us to use variable subsorting inside +rules, to define more rules syntactically. */ /* @@ -34,7 +34,7 @@ rule isExp('CastPrim(_)) => true rule isExp('CastRef(_)) => true -//@ Used to define statements syntactically +// Used to define statements syntactically. rule isStmt(_:K) => true //rule isStmt('ClassDecStm(_)) => true //rule isStmt('Block(_)) => true From 3f1f4b937478517b2da1111c1de38b90f30f3ecb Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Thu, 12 Mar 2015 19:19:29 +0200 Subject: [PATCH 38/43] Doc: Finished reviewing subsections in each module. Added many new subsections. --- src/common/aux-strings.k | 2 +- src/common/core-classes.k | 14 --- src/common/core-functions.k | 43 ++----- src/common/core-sorts.k | 70 +++++++++-- src/common/primitive-types.k | 4 +- src/common/subtyping.k | 14 +-- src/exec/api-core.k | 12 +- src/exec/api-threads.k | 178 +++++++++++++-------------- src/exec/arrays.k | 60 ++++----- src/exec/core-exec.k | 20 ++- src/exec/expressions-classes.k | 8 +- src/exec/expressions.k | 62 ++++------ src/exec/method-invoke.k | 7 ++ src/exec/new-instance.k | 4 +- src/exec/statements.k | 17 +-- src/exec/syntax-conversions.k | 8 +- src/exec/unfolding.k | 6 +- src/exec/var-lookup.k | 19 ++- src/prep/core-preprocessing.k | 8 +- src/prep/elaboration-arrays.k | 4 +- src/prep/elaboration-categories.k | 5 + src/prep/elaboration-core.k | 110 ++++++++--------- src/prep/elaboration-expressions.k | 37 +++--- src/prep/elaboration-method-invoke.k | 14 ++- src/prep/elaboration-new-instance.k | 2 - src/prep/elaboration-statements.k | 21 +++- src/prep/elaboration-top-blocks.k | 7 +- src/prep/elaboration-types.k | 2 - src/prep/elaboration-vars.k | 47 +++---- src/prep/process-class-decs.k | 10 +- src/prep/process-class-members.k | 43 ++++--- src/prep/process-comp-units.k | 4 +- src/prep/process-type-names.k | 2 +- src/sty/k-java.tex | 3 +- 34 files changed, 472 insertions(+), 395 deletions(-) diff --git a/src/common/aux-strings.k b/src/common/aux-strings.k index 9e1f94c4..ff7caf9b 100644 --- a/src/common/aux-strings.k +++ b/src/common/aux-strings.k @@ -1,5 +1,5 @@ module AUX-STRINGS -/*@ Auxiliary constructs related to Strings. Extension to string.k.*/ +/*@ Utility functions for string manipulation. No dependencies on other K-Java modules. Extension to string.k.*/ //@Retain the first Count chars in the string syntax KItem ::= retainHead ( String, Int ) [function] diff --git a/src/common/core-classes.k b/src/common/core-classes.k index e4708184..01f0e998 100644 --- a/src/common/core-classes.k +++ b/src/common/core-classes.k @@ -92,18 +92,4 @@ rule [restoreAfterProcessLocalClass]: syntax KItem ::= getConsName ( ClassType ) [function] rule getConsName(class ClassId:Id) => String2Id("$cons$" +String Id2String(ClassId)) -//@ \subsubsection{Computation terms produced during elaboration} - -/*@ These auxiliary terms functions that should be threated as expressions in the elaboration phase. -*/ -syntax Exp ::= AuxTermExp -syntax LHS ::= AuxTermExp -/*@ Wrapper of a statement followed by an expression, to be used in a place where an expression is expected, -such as an anonymous class declaration. Is typed with the type of the expression. -At runtime is rewritten into the statement, that should evaluate into .K, followed by the expression, -that should evaluate to value.*/ -syntax AuxTermExp ::= stmtAndExp ( K, K ) - -syntax AuxTermExp ::= cast ( Type, K ) [strict] //strictness on 1-st arcument - for runtime produced terms - endmodule diff --git a/src/common/core-functions.k b/src/common/core-functions.k index b37882a3..b55d6930 100644 --- a/src/common/core-functions.k +++ b/src/common/core-functions.k @@ -2,6 +2,8 @@ module CORE-FUNCTIONS imports CORE-SORTS imports CORE-CLASSES +//@ \subsection{Core utility functions} + /*@ Returns the type associated with various K terms. The implementation is scattered among various K files. For a type --- the type itself. For a typed expression - the type component. For some raw values - their most common type. @@ -60,7 +62,7 @@ rule getTypes([Ts:KList]) => types(Ts) when isKResult(Ts) -//@ \subsubsection{Other auxiliary constructs} +//@ \subsection{Utilities for general-purpose programming} /*@ Generalized equality with strictness, suitable to compare not only TypedVal-s but any K terms. */ @@ -154,22 +156,7 @@ rule length([Ks:KList]) => length(0, [Ks]) rule length(I:Int, [K:K,, Ks:KList]) => length(I +Int 1, [Ks]) rule length(I:Int, [.KList]) => I -/*@ \subsection{ClassType functions} */ - -//@ Converts a fully qualified class type into a simple name (Id) -syntax KItem ::= getSimpleName ( ClassType ) [function] -rule getSimpleName(class ClassId:Id) - => String2Id(trimHead( - Id2String(ClassId), - rfindString(Id2String(ClassId), ".", lengthString(Id2String(ClassId))) +Int 1 - )) - -/*@ \subsection{Identifiers}*/ - -/*@Convert the AST representation of an Id into a K Id.*/ -rule 'Id(Str:String) => String2Id(Str) [structural, anywhere] - -/*@ \subsection{Other auxiliary constructs} */ +/*@ \subsubsection{Other auxiliary constructs} */ /*@ \texttt{Generic guard.} A generic computational guard (should be builtin): it allows the computation to continue only if a prefix @@ -178,20 +165,14 @@ rule 'Id(Str:String) => String2Id(Str) [structural, anywhere] syntax KItem ::= "true?" rule true::bool ~> true? => . [structural] -//@ \subsection{Definition-wide rules} - -/*@ Represent a parser form for a sequence of terms. Is desugared into the pretty form [...]*/ -syntax KLabel ::= "'ListWrap" -rule 'ListWrap(Ks:KList) => [Ks] [structural, anywhere] -//todo: both 'KListWrap and 'ListWrap are associted with the same production, so how to get rid of it -syntax KListWrap ::= "[" KList "]" [klabel('KListWrap), latex(\terminal{[} {#1} \terminal{]})] - -//@ Sequence of terms and of any other statements. The first term is moved to the top of computation. -rule [S1:K,, Stmts:KList] => S1 ~> [Stmts] [structural] -rule [.KList] => .K [structural] +/*@ \subsection{ClassType functions} */ -//@ A wrapper over an arbitrary KList, wrapper being of type KResult. -syntax KRListWrap ::= "kr" "[" KList "]" [latex(\terminal{kr[} {#1} \terminal{]})] -syntax KResult ::= KRListWrap +//@ Converts a fully qualified class type into a simple name (Id) +syntax KItem ::= getSimpleName ( ClassType ) [function] +rule getSimpleName(class ClassId:Id) + => String2Id(trimHead( + Id2String(ClassId), + rfindString(Id2String(ClassId), ".", lengthString(Id2String(ClassId))) +Int 1 + )) endmodule diff --git a/src/common/core-sorts.k b/src/common/core-sorts.k index d04bbba6..4ab03edb 100644 --- a/src/common/core-sorts.k +++ b/src/common/core-sorts.k @@ -7,6 +7,12 @@ module CORE-SORTS imports LEXICAL-SYNTAX imports LITERAL-SYNTAX +/*@This module contains general-purpose utilities for the whole K-Java, both preprocessing and execution. + This is the lowest-level module of the whole semantics, imported by almost all other modules. + Because if its high accessibility status, it was somewhat abused, in a sense that I placed here some random + stuff for the lack of better place. +*/ + //@ \subsection{Computation phases} /*@ The computation Global Phase. See configuration documentation for details. @@ -92,17 +98,6 @@ syntax StaticInitStatus ::= "StaticUninitialized" | StaticInitializing ( Int ) | "StaticInitialized" - -/*@ A method signature. Required to be KResult by rules in METHOD-INVOKE.*/ -syntax Signature ::= sig ( Id, Types ) -syntax KResult ::= Signature - - -/*@ The member accessibility context of the current method --- either static or instance.*/ -syntax ContextType ::= "staticCT" [latex(\terminal{static})] - | "instanceCT" [latex(\terminal{instance})] -syntax KResult ::= ContextType - //@ \subsection{Values} /* Represents a Java value. May be either primitive --- int, float, bool, of reference. The values nothing and undefined @@ -164,6 +159,20 @@ syntax Exp ::= TypedVal | RawVal */ syntax KResult ::= TypedVal | Type +syntax KResult ::= "noValue" [latex({\dotCt{K}})] + +//@ \subsection{Class and member attributes} + +/*@ A method signature. Required to be KResult by rules in METHOD-INVOKE.*/ +syntax Signature ::= sig ( Id, Types ) +syntax KResult ::= Signature + + +/*@ The member accessibility context of the current method --- either static or instance.*/ +syntax ContextType ::= "staticCT" [latex(\terminal{static})] + | "instanceCT" [latex(\terminal{instance})] +syntax KResult ::= ContextType + /*@ Member access modes*/ syntax AccessMode ::= Public | Protected | Private | "package" syntax KResult ::= AccessMode @@ -175,7 +184,7 @@ syntax MethodMetaType ::= "methodMMT" | "constructorMMT" syntax ClassMetaType ::= "classCMT" [latex(\terminal{class})] | "interfaceCMT" [latex(\terminal{interface})] -syntax KResult ::= "noValue" [latex({\dotCt{K}})] +//@ \subsection{Misc definitions} /*@ Represents a reference to a method or constructor. */ syntax MethodRef ::= methodRef( @@ -209,6 +218,9 @@ syntax ClassOrName ::= Id | ClassType /*@ A fully qualified class name, or noClass where no valid class exists in the current context.*/ syntax ClassType ::= "class" Id | "noClass" [latex({\dotCt{K}})] + +/*@ \subsection{Random unsorted content, syntax converters}*/ + //Denis' syntax syntax Param ::= Type Id [klabel('ParamImpl)] @@ -221,4 +233,38 @@ syntax RefType ::= ClassType | "nullType" | "arrayOf" Type rule 'ArrayType(T:Type) => arrayOf T [anywhere] rule 'ClassOrInterfaceType(TypeK:K,, _) => TypeK [anywhere] + +/*@Convert the AST representation of an Id into a K Id.*/ +rule 'Id(Str:String) => String2Id(Str) [structural, anywhere] + +//@ \subsubsection{ListWrap and KListWrap} + +/*@ Represent a parser form for a sequence of terms. Is desugared into the pretty form [...]*/ +syntax KLabel ::= "'ListWrap" +rule 'ListWrap(Ks:KList) => [Ks] [structural, anywhere] +//todo: both 'KListWrap and 'ListWrap are associted with the same production, so how to get rid of it +syntax KListWrap ::= "[" KList "]" [klabel('KListWrap), latex(\terminal{[} {#1} \terminal{]})] + +//@ Sequence of terms and of any other statements. The first term is moved to the top of computation. +rule [S1:K,, Stmts:KList] => S1 ~> [Stmts] [structural] +rule [.KList] => .K [structural] + +//@ A wrapper over an arbitrary KList, wrapper being of type KResult. +syntax KRListWrap ::= "kr" "[" KList "]" [latex(\terminal{kr[} {#1} \terminal{]})] +syntax KResult ::= KRListWrap + +//@ \subsubsection{Computation terms produced during elaboration} + +/*@ These auxiliary terms functions that should be threated as expressions in the elaboration phase. +*/ +syntax Exp ::= AuxTermExp +syntax LHS ::= AuxTermExp +/*@ Wrapper of a statement followed by an expression, to be used in a place where an expression is expected, +such as an anonymous class declaration. Is typed with the type of the expression. +At runtime is rewritten into the statement, that should evaluate into .K, followed by the expression, +that should evaluate to value.*/ +syntax AuxTermExp ::= stmtAndExp ( K, K ) + +syntax AuxTermExp ::= cast ( Type, K ) [strict] //strictness on 1-st arcument - for runtime produced terms + endmodule diff --git a/src/common/primitive-types.k b/src/common/primitive-types.k index f113b7a8..183f30bf 100644 --- a/src/common/primitive-types.k +++ b/src/common/primitive-types.k @@ -2,7 +2,7 @@ module PRIMITIVE-TYPES imports CORE-SORTS imports SUBTYPING -//@ \subsection{Integer types normalization} +//@ \subsection{Integer value normalization} syntax Int ::= bitCount ( Type ) [function] rule bitCount(byte) => 8 @@ -77,6 +77,8 @@ rule toUnsigned(I:Int :: T:Type) I +Int (1 < ILT diff --git a/src/common/subtyping.k b/src/common/subtyping.k index 2fa6cb61..5ea09aff 100644 --- a/src/common/subtyping.k +++ b/src/common/subtyping.k @@ -10,13 +10,6 @@ syntax KItem ::= subtype ( ) [strict] -/*@ Checks whether the each type in the first list of types is a subtype -of the type at the same position in the second list. -If lists have different size, the function will evaluate to false. -Used in method call overloading resolution. -*/ -syntax KItem ::= subtypeList ( Types, Types ) - rule [subtype-same-type-True]: subtype( T:Type, T ) => true [structural] @@ -143,6 +136,13 @@ rule [subtype-OfNoClass]: /*@ \subsection{Subtyping lists of types}*/ +/*@ Checks whether the each type in the first list of types is a subtype +of the type at the same position in the second list. +If lists have different size, the function will evaluate to false. +Used in method call overloading resolution. +*/ +syntax KItem ::= subtypeList ( Types, Types ) + rule [subtypeList]: subtypeList(types(T1:Type,,Ts:KList), types(Tp1:Type,,Tps:KList)) => andAux( subtype(T1,Tp1), subtypeList(types(Ts), types(Tps)) ) diff --git a/src/exec/api-core.k b/src/exec/api-core.k index bf89e717..cafeb04a 100644 --- a/src/exec/api-core.k +++ b/src/exec/api-core.k @@ -4,12 +4,14 @@ module API-CORE imports ARRAYS // for allocAndInitArray() /*@ +This module contains the minimal part of Java API required to perform console read/write operations, +as well as a few other API functions mentioned in JLS. + All the methods defined in this module through invokeImpl are native, their body is \verb|'NoMethodBody(\_)|, thus they cannot be matched by rules in METHOD-INVOKE. */ -/*@ This module contains the minimal part of Java API required to perform console read/write operations, -as well as a few other API functions mentioned in JLS.*/ +//@ \subsection{\texttt{System.in}, \texttt{System.out}, \texttt{Scanner}} //@system-out-print-convert heat argument context @@ -78,6 +80,8 @@ rule [readString]: readString => Str :: classString ... ListItem(Str:String) => . ... +//@ \subsection{Class \texttt{Object}} + /*@ \verb|object.getClass()|*/ rule [object-getClass-on-object]: @@ -139,7 +143,7 @@ rule [object-hashCode]: when Class ==K classObject andBool Id2String(MethodName) ==String "hashCode" -//@\subsection{String methods} +//@ \subsection{Class \texttt{String}} //@ int \verb|String.length()| rule [String-length]: @@ -256,7 +260,7 @@ when rule [storeCopy-discard]: storeCopy(_, _, 0) => . -//@\subsection{Class literal --- .class} +//@\subsection{Class literal operator --- \texttt{A.class}} /*@ We need to synchronize access to class literals to avoid instantiation of the came .class by multiple threads. This is done by the term temp in \verb||. We cannot use 'Synchronized because it required an diff --git a/src/exec/api-threads.k b/src/exec/api-threads.k index 628eff1a..ecf31b08 100644 --- a/src/exec/api-threads.k +++ b/src/exec/api-threads.k @@ -2,7 +2,6 @@ module API-THREADS imports CORE-SORTS imports METHOD-INVOKE-REST //for invokeImpl imports VAR-LOOKUP //for typedLookup - imports API-THREADS-SELECTION /*@Java API related to threads and locks. Just the core part.*/ @@ -120,7 +119,91 @@ when Class ==K class String2Id("java.lang.Thread") andBool Id2String(MethodName) ==String "joinImpl" [transition-threading, transition-sync] -//@ \subsection{\texttt{Object.wait()}} +//@ \subsection{Methods \texttt{wait()} and \texttt{notify()} --- core rules} + +/*@ +When \verb|object.wait()| is called the method call expression is replaced by \verb|waitImpl()| +--- an auxiliary function that is used later to exit from the waiting state. +The id of the current thread (\verb|TId|) has to be registered in the set inside \cellref[]{waitingThreads}. + The cell \cellref[]{holds} attached to each thread stores the number of times the current thread + acquired the lock on each object. Here we use it to make sure that the current thread acquired the lock at least once + (see the side condition). Otherwise calling the method \verb|wait()| is illegal and we have to throw an exception, according + to Java API. The exceptional case is covered by other rules. Another cell matched here is \cellref[]{busy}. It stores + the set of objects that serve as synchronization monitors --- arguments of blocks \verb|synchronized|. When + an object enters the waiting state it have to release the ownership of this monitor, this is reflected by deleting + the entry \verb|OL| from the set. In this rule the cell \cellref[]{thread} is used solely for clarity, to separate + the cells that are attached to a thread from global cells. In fact, if we would delete \cellref[]{thread} here and + keep just what is inside, the semantics of the rule would not change. This is because configuration abstraction + mechanism of \K would infer the surrounding context for each of \cellref[]{k} \cellref[]{tid} and \cellref[]{holds}. + It would know to match them under the same \cellref[]{thread}, even if there are multiple \cellref[]{thread} cells. +*/ +rule [object-wait]: + //added just for clarity, to illustrate the distinctive context of and + + objectRef(OId:Int, _)::_ . methodRef(sig(Method:Id, _), Class:ClassType) (.TypedVals) + => waitImpl(OId) + ... + + TId:Int + ... OId |-> HoldLevel:Int ... + ... + + ... (SetItem(OId) => .) ... + ... (. => TId |-> OId ) ... +when + Class ==K classObject + andBool Id2String(Method) ==String "wait" + andBool HoldLevel >=Int 1 + [transition-threading] + +/*@ +When another thread calls \verb|notify()| we have to make sure that the thread holds the monitor on the target object + (the side condition). Otherwise we have to throw an exception. The actual logic of \verb|notify()| is delegated + to \verb|notifyImpl()|, in order to avoid duplication. The construct \verb|notifyImpl()| requires two rules for two + cases --- the case when there is at least one thread waiting on the target object, and the case when there is no one. +*/ +rule [object-notify]: + + objectRef(OId:Int, _)::_ . methodRef(sig(Method:Id, _), Class:ClassType) (.TypedVals) + => notifyImpl(OId) + ... + + ... OId |-> HoldLevel:Int ... +when + Class ==K classObject + andBool Id2String(Method) ==String "notify" + andBool HoldLevel >=Int 1 + +/*@ +Here we present the rule for the first case. If there is a thread waiting on the current object, then the object + identifier \verb|OId| will be present among the map values of \cellref[]{waitingThreads}. By deleting the whole entry + associated to that value we enable the waiting thread to proceed. If there is no thread waiting for this object then + the term \verb|notifyImpl()| is simply consumed. +*/ +rule [notifyImpl-someone-waiting]: + notifyImpl(OId:Int) => nothing::void ... + ... (_ |-> OId => .Map) ... + [transition-threading] + +/*@ +At this stage the rule for \verb|waitImpl()| could match. The rule checks in its side conditions that the current + thread id \verb|TId| is not among the waiting threads anymore. It also checks that the target object, represented by + \verb|OId| is not busy. This is required because the thread exiting from waiting state have to reacquire the monitor + on the target object. Finally, the rule have to make sure that the thread was not interrupted while it was waiting. + Otherwise another rule will match and will throw the appropriate exception. +*/ +rule [waitImpl-main]: + waitImpl(OId:Int) => nothing::void ... + TId:Int + Busy:Set (. => SetItem(OId)) + false + WT:Map +when + (notBool TId in keys(WT)) + andBool (notBool OId in Busy) + [transition-threading, transition-sync] + +//@ \subsection{\texttt{Object.wait()} --- additional} rule [object-wait-notify-notifyAll-without-sync]: @@ -157,7 +240,7 @@ when notBool OL in Busy [transition-threading, transition-sync] -//@ \subsection{\texttt{Object.notify()}, \texttt{Object.notifyAll()}} +//@ \subsection{\texttt{Object.notify()}, \texttt{Object.notifyAll()} --- additional} /*@Implementation of \verb|Object.notify()|, extracted here to avoid rule superfluousness*/ syntax KItem ::= notifyImpl ( @@ -285,92 +368,3 @@ rule [DissolveAllExceptOut]: => Out endmodule - -module API-THREADS-SELECTION - imports API-THREADS - -//@ \subsection{Methods \texttt{wait()} and \texttt{notify()}} - -/*@ -When \verb|object.wait()| is called the method call expression is replaced by \verb|waitImpl()| ---- an auxiliary function that is used later to exit from the waiting state. -The id of the current thread (\verb|TId|) has to be registered in the set inside \cellref[]{waitingThreads}. - The cell \cellref[]{holds} attached to each thread stores the number of times the current thread - acquired the lock on each object. Here we use it to make sure that the current thread acquired the lock at least once - (see the side condition). Otherwise calling the method \verb|wait()| is illegal and we have to throw an exception, according - to Java API. The exceptional case is covered by other rules. Another cell matched here is \cellref[]{busy}. It stores - the set of objects that serve as synchronization monitors --- arguments of blocks \verb|synchronized|. When - an object enters the waiting state it have to release the ownership of this monitor, this is reflected by deleting - the entry \verb|OL| from the set. In this rule the cell \cellref[]{thread} is used solely for clarity, to separate - the cells that are attached to a thread from global cells. In fact, if we would delete \cellref[]{thread} here and - keep just what is inside, the semantics of the rule would not change. This is because configuration abstraction - mechanism of \K would infer the surrounding context for each of \cellref[]{k} \cellref[]{tid} and \cellref[]{holds}. - It would know to match them under the same \cellref[]{thread}, even if there are multiple \cellref[]{thread} cells. -*/ -rule [object-wait]: - //added just for clarity, to illustrate the distinctive context of and - - objectRef(OId:Int, _)::_ . methodRef(sig(Method:Id, _), Class:ClassType) (.TypedVals) - => waitImpl(OId) - ... - - TId:Int - ... OId |-> HoldLevel:Int ... - ... - - ... (SetItem(OId) => .) ... - ... (. => TId |-> OId ) ... -when - Class ==K classObject - andBool Id2String(Method) ==String "wait" - andBool HoldLevel >=Int 1 - [transition-threading] - -/*@ -When another thread calls \verb|notify()| we have to make sure that the thread holds the monitor on the target object - (the side condition). Otherwise we have to throw an exception. The actual logic of \verb|notify()| is delegated - to \verb|notifyImpl()|, in order to avoid duplication. The construct \verb|notifyImpl()| requires two rules for two - cases --- the case when there is at least one thread waiting on the target object, and the case when there is no one. -*/ -rule [object-notify]: - - objectRef(OId:Int, _)::_ . methodRef(sig(Method:Id, _), Class:ClassType) (.TypedVals) - => notifyImpl(OId) - ... - - ... OId |-> HoldLevel:Int ... -when - Class ==K classObject - andBool Id2String(Method) ==String "notify" - andBool HoldLevel >=Int 1 - -/*@ -Here we present the rule for the first case. If there is a thread waiting on the current object, then the object - identifier \verb|OId| will be present among the map values of \cellref[]{waitingThreads}. By deleting the whole entry - associated to that value we enable the waiting thread to proceed. If there is no thread waiting for this object then - the term \verb|notifyImpl()| is simply consumed. -*/ -rule [notifyImpl-someone-waiting]: - notifyImpl(OId:Int) => nothing::void ... - ... (_ |-> OId => .Map) ... - [transition-threading] - -/*@ -At this stage the rule for \verb|waitImpl()| could match. The rule checks in its side conditions that the current - thread id \verb|TId| is not among the waiting threads anymore. It also checks that the target object, represented by - \verb|OId| is not busy. This is required because the thread exiting from waiting state have to reacquire the monitor - on the target object. Finally, the rule have to make sure that the thread was not interrupted while it was waiting. - Otherwise another rule will match and will throw the appropriate exception. -*/ -rule [waitImpl-main]: - waitImpl(OId:Int) => nothing::void ... - TId:Int - Busy:Set (. => SetItem(OId)) - false - WT:Map -when - (notBool TId in keys(WT)) - andBool (notBool OId in Busy) - [transition-threading, transition-sync] - -endmodule diff --git a/src/exec/arrays.k b/src/exec/arrays.k index 2139bbcd..87bc817d 100644 --- a/src/exec/arrays.k +++ b/src/exec/arrays.k @@ -2,9 +2,12 @@ module ARRAYS imports CORE-SORTS imports SUBTYPING imports EXPRESSIONS + imports VAR-LOOKUP imports SYNTAX-CONVERSIONS imports JAVA-SYNTAX +//@ \subsection{Array access} + /*@ The value in store that corresponds to an array element. The consturction "elem" Type is meant to distinguish between regular memory locations and array elements. Array elements need to be represented separately in order to support array polymorphism. @@ -47,12 +50,29 @@ rule [Field-array-length]: when Id2String(X) ==String "length" -//@ \subsection{New array allocation} -/*@ The dynamic semantics of typed array declarations is -similar to that in untyped SIMPLE, but we have to enforce that the -type of an array declaration be of the form \texttt{arrayOf $T$} -and assign the right type ($T$) to the allocated array locations. */ +//@ \subsection{Assignment to array elements} + +rule [storeImpl-array-elem]: + storeImpl(L:Int, V:RawVal :: T:Type) => . ... + ... L |-> (_ => V) :: elem T:Type ... + +rule [storeImpl-array-location-check-type]: + + storeImpl(L:Int, V:RawVal::T:Type) + => ifAux(subtype(typeOf(V), StoreType), + storeImpl(L, V::StoreType), + throw new class String2Id("java.lang.ArrayStoreException") ( + //the ArrayStoreException argument is the assigned object type + (V::T .((String2Id("getClass")):>MethodName) (.TypedVals)) .((String2Id("getName")):>MethodName) (.TypedVals) + ); + ) + ... + + ... L |-> _ :: elem StoreType:Type ... +when + T =/=K StoreType +//@ \subsection{Array allocation} /* For multi-dimensions arrays, it is expanded from the last DimExp, but currently, the tail element(s) matching is unavailable for user defined lists, so we reverse list for easier matching @@ -83,6 +103,7 @@ rule [NewArray-ArrayInit]: new arrayOf T:Type .Dims {InitContent:VarInits} => arrayInitAlloc((new T [length(InitContent)::int] .Dims), {InitContent}) +//@Length of an array initializer. syntax Int ::= length (VarInits) [function] rule length(V:VarInit, Vs:VarInits) => length(Vs)+Int 1 rule length(.VarInits) => 0 @@ -135,13 +156,6 @@ rule [allocAndInitArray]: LI:Int => LI +Int 1 -//@ Maximum of two numbers -syntax KItem ::= max ( Int, Int ) [function] -rule max(I1:Int, I2:Int) => #if I1 >=Int I2 - #then I1 - #else I2 - #fi - /*@ Allocates the given number of elements in the store of the given Type. Used by array instantiation logic. */ syntax KItem ::= allocArray ( @@ -180,28 +194,6 @@ when rule initArray(_, 0, _) => .K [structural] -//@ \subsection{Array element assignment} - -rule [storeImpl-array-elem]: - storeImpl(L:Int, V:RawVal :: T:Type) => . ... - ... L |-> (_ => V) :: elem T:Type ... - -rule [storeImpl-array-location-check-type]: - - storeImpl(L:Int, V:RawVal::T:Type) - => ifAux(subtype(typeOf(V), StoreType), - storeImpl(L, V::StoreType), - throw new class String2Id("java.lang.ArrayStoreException") ( - //the ArrayStoreException argument is the assigned object type - (V::T .((String2Id("getClass")):>MethodName) (.TypedVals)) .((String2Id("getName")):>MethodName) (.TypedVals) - ); - ) - ... - - ... L |-> _ :: elem StoreType:Type ... -when - T =/=K StoreType - //@ \subsection{Array initializer} //@ Allocates the array based on previously computed size, then proceeds to array initialization diff --git a/src/exec/core-exec.k b/src/exec/core-exec.k index 82185d95..b168bbaa 100644 --- a/src/exec/core-exec.k +++ b/src/exec/core-exec.k @@ -2,13 +2,26 @@ module CORE-EXEC imports CORE-SORTS imports SYNTAX-CONVERSIONS +/*@ +A collection of utility functions that many other, unrelated modules depend on. Grouped here to minimize +the dependencies between other modules. +*/ + //@ ListItem content as a stack layer syntax KItem ::= sl ( K, //K - rest of computation Bag //MethContext - the content of ) -//@ \subsection{Auxiliary methods} +//@Auxiliary constructs used in variable access semantics. +syntax KItem ::= lvalue ( K ) +syntax RawVal ::= loc ( Int ) + +//@Store to the given location in (first argument) the given value (second argument). +syntax KItem ::= store ( + Int, //OL - the store location + K //evaluates to TypedVal - the value to be stored + ) [strict(2)] //@ Restore the content of the cell \verb|| syntax KItem ::= restoreMethContext ( @@ -19,9 +32,4 @@ rule [restoreMethContext]: restoreMethContext(MethContext:Bag) => . ... _ => MethContext -/*@ \subsection{Syntax for lvalue and loc} */ - -syntax KItem ::= lvalue ( K ) -syntax RawVal ::= loc ( Int ) - endmodule diff --git a/src/exec/expressions-classes.k b/src/exec/expressions-classes.k index 0d42ed5f..ef28024d 100644 --- a/src/exec/expressions-classes.k +++ b/src/exec/expressions-classes.k @@ -8,13 +8,13 @@ module EXPRESSIONS-CLASSES /*@ Expressions that operate over objects. */ -/*@ \subsection{Operator instanceof} */ +/*@ \subsection{Instanceof operator} */ rule [InstanceOf]: V:RawVal::_ instanceof RT2:RefType => (V =/=K null) && subtype(typeOf(V), RT2) -/*@ \subsection{Cast for references} */ +/*@ \subsection{Cast operator --- reference types} */ rule [cast-RefType]: cast(RT1:RefType, V:RawVal :: RT2:RefType) => ifAux ( subtype(typeOf(V), RT1) , @@ -25,4 +25,8 @@ rule [cast-RefType]: ); ) +/*@ \subsection{Auxiliary constructs produced during elaboration} */ + +rule stmtAndExp(Stmt:K, Exp:K) => Stmt ~> Exp + endmodule diff --git a/src/exec/expressions.k b/src/exec/expressions.k index 4d21f110..41b851c5 100644 --- a/src/exec/expressions.k +++ b/src/exec/expressions.k @@ -5,13 +5,18 @@ module EXPRESSIONS imports PRIMITIVE-TYPES // for normalizeType imports TO-STRING imports VAR-LOOKUP // for lookup +/*@ The module defines expressions operating over primitive types and String. +*/ - -/*@ Used to denote a temporary type of an expression. Such an expression should always be wrapped inside a cast +/*@ Used to denote a placeholder for an expression type, until the proper, normalized type of an expression + is computed. Never referred in the semantics. + An expression containing a placeholder type should always be wrapped inside a cast expression. The cast will then replace tempType with the proper compile-time type. */ syntax Type ::= "tempType" +/*@ \subsection{Boolean operators} */ + rule /* true || _ */ true :: bool || _ => true //We use K:K instead of TE:TypedList because 'LazyAnd is used inside the semantics, not only in the source program. @@ -43,6 +48,8 @@ rule F1:Float :: _ <= F2:Float :: _ => (F1 <=Float F2)::bool rule /* I1 >= I2 */ I1:Int :: _ >= I2:Int :: _ => (I1 >=Int I2)::bool rule F1:Float :: _ >= F2:Float :: _ => (F1 >=Float F2)::bool +/*@ \subsection{Numeric operators} */ + rule /* I1 << I2 */ I1:Int :: NT1:Type << I2:Int :: _ => (I1 <> I2 */ I1:Int :: NT1:Type >> I2:Int :: _ @@ -52,15 +59,6 @@ rule /* I1 >>> I2 */ I1:Int :: NT1:Type >>> I2:Int :: NT2:NumericType rule /* I1 + I2 */ I1:Int::_ + I2:Int::_ => (I1 +Int I2) :: tempType rule /* F1 + F2 */ F1:Float :: _ + F2:Float :: _ => (F1 +Float F2) :: tempType -rule /* Str1 + Str2 */ Str1:String :: _ + Str2:String :: _ => (Str1 +String Str2) :: classString -rule /* Str + KR */ Str:String :: Class:ClassType + ( KR:KResult => toString(KR) ) -when ((typeOf(KR) =/=K classString) - andBool Class ==K classString) - orBool (KR ==K (null::classString)) -rule /* KR + Str */ ( KR:KResult => toString(KR) ) + Str:String :: Class:ClassType -when ((typeOf(KR) =/=K classString) - andBool Class ==K classString) - orBool (KR ==K (null::classString)) rule /* I1 - I2 */ I1:Int :: _ - I2:Int :: _ => (I1 -Int I2) :: tempType rule /* F1 - F2 */ F1:Float :: _ - F2:Float :: _ => (F1 -Float F2) :: tempType @@ -133,13 +131,27 @@ syntax KItem ::= rightTypedNumber ( Int, NumericType ) [function] rule rightTypedNumber(I:Int, IntT:IntType) => I::IntT rule rightTypedNumber(I:Int, FloatT:FloatType) => Int2Float(I)::FloatT +/*@ \subsection{String operators} */ + +rule /* Str1 + Str2 */ Str1:String :: _ + Str2:String :: _ => (Str1 +String Str2) :: classString +rule /* Str + KR */ Str:String :: Class:ClassType + ( KR:KResult => toString(KR) ) +when ((typeOf(KR) =/=K classString) + andBool Class ==K classString) + orBool (KR ==K (null::classString)) +rule /* KR + Str */ ( KR:KResult => toString(KR) ) + Str:String :: Class:ClassType +when ((typeOf(KR) =/=K classString) + andBool Class ==K classString) + orBool (KR ==K (null::classString)) + +/*@ \subsection{Conditional operator} */ + /*@ Conditional expression : ?: . Desugared into an if with cast. The biggest difficulty is computing the expression type, according to JLS1 \$15.24 The whole expression should always come wrapped into a cast, from elaboration. Thus we don't have to worry about proper type conversion here.*/ rule CondExp:Exp ? TrueExp:Exp : FalseExp:Exp => ifAux(CondExp,TrueExp,FalseExp) -/*@ \subsubsection{Assignment operators} +/*@ \subsection{Assignment operators} Both basic assignment and compound assignments like +=, -=, etc. */ context (_:KResult = HOLE)<:AssignExp @@ -173,7 +185,7 @@ rule loc(L:Int) :: T:Type &= Exp2:K => loc(L)::T = cast(T, lookup(L, T) & Exp2) rule loc(L:Int) :: T:Type ^= Exp2:K => loc(L)::T = cast(T, lookup(L, T) ^ Exp2) rule loc(L:Int) :: T:Type |= Exp2:K => loc(L)::T = cast(T, lookup(L, T) | Exp2) -/*@ \subsection{Cast expression --- primitive types} */ +/*@ \subsection{Cast operator --- primitive types} */ //@ The type of RV could either be NumericType or tempType. This rule matches both. rule [cast-Number]: cast(NT:NumericType, RV:RawVal::_) => normalize(RV::NT) @@ -245,28 +257,4 @@ rule [lvalue-Throw-desugar]: lvalue( throw E:Exp; ) => throw E; [structural] -/*@ \subsection{Auxiliary functions for store} */ - -syntax KItem ::= store ( - Int, //OL - the store location - K //evaluates to TypedVal - the value to be stored - ) [strict(2)] - -//@ Synchronization checkpoint have to be before the actual assignment, like for lookup. -rule [store]: - store(L:Int, V:RawVal :: T:Type) => fieldAccessCheckpoint(L) ~> storeImpl(L, V::T) - -syntax KItem ::= storeImpl ( - Int, //OL - the store location - K //TypedVal - the value to be stored - ) - -rule [storeImpl]: - storeImpl(L:Int, V:RawVal :: T:Type) => . ... - ... L |-> (_ => V) :: T ... - -/*@ \subsection{Auxiliary constructs produced during elaboration} */ - -rule stmtAndExp(Stmt:K, Exp:K) => Stmt ~> Exp - endmodule diff --git a/src/exec/method-invoke.k b/src/exec/method-invoke.k index de9fa71a..9852f07c 100644 --- a/src/exec/method-invoke.k +++ b/src/exec/method-invoke.k @@ -681,6 +681,9 @@ module METHOD-INVOKE-REST imports CORE-FUNCTIONS imports SYNTAX-CONVERSIONS imports METHOD-INVOKE +//@ The module contains additional semantics related to method invocation. + +//@ \subsection{Method information for arrays and strings} /*@ The next rule for method invocation is applied when the qualifier type is array. This array type is rewritten into the auxiliary class \verb|ArrayImpl|, that is used in K-Java to simulate method invocations over array objects. This rule is required in order to minimize the number of particular cases involving arrays in the rules that follow. @@ -698,6 +701,8 @@ rule [Invoke-methodInfo-on-array-or-string]: when isArrayRef(QualRV) ==K true orBool isString(QualRV) ==K true +//@ \subsection{Superclass method access --- \texttt{A.super(...)}} + // 'QSuperMethod(Class:ClassType,, _:K,, Name:Id) rule [Invoke-QSuperMethod]: 'Invoke( @@ -727,6 +732,8 @@ rule [superMethodImpl]: Class BaseClass:ClassType +//@ \subsection{Auxiliary functions} + rule [getClassChain-process]: getClassChain(MostBaseClass:ClassType, diff --git a/src/exec/new-instance.k b/src/exec/new-instance.k index d7c5e2b1..882a8a38 100644 --- a/src/exec/new-instance.k +++ b/src/exec/new-instance.k @@ -229,7 +229,7 @@ module NEW-INSTANCE-REST imports VAR-LOOKUP //for typedLookup() imports NEW-INSTANCE -/*@Additional cases of new instance creation. */ +/*@Additional semantics of new instance creation. */ //@\subsection{Instance field declarations} @@ -240,7 +240,7 @@ rule [FieldDec-instance]: ... . => L |-> FieldLocMetadata ... L:Int => L +Int 1 -//@\subsection{Execution of QSuperConstrInv, AltConstrInv} +//@\subsection{Explicit constructor invocation --- \texttt{this()} and \texttt{super()}} // 'QSuperConstrInv( Qual:K,, _:K,, [ Args:KList ] ) rule [QSuperConstrInv]: diff --git a/src/exec/statements.k b/src/exec/statements.k index d46e0666..4e36a63f 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -6,7 +6,7 @@ module STATEMENTS imports METHOD-INVOKE // for initParams imports STMT-SYNTAX -//@ \subsection{Call of main method} +//@ \subsection{Call of the main method} //For now main class may only be placed in the default package. rule [ExecutionPhase-Start]: @@ -41,7 +41,7 @@ rule [env-double-Discard]: (env(_) => .) ~> env(_) [structural] -/*@ \subsection{Local Variable Declaration Statements} JLS \$14.4 +/*@ \subsection{Local Variable Declarations} JLS \$14.4 Not only local but fields also*/ rule [LocalVarDec]: @@ -292,11 +292,7 @@ when KL =/=KLabel 'env andBool KL =/=KLabel 'labeledImpl -/*@\subsection{Return} At method return, we have to check that the type -of the returned -value is a subtype of the expected return type. Moreover, if that is -the case, then we also up-cast the returned value to one of the -expected type. */ +/*@\subsection{Return statement}*/ //context 'Return('Some(HOLE)) context return 'Some(HOLE); @@ -320,7 +316,7 @@ rule [Return-MethodEnd]: _:Bag => MethContext /*@ \subsection{Throw statement} -Exceptions are propagated now until a catch that can bind them is +Exceptions are propagated until a catch compatible with them is encountered. */ rule [Throw]: (. => checkCatch(subtype(typeOf(TV), T))) @@ -394,9 +390,6 @@ syntax KItem ::= catchBlocks ( CatchClauses ) //arg - list of catchImpl rule [catchBlocks-Discard]: catchBlocks(_) => .K -/*@ \subsubsection{Execution of try-finally} JLS \$14.20.2 -*/ - rule [Try-Finally]: try TryS:K .CatchClauses finally FinallyS:K => TryS ~> finallyBlock(FinallyS) @@ -407,4 +400,4 @@ syntax KItem ::= finallyBlock ( K ) //arg - finally block rule [finallyBlock-NormalEnd]: finallyBlock(FinallyS:K) => FinallyS -endmodule \ No newline at end of file +endmodule diff --git a/src/exec/syntax-conversions.k b/src/exec/syntax-conversions.k index 6d622db2..b4253b67 100644 --- a/src/exec/syntax-conversions.k +++ b/src/exec/syntax-conversions.k @@ -4,7 +4,9 @@ module SYNTAX-CONVERSIONS imports CORE-CLASSES //for cast imports CORE-EXEC -/*@ Defining the syntax for key portions of the semantics, and converting AST terms back int otheir syntactiv form. +/*@ Defining the syntax for key portions of the semantics, and converting AST terms back into their syntactic form. +This whole module is auxiliary, its purpose is to allow defining some portions of the semantics syntactically. +It will disappear once the main syntax of K-Java will be used instead. */ /*@ \subsection{Method parameter}*/ @@ -87,7 +89,7 @@ rule [NewInstance-to-QNewInstance-unpack]: new Class:ClassType(ArgExps:Exps) => noValue . new Class:ClassType(ArgExps:Exps) -/*@ \subsection{Syntactic lists --- Exps, TypedVals, ClassTypes}*/ +/*@ \subsection{Syntactic lists}*/ /*@ A list of expressions, usually a list of arguments of a method or constructor. @@ -124,7 +126,7 @@ rule getTypes(types(Ts:KList), .TypedVals) => types(Ts) syntax KResult ::= ClassTypes syntax ClassTypes ::= List{ClassType, ","} -//@ /subsubsection{Try -- syntax conversion macros} +//@ \subsubsection{Try/catch} rule 'Try(Trys:K,, ([Catches:KList] => toCatchClauses([Catches])),, _:KList) [anywhere] syntax CatchClauses ::= toCatchClauses( KListWrap ) [function] diff --git a/src/exec/unfolding.k b/src/exec/unfolding.k index 8d2ec809..310ffba1 100644 --- a/src/exec/unfolding.k +++ b/src/exec/unfolding.k @@ -3,7 +3,11 @@ module UNFOLDING imports CORE-FUNCTIONS imports SYNTAX-CONVERSIONS -/*@At the beginning of execution semantics \verb|| contains the term unfoldingPhase, \verb|| is non-empty and the global phase is UnfoldingPhase. +/*@ +The Unfolding phase of the execution semantics, opposite ot the folding phase of the preprocessing semantics. +In this phase the preprocessed program stored in cell is distributed into various cells inside . + +At the beginning of execution semantics \verb|| contains the term unfoldingPhase, \verb|| is non-empty and the global phase is UnfoldingPhase. */ syntax KItem ::= "unfoldingPhase" diff --git a/src/exec/var-lookup.k b/src/exec/var-lookup.k index 54a4f897..67bafc47 100644 --- a/src/exec/var-lookup.k +++ b/src/exec/var-lookup.k @@ -16,7 +16,7 @@ rule [lvalue-ExprName-local]: lvalue('ExprName(X:Id)) => typedLoc(L) ... ... X |-> L:Int ... -/*@ \subsection{QThis --- Self reference} */ +/*@ \subsection{Qualified \texttt{this} --- self reference} */ // 'QThis(Class:ClassType) rule [QThis]: @@ -136,7 +136,7 @@ rule [lvalue-Field-static]: TargetClass ... X |-> L:Int ... -/*@ \subsection{Functions typedLookup and typedLoc} */ +/*@ \subsection{Functions for accessing the store} */ //@ Typed version of lookup and loc syntax KItem ::= typedLookup ( Int ) @@ -157,8 +157,6 @@ rule [typedLoc]: rule [lvalue-typedLoc]: lvalue(typedLoc(L:Int)) => typedLoc(L) -/*@ \subsection{Function lookup} */ - /*@ Retrieve a value from the store based on its location and the given compile-time type. May be wrapped inside lvalue. If lookup is unwrapped, it evaluates to TypedVal --- the store value, of the type T --- the second lookup argument. If lookup is wrapped into lvalue, it evaluates to \verb|loc(OL)|::T. @@ -191,4 +189,17 @@ rule [fieldAccessCheckpoint-Field]: ... L |-> FieldLocMetadata ... [transition-threading] +//@ Synchronization checkpoint have to be before the actual assignment, like for lookup. +rule [store]: + store(L:Int, V:RawVal :: T:Type) => fieldAccessCheckpoint(L) ~> storeImpl(L, V::T) + +syntax KItem ::= storeImpl ( + Int, //OL - the store location + K //TypedVal - the value to be stored + ) + +rule [storeImpl]: + storeImpl(L:Int, V:RawVal :: T:Type) => . ... + ... L |-> (_ => V) :: T ... + endmodule diff --git a/src/prep/core-preprocessing.k b/src/prep/core-preprocessing.k index 84da59b3..b9df9e04 100644 --- a/src/prep/core-preprocessing.k +++ b/src/prep/core-preprocessing.k @@ -2,9 +2,11 @@ module CORE-PREPROCESSING imports CORE-SORTS imports CORE-FUNCTIONS -//@ Auxiliary functions related to preprocessing phases only. +/*@ Most commonly used auxiliary functions related to preprocessing semantics only. +This module is designed to be included in most other modules of preprocessing. +*/ -//@ \subsection{Auxiliary constructs for retrieving a set of classes} +//@ \subsection{Class-related functions} /*@ Returns a \verb|setWrap(Set[ClassType])|, containing all top level classes in the program. Uses \verb|| to compute the result. Used by the starting rule of several preprocessing phases. @@ -56,6 +58,8 @@ rule [getInnerClasses-no-inners]: when notBool toPackage(Class) in keys(TypeNamesMap) +//@ \subsection{Method-related functions} + //@ Returns the access mode of a method closure given as argument syntax KItem ::= getMethodAccessMode ( MethodRef ) [strict] rule [getMethodAccessMode]: diff --git a/src/prep/elaboration-arrays.k b/src/prep/elaboration-arrays.k index 3765ec9c..d4327e83 100644 --- a/src/prep/elaboration-arrays.k +++ b/src/prep/elaboration-arrays.k @@ -2,7 +2,7 @@ module ELABORATION-ARRAYS imports CORE-SORTS imports ELABORATION-CORE -//@ \subsection{Desugaring of array declarators with c-style dimensions and initializers} +//@ \subsection{Desugaring of c-style array declarators} /*@ C-style array declaration Applied in both elaboration and execution phase @@ -73,7 +73,7 @@ rule [Param-ArrayVarDecId-Discard]: ( 'ArrayVarDecId( X:Id,, [.KList] ) => X ) ) [structural, anywhere] -/*@ \subsection{Elaboration of array-related expressions} */ +/*@ \subsection{Main array-related expressions} */ rule [elabEnd-ArrayAccess]: elabEnd('ArrayAccess(cast(arrayOf T:Type, TargetExp:K),, IndexTE:K)) diff --git a/src/prep/elaboration-categories.k b/src/prep/elaboration-categories.k index 6351fa2f..ceea524c 100644 --- a/src/prep/elaboration-categories.k +++ b/src/prep/elaboration-categories.k @@ -1,5 +1,10 @@ module ELABORATION-CATEGORIES +/*@ +This module contains a few auxiliary functions governing what AST labels should be processed by default +rules for elaboration, and which ones need custom rules. + +*/ /*@ Java KLabels that are processed by default heating/cooling rules of elaboration. All KLabels that can be part of a code block during elaboration phase, except those members of customElabChildren or isElabNaked groups. diff --git a/src/prep/elaboration-core.k b/src/prep/elaboration-core.k index 7508d010..03b5f4f2 100644 --- a/src/prep/elaboration-core.k +++ b/src/prep/elaboration-core.k @@ -6,7 +6,10 @@ module ELABORATION-CORE /*@ \begin{markdown} -Elaborate the composition of code blocks of a class --- the last step of preprocessing (besides Folding). +\subsection{Elaboration phase --- introduction} + +In this phase we elaborate the content of code blocks inside a class --- the last step of preprocessing +(besides Folding). During this phase we inspect the contents of method bodies, instance initializers and static initializers of a class and perform the following transformations: \begin{itemize} @@ -60,8 +63,12 @@ During elaboration an expression transition through 6 phases: 7. Elaboration cooling. Once the top K Item was wrapped into elabRes, it is ready to be cooled back into its original context: elab('CastRef(\_,, elabRes('Minus(cast(int,cast(int, localVar(X))))))) \end{markdown} + +Module ELABORATION-CORE contains the backbone of elaboration phase. */ +/*@ \subsection{Core auxiliary definitions}*/ + /*@Custom hole used for custom heating/cooling rules in the elaboration phase.*/ syntax KItem ::= "CHOLE" @@ -72,59 +79,6 @@ syntax KItem ::= elab ( K ) syntax ElabKResult ::= elabRes ( K ) rule isElabKResult(KR:KResult) => true -/*@ \subsection{Operator ??}*/ - -/*@ Chain of responsibility pattern. -Evaluate the first argument. if it is KResult (except noValue) or \verb|elabRes()|, the result of the ?? expression is -the result of the first argument. Otherwise, if the first argument evaluates to noValue, the result of the -?? expression is the result of the second argument. -*/ -syntax KItem ::= K "??" K [right] - -rule [chainOfResponsibility-Heat]: - (. => Arg1) ~> (Arg1:K => CHOLE) ?? _ -when - notBool isElabKResult(Arg1) ==K true - -rule [chainOfResponsibility-Result1]: - ElabRes:ElabKResult ~> (CHOLE ?? _) => ElabRes -when ElabRes =/=K noValue - -rule [chainOfResponsibility-Result2]: - noValue ~> (CHOLE ?? K:K) => K - -/*@ -\begin{markdown} -Computes to true if the given argument is a list of elaboration results, false otherwise. -An elaborated result is either: - - - KResult - - \verb|elabRes(...)| - - It is notably NOT a \verb|cast()| expression. This, together with the fact that \verb|cast()| has no elaboration heatig rules, - makes the whole elaboration phase non-reentrant. -\end{markdown} -*/ -syntax KItem ::= isElabKList ( KListWrap ) [function] -rule isElabKList([ElabKR:ElabKResult,, Ks:KList]) => isElabKList([Ks]) -rule isElabKList([.KList]) => true - -//@ Elaborate parameter type, if not elaborated yet. For catch clause. -context elab('Param(_:K,, HOLE,, _:Id)) - -/*@Adds params to the \verb||. Used in both ELABORATION-TOP-BLOCKS and ELABORATION-BLOCKS -*/ -rule [elab-Param]: - elab('Param(K1:K,, T:Type,, X:Id)) => elabRes('Param(K1:K,, T:Type,, X:Id)) ... - ListItem(mapWrap((. => X |-> T) _)) ... - -//@Removes the last layer from \verb|| -syntax KItem ::= "removeLastElabEnv" -rule [removeLastElabEnv]: - removeLastElabEnv => . ... - ListItem(_) => . ... - ListItem(_) => . ... - /*@ \subsection{Elaboration of code blocks} */ /*@ Heating arguments for both expression and statement terms. @@ -240,7 +194,23 @@ rule [elabEnd-findQualifierOfType-top-level]: rule [elabEnd-findQualifierOfType-static]: findQualifierOfType(noClass, K:K) => noValue -/*@ \subsection{Elaboration of statements --- step elabEnd} */ +/*@ +\begin{markdown} +Computes to true if the given argument is a list of elaboration results, false otherwise. +An elaborated result is either: + + - KResult + - \verb|elabRes(...)| + + It is notably NOT a \verb|cast()| expression. This, together with the fact that \verb|cast()| has no elaboration heatig rules, + makes the whole elaboration phase non-reentrant. +\end{markdown} +*/ +syntax KItem ::= isElabKList ( KListWrap ) [function] +rule isElabKList([ElabKR:ElabKResult,, Ks:KList]) => isElabKList([Ks]) +rule isElabKList([.KList]) => true + +/*@ \subsection{Elaboration of statements --- the step elabEnd} */ /*@ Applies to all nodes that are not expressions --- statements and non-expression auxiliary functions */ @@ -291,4 +261,34 @@ when rule [elab-to-elabRes-KListWrap-empty]: elab([.KList]) => elabRes([.KList]) +/*@ \subsection{Auxiliary functions for other modules}*/ + +//@Removes the last layer from \verb|| +syntax KItem ::= "removeLastElabEnv" +rule [removeLastElabEnv]: + removeLastElabEnv => . ... + ListItem(_) => . ... + ListItem(_) => . ... + +/*@ \subsubsection{Operator ??}*/ + +/*@ Chain of responsibility pattern. +Evaluate the first argument. if it is KResult (except noValue) or \verb|elabRes()|, the result of the ?? expression is +the result of the first argument. Otherwise, if the first argument evaluates to noValue, the result of the +?? expression is the result of the second argument. +*/ +syntax KItem ::= K "??" K [right] + +rule [chainOfResponsibility-Heat]: + (. => Arg1) ~> (Arg1:K => CHOLE) ?? _ +when + notBool isElabKResult(Arg1) ==K true + +rule [chainOfResponsibility-Result1]: + ElabRes:ElabKResult ~> (CHOLE ?? _) => ElabRes +when ElabRes =/=K noValue + +rule [chainOfResponsibility-Result2]: + noValue ~> (CHOLE ?? K:K) => K + endmodule diff --git a/src/prep/elaboration-expressions.k b/src/prep/elaboration-expressions.k index 2e8761ae..5223c96a 100644 --- a/src/prep/elaboration-expressions.k +++ b/src/prep/elaboration-expressions.k @@ -4,13 +4,18 @@ module ELABORATION-EXPRESSIONS imports ELABORATION-CORE imports PRIMITIVE-TYPES -/*@ \subsection{Elaboration of numeric expressions} +/*@ \subsection{Numeric, boolean and String operators} Expression labels are not converted by the default rule in the phase \verb|elabDispose()| => \verb|elabRes(...)| Each expression needs a specialized rule for disposing, that will compute, among others, the type of the expression. */ +rule [elabEnd-BoolResultBinaryExp]: + elabEnd(KL:KLabel(TE1:K,, TE2:K)) => elabRes(cast(bool, KL(TE1,,TE2))) +when + isBoolResultBinaryExpLabel(KL) ==K true + syntax KItem ::= isBoolResultBinaryExpLabel ( KLabel ) [function] rule isBoolResultBinaryExpLabel('LazyOr) => true rule isBoolResultBinaryExpLabel('LazyAnd) => true @@ -21,11 +26,6 @@ rule isBoolResultBinaryExpLabel('Gt) => true rule isBoolResultBinaryExpLabel('LtEq) => true rule isBoolResultBinaryExpLabel('GtEq) => true -rule [elabEnd-BoolResultBinaryExp]: - elabEnd(KL:KLabel(TE1:K,, TE2:K)) => elabRes(cast(bool, KL(TE1,,TE2))) -when - isBoolResultBinaryExpLabel(KL) ==K true - rule [elabEnd-BoolOnlyResultExp-unary]: elabEnd('Not(TE:K)) => elabRes(cast(bool,'Not(TE))) @@ -71,6 +71,15 @@ rule [elabEnd-StringPlusAny]: when typeOf(TE1) ==K classString orBool typeOf(TE2) ==K classString +/*@ Heats the second argument, that is reduced into a type. + The whole expression is then rewritten into elabRes(cast(SecondArgAsType, FirstArg)) + We cannot eliminate this wrapper because the second argument in all usage places is not a function. +*/ +syntax KItem ::= elabExpAndType ( K, K ) [strict(2)] +rule elabExpAndType(K:K, T:Type) => elabRes(cast(T, K)) + +/*@ \subsection{Conditional operator}*/ + rule [elabEnd-Cond]: elabEnd('Cond(CondTE:K,, TE1:K,, TE2:K)) => elabExpAndType('Cond(CondTE,, TE1,, TE2), condType(typeOf(TE1), typeOf(TE2))) @@ -93,12 +102,7 @@ when rule [condType-FirstChar]: condType(char, T2:Type) => ifAux(subtype(char, T2), T2, int) -/*@ Heats the second argument, that is reduced into a type. - The whole expression is then rewritten into elabRes(cast(SecondArgAsType, FirstArg)) - We cannot eliminate this wrapper because the second argument in all usage places is not a function. -*/ -syntax KItem ::= elabExpAndType ( K, K ) [strict(2)] -rule elabExpAndType(K:K, T:Type) => elabRes(cast(T, K)) +/*@ \subsection{Assignment operator}*/ rule [elabEnd-Assign-SameType]: elabEnd('Assign(cast(T1:Type, Exp1:K),, TExp2:K)) => elabRes(cast(T1, 'Assign(Exp1,, TExp2))) @@ -114,6 +118,9 @@ when // elabEnd(KL:KLabel(cast(T1:Type, Exp1:K),, TE2:K)) => elabRes(cast(T1, KL(Exp1,, TE2))) //when // isCompoundAssignExp(KL(.KList)) ==K true + +/*@ \subsection{Cast operator} */ + rule elabEnd(cast(T1:Type, Exp1:K) *= TE2:K) => elabRes(cast(T1, Exp1 *= TE2)) rule elabEnd(cast(T1:Type, Exp1:K) /= TE2:K) => elabRes(cast(T1, Exp1 /= TE2)) rule elabEnd(cast(T1:Type, Exp1:K) %= TE2:K) => elabRes(cast(T1, Exp1 %= TE2)) @@ -126,8 +133,6 @@ rule elabEnd(cast(T1:Type, Exp1:K) &= TE2:K) => elabRes(cast(T1, Exp1 &= TE2)) rule elabEnd(cast(T1:Type, Exp1:K) ^= TE2:K) => elabRes(cast(T1, Exp1 ^= TE2)) rule elabEnd(cast(T1:Type, Exp1:K) |= TE2:K) => elabRes(cast(T1, Exp1 |= TE2)) -/*@ \subsection{Elaboration of non-numeric expressions} */ - //@ elab cast rule elabEnd('CastPrim(T:Type,, TExp:K) => cast(T, TExp)) [structural] rule elabEnd('CastRef(T:Type,, TExp:K) => cast(T, TExp)) [structural] @@ -135,13 +140,11 @@ rule elabEnd('CastRef(T:Type,, TExp:K) => cast(T, TExp)) [structural] rule [elabEnd-cast]: elabEnd(cast(T1:Type, TExp:K)) => elabRes(cast(T1, TExp)) -/*@ \subsubsection{Elaboration of class instanceof} */ +/*@ \subsection{Expressions over reference types} */ rule [elabEnd-InstanceOf]: elabEnd('InstanceOf(TExp:K,, RT2:RefType)) => elabRes(cast(bool, 'InstanceOf(TExp,, RT2))) -/*@ \subsubsection{Elaboration of class literals} */ - //@ Class literal types are heated by this rule. context elab('Lit('Class(HOLE))) diff --git a/src/prep/elaboration-method-invoke.k b/src/prep/elaboration-method-invoke.k index 41dea0c5..c49ad7f6 100644 --- a/src/prep/elaboration-method-invoke.k +++ b/src/prep/elaboration-method-invoke.k @@ -4,6 +4,8 @@ module ELABORATION-METHOD-INVOKE imports SUBTYPING imports ELABORATION-CORE +//@ \subsection{Regular method calls} + rule customElabEnd('Method) => true rule elabEnd('Method(Qual:K,, _:K,, Name:Id)) => elabEnd('Method('MethodName(Qual,, Name))) [structural] @@ -56,7 +58,7 @@ rule containsName((sig(Name, _) |-> _) _:Map, Name:Id) => true rule [elabEnd-findQualifierForName-static]: findQualifierForName(noClass, K:K) => noValue -// 'SuperMethod(_:K,, Name:Id) +//@ \subsection{Superclass method calls: \texttt{super.m()}} rule customElabEnd('SuperMethod) => true @@ -114,6 +116,8 @@ rule getLookupTargetType(arrayOf _) => classArrayImpl syntax KItem ::= isCastOfQThis ( K ) [function] rule isCastOfQThis(cast(_, 'QThis(_))) => true +//@ \subsection{Method reference lookup} + /*@ Lookup the right methodRef() based on supplied parameters. If the method is not found in the supplied class list, we should search for it in the class list corresponding to the enclosing class of the caller class. @@ -240,6 +244,8 @@ rule [methodProcessArguments-Invoke-end]: ) ) +//@ \subsection{Method signature lookup} + /*Search for the correct method signature to use when calling a given MethodName with the given argument types. computes mapWrap(Sig -> MethodTV)*/ @@ -304,8 +310,12 @@ when rule [lookupSignature-End]: lookupSignature(_,_, .Map,_, MethodRef:MethodRef, _) => MethodRef +//@ \subsection{Method accessibility check} +//@ Interaction between overloading and access modes. +//@ + /*@ Tests whether a method from a given class with a given AccessMode and ContextType -may be called from the current object environment*/ +may be called from the current object environment.*/ syntax KItem ::= isAccessible ( AccessMode, //the method access mode K, //evaluates to ContextType - staticCT or instanceCT diff --git a/src/prep/elaboration-new-instance.k b/src/prep/elaboration-new-instance.k index dbc336da..c3d6a57f 100644 --- a/src/prep/elaboration-new-instance.k +++ b/src/prep/elaboration-new-instance.k @@ -7,8 +7,6 @@ module ELABORATION-NEW-INSTANCE imports ELABORATION-METHOD-INVOKE // for lookupMethod, methodLookupResult imports PROCESS-LOCAL-CLASSES //for localClassGetExtraArgs -/*@ \subsubsection{Elaboration of 'NewInstance and 'QNewInstance} */ - /*@ elab('NewInstance()) is strict in arguments 2 and 3 --- class name and constrctor arguments. Constrctor arguments have to be heated if this class is anonymous. */ diff --git a/src/prep/elaboration-statements.k b/src/prep/elaboration-statements.k index 94aae278..54379cd3 100644 --- a/src/prep/elaboration-statements.k +++ b/src/prep/elaboration-statements.k @@ -4,6 +4,12 @@ module ELABORATION-STATEMENTS imports ELABORATION-METHOD-INVOKE //for lookupMethod imports PROCESS-LOCAL-CLASSES //for localClassGetExtraArgs +/*@ Only statements that need custom treatment during elaboration are included here. Most statements are elaborated by +generic rules. +*/ + +//@ \subsection{Statements for, block and catch} + //@ Elaboration of 'KListWrap, 'Block, 'For or 'Catch --- nodes that may contain variable declarations. //K bug: support for KListWrap. This rule was replaced by a special section for elaboration of KListWrap. @@ -42,7 +48,18 @@ rule [elabEnd-Block-For-Catch]: when isVarDecHolderLabel(KL) ==K true -//@ Local var declarations desugaring +/*@ \subsection{Elaboration of catch parameters}*/ + +//@ Elaborate parameter type, if not elaborated yet. For catch clause. +context elab('Param(_:K,, HOLE,, _:Id)) + +/*@Adds params to the \verb||. Used in both ELABORATION-TOP-BLOCKS and ELABORATION-BLOCKS +*/ +rule [elab-Param]: + elab('Param(K1:K,, T:Type,, X:Id)) => elabRes('Param(K1:K,, T:Type,, X:Id)) ... + ListItem(mapWrap((. => X |-> T) _)) ... + +//@ \subsection{Local variable declarations} rule [elab-LocalVarDecStm-desugar]: elab('LocalVarDecStm('LocalVarDec(Ks:KList)) @@ -74,7 +91,7 @@ rule [elab-LocalVarDec]: ListItem(mapWrap((. => X |-> T) _)) ... -//@\subsection{Elaboration of SuperConstrInv, QSuperConstrInv, AltConstrInv} +//@\subsection{Explicit constructor invocations --- \texttt{this()}, \texttt{super()}, \texttt{A.super()}} // 'SuperConstrInv( _:K,, [ Args:KList ] ) //@ Desugaring unqualified superclass constructor invocation into a qualified one diff --git a/src/prep/elaboration-top-blocks.k b/src/prep/elaboration-top-blocks.k index 7aafe20a..768d9777 100644 --- a/src/prep/elaboration-top-blocks.k +++ b/src/prep/elaboration-top-blocks.k @@ -1,11 +1,12 @@ -/*@ This module initialtes the elaboration phase. It is responsible for elaborating all top-level code blocks - in the program: methods, constructors, static and instance initializers. -*/ module ELABORATION-TOP-BLOCKS imports CORE-SORTS imports CORE-PREPROCESSING imports ELABORATION-CORE +/*@ This module initiates the elaboration phase. It is responsible for elaborating all top-level code blocks + in the program: methods, constructors, static and instance initializers. +*/ + rule [ElaborationPhase-start]: . => elaborateBlocks(getTopLevelClasses) ProcClassMembersPhase => ElaborationPhase diff --git a/src/prep/elaboration-types.k b/src/prep/elaboration-types.k index 7d41a2aa..da93a741 100644 --- a/src/prep/elaboration-types.k +++ b/src/prep/elaboration-types.k @@ -6,8 +6,6 @@ module ELABORATION-TYPES imports ELABORATION-CORE imports PROCESS-TYPE-NAMES // for getNamesMap() -/*@ \subsection{Elaboration of types} */ - rule 'ClassOrInterfaceType(TypeK:K,, _) => TypeK [structural] rule 'InterfaceType(TypeK:K,, _) => TypeK [structural] rule 'ClassType(TypeK:K,, _) => TypeK [structural] diff --git a/src/prep/elaboration-vars.k b/src/prep/elaboration-vars.k index 66839003..01df1268 100644 --- a/src/prep/elaboration-vars.k +++ b/src/prep/elaboration-vars.k @@ -3,10 +3,13 @@ module ELABORATION-VARS imports ELABORATION-CORE //@ Elaboration of terms defined in var-lookup.k +//@ //@ Both unqualified and qualified AmbName. rule [elabEnd-AmbName]: elabEnd('AmbName(Ks:KList)) => elabEnd('ExprName(Ks)) ?? 'TypeName(Ks) ?? 'PackageName([Ks]) +//@ \subsection{Unqualified variable references} + rule [elabEnd-ExprName-localVar-ok]: elabEnd('ExprName(X:Id)) => elabRes(cast(T, 'ExprName(X))) ... ListItem(mapWrap(X |-> T:Type _)) ... @@ -70,6 +73,22 @@ rule [elabOuterLocalVar-not-found]: when notBool X in keys(EnclosingLocalEnv) +//@ \subsection{Self-references: \texttt{this} and \texttt{A.this}} + +rule [elabEnd-This]: + elabEnd('This(.KList) => 'QThis(Class)) ... + Class:ClassType + +rule [elabEnd-QThis-InstanceCT]: + elabEnd('QThis(Class:ClassType)) => elabRes(cast(Class, 'QThis(Class))) ... + instanceCT + +rule [elabEnd-QThis-StaticCT]: + elabEnd('QThis(_)) => noValue ... + staticCT + +//@ \subsection{Fields} + rule [elabEnd-ExprName-qualified]: elabEnd('ExprName(QualK:K,,X:Id)) => elabEnd('Field(QualK,,X)) @@ -79,7 +98,13 @@ rule [elabEnd-Field-of-package]: rule [elabEnd-Field-of-noValue]: elabEnd('Field( noValue,, _:Id )) => noValue [structural] -//@Computation of instance and static environment of a class, e.g. set of fields +rule [elabEnd-Field-QualRef]: + elabEnd('Field(cast(Class:ClassType, Qual:K),, X:Id)) + => elabFieldImpl(cast(Class, Qual), elabLookup(X, Class)) + +rule [elabEnd-Field-QualClass]: + elabEnd('Field(Class:ClassType,, X:Id)) + => elabFieldImpl(noValue, elabLookup(X, Class)) /*@ Searches the given field name in the given type (set of types), both static and instance context. @@ -150,26 +175,6 @@ syntax KItem ::= nameInVarDecs( rule nameInVarDecs(X:Id, [_,, _:KLabel(.K,, T:Type,, ['VarDec(X)]),, _]) => true -rule [elabEnd-This]: - elabEnd('This(.KList) => 'QThis(Class)) ... - Class:ClassType - -rule [elabEnd-QThis-InstanceCT]: - elabEnd('QThis(Class:ClassType)) => elabRes(cast(Class, 'QThis(Class))) ... - instanceCT - -rule [elabEnd-QThis-StaticCT]: - elabEnd('QThis(_)) => noValue ... - staticCT - -rule [elabEnd-Field-QualRef]: - elabEnd('Field(cast(Class:ClassType, Qual:K),, X:Id)) - => elabFieldImpl(cast(Class, Qual), elabLookup(X, Class)) - -rule [elabEnd-Field-QualClass]: - elabEnd('Field(Class:ClassType,, X:Id)) - => elabFieldImpl(noValue, elabLookup(X, Class)) - // 'SuperField(X:Id) rule [elabEnd-SuperField]: diff --git a/src/prep/process-class-decs.k b/src/prep/process-class-decs.k index 201fef3d..2ad8f873 100644 --- a/src/prep/process-class-decs.k +++ b/src/prep/process-class-decs.k @@ -13,6 +13,8 @@ syntax KItem ::= processClassDecs ( ) [strict] +/*@ \subsection{Initiate the resolving of class bases}*/ + /*@ Question: how do we know if bases were already resolved for this class or not? Answer: When \verb|resolveBases(Class)| is consumed by the rule [resolveBasesEnd], the class changes its state: StoredCPhase => BasesResolvedCPhase @@ -58,7 +60,9 @@ rule [processClassDecs-resolveBases-Inner-Start]: when OuterClassPhase ==K DecsProcessedCPhase orBool OuterClassPhase ==K MembersProcessedCPhase -//@ Process the given class from StoredCPhase to BasesResolvedCPhase. +/*@ \subsection{Resolve bases}*/ + +//@ Process the given class from StoredCPhase to BasesResolvedCPhase. Resolve the base class (arg 2) and interfaces (arg 3) of a class (arg 1). syntax KItem ::= resolveBases ( ClassType, //The class for which we resolve bases K, //Base class @@ -77,6 +81,8 @@ rule [resolveBases]: StoredCPhase => BasesResolvedCPhase when isKResult(ImplTypes) +/*@ \subsection{Processing after bases were resolved}*/ + rule [processClassDecs-mark-Base-Processed]: processClassDecs(_) ... @@ -133,6 +139,8 @@ rule [saveImplements]: Class .Set => ImplSet +/*@ \subsection{Computing imports map}*/ + /*@ Computes the full names map used to resolve classes by simple name inside the class specified by the arg 4, and stores them inside \verb||.*/ diff --git a/src/prep/process-class-members.k b/src/prep/process-class-members.k index d377c1fe..90693610 100644 --- a/src/prep/process-class-members.k +++ b/src/prep/process-class-members.k @@ -3,8 +3,6 @@ module PROCESS-CLASS-MEMBERS imports CORE-CLASSES imports CORE-PREPROCESSING -/*@ \subsection{General rules} */ - /*@ We need to process Object first. Thus when we will process any interfaces, Object class will already be processed.*/ rule [Start-ProcClassMembersPhase]: @@ -16,6 +14,8 @@ syntax KItem ::= processClasses ( ) [strict] +/*@ \subsection{Triggering the processing of depending types} */ + rule [processClasses]: (. => processTypeWithDepends(Class)) ~> processClasses(setWrap( (SetItem(Class:ClassType) => .) _:Set)) @@ -48,6 +48,8 @@ rule [processTypeWithDepends-Discard]: rule [processTypeWithDepends-Discard2]: processTypeWithDepends(noClass) => .K +/*@ \subsection{Initiating class processing} */ + /*@ \begin{markdown} For each class computes the set of inherited interfaces, inherits all the members, @@ -106,6 +108,8 @@ rule [processType-discard]: Class MembersProcessedCPhase +/*@ \subsection{Inheriting base types} */ + //@ Compute \verb|| cell --- interfaces transitively implemented syntax KItem ::= computeImplTrans ( Set ) @@ -323,6 +327,7 @@ rule [storeMethod-discard-default-constructor]: Class ... Sig |-> _ ... +/*@ \subsection{Constructor declarations}*/ rule [ConstrDec-SuperCall-Desugar]: @@ -385,7 +390,7 @@ rule [ConstrDec]: Class:ClassType when paramTypesResolved([Params]) -//@ \subsection{Fields and initializers} +//@ \subsection{Instance fields and instance initializers} // 'FieldDec(Modifiers:K,, T:Type,, ['VarDec(X:Id,, InitExp:K),, _]) @@ -421,6 +426,21 @@ rule [InstanceInit]: [_,,(.KList => K)] [structural] +syntax KItem ::= "convertInstanceInitIntoMethod" + +rule [convertInstanceInitIntoMethod]: + + convertInstanceInitIntoMethod + => storeMethod([.KList], instanceCT, private, false::bool, methodMMT, noValue, 'Block([InstanceInitKs]), + sig(String2Id("$instance_init"), types(.KList)), void) + ... + + Class:ClassType + Class + ( [InstanceInitKs:KList] => .Bag) + +//@ \subsection{Static fields and static initializers} + /*@ Desugaring a static field declaration with initializer into a declaration without initializer. Followed by a static initializer block, if this field is not a compile-time constant.*/ rule [FieldDec-StaticInit-Desugar]: @@ -486,26 +506,15 @@ when getContextType(Modifiers) ==K staticCT andBool isFinalModifiers(Modifiers) +/*@\subsection{Other members}*/ + /*@ Discard inner class declarations at this phase. They are processed when their respective \verb|| tag is encountered as part of processClasses. */ rule [ClassDec-discard]: 'ClassDec(_) => . rule [InterfaceDec-discard]: 'InterfaceDec(_) => . -syntax KItem ::= "convertInstanceInitIntoMethod" - -rule [convertInstanceInitIntoMethod]: - - convertInstanceInitIntoMethod - => storeMethod([.KList], instanceCT, private, false::bool, methodMMT, noValue, 'Block([InstanceInitKs]), - sig(String2Id("$instance_init"), types(.KList)), void) - ... - - Class:ClassType - Class - ( [InstanceInitKs:KList] => .Bag) - -//@ \subsection{Auxiliary functions} +//@ \subsection{Functions for acceessing member modifiers} //@ Evaluates to true::bool if synchronized is among modifiers, false otherwise syntax KItem ::= isSynchronizedModifiers ( diff --git a/src/prep/process-comp-units.k b/src/prep/process-comp-units.k index abb5f960..6939a006 100644 --- a/src/prep/process-comp-units.k +++ b/src/prep/process-comp-units.k @@ -23,7 +23,7 @@ rule [ProcCompUnitsPhase-start]: ( Program:K => .) ProcTypeNamesPhase => ProcCompUnitsPhase -//ImpDecs will be processed in the module PROCESS-IMPORTS +//@ Import declarations are processed in the module PROCESS-IMPORTS rule [CompilationUnit]: 'CompilationUnit('Some('PackageDec(_:K,, Pack:PackageId)),, @@ -54,8 +54,6 @@ rule [processTypeDecsInPCUPhase-ElemDiscard]: processTypeDecsInPCUPhase([Label:KLabel(_)], _,_) => . when notBool( Label ==KLabel 'ClassDec orBool Label ==KLabel 'InterfaceDec ) -/*@ \subsection{Class declaration processing}*/ - rule [processTypeDecsInPCUPhase-typeDec-ComputeFullName]: processTypeDecsInPCUPhase( [KL:KLabel(_:KLabel(_:K,, (SimpleClass:Id => getClassType(Pack,SimpleClass)),, _:KList),, _)], diff --git a/src/prep/process-type-names.k b/src/prep/process-type-names.k index dedebe1d..1d4559ce 100644 --- a/src/prep/process-type-names.k +++ b/src/prep/process-type-names.k @@ -33,7 +33,7 @@ rule [CompilationUnit]: ProcTypeNamesPhase -/*@ \subsection{Packages}*/ +/*@ \subsection{Package declarations}*/ // 'PackageName([Ks]) diff --git a/src/sty/k-java.tex b/src/sty/k-java.tex index e91d3361..ef54a95f 100644 --- a/src/sty/k-java.tex +++ b/src/sty/k-java.tex @@ -38,7 +38,6 @@ \chapter{K-Java Dynamic semantics} \input{../.modules/method-invoke-rest.tex} \input{../.modules/static-init.tex} \input{../.modules/api-core.tex} -\input{../.modules/api-threads-selection.tex} \input{../.modules/api-threads.tex} \input{../.modules/unfolding.tex} \input{../.modules/to-string.tex} @@ -55,8 +54,8 @@ \chapter{K-Java Static semantics} \input{../.modules/process-class-members.tex} \input{../.modules/elaboration-core.tex} \input{../.modules/elaboration-top-blocks.tex} -\input{../.modules/elaboration-types.tex} \input{../.modules/elaboration-statements.tex} +\input{../.modules/elaboration-types.tex} \input{../.modules/elaboration-expressions.tex} \input{../.modules/elaboration-vars.tex} \input{../.modules/elaboration-method-invoke.tex} From 54b1c0123ffbbb1e91b7f95497bc1f7f6b8b3040 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Thu, 12 Mar 2015 21:56:24 +0200 Subject: [PATCH 39/43] Bugfix: fixed (hopefully) the last problems with failing tests. --- src/common/stmt-syntax.k | 3 ++- src/exec/statements.k | 28 +++++++++++++++++----------- src/exec/to-string.k | 6 +++--- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/common/stmt-syntax.k b/src/common/stmt-syntax.k index 4eb2a20f..94d6326d 100644 --- a/src/common/stmt-syntax.k +++ b/src/common/stmt-syntax.k @@ -28,8 +28,9 @@ syntax StmtWithoutTrailing ::= Block | TryStmt | StackConsumerStmt | SynchronizedStmt + | ThrowStmt -syntax StackConsumerStmt ::= ThrowStmt | ContinueStmt | BreakStmt | ReturnStmt +syntax StackConsumerStmt ::= ContinueStmt | BreakStmt | ReturnStmt syntax IfThenElseStmt ::= "if" "(" Exp ")" Stmt "else" Stmt [strict(1), klabel('If)] syntax IfThenStmt ::= "if" "(" Exp ")" Stmt [prefer, klabel('If)] diff --git a/src/exec/statements.k b/src/exec/statements.k index 4e36a63f..d60128fd 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -198,17 +198,6 @@ rule [For]: => 'Block(stm(InitClause) ~> ifAux(TestExp, ('Block(S) ~> whileImpl(stm(UpdClause) ~> TestExp,S)), .K)) [structural] -//totest model check - the argument of 'return and 'Throw must be evaluated. Otherwise some side effects during -// evaluation might be evaluated too late -/*@ Stack consumer stm - Return, Throw, Break or Continue reaches tryFinallySL layer*/ -rule [StackConsumerStmt-in-TryFinally]: - StackCons:StackConsumerStmt ~> finallyBlock(FinallyS:K) - => FinallyS ~> StackCons - -rule [StackConsumerStmt-RestoreEnv]: - StackCons:StackConsumerStmt ~> env(Env:Map) - => env(Env:Map) ~> StackCons - //@ \subsection{Break statement} /*K limitation: Looks like neither 'None nor 'Some can be expressed syntactically. @@ -400,4 +389,21 @@ syntax KItem ::= finallyBlock ( K ) //arg - finally block rule [finallyBlock-NormalEnd]: finallyBlock(FinallyS:K) => FinallyS +/*@ Only a throw with its value computed is stack consumer, not any throw. If we'll define any throw to be +StackConsumerStmt, then we'll get rare problems with ExceptionInInitializerError. +Other values for StackConsumerStmt are defined in the syntax. +*/ +rule isStackConsumerStmt(throw _:TypedVal;) => true + +//totest model check - the argument of 'return and 'Throw must be evaluated. Otherwise some side effects during +// evaluation might be evaluated too late +/*@ Stack consumer stm - Return, Throw, Break or Continue reaches tryFinallySL layer*/ +rule [StackConsumerStmt-in-TryFinally]: + StackCons:StackConsumerStmt ~> finallyBlock(FinallyS:K) + => FinallyS ~> StackCons + +rule [StackConsumerStmt-RestoreEnv]: + StackCons:StackConsumerStmt ~> env(Env:Map) + => env(Env:Map) ~> StackCons + endmodule diff --git a/src/exec/to-string.k b/src/exec/to-string.k index 143f2276..dde96f60 100644 --- a/src/exec/to-string.k +++ b/src/exec/to-string.k @@ -68,9 +68,9 @@ rule toString(objectRef(OId:Int, LowestClass:ClassType) :: T:Type) //@ \subsection{Debug helper functions} -syntax KItem ::= debugPrint ( K ) [strict] -rule debugPrint(Str:String::_) => . ... - ... . => ListItem(Str +String "\n") +syntax KItem ::= debugPrint ( K ) +rule debugPrint(K:K) => . ... + ... . => ListItem(K) syntax KItem ::= debugString( K ) [function] | debugStringList( KListWrap ) [function] From 5c099056225e24fef274a6c3115c7a513866c296 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Fri, 13 Mar 2015 10:46:19 +0200 Subject: [PATCH 40/43] Latex: Reviewed the order of modules. --- src/sty/k-java.tex | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sty/k-java.tex b/src/sty/k-java.tex index ef54a95f..fddea688 100644 --- a/src/sty/k-java.tex +++ b/src/sty/k-java.tex @@ -14,22 +14,13 @@ \tableofcontents -\chapter{K-Java Common modules} - -\input{../.modules/core-sorts.tex} -\input{../.modules/core-functions.tex} -\input{../.modules/core-classes.tex} -\input{../.modules/primitive-types.tex} -\input{../.modules/subtyping.tex} -\input{../.modules/aux-strings.tex} - \chapter{K-Java Dynamic semantics} \input{../.modules/configuration-exec.tex} -\input{../.modules/core-exec.tex} \input{../.modules/expressions.tex} \input{../.modules/expressions-classes.tex} \input{../.modules/statements.tex} +\input{../.modules/core-exec.tex} \input{../.modules/var-lookup.tex} \input{../.modules/arrays.tex} \input{../.modules/new-instance.tex} @@ -43,15 +34,24 @@ \chapter{K-Java Dynamic semantics} \input{../.modules/to-string.tex} \input{../.modules/syntax-conversions.tex} +\chapter{K-Java Common modules} + +\input{../.modules/core-sorts.tex} +\input{../.modules/core-functions.tex} +\input{../.modules/core-classes.tex} +\input{../.modules/primitive-types.tex} +\input{../.modules/subtyping.tex} +\input{../.modules/aux-strings.tex} + \chapter{K-Java Static semantics} \input{../.modules/configuration-prep.tex} -\input{../.modules/core-preprocessing.tex} \input{../.modules/process-type-names.tex} \input{../.modules/process-comp-units.tex} \input{../.modules/process-imports.tex} \input{../.modules/process-class-decs.tex} \input{../.modules/process-class-members.tex} +\input{../.modules/core-preprocessing.tex} \input{../.modules/elaboration-core.tex} \input{../.modules/elaboration-top-blocks.tex} \input{../.modules/elaboration-statements.tex} From 9a3eed9900cf417607d5bd3c174034a8e334820a Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Fri, 13 Mar 2015 15:07:50 +0200 Subject: [PATCH 41/43] Latex: Fixed paragraph rendering in various places. Now we have par indentation, justification and 0 bad boxes. --- src/common/class-syntax.k | 14 +++++++------- src/common/exp-syntax.k | 22 +++++++++++----------- src/common/interface-syntax.k | 10 +++++----- src/common/lexical-syntax.k | 6 +++--- src/common/literal-syntax.k | 14 +++++++------- src/common/stmt-syntax.k | 6 +++--- src/common/type-syntax.k | 8 ++++---- src/exec/method-invoke.k | 2 +- src/sty/custom-commands.tex | 20 ++++++++++++++++++-- 9 files changed, 59 insertions(+), 43 deletions(-) diff --git a/src/common/class-syntax.k b/src/common/class-syntax.k index 098982d8..611f488c 100644 --- a/src/common/class-syntax.k +++ b/src/common/class-syntax.k @@ -1,7 +1,7 @@ module CLASS-SYNTAX imports EXP-SYNTAX -//@ \paragraph{ClassDeclarations} +//@ \subsubsection{ClassDeclarations} syntax ClassDecHead ::= AnnoClassModList "class" Id OptionalTypeParams OptionalSuper OptionalInterfaces [klabel('ClassDecHead)] @@ -34,7 +34,7 @@ syntax InterfaceDec syntax SemiColon ::= ";" [klabel('SemiColon)] -//@ \paragraph{ConstructorDeclarations} +//@ \subsubsection{ConstructorDeclarations} syntax ConstrHead ::= AnnoConstrModList OptionalTypeParams Type Id "(" Params ")" OptionalThrows [klabel('ConstrDecHead)] @@ -53,7 +53,7 @@ syntax ConstrMod ::= Public syntax AnnoConstrMod ::= Anno | ConstrMod -//@ \paragraph{EnumDeclarations} +//@ \subsubsection{EnumDeclarations} syntax EnumDecHead ::= AnnoClassModList "enum" Id OptionalInterfaces [klabel('EnumDecHead)] /* Java allows , at the end of List. @@ -71,7 +71,7 @@ syntax EnumConstArgs ::= "(" Exps ")" [bracket syntax EnumBodyDecs ::= ";" ClassBodyDecList [klabel('EnumBodyDecs)] -//@ \paragraph{FieldDeclarations} +//@ \subsubsection{FieldDeclarations} syntax FieldDec ::= AnnoFieldModList Type VarDecList ";" [klabel('FieldDec)] syntax VarDec ::= VarDecId [klabel('VarDec)] @@ -92,7 +92,7 @@ syntax FieldMod ::= Public syntax AnnoFieldMod ::= Anno | FieldMod -//@ \paragraph{MethodDeclarations} +//@ \subsubsection{MethodDeclarations} syntax MethodDecHead ::= AnnoMethodModList OptionalTypeParams Type Id "(" Params ")" OptionalThrows [klabel('MethodDecHead)] @@ -123,11 +123,11 @@ syntax VarMod ::= Final syntax AnnoVarMod ::= Anno | VarMod -//@ \paragraph{InstanceInitializers} +//@ \subsubsection{InstanceInitializers} syntax InstanceInit ::= Block [klabel('InstanceInit)] -//@ \paragraph{StaticInitializers} +//@ \subsubsection{StaticInitializers} syntax StaticInit ::= "static" Block [klabel('StaticInit)] syntax Block diff --git a/src/common/exp-syntax.k b/src/common/exp-syntax.k index 814c15b7..03166469 100644 --- a/src/common/exp-syntax.k +++ b/src/common/exp-syntax.k @@ -4,7 +4,7 @@ module EXP-SYNTAX syntax Exp ::= StmtExp syntax StmtExp ::= PrefixPostfixExp | AssignExp | MethodInvokeExp | ClassInstanceCreationExp -//@ \paragraph{MethodInvocation} +//@ \subsubsection{MethodInvocation} syntax MethodInvokeExp ::= MethodSpec "(" Exps ")" [klabel('Invoke)] syntax MethodSpec ::= MethodName [klabel('Method)] | Exp "." OptionalTypeArgs Id [klabel('Method)] @@ -13,7 +13,7 @@ syntax MethodSpec ::= MethodName [klabel( | AmbName "." TypeArgs Id [klabel('GenericMethod)] -//@ \paragraph{ClassInstanceCreation} +//@ \subsubsection{ClassInstanceCreation} syntax ClassInstanceCreationExp ::= "new" OptionalTypeArgs ClassOrInterfaceType "(" Exps ")" OptionalClassBody [klabel('NewInstance)] @@ -22,7 +22,7 @@ syntax ClassInstanceCreationExp ::= [klabel('QNewInstance)] -//@ \paragraph{AssignmentOperators} +//@ \subsubsection{AssignmentOperators} syntax LHS ::= ExprName | FieldAccess | ArrayAccess syntax Exp ::= LHS @@ -42,7 +42,7 @@ syntax CompoundAssignExp ::= LHS "*=" Exp [klabel(' | LHS "|=" Exp [klabel('AssignOr)] -//@ \paragraph{UnaryOperators} +//@ \subsubsection{UnaryOperators} syntax Exp ::= "(" PrimType ")" Exp [klabel('CastPrim)] syntax Exp ::= "(" RefType ")" Exp [klabel('CastRef)] @@ -55,12 +55,12 @@ syntax PrefixPostfixExp ::= "++" Exp [klabel('PreIncr)] | "--" Exp [klabel('PreDecr)] -//@ \paragraph{Postfix} +//@ \subsubsection{Postfix} syntax PrefixPostfixExp ::= Exp "++" [klabel('PostIncr)] | Exp "--" [klabel('PostDecr)] -//@ \paragraph{BinaryOperators} +//@ \subsubsection{BinaryOperators} syntax Exp ::= Exp "*" Exp [seqstrict, klabel('Mul)] | Exp "/" Exp [seqstrict, klabel('Div)] | Exp "%" Exp [seqstrict, klabel('Remain)] @@ -86,18 +86,18 @@ syntax Exp ::= Exp "?" Exp ":" Exp [klabel('Cond)] syntax Exp ::= Exp "instanceof" RefType [strict, klabel('InstanceOf)] -//@ \paragraph{FieldAccess} +//@ \subsubsection{FieldAccess} syntax FieldAccess ::= Exp "." Id [klabel('Field)] | "super" "." Id [klabel('SuperField)] | TypeName "." "super" "." Id [klabel('QSuperField)] -//@ \paragraph{ArrayAccess} +//@ \subsubsection{ArrayAccess} //syntax ArraySubscript ::= "[" Exp "]" [bracket] syntax ArrayAccess ::= Exp "[" Exp "]" [seqstrict, klabel('ArrayAccess)] -//@ \paragraph{ArrayCreation} +//@ \subsubsection{ArrayCreation} /* Either 'NewArray( T:ElemType,, ['Dim(N1),,'Dim('N2),, ...],, [...,, 'Dim(.KList),, ...] ) Or 'NewArray( T:ElemType,, [...,, 'Dim(.KList),, ...],, 'ArrayInit(_) ) */ @@ -115,12 +115,12 @@ syntax Dim ::= "[" "]" [klabel('Dim syntax DimExp ::= "[" Exp "]" [strict, hybrid, klabel('Dim)] -//@ \paragraph{ArrayInitializers} +//@ \subsubsection{ArrayInitializers} syntax ArrayInit ::= "{" VarInits "}" [klabel('ArrayInit)] syntax ArrayInit ::= "{" VarInits "," "}" [klabel('ArrayInit)] -//@ \paragraph{Primary} +//@ \subsubsection{Primary} syntax Exp ::= Literal [klabel('Lit)] syntax Literal ::= IntLiteral | FloatLiteral diff --git a/src/common/interface-syntax.k b/src/common/interface-syntax.k index 4bdb6a3c..e8ed32ed 100644 --- a/src/common/interface-syntax.k +++ b/src/common/interface-syntax.k @@ -1,7 +1,7 @@ module INTERFACE-SYNTAX imports CLASS-SYNTAX -//@ \paragraph{AbstractMethodDeclarations} +//@ \subsubsection{AbstractMethodDeclarations} syntax AbstractMethodDec ::= AnnoAbstractMethodModList OptionalTypeParams Type Id "(" Params ")" OptionalThrows ";" [klabel('AbstractMethodDec)] @@ -10,7 +10,7 @@ syntax AbstractMethodMod ::= Public | Abstract syntax AnnoAbstractMethodMod ::= Anno | AbstractMethodMod -//@ \paragraph{Annotations} +//@ \subsubsection{Annotations} syntax Anno ::= "@" TypeName "(" ElemValPairList ")" [klabel('Anno)] | "@" TypeName "(" ElemVal ")" [klabel('SingleElemAnno)] | "@" TypeName [klabel('MarkerAnno)] @@ -23,7 +23,7 @@ syntax ElemVal ::= Exp syntax ElemValPair ::= Id "=" ElemVal [klabel('ElemValPair)] -//@ \paragraph{AnnotationTypes} +//@ \subsubsection{AnnotationTypes} syntax AnnoDecHead ::= AnnoInterfaceModList "@" "interface" Id [klabel('AnnoDecHead)] syntax AnnoDec ::= AnnoDecHead "{" AnnoElemDecList "}" [klabel('AnnoDec)] @@ -35,7 +35,7 @@ syntax AnnoElemDec ::= AbstractMethodModList Type Id "(" ")" OptionalDefaultVal syntax DefaultVal ::= "default" ElemVal [klabel('DefaultVal)] -//@ \paragraph{ConstantDeclarations} +//@ \subsubsection{ConstantDeclarations} syntax ConstantDec ::= AnnoConstantModList Type VarDecList ";" [klabel('ConstantDec)] syntax ConstantMod ::= Public @@ -45,7 +45,7 @@ syntax ConstantMod ::= Public syntax AnnoConstantMod ::= Anno | ConstantMod -//@ \paragraph{InterfaceDeclarations} +//@ \subsubsection{InterfaceDeclarations} syntax InterfaceDecHead ::= AnnoInterfaceModList "interface" Id OptionalTypeParams OptionalExtendsInterfaces [klabel('InterfaceDecHead)] diff --git a/src/common/lexical-syntax.k b/src/common/lexical-syntax.k index 7d640b40..3cfd7254 100644 --- a/src/common/lexical-syntax.k +++ b/src/common/lexical-syntax.k @@ -1,16 +1,16 @@ module LEXICAL-SYNTAX -//@ \paragraph{Identifiers} +//@ \subsubsection{Identifiers} syntax Id ::= ID [klabel('Id)] syntax ID ::= Token{[A-Za-z\_\$][A-Za-z0-9\_\$]*} [onlyLabel] -//@ \paragraph{LineTerminators} +//@ \subsubsection{LineTerminators} syntax LineTerminator ::= Token{[\r]} [onlyLabel] | Token{[\n]} [onlyLabel] | Token{[\r][\n]} [onlyLabel] -//@ \paragraph{Modifiers} +//@ \subsubsection{Modifiers} syntax Public ::= "public" [klabel('Public)] syntax Private ::= "private" [klabel('Private)] syntax Protected ::= "protected" [klabel('Protected)] diff --git a/src/common/literal-syntax.k b/src/common/literal-syntax.k index 0882c8cd..36d3424c 100644 --- a/src/common/literal-syntax.k +++ b/src/common/literal-syntax.k @@ -2,13 +2,13 @@ module LITERAL-SYNTAX imports LEXICAL-SYNTAX imports LIST-SYNTAX -//@ \paragraph{BooleanLiterals} +//@ \subsubsection{BooleanLiterals} syntax BoolLiteral ::= Boolean [klabel('Bool)] syntax Boolean ::= "true" [onlyLabel, klabel('True)] syntax Boolean ::= "false" [onlyLabel, klabel('False)] -//@ \paragraph{CharacterLiterals} +//@ \subsubsection{CharacterLiterals} syntax CharContent ::= SingleChar [klabel('Single)] | UnicodeEscape @@ -17,7 +17,7 @@ syntax CharContent ::= SingleChar [klabel('Single)] syntax SingleChar syntax CharLiteral //::= "'" CharContent "'" [klabel('Char)] -//@ \paragraph{EscapeSequences} +//@ \subsubsection{EscapeSequences} syntax EscapeSeq ::= OctaEscape | NamedEscape syntax NamedEscape ::= Token{"\\" [btnfr\"\'\\]} [onlyLabel, klabel('NamedEscape)] @@ -27,11 +27,11 @@ syntax OctaEscape ::= Token{"\\" [0-7]} [onlyLabel, klabel('Oct | Token{"\\" [0-3][0-7][0-7]} [onlyLabel, klabel('OctaEscape3)] -//@ \paragraph{FloatingPointLiterals} +//@ \subsubsection{FloatingPointLiterals} syntax FloatLiteral ::= Float [klabel('Float)] -//@ \paragraph{IntegerLiterals} +//@ \subsubsection{IntegerLiterals} syntax DeciLiteral ::= Token{[1-9][0-9]* [lL]?} [onlyLabel] syntax HexaLiteral ::= Token{[0][xX][0-9a-fA-F]+ [lL]?} [onlyLabel] syntax OctaLiteral ::= Token{[0][0-7]+ [lL]?} [onlyLabel] @@ -41,11 +41,11 @@ syntax IntLiteral ::= DeciLiteral [klabel('Deci)] | OctaLiteral [klabel('Octa)] -//@ \paragraph{NullLiteral} +//@ \subsubsection{NullLiteral} syntax NullLiteral ::= "null" [klabel('Null)] -//@ \paragraph{StringLiterals} +//@ \subsubsection{StringLiterals} syntax StringLiteral ::= "\"" StringPartList "\"" [klabel('String)] syntax StringPart ::= StringChars [klabel('Chars)] diff --git a/src/common/stmt-syntax.k b/src/common/stmt-syntax.k index 94d6326d..fa690de1 100644 --- a/src/common/stmt-syntax.k +++ b/src/common/stmt-syntax.k @@ -1,17 +1,17 @@ module STMT-SYNTAX imports CLASS-SYNTAX -//@ \paragraph{Blocks} +//@ \subsubsection{Blocks} syntax BlockStmt ::= Stmt | LocalVarDecStmt | ClassDec [klabel('ClassDecStm)] syntax Block ::= "{" K "}" [klabel('Block)] //was BlockStmList before -//@ \paragraph{LocalVariableDeclaraions} +//@ \subsubsection{LocalVariableDeclaraions} syntax LocalVarDecStmt ::= LocalVarDec ";" [prefer, klabel('LocalVarDecStm)] syntax LocalVarDec ::= AnnoVarModList Type VarDecList [prefer, klabel('LocalVarDec)] -//@ \paragraph{Statements} +//@ \subsubsection{Statements} syntax Stmt ::= StmtWithoutTrailing | LabeledStmt | IfThenElseStmt diff --git a/src/common/type-syntax.k b/src/common/type-syntax.k index ea5f0edb..969f11b0 100644 --- a/src/common/type-syntax.k +++ b/src/common/type-syntax.k @@ -8,7 +8,7 @@ syntax Type ::= PrimType since now "void" is Type, there is no need for another syntax of ResultType.*/ | "void" [klabel('Void)] -//@ \paragraph{ParameterizedTypes} +//@ \subsubsection{ParameterizedTypes} syntax TypeArgs ::= "<" ActualTypeArgList ">" [klabel('TypeArgs)] syntax ActualTypeArg ::= Type @@ -18,7 +18,7 @@ syntax WildcardBound ::= "extends" RefType [klabel('WildcardUpperBo | "super" RefType [klabel('WildcardLowerBound)] -//@ \paragraph{PrimitiveTypes} +//@ \subsubsection{PrimitiveTypes} syntax IntOrLongType ::= "int" [klabel('Int)] | "long" [klabel('Long)] syntax IntType ::= "byte" [klabel('Byte)] @@ -33,7 +33,7 @@ syntax NumericType ::= IntType | FloatType syntax PrimType ::= NumericType | "bool" [klabel('Boolean)] //sdf "boolean" -//@ \paragraph{ReferenceTypes} +//@ \subsubsection{ReferenceTypes} syntax ClassOrInterfaceType ::= TypeDecSpec OptionalTypeArgs [klabel('ClassOrInterfaceType)] @@ -50,7 +50,7 @@ syntax ArrayType ::= Type "[" "]" [strict, klabel( syntax RefType ::= ClassOrInterfaceType | ArrayType -//@ \paragraph{TypeVariables} +//@ \subsubsection{TypeVariables} syntax TypeVarId ::= Id syntax TypeBound ::= "extends" ClassOrInterfaceTypeList [klabel('TypeBound)] diff --git a/src/exec/method-invoke.k b/src/exec/method-invoke.k index 9852f07c..94ba7d47 100644 --- a/src/exec/method-invoke.k +++ b/src/exec/method-invoke.k @@ -319,7 +319,7 @@ An instance method derivedM declared in a class Derived overrides another method The transitive rule for overriding relation (2b) is required specifically for package access mode. Consider the following example: \end{markdown} -\begin{minipage}{\textwidth} +\begin{minipage}{\textwidth-\parindent} \begin{lstlisting} package a; public class A { diff --git a/src/sty/custom-commands.tex b/src/sty/custom-commands.tex index 6497e9d1..dddf27d0 100644 --- a/src/sty/custom-commands.tex +++ b/src/sty/custom-commands.tex @@ -63,5 +63,21 @@ % Environment "kdefinition" have effect only in poster style, thus in math style may be safely deleted. -%Disable text justification, will eliminate overfulls inside text. -\raggedright + +%%% Rendering the paragraphs without overfull hbox-es. + +% v1. \raggedright, no parskip, vspace between paragraphs. +%Terrible solution. Both wanted and unwanted vertical spaces are increased. Empty pages appear. +%Document size increased by from 214 to 234 pages! +%\usepackage{parskip} %with \raggedright + +% v2. \raggedright + parindent. Zero bad boxes. +%\raggedright + +% Better than without. Just paragraph indentation. +%\setlength{\parindent}{2em} + +% v3. Best solution: \sloppy. Is enough for 0 bad boxes. +% Source: http://tex.stackexchange.com/questions/10377/texttt-overfull-hbox-problem +\setlength{\parindent}{2em} +\sloppy From 6fde26d03b3aeed91729007d093fb730d9db1ea4 Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Fri, 13 Mar 2015 15:47:43 +0200 Subject: [PATCH 42/43] Latex: One character fix. --- src/exec/statements.k | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/exec/statements.k b/src/exec/statements.k index d60128fd..c785bd50 100644 --- a/src/exec/statements.k +++ b/src/exec/statements.k @@ -119,7 +119,7 @@ rule [Switch]: context switchImpl( _,[ 'SwitchGroup(['Case(HOLE),,_:KList],,_),, _:KList ], _) /*@ The type associated to V and V2 is not important for match, only the value. JLS3 \$14.11, page 377: Every case constant expression associated with -a switch statement must be assignable (�5.2) to the type of the switch Expression.*/ +a switch statement must be assignable (\$5.2) to the type of the switch Expression.*/ rule [switchImpl-CaseNotMatch]: switchImpl(V:RawVal :: _,[ 'SwitchGroup([ ( 'Case(V2:RawVal :: _) => .KList ),, _:KList ],,_),, _],_) when V =/=K V2 From b734e5506e9805565a62b3d5ebfd98a459e9c5ea Mon Sep 17 00:00:00 2001 From: Denis Bogdanas Date: Mon, 13 Apr 2015 18:50:51 +0300 Subject: [PATCH 43/43] Latex attributes: fixed to generate proper blank spaces in latex output. --- .gitignore | 2 ++ src/common/core-classes.k | 6 +++--- src/common/core-sorts.k | 18 +++++++++--------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 6c6405e5..2652bcc7 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,5 @@ /src/sty/*.pdf /src/sty/*.synctex /src/sty/.latex +/src/exec/java-exec-kompiled-bk +/src/prep/java-prep-kompiled-bk diff --git a/src/common/core-classes.k b/src/common/core-classes.k index 01f0e998..4d562b1e 100644 --- a/src/common/core-classes.k +++ b/src/common/core-classes.k @@ -13,15 +13,15 @@ module CORE-CLASSES //@Shortcuts for the most frequently used classes that need special treatment within the semantics. syntax KItem ::= "classObject" - [function, latex(\terminal{Object})] + [function, latex(\terminal{class} \terminal{Object} )] rule classObject => class String2Id("java.lang.Object") syntax KItem ::= "classString" - [function, latex(\terminal{String})] + [function, latex(\terminal{class} \terminal{String} )] rule classString => class String2Id("java.lang.String") syntax KItem ::= "classNullPointerException" - [function, latex(\terminal{NullPointerException})] + [function, latex(\terminal{class} \terminal{NullPointerException} )] rule classNullPointerException => class String2Id("java.lang.NullPointerException") syntax KItem ::= "classArrayImpl" [function] diff --git a/src/common/core-sorts.k b/src/common/core-sorts.k index 4ab03edb..84d351af 100644 --- a/src/common/core-sorts.k +++ b/src/common/core-sorts.k @@ -159,7 +159,7 @@ syntax Exp ::= TypedVal | RawVal */ syntax KResult ::= TypedVal | Type -syntax KResult ::= "noValue" [latex({\dotCt{K}})] +syntax KResult ::= "noValue" [latex(\dotCt{K} )] //@ \subsection{Class and member attributes} @@ -169,8 +169,8 @@ syntax KResult ::= Signature /*@ The member accessibility context of the current method --- either static or instance.*/ -syntax ContextType ::= "staticCT" [latex(\terminal{static})] - | "instanceCT" [latex(\terminal{instance})] +syntax ContextType ::= "staticCT" [latex(\terminal{static} )] + | "instanceCT" [latex(\terminal{instance} )] syntax KResult ::= ContextType /*@ Member access modes*/ @@ -181,8 +181,8 @@ syntax KResult ::= AccessMode syntax MethodMetaType ::= "methodMMT" | "constructorMMT" /*@ The two possibilities for a type represented by an objectRef: class or interface.*/ -syntax ClassMetaType ::= "classCMT" [latex(\terminal{class})] - | "interfaceCMT" [latex(\terminal{interface})] +syntax ClassMetaType ::= "classCMT" [latex(\terminal{class} )] + | "interfaceCMT" [latex(\terminal{interface} )] //@ \subsection{Misc definitions} @@ -192,7 +192,7 @@ syntax MethodRef ::= methodRef( RefType //Usually Class - class defining the method // Could also be array type, because we may invoke methods over arrays. ) - | "noMethodRef" [latex({\dotCt{K}})] + | "noMethodRef" [latex(\dotCt{K} )] syntax KResult ::= MethodRef syntax MethodName ::= MethodRef @@ -217,7 +217,7 @@ syntax ClassOrName ::= Id | ClassType //Denis' syntax /*@ A fully qualified class name, or noClass where no valid class exists in the current context.*/ -syntax ClassType ::= "class" Id | "noClass" [latex({\dotCt{K}})] +syntax ClassType ::= "class" Id | "noClass" [latex(\dotCt{K} )] /*@ \subsection{Random unsorted content, syntax converters}*/ @@ -243,14 +243,14 @@ rule 'Id(Str:String) => String2Id(Str) [structural, anywhere] syntax KLabel ::= "'ListWrap" rule 'ListWrap(Ks:KList) => [Ks] [structural, anywhere] //todo: both 'KListWrap and 'ListWrap are associted with the same production, so how to get rid of it -syntax KListWrap ::= "[" KList "]" [klabel('KListWrap), latex(\terminal{[} {#1} \terminal{]})] +syntax KListWrap ::= "[" KList "]" [klabel('KListWrap), latex(\terminal{[} {#1}\terminal{]} )] //@ Sequence of terms and of any other statements. The first term is moved to the top of computation. rule [S1:K,, Stmts:KList] => S1 ~> [Stmts] [structural] rule [.KList] => .K [structural] //@ A wrapper over an arbitrary KList, wrapper being of type KResult. -syntax KRListWrap ::= "kr" "[" KList "]" [latex(\terminal{kr[} {#1} \terminal{]})] +syntax KRListWrap ::= "kr" "[" KList "]" [latex(\terminal{kr[} {#1}\terminal{]} )] syntax KResult ::= KRListWrap //@ \subsubsection{Computation terms produced during elaboration}