Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

50 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ–₯️ Simple Machine Language (SML) Interpreter

A stack-based interpreter written in Java, demonstrating software engineering principles including reflection API, dependency injection, and object-oriented design patterns.

Java Spring Boot Maven Testing

πŸ“‹ Table of Contents

πŸš€ Project Overview

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.

Key Features

  • πŸ—οΈ 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

πŸ—οΈ Architecture

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
Loading

Core Components

  • Machine: Executes the fetch-decode-execute cycle and manages program execution
  • Frame: Represents method execution context with local variables and operand stack
  • SMLTranslator: Parses SML source code and builds the internal program representation
  • SMLInstructionFactory: Uses reflection to dynamically instantiate instruction objects
  • Instruction (Abstract): Base class for all SML instructions with polymorphic execution
  • CalculateInstruction (Sealed): Abstract base for arithmetic instructions
  • ComparisonInstruction (Sealed): Abstract base for comparison instructions

πŸ“ SML Language Features

Instruction Set

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

Example Program

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

πŸ› οΈ Technical Implementation Highlights

1. Reflection-Based Instruction Factory

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);
            }
        }
    }
}

2. Spring Dependency Injection Configuration

<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>

3. Sealed Class Hierarchies

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;
        };
}

πŸš€ Getting Started

Prerequisites

  • Java 21 or higher
  • Maven 3.6+

Local Development Setup

  1. Clone the repository

    git clone https://github.com/yourusername/sml-interpreter.git
    cd sml-interpreter
  2. Install dependencies and compile

    mvn clean compile
  3. 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
  4. Run all tests

    mvn test
  5. Generate test reports

    mvn surefire-report:report
    # View reports in target/site/surefire-report.html

IDE Setup

IntelliJ IDEA / Eclipse:

  1. Import as Maven project
  2. Set Project SDK to Java 21
  3. Enable annotation processing for Spring
  4. Run configuration: Main class RunSml, Program arguments resources/test1.sml

πŸ“ Project Structure

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

πŸ§ͺ Testing

The project includes comprehensive unit tests covering:

Test Coverage

  • Instruction Tests: CalculateInstructionTest, ComparisonInstructionTest, LoadInstructionTest
  • Core Functionality: MachineTest, MethodTest, SymbolTableTest
  • Integration Tests: End-to-end program execution

Running Tests

# 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

Example Test Scenarios

  • βœ… 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

🎯 Design Patterns and Concepts Implemented

  • 🏭 Abstract Factory: SMLInstructionFactory for creating instruction instances
  • πŸ”’ Sealed Classes: CalculateInstruction and ComparisonInstruction 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

πŸ”§ Technologies Used

Core Technologies

  • 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

Testing & Quality

  • JUnit: Unit testing framework
  • Java Reflection API: Dynamic class loading and field access

πŸ“ˆ Learning Outcomes

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

🀝 Extending the Interpreter

The architecture allows easy extension by:

  1. Creating new instruction classes extending the appropriate abstract base
  2. Adding the class name to the Spring beans configuration
  3. The reflection-based factory automatically handles instantiation

Example: Adding a Modulo Operation

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>

πŸ“§ Contact

Queenie Lee - Software Developer
πŸ“§ queenie.lee[at]live.ca
πŸ”— GitHub Portfolio
πŸ’Ό Project Repository

πŸ™ Acknowledgements

This project demonstrates advanced Java programming concepts within a provided educational framework from the Software Design and Programming course.

Architecture & Implementation

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.

πŸ”§ Key Technical Implementations:

  • Instruction System: Complete implementation of all concrete instruction classes with polymorphic execution
  • Sealed Class Hierarchies: CalculateInstruction and ComparisonInstruction 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

🎯 Technical Focus Areas:

  • 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

Resources & Documentation

  • 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.

About

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.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages