MLang is a custom programming language with a unique syntax and structure, built using ANTLR4 and Java.
It supports variables, arithmetic expressions, functions, control flow (if
, while
), output (show
), input (take()
), and block scoping.
-
Variable declarations (with
let
)let x > int = 5;
-
Assignments
x = x + 1;
-
Arithmetic expressions
x + 3 * 4;
-
Comparison expressions
if (x == 0) [ ... ]
-
show(...)
for printing valuesshow(x);
-
take()
for user inputlet x > int = take();
-
if-else
control flowif (x > 0) [ show(1); ] else [ show(0); ]
-
while
loopswhile (x < 5) [ ... ]
-
Function declarations and calls
func add(x > int, y > int) > int [ return x + y; ] let result > int = add(2, 3);
-
Block scoping using square brackets
[ stmt1; stmt2; ]
- ANTLR4 Grammar (
MLang.g4
) custom defined - AST Node Hierarchy:
ProgramNode
,LetDeclNode
,AssignStmtNode
,ExprStmtNode
BinaryOpNode
,IntLiteralNode
,IdNode
,InputExprNode
IfStmtNode
,WhileStmtNode
,ShowStmtNode
,BlockNode
FuncDeclNode
,FuncCallNode
,ReturnStmtNode
- AST built via
MLangASTBuilder.java
using ANTLRMLangBaseVisitor
- AST pretty-printer (
printAST
) for visualization
- Interpreter implemented (
runtime/Interpreter.java
) - Executes programs by visiting AST nodes:
- Variable environment management
- Expression evaluation
- Function call/return stack with local scope
- Control flow execution (
if
,while
) - Output to console using
show
- Input from user using
take()
- Handles both integer and boolean conditions
- Place
.ml
test programs inside thetests/
folder. - Example:
tests/input_test.ml
let x > int = take();
show(x + 1);
From the MLANG/
root directory:
make clean
make
✅ make
handles ANTLR code generation, Java compilation, and execution.
To run a specific test file:
Edit TestMLang.java
:
String inputCode = Files.readString(Paths.get("tests/input_test.ml"));
Then rerun make
.
MLANG/
├── src/
│ ├── MLang.g4 # ANTLR grammar
│ ├── MLangASTBuilder.java # AST builder
│ ├── TestMLang.java # Main driver (AST print + Interpreter run)
│ ├── ast/ # AST Node classes
│ └── runtime/ # Interpreter and Environment
├── gen/ # ANTLR-generated parser and lexer
├── bin/ # Compiled .class files
├── lib/ # antlr-4.13.1-complete.jar
├── tests/ # Test programs (.ml)
├── Makefile # Build automation
└── README.md
let num > int = take();
show(num + 1);
Program
VarDecl: num > int
InputExpr (take)
Show
BinaryOp: +
Id: num
IntLiteral: 1
take> 42
43
-
ANTLR Output Directory Problems:
Fixed by running ANTLR fromsrc/
with output togen/
. -
Classpath and Compilation Issues:
Used$(wildcard gen/*.java)
and explicitly includedsrc/runtime/*.java
. -
Variable Initialization Order:
Interpreter defines variable names before evaluating their initializers. -
Return flow handling in functions:
UsedReturnException
to simulate non-local returns. -
Local scope for functions:
Functions execute in isolated environments (not modifying global state). -
Input support:
Addedtake()
expression for reading integers viaScanner
.
- Add
float
andbool
types fully (currently onlyint
supported) - Add support for recursion and higher-order functions
- Add
arrays
,for
loops, and standard library support - Improve parser error messages (currently minimal error recovery)
🧠 Author
Mudit Golchha
CS571 – Programming Languages
Binghamton University