mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-29 06:48:04 +00:00
332 lines
7.9 KiB
Markdown
332 lines
7.9 KiB
Markdown
---
|
|
theme: dracula
|
|
title: Compiler ULTIMATE
|
|
# apply unocss classes to the current slide
|
|
class: text-center
|
|
# https://sli.dev/custom/highlighters.html
|
|
highlighter: shiki
|
|
# https://sli.dev/guide/drawing
|
|
drawings:
|
|
persist: false
|
|
# slide transition: https://sli.dev/guide/animations#slide-transitions
|
|
transition: slide-left
|
|
# enable MDC Syntax: https://sli.dev/guide/syntax#mdc-syntax
|
|
mdc: true
|
|
plantUmlServer: 'https://www.plantuml.com/plantuml'
|
|
---
|
|
|
|
# Compiler ULTIMATE
|
|
|
|
Kein Weg ist mir im Schlitten je zu weit.
|
|
|
|
---
|
|
|
|
# Parser
|
|
|
|
**Besonderheiten und Änderungen zu Java:**
|
|
|
|
- Pro Datei nur eine Klasse, mehrer Dateien einlesen
|
|
- Keine Accessmodifier
|
|
- print statt System.out.println
|
|
- i++ eingeschränkt
|
|
- Kein ++i
|
|
- Zugriff af Felder nur mit this
|
|
- Logische Statements Klammern, sonst von links nach rechts
|
|
- Recipient
|
|
- Fehlermeldungen werden gesammelt
|
|
|
|
---
|
|
|
|
## AST
|
|
|
|
<Transform :scale="1">
|
|
|
|
```plantuml
|
|
@startuml
|
|
|
|
top to bottom direction
|
|
|
|
|
|
entity Assignment << record >> {
|
|
+ Assignment(FieldVarAccess, Expression):
|
|
+ value(): Expression
|
|
+ location(): FieldVarAccess
|
|
}
|
|
entity Binary << record >> {
|
|
+ Binary(Expression, Operator, Expression):
|
|
+ op(): Operator
|
|
+ left(): Expression
|
|
+ right(): Expression
|
|
}
|
|
entity Block << record >> {
|
|
+ Block(List<Statement>):
|
|
+ stmts(): List<Statement>
|
|
}
|
|
entity BoolLiteral << record >> {
|
|
+ BoolLiteral(Boolean):
|
|
+ value(): Boolean
|
|
}
|
|
entity Break << record >> {
|
|
+ Break():
|
|
}
|
|
entity CharLiteral << record >> {
|
|
+ CharLiteral(char):
|
|
+ value(): char
|
|
}
|
|
entity Class << record >> {
|
|
+ Class(String, Block, List<Declaration>, List<Method>, List<Constructor>):
|
|
+ Class(String, List<Declaration>, List<Method>, List<Constructor>):
|
|
+ mainmeth(): Block
|
|
+ classname(): String
|
|
+ methods(): List<Method>
|
|
+ constructors(): List<Constructor>
|
|
+ fieldDeclarations(): List<Declaration>
|
|
}
|
|
entity Constructor << record >> {
|
|
+ Constructor(String, List<Parameter>, Block):
|
|
+ params(): List<Parameter>
|
|
+ block(): Block
|
|
+ className(): String
|
|
}
|
|
entity Continue << record >> {
|
|
+ Continue():
|
|
}
|
|
entity Declaration << record >> {
|
|
+ Declaration(String, Type):
|
|
+ type(): Type
|
|
+ name(): String
|
|
}
|
|
entity DoWhile << record >> {
|
|
+ DoWhile(Block, Expression):
|
|
+ cond(): Expression
|
|
+ block(): Block
|
|
}
|
|
interface Expression << interface >>
|
|
entity FieldVarAccess << record >> {
|
|
+ FieldVarAccess(Boolean, Expression, String):
|
|
+ recursiveOwnerChain(): Expression
|
|
+ field(): Boolean
|
|
+ id(): String
|
|
}
|
|
entity For << record >> {
|
|
+ For(Assignment, Expression, Assignment, Block):
|
|
+ block(): Block
|
|
+ cond(): Expression
|
|
+ inc(): Assignment
|
|
+ assign(): Assignment
|
|
}
|
|
entity IfElse << record >> {
|
|
+ IfElse(Expression, Block, Block):
|
|
+ elseBlock(): Block
|
|
+ cond(): Expression
|
|
+ ifBlock(): Block
|
|
}
|
|
entity IntLiteral << record >> {
|
|
+ IntLiteral(Integer):
|
|
+ value(): Integer
|
|
}
|
|
entity Method << record >> {
|
|
+ Method(Type, String, List<Parameter>, Block):
|
|
+ block(): Block
|
|
+ methodName(): String
|
|
+ type(): Type
|
|
+ params(): List<Parameter>
|
|
}
|
|
entity MethodCall << record >> {
|
|
+ MethodCall(FieldVarAccess, List<Expression>):
|
|
+ recipient(): FieldVarAccess
|
|
+ args(): List<Expression>
|
|
}
|
|
entity New << record >> {
|
|
+ New(Type, List<Expression>):
|
|
+ type(): Type
|
|
+ args(): List<Expression>
|
|
}
|
|
interface Node << interface >>
|
|
enum Operator << enumeration >> {
|
|
+ Operator():
|
|
+ values(): Operator[]
|
|
+ valueOf(String): Operator
|
|
}
|
|
entity Parameter << record >> {
|
|
+ Parameter(String, Type):
|
|
+ type(): Type
|
|
+ name(): String
|
|
}
|
|
entity Print << record >> {
|
|
+ Print(Expression):
|
|
+ value(): Expression
|
|
}
|
|
entity Program << record >> {
|
|
+ Program(List<Class>):
|
|
+ classes(): List<Class>
|
|
}
|
|
entity Return << record >> {
|
|
+ Return(Expression):
|
|
+ ret(): Expression
|
|
}
|
|
interface Statement << interface >>
|
|
entity Unary << record >> {
|
|
+ Unary(UnaryOperator, Expression):
|
|
+ right(): Expression
|
|
+ op(): UnaryOperator
|
|
}
|
|
enum UnaryOperator << enumeration >> {
|
|
+ UnaryOperator():
|
|
+ values(): UnaryOperator[]
|
|
+ valueOf(String): UnaryOperator
|
|
}
|
|
entity While << record >> {
|
|
+ While(Expression, Block):
|
|
+ cond(): Expression
|
|
+ block(): Block
|
|
}
|
|
|
|
Assignment -[#008200,dashed]u-^ Statement
|
|
Binary -[#008200,dashed]u-^ Expression
|
|
Block -[#008200,dashed]u-^ Node
|
|
BoolLiteral -[#008200,dashed]u-^ Expression
|
|
Break -[#008200,dashed]u-^ Statement
|
|
CharLiteral -[#008200,dashed]u-^ Expression
|
|
Class -[#008200,dashed]u-^ Node
|
|
Constructor -[#008200,dashed]u-^ Node
|
|
Continue -[#008200,dashed]u-^ Statement
|
|
Declaration -[#008200,dashed]u-^ Statement
|
|
DoWhile -[#008200,dashed]u-^ Statement
|
|
Expression -[#008200,plain]u-^ Node
|
|
FieldVarAccess -[#008200,dashed]u-^ Expression
|
|
For -[#008200,dashed]u-^ Statement
|
|
IfElse -[#008200,dashed]u-^ Statement
|
|
IntLiteral -[#008200,dashed]u-^ Expression
|
|
Method -[#008200,dashed]u-^ Node
|
|
MethodCall -[#008200,dashed]u-^ Expression
|
|
MethodCall -[#008200,dashed]u-^ Statement
|
|
New -[#008200,dashed]u-^ Expression
|
|
New -[#008200,dashed]u-^ Statement
|
|
Parameter -[#008200,dashed]u-^ Node
|
|
Print -[#008200,dashed]u-^ Statement
|
|
Program -[#008200,dashed]u-^ Node
|
|
Return -[#008200,dashed]u-^ Statement
|
|
Statement -[#008200,plain]u-^ Node
|
|
Unary -[#008200,dashed]u-^ Expression
|
|
While -[#008200,dashed]u-^ Statement
|
|
@enduml
|
|
```
|
|
|
|
</Transform>
|
|
|
|
---
|
|
|
|
# Code Generierung
|
|
|
|
- Nutzung von ASM
|
|
- Dynamische Bindung/Polymorphie
|
|
|
|
<Transform :scale="0.8">
|
|
|
|
```java
|
|
public class TypedWhile implements TypedStatement {
|
|
|
|
...
|
|
|
|
@Override
|
|
public void codeGen(MethodContext ctx) {
|
|
Label loopStart = new Label();
|
|
Label loopEnd = new Label();
|
|
ctx.getBreakLabels().push(loopEnd);
|
|
ctx.getContinueLabels().push(loopStart);
|
|
|
|
ctx.getMv().visitLabel(loopStart);
|
|
cond.codeGen(ctx);
|
|
|
|
ctx.getMv().visitJumpInsn(Opcodes.IFEQ, loopEnd);
|
|
ctx.popStack();
|
|
typedBlock.codeGen(ctx);
|
|
ctx.getMv().visitJumpInsn(Opcodes.GOTO, loopStart);
|
|
ctx.getMv().visitLabel(loopEnd);
|
|
ctx.getContinueLabels().pop();
|
|
ctx.getBreakLabels().pop();
|
|
}
|
|
}
|
|
```
|
|
|
|
</Transform>
|
|
|
|
---
|
|
transition: none
|
|
---
|
|
|
|
# Code Generierung
|
|
|
|
- Nutzung von ASM
|
|
- Dynamische Bindung/Polymorphie
|
|
|
|
```java
|
|
public class TypedIntLiteral implements TypedExpression {
|
|
|
|
...
|
|
|
|
@Override
|
|
public void codeGen(MethodContext ctx) {
|
|
if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
|
|
ctx.getMv().visitIntInsn(Opcodes.BIPUSH, value);
|
|
} else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
|
|
ctx.getMv().visitIntInsn(Opcodes.SIPUSH, value);
|
|
} else {
|
|
ctx.getMv().visitLdcInsn(value);
|
|
}
|
|
ctx.pushInstantToStack();
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Context Klassen für Class und Method
|
|
|
|
```plantuml
|
|
|
|
@startuml
|
|
|
|
top to bottom direction
|
|
skinparam linetype ortho
|
|
|
|
class ClassContext {
|
|
+ ClassContext(String, ClassWriter):
|
|
- name: String
|
|
- cw: ClassWriter
|
|
- type: Type
|
|
+ hashCode(): int
|
|
+ toString(): String
|
|
}
|
|
class MethodContext {
|
|
+ MethodContext(ClassContext, MethodVisitor, Type):
|
|
- variableIndex: Map<String, LocalVariable>
|
|
- mv: MethodVisitor
|
|
- stack: Deque<Integer>
|
|
- returnType: Type
|
|
- breakLabels: Deque<Label>
|
|
- continueLabels: Deque<Label>
|
|
- classContext: ClassContext
|
|
- maxStack: int
|
|
- localVarIndex: int
|
|
+ pushInstantToStack(): void
|
|
+ popStack(): void
|
|
+ getLocalVar(String): Optional<LocalVariable>
|
|
+ registerVariable(String, Type): void
|
|
+ pushAnonToStack(): void
|
|
+ pushStack(String): void
|
|
+ wrapUp(): void
|
|
}
|
|
|
|
@enduml
|
|
|
|
```
|
|
|
|
---
|
|
|
|
## ASMifier
|
|
|
|
Tool, um aus Java Bytecode ASM Code zu generieren.
|
|
|
|
<a href="https://simon.webhop.me" target="_blank">Klick</a> |