A stack-based interpreter written in Java, demonstrating software engineering principles including reflection API, dependency injection, and object-oriented design patterns.
- π Project Overview
- ποΈ Architecture
- π SML Language Features
- π οΈ Technical Implementation Highlights
- π Getting Started
- π Project Structure
- π§ͺ Testing
- π― Design Patterns and Concepts
- π§ Technologies Used
- π Learning Outcomes
- π€ Extending the Interpreter
- π§ Contact
- π Acknowledgements
SML is a simple assembly-like programming language interpreter that operates on a stack-based execution model. The project demonstrates object-oriented design principles, reflection usage, and dependency injection patterns.
- ποΈ Stack-based Execution: Implements an execution environment with method frames, operand stacks, and program counters
- βοΈ Complete Instruction Set: Supports arithmetic operations, control flow, method invocation, and variable management
- π Reflection-based Instruction Factory: Uses Java reflection to instantiate instruction objects dynamically
- π± Spring Dependency Injection: Uses Spring Framework for component management
- 𧬠Abstract Class Hierarchies: Implements sealed classes and inheritance patterns to reduce code duplication
- π§ͺ Comprehensive Testing: Unit tests for instruction implementations and core components
The interpreter follows a layered architecture for executing SML programs:
graph TD
A[SML Source File] --> B[SMLTranslator]
B --> C[Machine]
C --> D[Frame Stack]
D --> E[Method Execution]
B --> F[SMLInstructionFactory]
F --> G{Instruction Type}
G --> H[CalculateInstruction<br/>Sealed Abstract]
G --> I[ComparisonInstruction<br/>Sealed Abstract]
G --> J[Other Instructions]
H --> K[Math Operations<br/>add, sub, mul, div]
I --> L[Comparisons<br/>if_cmpgt, if_cmpeq]
J --> M[Stack & Flow<br/>load, store, push<br/>goto, invoke, return, print]
style F fill:#e1f5fe
style H fill:#f3e5f5
style I fill:#f3e5f5
style B fill:#e1f5fe
classDef sealed fill:#f3e5f5,stroke:#9c27b0
classDef spring fill:#e1f5fe,stroke:#2196f3
class H,I sealed
class F,B spring
Machine
: Executes the fetch-decode-execute cycle and manages program executionFrame
: Represents method execution context with local variables and operand stackSMLTranslator
: Parses SML source code and builds the internal program representationSMLInstructionFactory
: Uses reflection to dynamically instantiate instruction objectsInstruction
(Abstract): Base class for all SML instructions with polymorphic executionCalculateInstruction
(Sealed): Abstract base for arithmetic instructionsComparisonInstruction
(Sealed): Abstract base for comparison instructions
Category | Instructions | Description |
---|---|---|
Arithmetic | add , sub , mul , div |
Basic mathematical operations |
Stack Operations | push , load , store |
Stack and variable manipulation |
Control Flow | goto , if_cmpgt , if_cmpeq |
Branching and jumps |
Method Management | invoke , return |
Method calls and returns |
I/O | print |
Output operations |
Here's a recursive Fibonacci implementation in SML:
@main:
push 10
invoke @fib
print
push 1
return
@fib: n
load n
push 1
if_cmpgt L7
push 1
return
L7: load n
push 1
sub
invoke @fib
load n
push 2
sub
invoke @fib
add
return
The instruction factory uses reflection to dynamically instantiate instructions based on opcode:
// Dynamically find and instantiate instruction classes
for (Class<?> instruction : instructionClasses) {
Field[] fields = instruction.getDeclaredFields();
for (Field field : fields) {
if (field.getName().equals("OP_CODE")) {
String opcodeValue = String.valueOf(field.get(null));
if (opcodeValue.equals(opcode)) {
return buildInstruction(label, programInstruction, instruction);
}
}
}
}
<bean id="instruction-factory" class="sml.SMLInstructionFactory">
<constructor-arg>
<list>
<value>sml.instruction.AdditionInstruction</value>
<value>sml.instruction.LoadInstruction</value>
<!-- Additional instruction types configured in beans.xml -->
</list>
</constructor-arg>
</bean>
Using modern Java sealed classes to control inheritance:
public sealed abstract class CalculateInstruction extends Instruction
permits AdditionInstruction, DivisionInstruction,
MultiplicationInstruction, SubtractionInstruction {
// Pattern matching with switch expressions
Function<CalculateInstruction,Integer> calculate = c ->
switch (c) {
case AdditionInstruction a -> Math.addExact(a.value1, a.value2);
case SubtractionInstruction s -> Math.subtractExact(s.value1, s.value2);
case MultiplicationInstruction m -> Math.multiplyExact(m.value1, m.value2);
case DivisionInstruction d -> d.value1 / d.value2;
};
}
- Java 21 or higher
- Maven 3.6+
-
Clone the repository
git clone https://github.com/yourusername/sml-interpreter.git cd sml-interpreter
-
Install dependencies and compile
mvn clean compile
-
Run sample programs
# Fibonacci example (calculates 10th Fibonacci number) java -cp target/classes RunSml resources/test1.sml # Alternative implementation example java -cp target/classes RunSml resources/test2.sml
-
Run all tests
mvn test
-
Generate test reports
mvn surefire-report:report # View reports in target/site/surefire-report.html
IntelliJ IDEA / Eclipse:
- Import as Maven project
- Set Project SDK to Java 21
- Enable annotation processing for Spring
- Run configuration: Main class
RunSml
, Program argumentsresources/test1.sml
src/
βββ main/java/
β βββ RunSml.java # Main entry point
β βββ sml/
β βββ Machine.java # Interpreter execution engine
β βββ Frame.java # Execution frame
β βββ Instruction.java # Abstract instruction base
β βββ SMLTranslator.java # Source code parser
β βββ SMLInstructionFactory.java # Reflection-based factory
β βββ instruction/ # Instruction implementations
β βββ CalculateInstruction.java # Sealed abstract class
β βββ ComparisonInstruction.java # Sealed abstract class
β βββ AdditionInstruction.java # Concrete arithmetic
β βββ LoadInstruction.java # Variable operations
β βββ [other instructions...]
βββ test/
βββ sml/ # Unit tests
βββ instruction/ # Instruction-specific tests
βββ MachineTest.java
βββ MethodTest.java
βββ SymbolTableTest.java
resources/
βββ beans.xml # Spring DI configuration
βββ test1.sml # Fibonacci example
βββ test2.sml # Additional examples
The project includes comprehensive unit tests covering:
- Instruction Tests:
CalculateInstructionTest
,ComparisonInstructionTest
,LoadInstructionTest
- Core Functionality:
MachineTest
,MethodTest
,SymbolTableTest
- Integration Tests: End-to-end program execution
# Run all tests
mvn test
# Run specific test class
mvn test -Dtest=CalculateInstructionTest
# Run tests with verbose output
mvn test -Dtest=* -DforkCount=1 -DreuseForks=false
# Generate coverage report
mvn jacoco:report
- β Arithmetic Operations: Addition, subtraction, multiplication, division
- β Control Flow: Conditional branching, goto statements
- β Method Invocation: Recursive calls, parameter passing
- β Variable Management: Load/store operations, scope handling
- β Error Handling: Invalid operations, stack underflow
- π Abstract Factory:
SMLInstructionFactory
for creating instruction instances - π Sealed Classes:
CalculateInstruction
andComparisonInstruction
with controlled inheritance - π Template Method: Abstract instruction classes defining execution patterns
- π Dependency Injection: Spring-managed components (
@Component
,@Autowired
) - π Reflection: Dynamic class loading and field access for instruction creation
- π― Pattern Matching: Modern Java switch expressions with sealed classes
- Java 21: Modern Java features including sealed classes and pattern matching
- Spring Boot 3.4.3: Dependency injection framework
- Spring Context: Bean management and configuration
- Maven: Build automation and dependency management
- JUnit: Unit testing framework
- Java Reflection API: Dynamic class loading and field access
This project demonstrates:
- π§ Modern Java Features: Sealed classes, pattern matching, switch expressions
- ποΈ Object-Oriented Design: Abstract classes, inheritance hierarchies, polymorphism
- π Reflection API: Dynamic class loading, field access, constructor invocation
- π± Spring Framework: Dependency injection, component scanning, XML configuration
- ποΈ Software Architecture: Clean separation of concerns, extensible design
- π§ͺ Testing: Unit test coverage with JUnit
- βοΈ Build Tools: Maven project structure and dependency management
The architecture allows easy extension by:
- Creating new instruction classes extending the appropriate abstract base
- Adding the class name to the Spring beans configuration
- The reflection-based factory automatically handles instantiation
public non-sealed class ModuloInstruction extends CalculateInstruction {
public static final String OP_CODE = "mod";
public ModuloInstruction(Label label) {
super(label, OP_CODE);
}
}
Then add to beans.xml
:
<value>sml.instruction.ModuloInstruction</value>
Queenie Lee - Software Developer
π§ queenie.lee[at]live.ca
π GitHub Portfolio
πΌ Project Repository
This project demonstrates advanced Java programming concepts within a provided educational framework from the Software Design and Programming course.
Framework Foundation: Built upon a robust architectural skeleton including core VM components (Machine
, Frame
, Method
, SymbolTable
) and parsing infrastructure, allowing focus on advanced implementation techniques.
- Instruction System: Complete implementation of all concrete instruction classes with polymorphic execution
- Sealed Class Hierarchies:
CalculateInstruction
andComparisonInstruction
using modern Java pattern matching - Reflection-Based Factory: Dynamic instruction instantiation using Java reflection API
- Spring Integration: Dependency injection implementation with
@Component
and@Autowired
patterns - Testing Suite: Comprehensive unit tests covering instruction implementations and core functionality
- Modern Java Features: Leveraged Java 21 sealed classes, pattern matching, and switch expressions
- Code Extension & Modification: Working with existing architectural patterns
- Advanced OOP: Abstract class hierarchies and polymorphic design
- Reflection API: Dynamic object creation and field access
- Dependency Injection: Spring Framework integration patterns
- Test-Driven Development: Comprehensive unit test coverage
- Java Language Specifications for sealed classes and pattern matching implementation
- Spring Framework Documentation for dependency injection best practices
- Course Materials for foundational architecture and advanced Java concepts
Note: This project showcases the ability to work with existing codebases while implementing sophisticated features - a crucial skill in professional software development.
Built with β€οΈ using Java 21, Spring Framework, and Maven
Stack-based interpreter for SML assembly language in Java. Features reflection API, Spring dependency injection, sealed classes, and modern design patterns. Demonstrates advanced OOP and enterprise development practices.