Skip to content

Bivas-Biswas/PyASM-Sim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PyASM-Sim: A Python-based Assembly Language Simulator using PLY

PyASM-Sim is a simulator for a custom, simple assembly-like language, built entirely in Python using the PLY (Python Lex-Yacc) library. It parses and executes assembly code, managing a simulated memory architecture with registers, memory, and program control flow. The project demonstrates the power of PLY for creating parsers and interpreters for custom languages.


🚀 Features

  • Custom Assembly Language: A well-defined instruction set for memory, arithmetic, logical, and control flow operations.
  • Labeled Instructions: Supports labels for branching and looping, enabling complex control flow.
  • Simulated Memory: Implements a register-based architecture with a separate main memory space.
  • Multiple Addressing Modes:
    • Immediate: STOR A, 10
    • Register: SUM A, B
    • Direct (Register Indirect): STOR @A, 100 (uses the value in register A as a memory address)
  • Rich Data Type Support: Natively handles Integers, Floats, and Strings.
  • Comprehensive Instruction Set: Includes arithmetic (SUM, DIV), logical (AND, NOT), string manipulation (CONCAT, SUBSTR), and control flow (IF, GOTO) instructions.
  • Robust Parsing: Built with the PLY library, ensuring reliable and efficient parsing of the source code.
  • Detailed Error Handling: Catches both syntax errors during parsing and runtime errors (e.g., division by zero, invalid types, undefined labels) during execution.

🛠️ Language Specification

The language uses a simple format where each line can have an optional label followed by an instruction, separated by $$$.

Instruction Format

LABEL $$$ INSTRUCTION operand1, operand2, ...

If a line has no label, it starts directly with the instruction.

Instruction Set

1. Memory Operations

  • STOR dest, value: Stores a value into a destination register or memory address.

    L1 $$$ STOR A, 10          ; A = 10
    L2 $$$ STOR B, "Hello"     ; B = "Hello"
    L3 $$$ STOR @A, 50         ; Memory[A] (i.e., Memory[10]) = 50

2. Arithmetic Operations

  • SUM reg1, reg2/value: reg1 = reg1 + reg2/value

  • SUB reg1, reg2/value: reg1 = reg1 - reg2/value

  • MUL reg1, reg2/value: reg1 = reg1 * reg2/value

  • DIV reg1, reg2/value: reg1 = reg1 / reg2/value (Floating-point division)

  • MOD reg1, reg2/value: reg1 = reg1 % reg2/value

    SUM A, 5      ; A = A + 5
    SUB B, C      ; B = B - C
    DIV D, @A     ; D = D / Memory[A]

3. Logical Operations (Integer Only)

  • AND reg1, reg2/value: reg1 = reg1 & reg2/value

  • OR reg1, reg2/value: reg1 = reg1 | reg2/value

  • XOR reg1, reg2/value: reg1 = reg1 ^ reg2/value

  • NOT reg: reg = ~reg

  • SHL reg, shift_value: reg = reg << shift_value

  • SHR reg, shift_value: reg = reg >> shift_value

    SHL A, 2      ; A = A << 2
    NOT B         ; B = ~B

4. String Operations

  • CONCAT reg1, reg2/value: Concatenates the string in reg2/value to reg1. reg1 = reg1 + reg2/value.

  • LENGTH dest_reg, src_reg/value: Stores the length of the string in src_reg/value into dest_reg.

  • SUBSTR reg, pos1, pos2: Extracts a substring from reg from pos1 (inclusive) to pos2 (exclusive).

    STOR A, "Hello"
    STOR B, " World"
    CONCAT A, B              ; A is now "Hello World"
    LENGTH C, A              ; C is now 11
    SUBSTR A, 0, 5           ; A is now "Hello"

5. Control Flow

  • GOTO label: Unconditionally jumps to the specified label.

  • IF condition INSTRUCTION: Executes the INSTRUCTION only if the condition is true.

    • Conditions: reg == value, reg != value, reg > value, reg < value
  • HLT: Stops program execution and prints the final state of all registers and memory.

    STOR COUNT, 5
    LOOP $$$ SUB COUNT, 1
           PRINT COUNT
           IF COUNT > 0 GOTO LOOP
    HLT

6. Output Operations

  • PRINT reg/mem_addr: Prints the value of a register or memory location to the console.

    PRINT A        ; Prints value of register A
    PRINT @B       ; Prints value from Memory[B]

⚙️ Prerequisites

  • Python 3.8+
  • PLY library

▶️ How to Run

  1. Clone the repository:

    git clone https://github.com/Bivas-Biswas/PyASM-Sim.git
    cd PyASM-Sim
  2. Install dependencies:

    pip install ply
  3. Create your assembly file (e.g., program.asm) or use one of the examples provided.

  4. Execute the simulator:

    python main.py program.asm

    The output of the PRINT statements and the final memory dump from HLT will be displayed in the terminal.


📝 Example Program: Factorial

This program calculates the factorial of a number (e.g., 5) and prints the result.

factorial.asm

; PyASM-Sim Program to Calculate Factorial of 5

STOR N, 5            ; The number to find the factorial of
STOR RES, 1          ; Initialize result to 1
STOR I, 1            ; Initialize loop counter i to 1

LOOP $$$ SUM I, 1            ; i = i + 1
       MUL RES, I          ; result = result * i
       IF I < N GOTO LOOP  ; If i is still less than N, continue loop

PRINT RES            ; Print the final result
HLT                  ; Halt execution

Running the program:

python main.py factorial.asm

Expected Output:

120
=======================================
            HALTING
=======================================
FINAL REGISTER STATE:
  N: 5
  RES: 120
  I: 5

FINAL MEMORY STATE:
  {...}
=======================================

⚠️ Error Handling

The simulator is designed to be robust and provides clear error messages for various issues:

  • Syntax Errors: The parser will report invalid syntax, the unexpected token, and the line number.
    • SyntaxError: Unexpected token 'INVALID_OP' at line 5
  • Runtime Errors: The executor handles errors that occur during the program's run.
    • NameError: Undefined label 'UNDEFINED_LABEL' referenced at line 10.
    • TypeError: Unsupported operand type for SUM: 'int' and 'str' at line 8.
    • ValueError: Cannot perform logical NOT on non-integer value in register B at line 12.
    • ZeroDivisionError: Division by zero at line 6.

About

A Python-based Assembly Language Simulator using PLY

Topics

Resources

Stars

Watchers

Forks