120 likes | 156 Views
Explore the static semantics of JavaI, covering primitive types, syntax rules, type checking, and transition rules for expressions and statements. Learn about type verification, transitions, and derived language constructs in JavaI.
E N D
Java and the Java Virtual Machine 3. The imperative Core JavaI of Java Pslab 오민경
Static semantics of JavaI • Primitive type • Numeric type • Integral type : byte, short, int long, char • Floating point type : float, double • Conditional type • boolean • Literal • External representations of values of primitive type • i.e. 11, 3.14f, true …
Static semantics of JavaI • Relation ‘⊆’ • A ⊆ B • A is subtype of B ( A, B : Type) • exist a widening primitive conversion from A to B • Each value of A can used as a value of B, however, information may be lost. • Relation ‘⊆’ • Byte ⊆ short ⊆ int ⊆ long ⊆ float ⊆ double, char ⊆ int • Reflexive : A ⊆ A • Transitive : if A ⊂ B and B ⊂ C, then A ⊂ C
Syntax of JavaI • Domain • Domains (or universes) : words beginning with a capital letter • i.e. Exp … expressions, Stm … statements • Elements of ‘Dom’ : ‘dom’ • Local variable • Local variable declaration : ‘A loc;’ • The scope of loc consists of the statements following the variable declaration in the block.
Type checking of JavaI • Position • Position : small Greek letters α, β, γ. • i.e. αexp, βstm • The universe of positions is called ‘Pos’. • Compiler verification : type checking • The compiler has to verify that a program is well-typed. • As a result of pasing and elaboration the parse tree annotated with type information : T(α). • During compilation and type checking explicit unary conversion operators (type cast) are inserted at places where they are necessary.
Transition rules for JavaI • execJavaI = execJavaExpI execJava StmI • execJavaExpI • All expressions are evaluated from innermost to outermost. • For this purpose, • the current control is transferred, by updating pos. • from unevaluated expressions to the appropriate subexpressions. • until an atom (a literal or a variable) is reached.
Transition rules for JavaI • execJava StmI • The syntactical structure of the statement to be computed by transferring. • For this purpose • through updates of pos, the current control from structured statements to the appropriate substatements • until the current statement has been computed normally or abrupts the computation. • Abruption : Jump statement (break, continue) • Not a labeled phrase, not degree labeled phrase : Abruption is propagated upwards. • Break(labb) : execution proceeds normally at the next phrase of the target • Continue(labc) : execution proceeds with the next iteration of the corresponding while statement.
Derived language constructs • Java constructs that can be syntactically reduced to the core language • ++loc : loc=(A)(loc+1) • --loc : loc=(A)(loc-1) • If (exp) stm : if (exp) stm else; • The ‘if statement without else’ suffers from the so-called ‘dangling else problem’ • If (exp1) if (exp2) stm1 else stm2 • If (exp1) { if (exp2) stm1 else stm2 } => O • If (exp1) { if (exp2) stm1 } else stm2 => X
Syntax of Java Exp := Lit | Loc | Uop Exp | Exp Bop Exp | Exp ? Exp : Exp | Asgn Asgn := Loc = Exp Stm := ; | Asgn; | Lab : Stm | break Lab; | continue Lab; | if (Exp) Stm else Stm | while (Exp) Stm | Block Block := {Bstm1 … Bstmn} Bstm := Type Loc; | Stm Phrase := Exp | Bstm | Val | Abr | Norm
Execution of JavaI expressions execJavaExpI = case context(pos) of lit → yield(JLS(lit)) loc → yield(locals(loc)) uop αexp → pos := α uop ►val → yieldUp(JLS(uop, val)) αexp1 bop βexp2 → pos := α ► val bop βexp → pos := β αval1 bop ► val2 → if ¬(bop 2 divMod ∧ isZero(val2)) then yieldUp(JLS(bop, val1, val2)) loc = αexp → pos := α loc = ►val → locals := locals + {(loc, val)} yieldUp(val) αexp0 ? βexp1 : γexp2 → pos := α ►val ? βexp1 : γexp2 → if val then pos := β else pos := γ αTrue ? ►val : γexp → yieldUp(val) αFalse ? βexp : ►val → yieldUp(val)
Execution of JavaI statements execJavaStmI = case context(pos) of ; → yield(Norm) αexp; → pos := α ► val; → yieldUp(Norm) break lab; → yield(Break(lab)) continue lab; → yield(Continue(lab)) lab : αstm → pos := α lab : ► Norm → yieldUp(Norm) lab : ► Break(labb) → if lab = labb then yieldUp(Norm) else yieldUp(Break(labb)) lab : ► Continue(labc) → if lab = labc then yield(body/pos) else yieldUp(Continue(labc)) phrase(► abr) → if pos ≠ firstPos ∧propagatesAbr(restbody/up(pos)) then yieldUp(abr)
Execution of JavaI statements { } → yield(Norm) {α1stm1…αn stmn} → pos := α1 {α1Norm …► Norm} → yieldUp(Norm) {α1Norm …► Normαi+1stmi+1…αnstmn} → pos := αi+1 if (αexp) βstm1 else γstm2 → pos := α if (► val) βstm1 else γstm2 → if val then pos := β else pos := γ if (αTrue) ► Norm else γstm → yieldUp(Norm) if (αFalse) βstm else ► Norm → yieldUp(Norm) while (αexp) βstm → pos := α while (► val) βstm → if val then pos := β else yieldUp(Norm) while (αTrue) ► Norm → yieldUp(body/up(pos)) Type x ; → yield(Norm)