mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-28 14:48:03 +00:00
7.9 KiB
7.9 KiB
theme | title | class | highlighter | drawings | transition | mdc | plantUmlServer | ||
---|---|---|---|---|---|---|---|---|---|
dracula | Compiler ULTIMATE | text-center | shiki |
|
slide-left | true | 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
@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
Code Generierung
- Nutzung von ASM
- Dynamische Bindung/Polymorphie
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();
}
}
transition: none
Code Generierung
- Nutzung von ASM
- Dynamische Bindung/Polymorphie
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
@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.