Sources
The project can be cloned from github repository.
The revision described in this post is 50e6996a4faf8d5b469d291a029be05f9e6c9520.
Parser rules changes
In previous post I mentioned few things I would like to add to the language. The first one is going to be obviously a class scope.
Modification made to the language parsing rules:
compilationUnit : ( variable | print )* EOF;
variable : VARIABLE ID EQUALS value;
has been changed to:
compilationUnit : classDeclaration EOF ; //root rule - our code consist consist only of variables and prints (see definition below)
classDeclaration : className '{' classBody '}' ;
className : ID ;
classBody : ( variable | print )* ;
- The file must consist of one and only one classDeclaration.
- class declaration consist of className followed by body inside curly brackets
- the body is the same thing as it used to be in prototype - variable declaration or prints
This is how the parse tree looks after modifications (You can live preview parse tree using intellij plugin - https://www.youtube.com/watch?v=h60VapD1rOo):
Compiler changes
Most of the changes involve moving top-level code from ByteCodeGenerator
class to CompilationUnit
and ClassDeclaration
.
The logic is as follows:
- Compiler grabs parse tree values from
SyntaxParseTreeTraverser
: -
Compiler instantiates CompilationUnit:
//Compiler.java final CompilationUnit compilationUnit = new SyntaxTreeTraverser().getCompilationUnit(fileAbsolutePath); //Check getCompilationUnit() method body on github
- CompilationUnit instantiates ClassDeclaration (passes class name, and instructions list)
-
ClassDeclaration executes class specific instructions and loops over ClassScopeInstructions:
//ClassDeclaration.java MethodVisitor mv = classWriter.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null); instructions.forEach(classScopeInstruction -> classScopeInstruction.apply(mv));
One additional thing that changes is that the output .class file will have name based on the class declaration regardless of input *.enk filename:
String className = compilationUnit.getClassName();
String fileName = className + ".class";
OutputStream os = new FileOutputStream(fileName);
IOUtils.write(byteCode,os);
- enkel (21) ,
- jvm (22) ,
- asm (17) ,
- antlr (36) ,
- antlr4 (18) ,
- antlr (36) ,
- java (24) ,
- language (19)