toolchain: retro-muri.py gets some comments, minor internal layout change
FossilOrigin-Name: ca10fc2d2b2c757ca6b1b7e073ee9b8e3b25c13cb137f011f9393efd8b376f75
This commit is contained in:
parent
de6c62d5f2
commit
a8b8f5a2bc
1 changed files with 57 additions and 24 deletions
|
@ -1,34 +1,34 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# retro-muri is an assembler for Nga, the virtual machine at the heart of
|
||||
# Retro. It is used to build the image file containing the actual Retro
|
||||
# language.
|
||||
#
|
||||
# This will extract the code blocks in the specified file and generate an
|
||||
# image file named `ngaImage`.
|
||||
#
|
||||
# Copyright (c) 2020, Charles Childers
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# retro.muri.py filename
|
||||
|
||||
import sys, struct
|
||||
|
||||
# labels stores the label names as a dictionary, with the key being
|
||||
# the label name and the value being the location in memory.
|
||||
#
|
||||
# image stores the assembled opcodes and data.
|
||||
|
||||
labels = dict()
|
||||
image = []
|
||||
|
||||
# the first pass identifies the labels and fills in a dictionary
|
||||
# that will be used in the second pass
|
||||
|
||||
|
||||
def pass1():
|
||||
global labels
|
||||
i = 0
|
||||
f = sys.argv[1]
|
||||
in_block = False
|
||||
with open(f, "r") as source:
|
||||
for line in source.readlines():
|
||||
if line.rstrip() == "~~~":
|
||||
in_block = not in_block
|
||||
elif in_block:
|
||||
if line[0] == "i":
|
||||
i += 1
|
||||
if line[0] == "d":
|
||||
i += 1
|
||||
if line[0] == "r":
|
||||
i += 1
|
||||
if line[0] == "s":
|
||||
i += len(line[2:].rstrip()) + 1
|
||||
if line[0] == ":":
|
||||
labels[line[2:].rstrip()] = i
|
||||
# assemble() takes a string representation of an opcode bundle,
|
||||
# finds the individual opcodes, packs them into a cell-sized value,
|
||||
# and returns this value.
|
||||
#
|
||||
# Each instruction bundle has four two character instruction names,
|
||||
# with `..` used to represent a non-operation instruction.
|
||||
|
||||
|
||||
def assemble(inst):
|
||||
|
@ -72,6 +72,36 @@ def assemble(inst):
|
|||
return o
|
||||
|
||||
|
||||
# muri performs two passes. The first identifies the labels
|
||||
# and populates the `labels` dictionary
|
||||
|
||||
|
||||
def pass1():
|
||||
global labels
|
||||
i = 0
|
||||
f = sys.argv[1]
|
||||
in_block = False
|
||||
with open(f, "r") as source:
|
||||
for line in source.readlines():
|
||||
if line.rstrip() == "~~~":
|
||||
in_block = not in_block
|
||||
elif in_block:
|
||||
if line[0] == "i":
|
||||
i += 1
|
||||
if line[0] == "d":
|
||||
i += 1
|
||||
if line[0] == "r":
|
||||
i += 1
|
||||
if line[0] == "s":
|
||||
i += len(line[2:].rstrip()) + 1
|
||||
if line[0] == ":":
|
||||
labels[line[2:].rstrip()] = i
|
||||
|
||||
|
||||
# The second pass actually assembles the instructions and fills
|
||||
# the `image` array with the opcodes and data provided.
|
||||
|
||||
|
||||
def pass2():
|
||||
global image
|
||||
i = 0
|
||||
|
@ -101,6 +131,9 @@ def pass2():
|
|||
i += 1
|
||||
|
||||
|
||||
# save() handles writing the image to a file
|
||||
|
||||
|
||||
def save(filename):
|
||||
with open(filename, "wb") as file:
|
||||
j = 0
|
||||
|
|
Loading…
Reference in a new issue