Exemple #1
0
 def writeByte(self, address, num):
     if num == None:
         report(self.line, self.column, f'{num}, Wrote Nothing ',
                RuntimeWarning)
         return
     address = self.toSigned(address)
     memory[address] = num
    def buildStmt(self):
        #We have no errors at the start of the stmt
        self.currentStmtError = False
        #Since Stmt doesn't hold any data but instead contains links to other nodes
        #We use peek and not advance
        currentToken = self.peek()
        #If it's a single length insturction we build that up
        if self.isSingleLength(currentToken):
            singleNode = self.buildSingleChain()
            stmt = (singleNode)

        #If it's a double instruction, we build that
        elif self.isDoubleLength(currentToken):
            doubleNode = self.buildDouble()
            stmt = (doubleNode)

        #Otherwise we have a Parser Error for not having an instruction
        else:
            report(currentToken.line, currentToken.column,
                   "Invalid Instruction : " + currentToken.text, ParsingError)
            self.currentStmtError = True
        #If we've had an error in the statement we let our error handler handle it
        if (self.currentStmtError):
            self.hadError = True
            self.errorHandle()
            return
        return stmt
    def buildOperation(self):
        #buildOperation consumes the next opeartion token so we use advance here
        operationToken = self.advance()
        #We match the next token with the appropriate type
        if self.isPrefix(operationToken):
            label = 'Prefix'
        elif self.isOffset(operationToken):
            label = 'Offset'
        else:
            label = 'Single'
        node = reps.Node(label, True, self.distance)

        operandToken = self.peek()
        #After checking if the following token is a Number we eat it and move on
        if self.isInteger(operandToken):
            self.advance()
            node.setInstruc(operationToken)
            node.setOperand(operandToken)
            self.distance += 1
            #We then check if the next Token is NEXT and if so we just consume it
            self.eatIfNext()
        #If not we have an error and we let the error handler in buildstmt handle it
        else:
            report(operandToken.line, operandToken.column,
                   "Invalid Operand: " + operandToken.text, ParsingError)
            self.currentStmtError = True
        return node
    def buildSingleChain(self):
        #First we check what type the next token
        currentToken = self.peek()

        #If we match S O we build that and return
        if not self.isPrefix(currentToken):
            operationNode = self.buildOperation()
            return operationNode

        #If we have a prefix we branch to match (P O) I
        tree = reps.Node('Chain', distance=self.distance)
        while self.isPrefix(currentToken):
            prefixNode = self.buildOperation()
            tree.add(prefixNode)
            currentToken = self.peek()

        #This sequence must end with a S O
        if self.isSingleLength(currentToken):
            operationNode = self.buildOperation()
            tree.add(operationNode)
        #If it doesn't end in S O we have an error
        #We check if a relevant error has already been raised. If so we don't raise another error
        elif self.currentStmtError == False:
            report(currentToken.line, currentToken.column,
                   "Not a Single Length Instruction: " + currentToken.text,
                   ParsingError)
            self.currentStmtError = True
        return tree
Exemple #5
0
 def LDL(self):
     value = self.readMem(self.workspace(self.Oreg))
     if value == None:
         report(
             self.line, self.column,
             f'At: {self.currentInstrucName} {self.Oreg}, Loaded Nothing',
             RuntimeWarning)
     self.push(value)
     self.Oreg = 0
Exemple #6
0
 def pop(self):
     #Pop an item from the stack [A,B,C] and let the user know if it would be invalid.
     result = self.Areg
     self.Areg = self.Breg
     self.Breg = self.Creg
     if self.stackdepth == 0:
         report(self.line, self.column,
                f'{self.currentInstrucName}Stack is empty', RuntimeWarning)
     else:
         self.stackdepth -= 1
     return result
Exemple #7
0
 def LDNL(self):
     if not self.isValidReg('Areg', True):
         return
     if self.Areg & self.byteSelectMask == 0:
         index = self.Areg + self.bytesPerWord * self.Oreg
         self.Areg = self.readMem(index)
     else:
         report(
             self.line, self.column,
             f'At: {self.currentInstrucName} {self.Oreg}, Loaded Nothing',
             RuntimeWarning)
     self.Oreg = 0
Exemple #8
0
 def STNL(self):
     if not self.isValidReg('Areg', True):
         return
     if self.Areg & self.byteSelectMask == 0:
         movement = self.pop()
         value = self.pop()
         if value == None:
             report(
                 self.line, self.column,
                 f'At: {self.currentInstrucName} {self.Oreg}, Stored \'None\' ',
                 RuntimeWarning)
         movement = movement + self.Oreg
     self.Oreg = 0
Exemple #9
0
 def execute(self, name):
     self.currentInstrucName = name
     try:
         eval('self.' + name + '()')
     #If we can't match that means we've not implemented it yet
     except Warning:
         pass
     except AttributeError:
         message = f'{name} is not yet implemented in the simulator'
         report(self.line, self.column, message, InstructionNotImplemented)
         self.error = True
     except Exception as inst:
         print(inst)
Exemple #10
0
 def ADC(self):
     self.Areg += self.Oreg
     if self.Areg > 2**(self.bit - 1) - 1:
         report(
             self.line, self.column,
             f'At: {self.currentInstrucName} {self.Oreg+self}, Integer Overflow',
             RunTimeError)
         self.haltFlag = True
     elif self.Areg < -2**(self.bit - 1):
         report(
             self.line, self.column,
             f'At: {self.currentInstrucName} {self.Oreg+self}, Integer Underflow',
             RunTimeError)
         self.haltFlag = True
     self.Oreg = 0
Exemple #11
0
 def readMem(self, address):
     address = self.toSigned(address)
     if address % self.bytesPerWord == 0:
         i = 0
         result = 0
         while i < self.bytesPerWord:
             result += (self.memory[address + i]) * (2**(8 * i))
             i += 1
     else:
         report(
             self.line, self.column,
             f'At: {self.currentInstrucName}, {address} is not a wordLength Address',
             RuntimeWarning)
         result = None
     return result
Exemple #12
0
 def isValidReg(self, reg, error):
     registerValue = eval('self.' + reg)
     if registerValue == None:
         if error:
             report(
                 self.line, self.column,
                 f'At: {self.currentInstrucName} {self.Oreg}, {reg} is Empty',
                 RunTimeError)
             self.hadError = True
         else:
             report(
                 self.line, self.column,
                 f'At: {self.currentInstrucName} {self.Oreg}, {reg} + is Empty',
                 RuntimeWarning)
         return False
     else:
         return True
	def scanToken(self):
		char = self.advance()
		#If the next charecter is a letter we are only interested
		#in it if it the start of an instruction
		if self.isAlpha(char):
			#Check if the following word is an insturction
			isInstruc = self.isInstruc()
			#If we have an instruction we add it and move on to the next token
			if (isInstruc):
				name = self.code[self.start:self.current]
				self.addToken(name, name)
				return
			#If we don't match here the error is caught at the end of the scan
			#and the token is rejected there

		#If the charecter is a "-" and the one after is a digit, we have a number
		if (char == "-" and self.isDigit(self.peek())):
			self.number()
			return

		#If the next charecter is a digit we make an integer token
		if self.isDigit(char):
			self.number()
			return

		#If we've hit a space or a 	tab then we move onto the next token
		if char == ' ' or char == '\t':
			return

		#If we're at a new line we increment the line counter
		if char == '\n':
			self.addToken('NEXT','NEWLINE',text = 'NEWLINE')
			self.lineno += 1
			self.column = 0
			return

		if char == ';':
			self.addToken('NEXT',';')
			return

		#If nothing matches then we have a lexical error
		#We create the unmatched string and then print it
		unmatched = self.code[self.start:self.current]
		report(self.lineno, self.column, "Unrecognised token: " + unmatched, LexicalError)
		self.hadError = True
Exemple #14
0
 def ADD(self):
     if not self.isValidReg('Areg', True):
         return
     if not self.isValidReg('Breg', True):
         return
     value = self.pop()
     self.Areg += value
     if self.Areg > 2**(self.bit - 1) - 1:
         report(
             self.line, self.column,
             f'At: {self.currentInstrucName} {self.Oreg+self}, Integer Overflow',
             RunTimeError)
         self.haltFlag = True
     elif self.Areg < -2**(self.bit - 1):
         report(
             self.line, self.column,
             f'At: {self.currentInstrucName} {self.Oreg+self}, Integer Underflow',
             RunTimeError)
         self.haltFlag = True
Exemple #15
0
 def OPR(self):
     if self.Oreg < 0:
         report(self.line, self.column, f'OPR {self.Oreg} is not valid',
                RunTimeError)
         self.Oreg = 0
         self.haltFlag = True
         return
     instructionCodeToRun = hex(self.Oreg)[2:].upper()
     #If we've only got a single length we add a zero so we can match it correctly
     if len(instructionCodeToRun) == 1:
         instructionCodeToRun = '0' + instructionCodeToRun
     instructionCodeToRun = '#' + instructionCodeToRun
     try:
         instruction = reps.TokenType(instructionCodeToRun).name
         self.execute(instruction)
     except ValueError:
         report(self.line, self.column, f'OPR {self.Oreg} is not valid',
                RunTimeError)
         self.haltFlag = True
     finally:
         self.Oreg = 0
         return
Exemple #16
0
 def writeMem(self, address, num):
     address = self.toSigned(address)
     if num == None:
         report(self.line, self.column, f'{num}, Wrote Nothing ',
                RuntimeWarning)
         return
     #Normalise it to n bits
     num = self.toSigned(num)
     num = self.fromSigned(num)
     if address % self.bytesPerWord == 0:
         i = 0
         while i < self.bytesPerWord - 1:
             #Set it to be the lowest bye
             self.memory[address + i] = num & 0xFF
             num = num >> 8
             i += 1
         self.memory[address + i] = num
     else:
         report(
             self.line, self.column,
             f'At: {self.currentInstrucName}, {address} is not a wordLength Address',
             RuntimeWarning)