| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- #!/usr/bin/python3
- import argparse
- import sys
- from os import path
- ch_add = {'+'}
- ch_sub = {'-'}
- ch_left = {'<'}
- ch_right = {'>'}
- ch_print = {'.'}
- ch_start = {'['}
- ch_stop = {']'}
- def compileBF(filename):
- program = []
- # Init program
- # $ra: Current value
- # $rb: ??
- # $rc: Memory pointer
- # $re: The +/- 1 value
- program.append("CPY $rc 0xFF")
- program.append("CPY $re 1")
- program.append("memInitStart:")
- program.append("JEQ $ra $rc memInitFinish")
- program.append("SW $rb $ra")
- program.append("ADD $ra $re")
- program.append("JMP memInitStart")
- program.append("memInitFinish:")
- program.append("CPY $rb 0")
- program.append("CPY $ra $rb")
- program.append("CPY $rc $rb")
- f = open(filename, 'r')
- pc = 0
- nc = 0
- lc = 0
- rc = 0
- nodePrev = []
- nodeCount = 0
- while 1:
- c = f.read(1)
- if c == '':
- break
- if c in ch_add:
- pc += 1
- elif pc > 0:
- program.append(f"CPY $re {pc}")
- pc = 0
- program.append("ADD $ra $re")
- if c in ch_sub:
- nc += 1
- elif nc > 0:
- program.append(f"CPY $re {nc}")
- nc = 0
- program.append("SUB $ra $re")
- if c in ch_right:
- rc += 1
- elif rc > 0:
- program.append("SW $ra $rc")
- program.append(f"CPY $re {rc}")
- program.append("ADD $rc $re")
- program.append("LW $ra $rc")
- rc = 0
- if c in ch_left:
- lc += 1
- elif lc > 0:
- program.append("SW $ra $rc")
- program.append(f"CPY $re {lc}")
- program.append("SUB $rc $re")
- program.append("LW $ra $rc")
- lc = 0
- if c in ch_print:
- program.append("CPY $re 0xFF")
- program.append("SW $ra $re")
- if c in ch_start:
- nodePrev.append(nodeCount)
- program.append(f"node{nodeCount:04d}s:")
- program.append(f"JEQ $ra $rb node{nodeCount:04d}e")
- nodeCount += 1
- if c in ch_stop:
- node = nodePrev.pop(-1)
- program.append(f"JMP node{node:04d}s")
- program.append(f"node{node:04d}e:")
- f.close()
- return program
- if __name__ == '__main__':
- parser = argparse.ArgumentParser(description='Assembly compiler', add_help=True)
- parser.add_argument('file', help='Files to compile')
- # parser.add_argument('-t', '--output_type', choices=['asm', 'mem', 'binary'], default='mem', help='Output type')
- parser.add_argument('-o', '--output', help='Output file')
- parser.add_argument('-f', '--force', action='store_true', help='Force override output file')
- args = parser.parse_args(sys.argv[1:])
- if not path.isfile(args.file):
- print(f'No file {args.file}!')
- sys.exit(1)
- asm = compileBF(args.file)
- data = '\n'.join(asm)
- if args.output and (not path.isfile(args.output) or args.force):
- with open(args.output, 'w') as o:
- o.write(data)
- elif args.output is None:
- print(data)
|