初步实现编译器
This commit is contained in:
parent
e4c1087290
commit
c56daff802
|
@ -1,4 +1,5 @@
|
||||||
from error import *
|
from error import *
|
||||||
|
|
||||||
CMDs = ["jmp", "jmp_if"]
|
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):
|
def CheckArg(operand):
|
||||||
run = False
|
run = False
|
||||||
|
@ -12,6 +13,7 @@ def CheckArg(operand):
|
||||||
raise BadOperand()
|
raise BadOperand()
|
||||||
return run
|
return run
|
||||||
|
|
||||||
|
|
||||||
def eq(self, operand):
|
def eq(self, operand):
|
||||||
if CheckArg(operand) and operand[2].isRegister():
|
if CheckArg(operand) and operand[2].isRegister():
|
||||||
# 是否等于
|
# 是否等于
|
||||||
|
@ -21,6 +23,7 @@ def eq(self, operand):
|
||||||
operand[2].set(1)
|
operand[2].set(1)
|
||||||
else:
|
else:
|
||||||
operand[2].set(0)
|
operand[2].set(0)
|
||||||
|
|
||||||
|
|
||||||
def halt(self, operand):
|
def halt(self, operand):
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
import program
|
import program
|
||||||
from error import *
|
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():
|
if operand[0].isRegister() and operand[1].isMemory():
|
||||||
operand[0].set(operand[1].get())
|
operand[0].set(operand[1].get())
|
||||||
else:
|
else:
|
||||||
|
@ -17,3 +17,4 @@ def str(self, operand):
|
||||||
operand[1].set(operand[0].get())
|
operand[1].set(operand[0].get())
|
||||||
else:
|
else:
|
||||||
raise BadOperand()
|
raise BadOperand()
|
||||||
|
|
||||||
|
|
13
ASM/count.py
13
ASM/count.py
|
@ -1,6 +1,8 @@
|
||||||
from error import *
|
from error import *
|
||||||
|
|
||||||
CMDs = ["add", "sub", "mul", "div"]
|
CMDs = ["add", "sub", "mul", "div"]
|
||||||
|
|
||||||
|
|
||||||
def CheckArg(operand):
|
def CheckArg(operand):
|
||||||
run = False
|
run = False
|
||||||
if operand[0].isRegister():
|
if operand[0].isRegister():
|
||||||
|
@ -12,21 +14,23 @@ def CheckArg(operand):
|
||||||
else:
|
else:
|
||||||
raise BadOperand()
|
raise BadOperand()
|
||||||
return run
|
return run
|
||||||
|
|
||||||
|
|
||||||
def add(self, operand):
|
def add(self, operand):
|
||||||
run = CheckArg(operand)
|
run = CheckArg(operand)
|
||||||
if run:
|
if run:
|
||||||
a = operand[0].get()
|
a = operand[0].get()
|
||||||
b = operand[1].get()
|
b = operand[1].get()
|
||||||
operand[0].set(a + b)
|
operand[0].set(a + b)
|
||||||
|
|
||||||
|
|
||||||
def sub(self, operand):
|
def sub(self, operand):
|
||||||
run = CheckArg(operand)
|
run = CheckArg(operand)
|
||||||
if run:
|
if run:
|
||||||
a = operand[0].get()
|
a = operand[0].get()
|
||||||
b = operand[1].get()
|
b = operand[1].get()
|
||||||
operand[0].set(a - b)
|
operand[0].set(a - b)
|
||||||
|
|
||||||
|
|
||||||
def mul(self, operand):
|
def mul(self, operand):
|
||||||
run = CheckArg(operand)
|
run = CheckArg(operand)
|
||||||
|
@ -34,7 +38,7 @@ def mul(self, operand):
|
||||||
a = operand[0].get()
|
a = operand[0].get()
|
||||||
b = operand[1].get()
|
b = operand[1].get()
|
||||||
operand[0].set(a * b)
|
operand[0].set(a * b)
|
||||||
|
|
||||||
|
|
||||||
def div(self, operand):
|
def div(self, operand):
|
||||||
run = CheckArg(operand)
|
run = CheckArg(operand)
|
||||||
|
@ -42,4 +46,3 @@ def div(self, operand):
|
||||||
a = operand[0].get()
|
a = operand[0].get()
|
||||||
b = operand[1].get()
|
b = operand[1].get()
|
||||||
operand[0].set(a // b)
|
operand[0].set(a // b)
|
||||||
|
|
10
CPU.py
10
CPU.py
|
@ -22,12 +22,14 @@ class Core:
|
||||||
self.pc = 0 # 程序计数器
|
self.pc = 0 # 程序计数器
|
||||||
self.stack = queue.LifoQueue(maxsize=10 * self.registers.size) # 栈
|
self.stack = queue.LifoQueue(maxsize=10 * self.registers.size) # 栈
|
||||||
|
|
||||||
self.ASMModule = []
|
|
||||||
self.ASMs = {}
|
self.ASMs = {}
|
||||||
|
|
||||||
for file in pathlib.Path("ASM").iterdir():
|
for file in pathlib.Path("ASM").iterdir():
|
||||||
if file.is_dir():
|
if file.is_dir():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if str(file).split('.')[-1] not in ['py', 'pyc', 'pyd', 'so']:
|
||||||
|
continue
|
||||||
module = "ASM." + file.name.split(".")[0]
|
module = "ASM." + file.name.split(".")[0]
|
||||||
module = importlib.import_module(module)
|
module = importlib.import_module(module)
|
||||||
for cmd in module.CMDs:
|
for cmd in module.CMDs:
|
||||||
|
@ -35,7 +37,7 @@ class Core:
|
||||||
|
|
||||||
def loadProgram(self, code):
|
def loadProgram(self, code):
|
||||||
# 加载程序至cmdMemroy
|
# 加载程序至cmdMemroy
|
||||||
self.cmdMemory[: len(code)] = code
|
self.cmdMemory.write_batch(0,code)
|
||||||
|
|
||||||
def fetchInstruction(self):
|
def fetchInstruction(self):
|
||||||
# 取指令
|
# 取指令
|
||||||
|
@ -75,7 +77,7 @@ class Core:
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
raise InvalidInstruction()
|
raise InvalidInstruction(instruction)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
# 开始执行
|
# 开始执行
|
||||||
|
@ -117,7 +119,7 @@ class CPU(Core):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
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)
|
program.Operand(["r0"], cpu)[0].set(2)
|
||||||
f = open('Example/加法器.txt')
|
f = open('Example/加法器.txt')
|
||||||
code = f.read().split('\n')
|
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:
|
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:
|
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)
|
10
Memory.py
10
Memory.py
|
@ -19,15 +19,15 @@ class Memory:
|
||||||
if index > self.size:
|
if index > self.size:
|
||||||
raise AddressError()
|
raise AddressError()
|
||||||
self.data[index] = val
|
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:
|
if start + len(dt) > self.size:
|
||||||
raise OutOfMemory('内存用尽')
|
raise OutOfMemory("内存用尽")
|
||||||
|
|
||||||
for i in dt:
|
for i in dt:
|
||||||
self.write(start, i)
|
self.write(start, i)
|
||||||
start += 1
|
start += 1
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return self.size
|
return self.size
|
||||||
|
|
||||||
|
|
15
error.py
15
error.py
|
@ -1,17 +1,22 @@
|
||||||
class dtMemoryError(Exception):
|
class dtMemoryError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class AddressError(dtMemoryError):
|
class AddressError(dtMemoryError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OutOfMemory(dtMemoryError):
|
class OutOfMemory(dtMemoryError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InstructionError(Exception):
|
class InstructionError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InvalidInstruction(InstructionError):
|
class InvalidInstruction(InstructionError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BadOperand(InstructionError):
|
class BadOperand(InstructionError):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -4,6 +4,11 @@ from error import *
|
||||||
class Program:
|
class Program:
|
||||||
def __init__(self, code: str):
|
def __init__(self, code: str):
|
||||||
self.codelist = code.split("\n")
|
self.codelist = code.split("\n")
|
||||||
|
self.res = []
|
||||||
|
def parser(self):
|
||||||
|
for i in self.codelist:
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BaseArg:
|
class BaseArg:
|
||||||
|
@ -61,7 +66,7 @@ class Operand:
|
||||||
def __init__(self, operList, cpu):
|
def __init__(self, operList, cpu):
|
||||||
self.List = []
|
self.List = []
|
||||||
for i in operList:
|
for i in operList:
|
||||||
|
|
||||||
if i[0] == "r":
|
if i[0] == "r":
|
||||||
self.List.append(RegisterArg(int(i[1:]), cpu))
|
self.List.append(RegisterArg(int(i[1:]), cpu))
|
||||||
elif i[0:2] == "0x":
|
elif i[0:2] == "0x":
|
||||||
|
@ -69,6 +74,6 @@ class Operand:
|
||||||
self.List.append(MemoryArg(index, cpu))
|
self.List.append(MemoryArg(index, cpu))
|
||||||
elif i.isdigit():
|
elif i.isdigit():
|
||||||
self.List.append(ImmediateArg(int(i)))
|
self.List.append(ImmediateArg(int(i)))
|
||||||
|
|
||||||
def __getitem__(self, key: int):
|
def __getitem__(self, key: int):
|
||||||
return self.List[key]
|
return self.List[key]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user