kotlin compiler construction (very brief)

29
/29 Kotlin Kotlin Compiler Construction Nurgaliev Ildar

Upload: ildar-nurgaliev

Post on 06-Aug-2015

115 views

Category:

Software


3 download

TRANSCRIPT

/29

Kotlin

Kotlin Compiler Construction

Nurgaliev Ildar

Ildar Nurgaliev
http://kotlin-demo.jetbrains.com/

/29

Kotlin

Why?

One reason is enough:Java platform and Java language there is huge gap

/29

Kotlin

Chalenges in JVM language design.

/29

Kotlin

Introduction● Statically typed● Compiles to JVM byte codes or JavaScript● JVM version is Java compatible both ways● Intended for industrial use

o Designed for READABILITYo Relies simple (but powerful) abstractionso Performance is a priorityo Tooling matters

● Open Source (Apache 2) o http://github.com/JetBrains/Kotlin

/29

Kotlin

Keywordsfor

while

match

case

if

then

else

do

return

fun

initial

invalvarnullcontinueStringpackageclassprivatevoidinternalprotected

/29

Kotlin

Java

type

Kotlin type

byte kotlin.Byte

short kotlin.Short

int kotlin.Int

double kotlin.Double

boolean kotlin.Boolea

n

Mapped types

Kotlin treats some Java types specially. Such types are

not loaded from Java “as is”, but are mapped to

corresponding Kotlin types. The mapping only matters

at compile time, the runtime representation remains

unchanged. Java’s primitive types are mapped to

corresponding Kotlin types (keeping platform types in

mind):

java.lang.Objec

t

kotlin.Any

!

int[] kotlin.IntArray!

/29

Kotlin

Basic syntax● You do not need ; to break statements.

● Comments are similar to Java or C#, /* This is comment */ for multi line comments and // for single

line comment.

● Unlike Java, you do not need to match your file name to your class name.

● Like JavaScript, you can create functions outside classes. So there is no need to stuff your functions as static

members of classes like what you do in C# or Java.

● Kotlin has string templates, which is awesome. e.g. "$firstName $lastName" for simple variable name or "$

{person.name} is ${1 * 2}" for any expressions. You can still do the string concatenation if you like e.g.

"hello " + "world", but that means being stupid.

● It has no tuple although Kotlin's data classes is an option to use in place of tuple.

● Use function literals to filter and map collections: basic functional programming inside

Ex: names filter {it.startsWith("A")} sortBy {it} map {it.toUpperCase()} forEach {print(it)}

/29

Kotlin

Variable semantic● There are two keywords for variable declaration, var and val.

● Use var when the variable value is to be modified and val where the variable value will not change after first

assigned.

● This val is similar to readonly keyword in C# or final keyword in Java.

● val variable must be initialized at declaration.

● Unlike Java or C#, you declare the type of a variable after the name, e.g. var firstName : String

● Number primitive types are as follows: Double, Float, Long, Int, Short, Byte. There is no automatic conversion

between types. You have to explicitly convert them.

● More primitive types: Char, String, Boolean.

● All variable declarations in Kotlin must be initialized.

● The keyword void common in Java or C# is called Unit in Kotlin.

/29

Kotlin

Identifiers4 types of identifiers supported by Scala:

● ALPHANUMERIC IDENTIFIERS

● OPERATOR IDENTIFIERS

● LITERAL IDENTIFIERS

/29

Kotlin

ALPHANUMERIC IDENTIFIERS

● An ALPHANUMERIC IDENTIFIERS starts with a letter or underscore,

which can be followed by further letters, digits, or underscores.

● '$' character is a reserved keyword

Legal alphanumeric identifiers:

age, salary, _value, __1_value

Illegal identifiers:

$salary, 123abc, -salary

/29

Kotlin

grammar

На сайте выложено, EBNF

/29

Kotlin

Semantic- arrays the index used in an array selection expression must be of

integer type- expressions the two operands to logical && must both be bool type, the result

is bool type- functions the type of each actual argument in a function call must be

compatible with the formal parameter- classes if specified, the parent of a class must be a properly declared class

type- interfaces all methods of the interface must be implemented if a class states

that it implements the interface

/29

Kotlin

Semantic (easy stuff)

Class names can be used before being defined• We can’t check class names– using a symbol table– or even in one pass• Solution– Pass 1: Gather all class names– Pass 2: Do the checking

/29

Kotlin

AST

– Before: Process an AST node n– Recurse: Process the children of n– After: Finish processing the AST node n

/29

Kotlin

Example AST rules● Before processing e, add definition of x to current

definitions, overriding any other definition of x● – Recurse● – After processing e, remove definition of x and restore

old definition of x

for (x : Char in “abc”){ ( x )Expressions…. ( e )}

/29

Kotlin

Symbol table operations● addSymbol(x) push x and associated info, such as

x’s type, on the stack● findSymbol(x) search stack, starting from top, for

x. Return first x found or NULL if none found● removeSymbol() pop the stack● enterScope() start a new nested scope● findSymbol(x) finds current x (or null)● addSymbol(x) add a symbol x to the table● checkScope(x) true if x defined in current scope● exitScope() exit current scope

/29

Kotlin

Recall to symbol tables for resolving

fun main(args: Array<String>) { if (args.size == 0) { println("Provide a name") return } println("Hello, ${args[0]}!")

//String Interpolation to cut down ceremony.

}

/29

Kotlin

Method declaration

● Method names have complex rules● A method need not to be defined in the class in which itis used, but in some parent class● Methods may also be redefined (overridden) (Hard point)

/29

Kotlin

Type checkingType checking computes via reasoning:If E1 and E2 have certain types, then E3 has a certain type(e1 : Int AND e2: Int) IMPLIES e1 + e2: Int

We work with hypotheses and conclusions.So we create type rules.Ex: is add minus

/29

Kotlin

Type checking

Type checking proves facts e: T– Proof is on the structure of the AST– Proof has the shape of the AST– One type rule is used for each AST node• In the type rule used for a node e:– Hypotheses are the proofs of types of e’s subexpressions– Conclusion is the type of e• Types are computed in a bottom-up pass over the AST

/29

Kotlin

Type environment before type check

The type environment gives types to the freeidentifiers in the current scope• The type environment is passed down the AST fromthe root towards the leaves• Types are computed up the AST from the leavestowards the root

/29

Kotlin

SubtypingConsider:if e0 then e1 else e2• The result can be either e1 or e2• The type is either e1’s type or of e2’s type• The best we can do is the smallest supertype larger than the type of e1 or e2

/29

Kotlin

Subtyping

lub(X,Y), the Least Upper Bound of X and Y, is Z if– X Z AND Y Z⩽ ⩽Z is an upper bound– X Z’ AND Y Z’ IMPLIES Z Z’⩽ ⩽ ⩽Z is least among upper bounds

so the least upper bound of two types is theirleast common ancestor in the inheritance tree

/29

Kotlin

Subtyping

Ex 2: The rule for case expressions takes a lub over all branches

Ex 1: if-Then-Else

/29

Kotlin

Typing methods

prelude: A method foo and an object foo can coexist in the same scope• In the type rules, this is reflected by a separate mappingM for method signaturesM(C,f) = (T1,. . .Tn,Tn+1)means in class C there is a method ff(x1:T1,. . .,xn:Tn): Tn+1 the last one is type of return st

/29

Kotlin

Polymorphism (Self type)class Count {

val i = 0;fun inc() : Count {

i++ return this }

};

inc() should return “dynamic type”

class Stock extends Count(var name:String) {};

fun main(args: Array<>String){val a = Stock(“test”)

a = (new Stock).inc (); // fail … a.name …};

/29

Kotlin

Polymorphism (Self type)– So, we must redefine inc for each of the subclasses, with a specialized return type ● Introduce the keyword SELF_TYPE to use for the return value of such

functionsSELF_TYPE is not a dynamic type– It is a static type– It helps the type checker to keep better track of types– It enables the type checker to accept more correctprograms

/29

Kotlin

SemanticElse one Hard aspect:1) Lamda expressions as new feature of the language:

val positiveNumbers = list.filter {it > 0}

Правила редукции типовых и без типовых лямбда исчислений

Область видимо-сти. Операционная семантика, виды редукций.Представление термов без использования имён (индексы де Брауна)Безопасность, продвижение, сохранение.Простое типизированное лямбда-исчисление: Типы функций.Отношение типизации. Свойства типизации. Соответствие Карри–Говарда(введения устранения, при совпадении вычисление).Стирание типов и типизируемость

/29

Kotlin

Code generation

Вряд ли я с этим справлюсь