117 lines
4.3 KiB
Python
117 lines
4.3 KiB
Python
def parse_math_to_instructions(math_expression, memory_map):
|
|
"""
|
|
Converts a simple math expression or variable assignment to assembly instructions.
|
|
:param math_expression: The math expression to convert.
|
|
:param memory_map: A dictionary tracking variable memory locations.
|
|
:return: A list of assembly instructions.
|
|
"""
|
|
instructions = []
|
|
temp_memory_address = 0xFF # Starting memory address for variables
|
|
|
|
# Check for assignment
|
|
if '=' in math_expression:
|
|
var_name, expr = map(str.strip, math_expression.split('='))
|
|
expr = expr.strip(';') # Remove trailing semicolon
|
|
var_name = var_name.strip()
|
|
|
|
var_name = var_name.strip("int ")
|
|
|
|
# Generate instructions for the expression
|
|
expr_instructions, result_register = parse_expression(expr, memory_map, temp_memory_address)
|
|
instructions.extend(expr_instructions)
|
|
|
|
# Assign the result to the variable
|
|
if var_name not in memory_map:
|
|
memory_map[var_name] = temp_memory_address
|
|
temp_memory_address -= 1
|
|
instructions.append(f"str {result_register}, 0x{memory_map[var_name]:X} ; Save variable {var_name} in memory")
|
|
else:
|
|
# Generate instructions for the expression
|
|
expr_instructions, _ = parse_expression(math_expression, memory_map, temp_memory_address)
|
|
instructions.extend(expr_instructions)
|
|
|
|
return instructions
|
|
|
|
def precedence(op):
|
|
"""
|
|
Returns the precedence of the given operator.
|
|
"""
|
|
if op in ('+', '-'):
|
|
return 1
|
|
if op in ('*', '/'):
|
|
return 2
|
|
return 0
|
|
|
|
def apply_operator(instructions, operand_stack, operator):
|
|
"""
|
|
Applies an operator to the top two operands in the operand stack and generates instructions.
|
|
"""
|
|
b = operand_stack.pop()
|
|
a = operand_stack.pop()
|
|
if operator == '+':
|
|
instructions.append("add a, b")
|
|
elif operator == '-':
|
|
instructions.append("sub a, b")
|
|
elif operator == '*':
|
|
instructions.append("mul a, b")
|
|
elif operator == '/':
|
|
instructions.append("div a, b")
|
|
operand_stack.append('a')
|
|
|
|
def parse_expression(expr, memory_map, temp_memory_address):
|
|
"""
|
|
Parses a math expression and generates instructions.
|
|
:param expr: The math expression.
|
|
:param memory_map: Memory map for variables.
|
|
:param temp_memory_address: Memory address to use for new variables.
|
|
:return: (list of instructions, result_register)
|
|
"""
|
|
instructions = []
|
|
tokens = expr.replace('(', ' ( ').replace(')', ' ) ').split()
|
|
operator_stack = []
|
|
operand_stack = []
|
|
|
|
for token in tokens:
|
|
if token.isdigit():
|
|
if 'a' not in operand_stack:
|
|
instructions.append(f"ldw a, {token}")
|
|
operand_stack.append('a')
|
|
else:
|
|
instructions.append(f"ldw b, {token}")
|
|
operand_stack.append('b')
|
|
elif token in memory_map:
|
|
if 'a' not in operand_stack:
|
|
instructions.append(f"ldr a, 0x{memory_map[token]:X}")
|
|
operand_stack.append('a')
|
|
else:
|
|
instructions.append(f"ldr b, 0x{memory_map[token]:X}")
|
|
operand_stack.append('b')
|
|
elif token in ['+', '-', '*', '/']:
|
|
while (operator_stack and precedence(operator_stack[-1]) >= precedence(token)):
|
|
apply_operator(instructions, operand_stack, operator_stack.pop())
|
|
operator_stack.append(token)
|
|
elif token == '(':
|
|
operator_stack.append(token)
|
|
elif token == ')':
|
|
while operator_stack and operator_stack[-1] != '(':
|
|
apply_operator(instructions, operand_stack, operator_stack.pop())
|
|
operator_stack.pop() # Remove '('
|
|
|
|
while operator_stack:
|
|
apply_operator(instructions, operand_stack, operator_stack.pop())
|
|
|
|
return instructions, 'a'
|
|
|
|
# Example Usage
|
|
memory_map = {}
|
|
expressions = [
|
|
"1 + ( 3 + 8 )",
|
|
"int variable = 1 + ( 3 + 8 );",
|
|
"int variable_dose = variable + ( 4 + 4 );"
|
|
]
|
|
|
|
for expr in expressions:
|
|
instructions = parse_math_to_instructions(expr, memory_map)
|
|
for instr in instructions:
|
|
print(instr)
|
|
print('; - - - - - - - - - -') |