A simple compiler for the .my-java language that compiles to JVM bytecode.
- Variable declarations (int, string)
- Print statements
- ANTLR grammar
- Bytecode generation
- Compile to
.classfiles
- Arithmetic operators (+, -, *, /, %)
- Comparison operators (==, !=, <, >, <=, >=)
- Logical operators (&&, ||, !)
- Boolean type
- Type checking
- If-else statements
- While loops
- For loops
- Break and continue
- Function declarations
- Function calls with parameters
- Return statements
- Local variable scope
- Array declaration
- Array initialization
- Array access and assignment
- Array length property
- Class declarations
- Constructors
- Instance variables
- Instance methods
- Object instantiation (new)
- this keyword
- Inheritance (extends)
- Method overriding
- Access modifiers (public, private)
- Static members
- Try-catch-finally
- Throw exceptions
- Built-in exception types
- Console input (readLine, readInt)
- String methods (length, substring, charAt)
- Math functions (abs, sqrt, pow, random)
- Array utilities (sort, reverse)
- Import statements (import other .my-java files)
- Package/namespace system
- Compile multiple files together
- Main class/entry point detection
- Build a complete Calculator app using multiple files
Build a calculator that evolves with each phase:
Phase 1 (Current): ✅
var result = 42
print result
Phase 2 (Arithmetic):
var a = 10
var b = 5
var sum = a + b
var product = a * b
print sum
print product
Phase 3 (Control Flow):
var operation = "add"
var a = 10
var b = 5
if operation == "add" {
print a + b
} else if operation == "multiply" {
print a * b
}
Phase 4 (Functions):
function add(x, y) {
return x + y
}
function multiply(x, y) {
return x * y
}
print add(10, 5)
print multiply(10, 5)
Phase 6 (Classes):
class Calculator {
var result
function add(a, b) {
this.result = a + b
return this.result
}
function multiply(a, b) {
this.result = a * b
return this.result
}
}
var calc = new Calculator()
print calc.add(10, 5)
print calc.multiply(10, 5)
Phase 10 (Final - Multi-file):
// Calculator.my-java
class Calculator {
function calculate(a, b, operation) {
if operation == "+" { return a + b }
if operation == "-" { return a - b }
if operation == "*" { return a * b }
if operation == "/" { return a / b }
}
}
// Main.my-java
import Calculator
var calc = new Calculator()
print calc.calculate(10, 5, "+")
print calc.calculate(10, 5, "*")
You need the following JAR files in your project directory:
antlr-4.13.1-complete.jar- ANTLR parser generatorcommons-lang3-3.14.0.jar- Apache Commons Lang utilitiesasm-9.6.jar- ASM bytecode manipulation library
# Download Apache Commons Lang
wget https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.14.0/commons-lang3-3.14.0.jar
# Download ASM library
wget https://repo1.maven.org/maven2/org/ow2/asm/asm/9.6/asm-9.6.jar
# Download antlr4
wget https://repo1.maven.org/maven2/org/antlr/antlr4/4.13.1/antlr4-4.13.1-complete.jar -O antlr-4.13.1-complete.jarjavac -cp "antlr-4.13.1-complete.jar:commons-lang3-3.14.0.jar:asm-9.6.jar:." *.javajava -cp "antlr-4.13.1-complete.jar:commons-lang3-3.14.0.jar:asm-9.6.jar:." Compiler first.my-javaThis will:
- Parse
first.my-java - Generate bytecode
- Create
first.classfile
java firstInput file (first.my-java):
var lol=4
print lol
var faker="T1"
print faker
Output:
4
"T1"
A .class file is a compiled Java bytecode file:
- Binary format: Contains bytecode (not human-readable)
- Platform-independent: Runs on any system with a JVM
- Generated by javac: Created from
.javasource files - Executed by JVM: The
javacommand runs.classfiles
MyJava.g4- ANTLR grammar definitionCompiler.java- Main compiler entry pointBytecodeGenerator.java- Generates JVM bytecode using ASMSyntaxTreeTraverser.java- Traverses the parse treeTreeWalkListener.java- Handles parse tree eventsInstruction.java- Interface for bytecode instructionsVariable.java- Represents a variableVariableDeclaration.java- Variable declaration instructionPrintVariable.java- Print statement instruction