# 编译一位数四则运算
# 原教材 第二篇。
#
# 若改为x86,则需要调整输出语句。同时R0可设为eax,R1设为edx。
# x86 也差不多式微了,苹果都抛弃了它。不知说什么好。
#--------------------------------------------------------------
"""program Cradle"""
#--------------------------------------------------------------
# Constant Declarations
TAB = ' ● '
src="1+2*4+5-6*(1+2)/((-3+4)+(5-6))" # 源代码脚本
#src='1-2'
print(src+"\n")
#___________________________
class source():
def __init__(self,f):
self.file=f
self.step=0
self.size=len(f)
def read(self):
if self.step < self.size:
rt=self.file[self.step]
self.step+=1
print(rt)
return rt
else:
return None
src=source(src)
#--------------------------------------------------------------
# Variable Declarations
Look="" # char # Lookahead Character
#--------------------------------------------------------------
# Read New Character From Input Stream
def GetChar():
global Look
Look=src.read()
#--------------------------------------------------------------
# Report an Error
def Error(s: str):
WriteLn=print
WriteLn('Error: ', s, '.')
#--------------------------------------------------------------
# Report Error and Halt
def Abort(s: str):
Error(s)
quit()
#--------------------------------------------------------------
# Report What Was Expected
def Expected(s: str):
Abort(s + ' Expected')
#--------------------------------------------------------------
# Match a Specific Input Character
def Match(x: chr):
if Look == x :
GetChar ()
else: Expected('☞ ' + x + ' ')
#--------------------------------------------------------------
# Recognize an Alpha Character
def IsAlpha(c: chr): #boolean
return c.isalpha()
#--------------------------------------------------------------
# Recognize a Decimal Digit
def IsDigit(c: chr): # boolean
return c.isdigit()
#--------------------------------------------------------------
# Get an Identifier
def GetName(): #char
if not IsAlpha(Look) :
Expected('Name')
rt= Look.upper()
GetChar()
return rt
#--------------------------------------------------------------
# Get a Number
def GetNum(): #char
if not IsDigit(Look) :
Expected('Integer')
rt = Look
GetChar()
return rt
#--------------------------------------------------------------
# Output a String with Tab
def Emit(s: str):
Write=print
Write(TAB, s)
#--------------------------------------------------------------
# Output a String with Tab and CRLF
def EmitLn(s: str):
Emit(s)
WriteLn=print
WriteLn()
#--------------------------------------------------------------
# Initialize
def Init():
GetChar()
#------------------------------------------------------
#def Expression(): # 2.1
#def Term(): # 2.2
#------------------------------------------------------
def Factor():
global Look
if Look == '(' :
Match ('(')
Expression()
Match(')' )
else:
EmitLn('#' + GetNum() + ' --> R0')
#--------------------------------------------------------------
def IsAddop(c: chr): # boolean
return c in ['+', '-']
def Expression(): # 2 expression ::= term [op term]*
global Look
if IsAddop(Look) :
EmitLn('CLR D0')
else:
Term()
while Look in ['+', '-'] :
EmitLn('R0 --> PUSH')
if Look =='+': Add()
elif Look == '-': Subtract()
else: Expected('加法操作符')
#--------------------------------------------------------------
def Add():
Match('+')
Term()
#EmitLn('ADD D1,D0')
EmitLn ("POP --> R1" ) #('ADD (SP)+,R0')
EmitLn ('ADD R1, R0 --> R0')
# x86
# ADD R0, R1 --> R0
#--------------------------------------------------------------
def Subtract():
Match('-')
Term()
EmitLn('POP -->R1') # ('SUB (SP)+,R0')
EmitLn('SUB R1, R0 --> R0 ')
EmitLn('NEG R0')
# x86
# SUB R1, R0 --> R1
# MOV R0 , R1 --> R0
#--------------------------------------------------------------
# Recognize and Translate a Multiply
def Multiply():
Match('*')
Factor()
EmitLn("POP --> R1") # ('MULS (SP)+,R0')
EmitLn("MULS R1, R0 --> R0")
# x86
# MUL R0,R1 --> R0
#--------------------------------------------------------------
def Divide():
Match('/')
Factor()
EmitLn('POP --> R1')
EmitLn('DIVS R1, R0 --> R0')
# x86
# DIV R1, R0 --> R1
# MOV R0, R1 --> R0
#--------------------------------------------------------------
def Term():
global Look
Factor()
while Look in ['*', '/'] :
EmitLn('R0 --> PUSH')
if Look == '*': Multiply()
elif Look == '/': Divide()
else: Expected('Mulop')
#--------------------------------------------------------------
Init()
Expression()