Senior Team Portfolio
Total Page:16
File Type:pdf, Size:1020Kb
Joshua Leger Fred Kneeland April 30, 2016 Senior Team Portfolio Section 1: CSCI 468, source code included in compiler folder. Section 2: Team member 1: Team member 1 wrote the lexer and code generation. Team member 2: Team member 2 wrote the parser and symbol table. Each team member did 50% of the work. Section 3: Our project did not use any design patterns. Section 4: The technical document is included as report.pdf. Section 5: Section 6: The main design trade-off our team had was in what language and library to use. We chose python with PLY because it was the recommended solution and easy to use, even though it was not the most efficient choice. Section 7: We used an agile development cycle with 4 sprints to complete the 4 parts of our project. It was helpful in letting each other know what our progress on the project was throughout development. class IRRep: def __init__(self): self.lastTemp = 1 self.lastLabel = 1 self.first = None self.last = None def getLast(self): return self.last def addToEnd(self, nextNode): if(nextNode is not None): if(self.last is None): self.first = nextNode self.last = nextNode else: self.last.nextNode = nextNode while(self.last.nextNode is not None): self.last = self.last.nextNode def nextTemp(self): self.lastTemp += 1 return "$T" + str(self.lastTemp - 1) def nextLabel(self): self.lastLabel += 1 return "label" + str(self.lastLabel - 1) def printIR(self): temp = self.first while(temp is not None): if(len(temp.second) > 0): print(temp.opcode + " " + temp.first + " " + temp.second + " " + temp.result) else: print(temp.opcode + " " + temp.first + " " + temp.result) temp = temp.nextNode def printTiny(self, symbolTable): temp = self.first print(";IR code") while(temp is not None): if(len(temp.second) > 0): print(";" + temp.opcode + " " + temp.first + " " + temp.second + " " + temp.result) else: print(";" + temp.opcode + " " + temp.first + " " + temp.result) temp = temp.nextNode temp = self.first print(";tiny code") #declare variables symbolTable.printTableTiny() count = 0 references = {} while(temp is not None): first = temp.first if "$" in first: if first in references: first = references[first] else: references[first] = "r" + str(count) first = references[first] count += 1 second = temp.second if "$" in second: if second in references: second = references[second] else: references[second] = "r" + str(count) second = references[second] count += 1 result = temp.result if "$" in result: if result in references: result = references[result] else: references[result] = "r" + str(count) result = references[result] count += 1 if(temp.opcode == "STOREI" or temp.opcode == "STOREF"): if(first[0] != "r" and result[0] != "r"): compare = "r" + str(count) count += 1 print("move " + first + " " + compare) print("move " + compare + " " + result) else: print("move " + first + " " + result) elif(temp.opcode == "READI"): print("sys readi " + temp.first) elif(temp.opcode == "READF"): print("sys readr " + temp.first) elif(temp.opcode == "WRITEI"): print("sys writei " + temp.first) elif(temp.opcode == "WRITEF"): print("sys writer " + temp.first) elif(temp.opcode == "WRITES"): print("sys writes " + temp.first) elif(temp.opcode == "ADDI"): print("move " + first + " " + result) print("addi " + second + " " + result) elif(temp.opcode == "ADDF"): print("move " + first + " " + result) print("addr " + second + " " + result) elif(temp.opcode == "SUBI"): print("move " + first + " " + result) print("subi " + second + " " + result) elif(temp.opcode == "SUBF"): print("move " + first + " " + result) print("subr " + second + " " + result) elif(temp.opcode == "MULTI"): print("move " + first + " " + result) print("muli " + second + " " + result) elif(temp.opcode == "MULTF"): print("move " + first + " " + result) print("mulr " + second + " " + result) elif(temp.opcode == "DIVI"): print("move " + first + " " + result) print("divi " + second + " " + result) elif(temp.opcode == "DIVF"): print("move " + first + " " + result) print("divr " + second + " " + result) elif(temp.opcode == "LABEL"): print("label " + first) elif(temp.opcode == "JUMP"): print("jmp " + first) elif(temp.opcode == "GTI" or temp.opcode == "GTF"): tstring = "i" if(temp.opcode == "GTF"): tstring = "r" compare = "r" + str(count) count += 1 print("move " + second + " " + compare) print("cmp" + tstring + " " + first + " " + compare) print("jgt " + result) elif(temp.opcode == "GEI" or temp.opcode == "GEF"): tstring = "i" if(temp.opcode == "GEF"): tstring = "r" compare = "r" + str(count) count += 1 print("move " + second + " " + compare) print("cmp" + tstring + " " + first + " " + compare) print("jge " + result) elif(temp.opcode == "LTI" or temp.opcode == "LTF"): tstring = "i" if(temp.opcode == "LTF"): tstring = "r" compare = "r" + str(count) count += 1 print("move " + second + " " + compare) print("cmp" + tstring + " " + first + " " + compare) print("jlt " + result) elif(temp.opcode == "LEI" or temp.opcode == "LEF"): tstring = "i" if(temp.opcode == "LEF"): tstring = "r" compare = "r" + str(count) count += 1 print("move " + second + " " + compare) print("cmp" + tstring + " " + first + " " + compare) print("jle " + result) elif(temp.opcode == "NEI" or temp.opcode == "NEF"): tstring = "i" if(temp.opcode == "NEF"): tstring = "r" compare = "r" + str(count) count += 1 print("move " + second + " " + compare) print("cmp" + tstring + " " + first + " " + compare) print("jne " + result) elif(temp.opcode == "EQI" or temp.opcode == "EQF"): tstring = "i" if(temp.opcode == "EQF"): tstring = "r" compare = "r" + str(count) count += 1 print("move " + second + " " + compare) print("cmp" + tstring + " " + first + " " + compare) print("jeq " + result) temp = temp.nextNode print("sys halt") class IRNode: def __init__(self, opcode, first, second, result, nextNode, branchNode): self.opcode = opcode self.first = first self.second = second self.result = result self.nextNode = nextNode self.branchNode = branchNode # ------------------------------------------------------------------------ ----- # ply: lex.py # # Copyright (C) 2001-2015, # David M. Beazley (Dabeaz LLC) # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # * Neither the name of the David Beazley or Dabeaz LLC may be used to # endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ------------------------------------------------------------------------ ----- __version__ = '3.8' __tabversion__ = '3.8' import re import sys import types import copy import os import inspect # This tuple contains known string types try: # Python 2.6 StringTypes = (types.StringType, types.UnicodeType) except AttributeError: # Python 3.0 StringTypes = (str, bytes) # This regular expression is used to match valid token names _is_identifier = re.compile(r'^[a-zA-Z0-9_]+$') # Exception thrown when invalid token encountered and no default error # handler is defined. class LexError(Exception): def __init__(self, message, s): self.args = (message,) self.text = s # Token class. This class is used to represent the tokens produced. class LexToken(object): def __str__(self): return 'LexToken(%s,%r,%d,%d)' % (self.type, self.value, self.lineno, self.lexpos) def __repr__(self): return str(self) # This object is a stand-in for a logging object created by the # logging module. class PlyLogger(object): def __init__(self, f): self.f = f def critical(self, msg, *args, **kwargs): self.f.write((msg % args) + '\n') def warning(self, msg, *args, **kwargs): self.f.write('WARNING: ' + (msg % args) + '\n') def error(self, msg, *args, **kwargs): self.f.write('ERROR: ' + (msg % args) + '\n') info = critical debug = critical # Null logger is used when no output is generated. Does nothing. class NullLogger(object): def __getattribute__(self, name): return self def __call__(self, *args, **kwargs): return self # ------------------------------------------------------------------------ ----- # === Lexing Engine === # # The following Lexer class implements the lexer runtime. There are only # a few public methods and attributes: # # input() - Store a new string in the lexer # token() - Get the next token # clone() - Clone the lexer # # lineno - Current line number # lexpos - Current position in the input string # ------------------------------------------------------------------------ ----- class Lexer: def __init__(self): self.lexre