初步实现编译器
This commit is contained in:
parent
e4c1087290
commit
c56daff802
|
@ -1,4 +1,5 @@
|
|||
from error import *
|
||||
|
||||
CMDs = ["jmp", "jmp_if"]
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
CMDs = ["eq", 'halt'] # , 'en', 'gt', 'lt', 'ge', 'le']
|
||||
CMDs = ["eq", "halt"] # , 'en', 'gt', 'lt', 'ge', 'le']
|
||||
|
||||
|
||||
def CheckArg(operand):
|
||||
run = False
|
||||
|
@ -12,6 +13,7 @@ def CheckArg(operand):
|
|||
raise BadOperand()
|
||||
return run
|
||||
|
||||
|
||||
def eq(self, operand):
|
||||
if CheckArg(operand) and operand[2].isRegister():
|
||||
# 是否等于
|
||||
|
@ -22,5 +24,6 @@ def eq(self, operand):
|
|||
else:
|
||||
operand[2].set(0)
|
||||
|
||||
|
||||
def halt(self, operand):
|
||||
return False
|
|
@ -2,10 +2,10 @@
|
|||
import program
|
||||
from error import *
|
||||
|
||||
CMDs = ["ldr", "str"]
|
||||
CMDs = ["ldr", "str", 'ldrb']
|
||||
|
||||
|
||||
def ldr(self, operand:program.Operand):
|
||||
def ldr(self, operand: program.Operand):
|
||||
if operand[0].isRegister() and operand[1].isMemory():
|
||||
operand[0].set(operand[1].get())
|
||||
else:
|
||||
|
@ -17,3 +17,4 @@ def str(self, operand):
|
|||
operand[1].set(operand[0].get())
|
||||
else:
|
||||
raise BadOperand()
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from error import *
|
||||
|
||||
CMDs = ["add", "sub", "mul", "div"]
|
||||
|
||||
|
||||
def CheckArg(operand):
|
||||
run = False
|
||||
if operand[0].isRegister():
|
||||
|
@ -13,6 +15,7 @@ def CheckArg(operand):
|
|||
raise BadOperand()
|
||||
return run
|
||||
|
||||
|
||||
def add(self, operand):
|
||||
run = CheckArg(operand)
|
||||
if run:
|
||||
|
@ -20,6 +23,7 @@ def add(self, operand):
|
|||
b = operand[1].get()
|
||||
operand[0].set(a + b)
|
||||
|
||||
|
||||
def sub(self, operand):
|
||||
run = CheckArg(operand)
|
||||
if run:
|
||||
|
@ -42,4 +46,3 @@ def div(self, operand):
|
|||
a = operand[0].get()
|
||||
b = operand[1].get()
|
||||
operand[0].set(a // b)
|
||||
|
10
CPU.py
10
CPU.py
|
@ -22,12 +22,14 @@ class Core:
|
|||
self.pc = 0 # 程序计数器
|
||||
self.stack = queue.LifoQueue(maxsize=10 * self.registers.size) # 栈
|
||||
|
||||
self.ASMModule = []
|
||||
self.ASMs = {}
|
||||
|
||||
for file in pathlib.Path("ASM").iterdir():
|
||||
if file.is_dir():
|
||||
continue
|
||||
|
||||
if str(file).split('.')[-1] not in ['py', 'pyc', 'pyd', 'so']:
|
||||
continue
|
||||
module = "ASM." + file.name.split(".")[0]
|
||||
module = importlib.import_module(module)
|
||||
for cmd in module.CMDs:
|
||||
|
@ -35,7 +37,7 @@ class Core:
|
|||
|
||||
def loadProgram(self, code):
|
||||
# 加载程序至cmdMemroy
|
||||
self.cmdMemory[: len(code)] = code
|
||||
self.cmdMemory.write_batch(0,code)
|
||||
|
||||
def fetchInstruction(self):
|
||||
# 取指令
|
||||
|
@ -75,7 +77,7 @@ class Core:
|
|||
|
||||
else:
|
||||
|
||||
raise InvalidInstruction()
|
||||
raise InvalidInstruction(instruction)
|
||||
|
||||
def run(self):
|
||||
# 开始执行
|
||||
|
@ -117,7 +119,7 @@ class CPU(Core):
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cpu = CPU(registers=64, dtMemory=1024, cmdMemory=1024)
|
||||
cpu = CPU(registers=64, dtMemory=1024, cmdMemory=10)
|
||||
program.Operand(["r0"], cpu)[0].set(2)
|
||||
f = open('Example/加法器.txt')
|
||||
code = f.read().split('\n')
|
||||
|
|
51
Compiler.py
Normal file
51
Compiler.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
from Device import Codec
|
||||
import time
|
||||
class Compiler:
|
||||
def __init__(self, codes, filename='a.out'):
|
||||
self.filename = filename
|
||||
self.data = []
|
||||
|
||||
for i in codes:
|
||||
self.data.append(Codec.str2int(i))
|
||||
|
||||
self.write()
|
||||
|
||||
def write(self):
|
||||
# 打开文件,以二进制写入模式打开
|
||||
with open(self.filename, 'wb') as f:
|
||||
maxNum = max(self.data)
|
||||
byte_representation = (maxNum.bit_length() + 7) // 8
|
||||
if byte_representation > 139:
|
||||
raise MemoryError()
|
||||
# 写入整数数据
|
||||
f.write(b'\x5a\xe3'+byte_representation.to_bytes(1, 'little'))
|
||||
for num in self.data:
|
||||
# 将整数转换为字节,并写入文件
|
||||
f.write(num.to_bytes(byte_representation , 'little')) # 假设每个整数都用4个字节表示
|
||||
|
||||
def read(self):
|
||||
int_data_read = [] # 用于存储读取的整数数据
|
||||
|
||||
# 打开文件,以二进制读取模式打开
|
||||
with open(self.filename, 'rb') as f:
|
||||
# 读取整数数据
|
||||
MagicNumber = f.read(2)
|
||||
|
||||
size = int.from_bytes(f.read(1), 'little')
|
||||
while True:
|
||||
# 从文件中读取4个字节,并将其转换为整数
|
||||
int_bytes = f.read(size)
|
||||
|
||||
if not int_bytes: # 如果读取完整个文件,则退出循环
|
||||
break
|
||||
int_value = int.from_bytes(int_bytes, 'little') # 假设之前用little-endian序列化
|
||||
int_value = Codec.int2list(int_value)
|
||||
|
||||
int_value = Codec.int2str(int_value)
|
||||
int_data_read.append(int_value)
|
||||
|
||||
return int_data_read
|
||||
start = time.time()
|
||||
c = Compiler(["l","h",'kakshdhsh sjjsvav'])
|
||||
print(time.time()-start)
|
||||
print(list(c.read()))
|
|
@ -1,7 +1,56 @@
|
|||
def byte2int(dt: bytes):
|
||||
from functools import lru_cache
|
||||
import math
|
||||
def str2int(dt: str):
|
||||
a = []
|
||||
maxInt = 0
|
||||
# 遍历输入的字符串
|
||||
for i in dt:
|
||||
yield i # 这将直接生成每个字节
|
||||
# 使用ord函数将每个字符转换为对应的ASCII码,生成整数流
|
||||
this = ord(i)
|
||||
if this >maxInt:
|
||||
maxInt = this
|
||||
a.append(str(this))
|
||||
IntSize = len(str(maxInt))
|
||||
out = str(IntSize)
|
||||
for i in a:
|
||||
i.zfill(IntSize)
|
||||
# 将处理后的整数字符串添加到输出字符串中
|
||||
out += i
|
||||
return int(out)
|
||||
|
||||
def int2bytes(dt: list[int]):
|
||||
def int2str(dt: list[int]):
|
||||
# 遍历整数列表
|
||||
a = []
|
||||
for i in dt:
|
||||
yield i.to_bytes(1, byteorder='big') # 将整数转换为字节
|
||||
# 使用chr函数将每个整数转换为对应的字符,生成字节流
|
||||
a.append(chr(i))
|
||||
return a
|
||||
|
||||
def list2int(dt: list[str]):
|
||||
# 防止第一个数为零
|
||||
maxInt = max(dt)
|
||||
IntSize = len(str(maxInt))
|
||||
out = str(IntSize)
|
||||
|
||||
# 遍历整数列表
|
||||
for i in dt:
|
||||
# 将整数转换为字符串
|
||||
i = str(i)
|
||||
# 如果字符串长度小于3,则在前面补0,使其长度为3
|
||||
if len(i) < IntSize:
|
||||
while len(i) < IntSize:
|
||||
i = '0' + i
|
||||
# 将处理后的整数字符串添加到输出字符串中
|
||||
out += i
|
||||
# 将结果字符串转换为整数并返回
|
||||
return int(out)
|
||||
|
||||
def int2list(dt: int):
|
||||
# 将整数转换为字符串,并去掉前面的'100'
|
||||
size = int(str(dt)[0])
|
||||
dt = str(dt)[1:]
|
||||
# 将字符串按照每3个字符分割为子列表
|
||||
sub_lists = [dt[i:i+size] for i in range(0, len(dt), size)]
|
||||
# 遍历子列表并将其转换为整数后返回
|
||||
for i in sub_lists:
|
||||
yield int(i)
|
|
@ -20,9 +20,9 @@ class Memory:
|
|||
raise AddressError()
|
||||
self.data[index] = val
|
||||
|
||||
def write_batch(self, start ,dt:list[int]):
|
||||
def write_batch(self, start, dt: list[int]):
|
||||
if start + len(dt) > self.size:
|
||||
raise OutOfMemory('内存用尽')
|
||||
raise OutOfMemory("内存用尽")
|
||||
|
||||
for i in dt:
|
||||
self.write(start, i)
|
||||
|
|
5
error.py
5
error.py
|
@ -1,17 +1,22 @@
|
|||
class dtMemoryError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class AddressError(dtMemoryError):
|
||||
pass
|
||||
|
||||
|
||||
class OutOfMemory(dtMemoryError):
|
||||
pass
|
||||
|
||||
|
||||
class InstructionError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidInstruction(InstructionError):
|
||||
pass
|
||||
|
||||
|
||||
class BadOperand(InstructionError):
|
||||
pass
|
|
@ -4,6 +4,11 @@ from error import *
|
|||
class Program:
|
||||
def __init__(self, code: str):
|
||||
self.codelist = code.split("\n")
|
||||
self.res = []
|
||||
def parser(self):
|
||||
for i in self.codelist:
|
||||
print(i)
|
||||
|
||||
|
||||
|
||||
class BaseArg:
|
||||
|
|
Loading…
Reference in New Issue
Block a user