--- 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 ```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): + stmts(): List } 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, List, List): + Class(String, List, List, List): + mainmeth(): Block + classname(): String + methods(): List + constructors(): List + fieldDeclarations(): List } entity Constructor << record >> { + Constructor(String, List, Block): + params(): List + 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, Block): + block(): Block + methodName(): String + type(): Type + params(): List } entity MethodCall << record >> { + MethodCall(FieldVarAccess, List): + recipient(): FieldVarAccess + args(): List } entity New << record >> { + New(Type, List): + type(): Type + args(): List } 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): + classes(): List } 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 ```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(); } } ``` --- 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 - mv: MethodVisitor - stack: Deque - returnType: Type - breakLabels: Deque