OpenCores
URL https://opencores.org/ocsvn/tcp_socket/tcp_socket/trunk

Subversion Repositories tcp_socket

[/] [tcp_socket/] [trunk/] [chips2/] [chips/] [compiler/] [parse_tree.py] - Diff between revs 2 and 4

Show entire file | Details | Blame | View Log

Rev 2 Rev 4
Line 1... Line 1...
__author__ = "Jon Dawson"
__author__ = "Jon Dawson"
__copyright__ = "Copyright (C) 2012, Jonathan P Dawson"
__copyright__ = "Copyright (C) 2012, Jonathan P Dawson"
__version__ = "0.1"
__version__ = "0.1"
 
 
 
import struct
 
 
class NotConstant(Exception):
class NotConstant(Exception):
  pass
  pass
 
 
def value(expression):
 
 
 
  """If an expression can be evaluated at compile time, return the value"""
 
 
 
  if hasattr(expression, "value"):
 
    return truncate(expression.value())
 
  else:
 
    raise NotConstant
 
 
 
def constant_fold(expression):
def constant_fold(expression):
 
 
  """Replace an expression with a constant if possible"""
  """Replace an expression with a constant if possible"""
 
 
  try:
  try:
    return Constant(value(expression))
        return Constant(expression.value(), expression.type_(), expression.size(), expression.signed())
  except NotConstant:
  except NotConstant:
    return expression
    return expression
 
 
def truncate(number):
 
 
 
  """Truncate arithmetic results to the target number of bits"""
 
 
 
  #sign = number & 0x10000
 
  #number = number & 0xffff
 
  #if sign:
 
    #number =  ~0xffff | number
 
  return int(number)
 
 
 
class Process:
class Process:
 
 
  def generate(self):
  def generate(self):
    instructions = []
    instructions = []
    for function in self.functions:
    for function in self.functions:
      if hasattr(function, "declarations"):
      if hasattr(function, "declarations"):
          instructions.extend(function.generate())
          instructions.extend(function.generate())
    instructions.append({"op"   :"jmp_and_link",
 
 
        instructions.append(
 
            {"op"   :"jmp_and_link",
                         "dest" :self.main.return_address,
                         "dest" :self.main.return_address,
                         "label":"function_%s"%id(self.main)})
                         "label":"function_%s"%id(self.main)})
    instructions.append({"op":"stop"})
 
 
        instructions.append(
 
            {"op":"stop"})
 
 
    for function in self.functions:
    for function in self.functions:
      if not hasattr(function, "declarations"):
      if not hasattr(function, "declarations"):
          instructions.extend(function.generate())
          instructions.extend(function.generate())
    return instructions
    return instructions
 
 
 
 
class Function:
class Function:
 
 
  def generate(self):
  def generate(self):
    instructions = []
    instructions = []
    instructions.append({"op":"label", "label":"function_%s"%id(self)})
    instructions.append({"op":"label", "label":"function_%s"%id(self)})
    instructions.extend(self.statement.generate())
    instructions.extend(self.statement.generate())
    if not hasattr(self, "return_value"):
    if not hasattr(self, "return_value"):
        instructions.append({"op":"jmp_to_reg", "src":self.return_address})
        instructions.append({"op":"jmp_to_reg", "src":self.return_address})
    return instructions
    return instructions
 
 
 
 
class Break:
class Break:
  def generate(self): return [{"op":"goto", "label":"break_%s"%id(self.loop)}]
 
 
    def generate(self): return [
 
        {"op":"goto", "label":"break_%s"%id(self.loop)}]
 
 
 
 
class Continue:
class Continue:
  def generate(self): return [{"op":"goto", "label":"continue_%s"%id(self.loop)}]
 
 
    def generate(self): return [
 
        {"op":"goto", "label":"continue_%s"%id(self.loop)}]
 
 
 
 
class Assert:
class Assert:
 
 
  def generate(self):
  def generate(self):
    result = self.allocator.new(self.expression.size)
        result = self.allocator.new(self.expression.size())
    instructions = self.expression.generate(result)
        instructions = self.expression.generate(result, self.allocator)
    self.allocator.free(result)
    self.allocator.free(result)
    instructions.append({"op":"assert", "src":result, "line":self.line, "file":self.filename})
 
 
        instructions.append(
 
            {"op":"assert",
 
             "src":result,
 
             "line":self.line,
 
             "file":self.filename})
 
 
    return instructions
    return instructions
 
 
 
 
class Return:
class Return:
 
 
  def generate(self):
  def generate(self):
    if hasattr(self, "expression"):
    if hasattr(self, "expression"):
        instructions = self.expression.generate(self.function.return_value)
 
 
            result = self.allocator.new(self.function.size)
 
            instructions=self.function.return_value.copy(
 
                self.expression,
 
                result,
 
                self.allocator)
 
            self.allocator.free(result)
 
 
    else:
    else:
        instructions = []
        instructions = []
    instructions.append({"op":"jmp_to_reg", "src":self.function.return_address})
 
 
        instructions.append(
 
            {"op":"jmp_to_reg",
 
             "src":self.function.return_address})
 
 
    return instructions
    return instructions
 
 
 
 
class Report:
class Report:
 
 
  def generate(self):
  def generate(self):
    result = self.allocator.new(self.expression.size)
        result = self.allocator.new(self.expression.size())
    instructions = self.expression.generate(result)
        instructions = self.expression.generate(result, self.allocator)
    self.allocator.free(result)
    self.allocator.free(result)
    instructions.append({"op":"report",
 
 
        instructions.append(
 
            {"op":"report",
                         "src":result,
                         "src":result,
                         "line":self.line,
                         "line":self.line,
                         "file":self.filename,
                         "file":self.filename,
                         "signed":self.expression.signed})
             "type":self.expression.type_(),
 
             "signed":self.expression.signed()})
 
 
    return instructions
    return instructions
 
 
 
 
class WaitClocks:
class WaitClocks:
 
 
  def generate(self):
  def generate(self):
    result = self.allocator.new(self.expression.size)
        result = self.allocator.new(self.expression.size())
    instructions = self.expression.generate(result)
        instructions = self.expression.generate(result, self.allocator)
    self.allocator.free(result)
    self.allocator.free(result)
    instructions.append({"op":"wait_clocks", "src":result})
    instructions.append({"op":"wait_clocks", "src":result})
    return instructions
    return instructions
 
 
 
 
class If:
class If:
 
 
  def generate(self):
  def generate(self):
 
 
    try:
    try:
      if value(self.expression):
 
 
            if self.expression.value():
        return self.true_statement.generate()
        return self.true_statement.generate()
      else:
      else:
        if self.false_statement:
        if self.false_statement:
          return self.false_statement.generate()
          return self.false_statement.generate()
        else:
        else:
          return []
          return []
 
 
    except NotConstant:
    except NotConstant:
      result = self.allocator.new(self.expression.size)
 
 
            result = self.allocator.new(self.expression.size())
      instructions = []
      instructions = []
      instructions.extend(self.expression.generate(result))
            instructions.extend(self.expression.generate(result, self.allocator))
      instructions.append({"op"   :"jmp_if_false",
 
 
            instructions.append(
 
                {"op"    : "jmp_if_false",
                           "src" :result,
                           "src" :result,
                           "label":"else_%s"%id(self)})
                           "label":"else_%s"%id(self)})
 
 
      self.allocator.free(result)
      self.allocator.free(result)
      instructions.extend(self.true_statement.generate())
      instructions.extend(self.true_statement.generate())
      instructions.append({"op":"goto", "label":"end_%s"%id(self)})
      instructions.append({"op":"goto", "label":"end_%s"%id(self)})
      instructions.append({"op":"label", "label":"else_%s"%id(self)})
      instructions.append({"op":"label", "label":"else_%s"%id(self)})
      if self.false_statement:
      if self.false_statement:
        instructions.extend(self.false_statement.generate())
        instructions.extend(self.false_statement.generate())
      instructions.append({"op":"label", "label":"end_%s"%id(self)})
      instructions.append({"op":"label", "label":"end_%s"%id(self)})
      return instructions
      return instructions
 
 
 
 
class Switch:
class Switch:
 
 
  def generate(self):
  def generate(self):
    result = self.allocator.new(self.expression.size)
        result = self.allocator.new(self.expression.size())
    test = self.allocator.new(self.expression.size)
        test = self.allocator.new(self.expression.size())
    instructions = self.expression.generate(result)
        instructions = self.expression.generate(result, self.allocator)
    for value, case in self.cases.iteritems():
    for value, case in self.cases.iteritems():
      instructions.append({"op":"==", "dest":test, "src":result, "right":value, "signed":True})
 
      instructions.append({"op":"jmp_if_true", "src":test, "label":"case_%s"%id(case)})
            instructions.append(
 
                {"op":"==",
 
                 "dest":test,
 
                 "src":result,
 
                 "right":value,
 
                 "size": self.expression.size(),
 
                 "signed":True})
 
 
 
            instructions.append(
 
                {"op":"jmp_if_true",
 
                 "src":test,
 
                 "label":"case_%s"%id(case)})
 
 
    if hasattr(self, "default"):
    if hasattr(self, "default"):
      instructions.append({"op":"goto", "label":"case_%s"%id(self.default)})
 
 
            instructions.append(
 
                {"op":"goto",
 
                 "label":"case_%s"%id(self.default)})
 
 
    self.allocator.free(result)
    self.allocator.free(result)
    self.allocator.free(test)
    self.allocator.free(test)
    instructions.extend(self.statement.generate())
    instructions.extend(self.statement.generate())
    instructions.append({"op":"label", "label":"break_%s"%id(self)})
    instructions.append({"op":"label", "label":"break_%s"%id(self)})
    return instructions
    return instructions
 
 
 
 
class Case:
class Case:
 
 
  def generate(self):
  def generate(self):
    return [{"op":"label", "label":"case_%s"%id(self)}]
    return [{"op":"label", "label":"case_%s"%id(self)}]
 
 
 
 
class Default:
class Default:
 
 
  def generate(self):
  def generate(self):
    return [{"op":"label", "label":"case_%s"%id(self)}]
    return [{"op":"label", "label":"case_%s"%id(self)}]
 
 
 
 
class Loop:
class Loop:
 
 
  def generate(self):
  def generate(self):
      instructions = [{"op":"label", "label":"begin_%s"%id(self)}]
      instructions = [{"op":"label", "label":"begin_%s"%id(self)}]
      instructions.append({"op":"label", "label":"continue_%s"%id(self)})
      instructions.append({"op":"label", "label":"continue_%s"%id(self)})
      instructions.extend(self.statement.generate())
      instructions.extend(self.statement.generate())
      instructions.append({"op":"goto", "label":"begin_%s"%id(self)})
      instructions.append({"op":"goto", "label":"begin_%s"%id(self)})
      instructions.append({"op":"label", "label":"break_%s"%id(self)})
      instructions.append({"op":"label", "label":"break_%s"%id(self)})
      return instructions
      return instructions
 
 
 
 
class For:
class For:
 
 
  def generate(self):
  def generate(self):
    instructions = []
    instructions = []
    if hasattr(self, "statement1"):
    if hasattr(self, "statement1"):
      instructions.extend(self.statement1.generate())
      instructions.extend(self.statement1.generate())
    instructions.append({"op":"label", "label":"begin_%s"%id(self)})
    instructions.append({"op":"label", "label":"begin_%s"%id(self)})
    if hasattr(self, "expression"):
    if hasattr(self, "expression"):
      result = self.allocator.new(self.expression.size)
            result = self.allocator.new(self.expression.size())
      instructions.extend(self.expression.generate(result))
 
      instructions.append({"op":"jmp_if_false", "src":result, "label":"end_%s"%id(self)})
            instructions.extend(
 
                self.expression.generate(result, self.allocator))
 
 
 
            instructions.append(
 
                {"op":"jmp_if_false",
 
                 "src":result,
 
                 "label":"end_%s"%id(self)})
 
 
      self.allocator.free(result)
      self.allocator.free(result)
    instructions.extend(self.statement3.generate())
    instructions.extend(self.statement3.generate())
    instructions.append({"op":"label", "label":"continue_%s"%id(self)})
    instructions.append({"op":"label", "label":"continue_%s"%id(self)})
    if hasattr(self, "statement2"):
    if hasattr(self, "statement2"):
      instructions.extend(self.statement2.generate())
      instructions.extend(self.statement2.generate())
    instructions.append({"op":"goto", "label":"begin_%s"%id(self)})
    instructions.append({"op":"goto", "label":"begin_%s"%id(self)})
    instructions.append({"op":"label", "label":"end_%s"%id(self)})
    instructions.append({"op":"label", "label":"end_%s"%id(self)})
    instructions.append({"op":"label", "label":"break_%s"%id(self)})
    instructions.append({"op":"label", "label":"break_%s"%id(self)})
    return instructions
    return instructions
 
 
 
 
class Block:
class Block:
 
 
  def generate(self):
  def generate(self):
    instructions = []
    instructions = []
    for statement in self.statements:
    for statement in self.statements:
      instructions.extend(statement.generate())
      instructions.extend(statement.generate())
    return instructions
    return instructions
 
 
 
 
class CompoundDeclaration:
class CompoundDeclaration:
 
 
  def __init__(self, declarations):
  def __init__(self, declarations):
    self.declarations = declarations
    self.declarations = declarations
 
 
  def generate(self):
  def generate(self):
    instructions = []
    instructions = []
    for declaration in self.declarations:
    for declaration in self.declarations:
      instructions.extend(declaration.generate());
      instructions.extend(declaration.generate());
    return instructions
    return instructions
 
 
 
 
class VariableDeclaration:
class VariableDeclaration:
  def __init__(self, allocator, initializer, name, type_, size, signed):
 
 
    def __init__(self, allocator, initializer, name, type_, size, signed, const):
    self.initializer = initializer
    self.initializer = initializer
    self.allocator = allocator
    self.allocator = allocator
    self.type_ = type_
        self._type = type_
    self.size = size
        self._size = size
    self.signed = signed
        self._signed = signed
 
        self._const = const
    self.name = name
    self.name = name
 
 
  def instance(self):
  def instance(self):
    register = self.allocator.new(self.size, "variable "+self.name)
        register = self.allocator.new(self.size(), "variable "+self.name)
    return VariableInstance(register, self.initializer, self.type_, self.size, self.signed)
 
 
        return VariableInstance(
 
            register,
 
            self.initializer,
 
            self.type_(),
 
            self.size(),
 
            self.signed(),
 
            self.const(),
 
            self.allocator)
 
 
 
    def type_(self):
 
        return self._type
 
 
 
    def size(self):
 
        return self._size
 
 
 
    def signed(self):
 
        return self._signed
 
 
 
    def const(self):
 
        return self._const
 
 
 
 
class VariableInstance:
class VariableInstance:
  def __init__(self, register, initializer, type_, size, signed):
 
 
    def __init__(self, register, initializer, type_, size, signed, const, allocator):
    self.register = register
    self.register = register
    self.type_ = type_
        self._type = type_
    self.initializer = initializer
    self.initializer = initializer
    self.size = size
        self._size = size
    self.signed = signed
        self._signed = signed
 
        self._const = const
 
        self.allocator = allocator
 
 
  def generate(self):
  def generate(self):
    return self.initializer.generate(self.register)
        return self.initializer.generate(self.register, self.allocator)
 
 
 
    def reference(self):
 
        return Variable(self)
 
 
 
    def type_(self):
 
        return self._type
 
 
 
    def size(self):
 
        return self._size
 
 
 
    def signed(self):
 
        return self._signed
 
 
 
    def const(self):
 
        return self._const
 
 
 
 
class ArrayDeclaration:
class ArrayDeclaration:
 
 
  def __init__(self,
  def __init__(self,
               allocator,
               allocator,
               size,
               size,
               type_,
               type_,
               element_type,
               element_type,
Line 228... Line 348...
               element_signed,
               element_signed,
               initializer = None,
               initializer = None,
               initialize_memory = False):
               initialize_memory = False):
 
 
    self.allocator = allocator
    self.allocator = allocator
    self.type_ = type_
        self._type = type_
    self.size = size
        self._size = size
    self.signed = False
        self._signed = False
    self.element_type = element_type
    self.element_type = element_type
    self.element_size = element_size
    self.element_size = element_size
    self.element_signed = element_signed
    self.element_signed = element_signed
    self.initializer = initializer
    self.initializer = initializer
    self.initialize_memory = initialize_memory
    self.initialize_memory = initialize_memory
 
 
  def instance(self):
  def instance(self):
    location = self.allocator.new_array(self.size, self.initializer, self.element_size)
 
 
        location = self.allocator.new_array(
 
            self.size(),
 
            self.initializer,
 
            self.element_size)
 
 
    register = self.allocator.new(2, "array")
    register = self.allocator.new(2, "array")
    return ArrayInstance(location,
 
 
        return ArrayInstance(
 
            location,
                         register,
                         register,
                         self.size,
            self.size(),
                         self.type_,
            self.type_(),
                         self.initializer,
                         self.initializer,
                         self.initialize_memory,
                         self.initialize_memory,
                         self.element_type,
                         self.element_type,
                         self.element_size,
                         self.element_size,
                         self.element_signed)
                         self.element_signed)
 
 
 
    def type_(self):
 
        return self._type
 
 
 
    def size(self):
 
        return self._size
 
 
 
    def signed(self):
 
        return self._signed
 
 
class ArrayInstance:
class ArrayInstance:
 
 
  def __init__(self,
  def __init__(self,
               location,
               location,
               register,
               register,
               size,
               size,
               type_,
               type_,
Line 264... Line 401...
               element_size,
               element_size,
               element_signed):
               element_signed):
 
 
    self.register = register
    self.register = register
    self.location = location
    self.location = location
    self.type_ = type_
        self._type = type_
    self.size = size
        self._size = size * element_size
    self.signed = False
        self._signed = False
    self.element_type = element_type
    self.element_type = element_type
    self.element_size = element_size
    self.element_size = element_size
    self.element_signed = element_signed
    self.element_signed = element_signed
    self.initializer = initializer
    self.initializer = initializer
    self.initialize_memory = initialize_memory
    self.initialize_memory = initialize_memory
Line 278... Line 415...
  def generate(self, result=None):
  def generate(self, result=None):
      instructions = []
      instructions = []
      #If initialize memory is true, the memory content will initialised (as at configuration time)
      #If initialize memory is true, the memory content will initialised (as at configuration time)
      #If initialize memory is false, then the memory will need to be filled by the program.
      #If initialize memory is false, then the memory will need to be filled by the program.
      if not self.initialize_memory and self.initializer is not None:
      if not self.initialize_memory and self.initializer is not None:
          location = 0
            location=self.location
          for value in self.initializer:
          for value in self.initializer:
              instructions.append({
 
                  "op":"memory_write_literal",
                instructions.append(
 
                    {"op":"memory_write_literal",
                  "address":location,
                  "address":location,
                  "value":value,
                  "value":value,
                  "element_size":self.element_size
                     "element_size":self.element_size})
              })
 
              location += 1
              location += 1
      instructions.append({
 
          "op":"literal",
        instructions.append(
 
            {"op":"literal",
          "literal":self.location,
          "literal":self.location,
          "dest":self.register
             "dest":self.register})
      })
 
      #this bit here is to make string literals work, 
 
      #in this case an array instance is created implicitly, 
 
      #but the value of the expression is the array register.
 
      if result is not None and result != self.register:
 
          instructions.append({
 
              "op"  :"move",
 
              "dest":result,
 
              "src" :self.register
 
          })
 
      return instructions
      return instructions
 
 
 
 
 
    def reference(self):
 
        return Array(self)
 
 
 
    def type_(self):
 
        return self._type
 
 
 
    def size(self):
 
        return self._size
 
 
 
    def signed(self):
 
        return self._signed
 
 
 
 
class StructDeclaration:
class StructDeclaration:
 
 
  def __init__(self, members):
  def __init__(self, members):
    self.members = members
    self.members = members
 
        self._type = "struct {%s}"%"; ".join(
 
            [i.type_() for i in members.values()])
 
        self._size = sum([i.size() for i in members.values()])
 
        self._signed = False
 
 
  def instance(self):
  def instance(self):
    instances = {}
    instances = {}
    for name, declaration in self.members.iteritems():
    for name, declaration in self.members.iteritems():
      instances[name] = declaration.instance()
      instances[name] = declaration.instance()
    return StructInstance(instances)
    return StructInstance(instances)
 
 
 
    def type_(self):
 
        return self._type
 
 
 
    def size(self):
 
        return self._size
 
 
 
    def signed(self):
 
        return self._signed
 
 
 
 
class StructInstance:
class StructInstance:
 
 
  def __init__(self, members):
  def __init__(self, members):
    self.members = members
    self.members = members
    self.type_ = "struct"
        self._type = "struct {%s}"%"; ".join(
 
            [i.type_() for i in members.values()])
 
        self._size = sum([i.size() for i in members.values()])
 
        self._signed = False
 
 
  def generate(self):
  def generate(self):
    instructions = []
    instructions = []
    for member in self.members.values():
    for member in self.members.values():
      instructions.extend(member.generate())
      instructions.extend(member.generate())
    return instructions
    return instructions
 
 
class Argument:
    def reference(self):
  def __init__(self,
        return Struct(self)
        name,
 
        type_,
    def type_(self):
        size,
        return self._type
        signed,
 
        parser,
    def size(self):
        element_type,
        return self._size
        element_size,
 
        element_signed):
    def signed(self):
    self.type_=type_
        return self._signed
    self.size=size
 
    self.signed=signed
 
    self.element_type = element_type
 
    self.element_size = element_size
 
    self.element_signed = element_signed
 
    parser.scope[name] = self
 
    self.register = parser.allocator.new(size, "function argument "+name)
 
  def generate(self): return []
 
 
 
class DiscardExpression:
class DiscardExpression:
 
 
  def __init__(self, expression, allocator):
  def __init__(self, expression, allocator):
    self.expression = expression
    self.expression = expression
    self.allocator = allocator
    self.allocator = allocator
 
 
  def generate(self):
  def generate(self):
    result = self.allocator.new(self.expression.size)
        result = self.allocator.new(self.expression.size())
    instructions = self.expression.generate(result)
        instructions = self.expression.generate(result, self.allocator)
    self.allocator.free(result)
    self.allocator.free(result)
    return instructions
    return instructions
 
 
#...then Expressions...
 
 
 
#Expressions generate methods accept a result argument.
class Expression:
#This indicates which register to put the result in.
 
 
    def __init__(self, t, size, signed):
 
        self.type_var=t
 
        self.size_var=size
 
        self.signed_var=signed
 
 
 
    def type_(self):
 
        return self.type_var
 
 
 
    def size(self):
 
        return self.size_var
 
 
 
    def signed(self):
 
        return self.signed_var
 
 
 
    def value(self):
 
        raise NotConstant
 
 
 
    def const(self):
 
        return True
 
 
 
    def int_value(self):
 
        if self.type_() == "float":
 
            byte_value = struct.pack(">f", self.value())
 
            value  = ord(byte_value[0]) << 24
 
            value |= ord(byte_value[1]) << 16
 
            value |= ord(byte_value[2]) << 8
 
            value |= ord(byte_value[3])
 
            return value
 
        else:
 
            return self.value()
 
 
 
 
 
class Object(Expression):
 
 
 
    def __init__(self, instance):
 
        Expression.__init__(self, instance.type_(), instance.size(), instance.signed())
 
        self.instance = instance
 
 
 
    def value(self):
 
        raise NotConstant
 
 
 
    def const(self):
 
        return False
 
 
#Expressions may also provide a value method which returns the value of an xpression
 
#if it can be calculated at compile time.
 
 
 
def AND(left, right):
def AND(left, right):
  return ANDOR(left, right, "jmp_if_false")
  return ANDOR(left, right, "jmp_if_false")
 
 
 
 
def OR(left, right):
def OR(left, right):
  return ANDOR(left, right, "jmp_if_true")
  return ANDOR(left, right, "jmp_if_true")
 
 
class ANDOR:
 
 
class ANDOR(Expression):
 
 
  def __init__(self, left, right, op):
  def __init__(self, left, right, op):
    self.left = constant_fold(left)
    self.left = constant_fold(left)
    self.right = constant_fold(right)
    self.right = constant_fold(right)
    self.op = op
    self.op = op
    self.type_ = "int"
 
    self.size = left.size
 
    self.signed = left.signed
 
 
 
  def generate(self, result):
        Expression.__init__(
    instructions = self.left.generate(result)
            self,
 
            "int",
 
            max(left.size(), right.size()),
 
            left.signed() and right.signed())
 
 
 
    def generate(self, result, allocator):
 
        instructions = self.left.generate(result, allocator)
    instructions.append({"op":self.op, "src":result, "label":"end_%s"%id(self)})
    instructions.append({"op":self.op, "src":result, "label":"end_%s"%id(self)})
    instructions.extend(self.right.generate(result))
        instructions.extend(self.right.generate(result, allocator))
    instructions.append({"op":"label", "label":"end_%s"%id(self)})
    instructions.append({"op":"label", "label":"end_%s"%id(self)})
    return instructions
    return instructions
 
 
  def value(self):
  def value(self):
    if self.op == "jmp_if_false":
    if self.op == "jmp_if_false":
      return value(self.left) and value(self.right)
            return self.left.value() and self.right.value()
    else:
    else:
      return value(self.left) or value(self.right)
            return self.left.value() or self.right.value()
 
 
 
 
 
def get_binary_type(left, right, operator):
 
    """
 
    Given the type of the left and right hand operators, determine the type
 
    of the resulting value.
 
    """
 
 
 
    binary_types = {
 
        "float,float,+"  : ("float", 4, True),
 
        "float,float,-"  : ("float", 4, True),
 
        "float,float,*"  : ("float", 4, True),
 
        "float,float,/"  : ("float", 4, True),
 
        "float,float,==" : ("int", 4, True),
 
        "float,float,!=" : ("int", 4, True),
 
        "float,float,<"  : ("int", 4, True),
 
        "float,float,>"  : ("int", 4, True),
 
        "float,float,<=" : ("int", 4, True),
 
        "float,float,>=" : ("int", 4, True)}
 
 
 
    signature = ",".join([left.type_(), right.type_(), operator])
 
    if signature in binary_types:
 
        type_, size, signed = binary_types[signature]
 
    else:
 
        type_ = left.type_()
 
        size = max(left.size(), right.size())
 
        signed = left.signed() and right.signed()
 
 
 
    return type_, size, signed
 
 
 
class Binary(Expression):
 
 
class Binary:
    def __init__(self, operator, left, right):
  def __init__(self, operator, left, right, allocator):
 
    self.left = constant_fold(left)
    self.left = constant_fold(left)
    self.right = constant_fold(right)
    self.right = constant_fold(right)
    self.operator = operator
    self.operator = operator
    self.allocator = allocator
        type_, size, signed = get_binary_type(left, right, operator)
    self.type_ = self.left.type_
 
    self.size = max(left.size, right.size)
 
    self.signed = left.signed and right.signed
 
 
 
  def generate(self, result):
        Expression.__init__(
    new_register = self.allocator.new(self.size)
            self,
 
            type_,
 
            size,
 
            signed)
 
 
 
    def generate(self, result, allocator):
 
        new_register = allocator.new(self.size())
    try:
    try:
      instructions = self.right.generate(new_register)
            instructions = self.right.generate(new_register, allocator)
      instructions.append({"op"  :self.operator,
 
 
            instructions.append(
 
                {"op"  :self.operator,
                           "dest":result,
                           "dest":result,
                           "left":value(self.left),
                 "left":self.left.int_value(),
                           "src":new_register,
                           "src":new_register,
                           "signed":self.signed})
                 "type":self.type_(),
 
                 "size":self.size(),
 
                 "signed":self.signed()})
 
 
    except NotConstant:
    except NotConstant:
      try:
      try:
        instructions = self.left.generate(new_register)
                instructions = self.left.generate(new_register, allocator)
        instructions.append({"op"   :self.operator,
 
 
                instructions.append(
 
                    {"op"   :self.operator,
                             "dest" :result,
                             "dest" :result,
                             "src"  :new_register,
                             "src"  :new_register,
                             "right":value(self.right),
                     "right":self.right.int_value(),
                             "signed" :self.signed})
                     "type":self.type_(),
 
                     "size":self.size(),
 
                     "signed" :self.signed()})
 
 
      except NotConstant:
      except NotConstant:
        instructions = self.left.generate(new_register)
                instructions = self.left.generate(new_register, allocator)
        right = self.allocator.new(self.right.size)
                right = allocator.new(self.size())
        instructions.extend(self.right.generate(right))
                instructions.extend(self.right.generate(right, allocator))
        instructions.append({"op"  :self.operator,
 
 
                instructions.append(
 
                    {"op"  :self.operator,
                             "dest":result,
                             "dest":result,
                             "src" :new_register,
                             "src" :new_register,
                             "srcb":right,
                             "srcb":right,
                             "signed":self.signed})
                     "type":self.type_(),
        self.allocator.free(right)
                     "size":self.size(),
    self.allocator.free(new_register)
                     "signed":self.signed()})
 
 
 
                allocator.free(right)
 
        allocator.free(new_register)
    return instructions
    return instructions
 
 
  def value(self):
  def value(self):
    return eval("%s %s %s"%(value(self.left), self.operator, value(self.right)))
 
 
        if self.type_() == "int":
 
 
 
            return int(eval("%s %s %s"%(
 
                self.left.value(),
 
                self.operator,
 
                self.right.value())))
 
 
 
        else:
 
 
 
            return float(eval("%s %s %s"%(
 
                self.left.value(),
 
                self.operator,
 
                self.right.value())))
 
 
 
 
 
 
def SizeOf(expression):
def SizeOf(expression):
    return Constant(expression.size)
    return Constant(expression.size())
 
 
 
 
 
class IntToFloat(Expression):
 
 
 
    def __init__(self, expression):
 
        self.expression = constant_fold(expression)
 
 
 
        Expression.__init__( self, "float", 4, True)
 
 
 
    def generate(self, result, allocator):
 
        new_register = allocator.new(self.size())
 
        instructions = self.expression.generate(new_register, allocator)
 
 
 
        instructions.extend([
 
            {"op"   : "int_to_float",
 
             "dest" : result,
 
             "src"  : new_register}])
 
 
 
        allocator.free(new_register)
 
        return instructions
 
 
 
    def value(self):
 
        return float(self.expression.value())
 
 
 
 
 
class FloatToInt(Expression):
 
 
class Unary:
    def __init__(self, expression):
  def __init__(self, operator, expression, allocator):
        self.expression = constant_fold(expression)
 
 
 
        Expression.__init__( self, "int", 4, True)
 
 
 
    def generate(self, result, allocator):
 
        new_register = allocator.new(self.size())
 
        instructions = self.expression.generate(new_register, allocator)
 
 
 
        instructions.extend([
 
            {"op"   : "float_to_int",
 
             "dest" : result,
 
             "src"  : new_register}])
 
 
 
        allocator.free(new_register)
 
        return instructions
 
 
 
    def value(self):
 
        return int(self.expression.value())
 
 
 
 
 
class Unary(Expression):
 
 
 
    def __init__(self, operator, expression):
    self.expression = constant_fold(expression)
    self.expression = constant_fold(expression)
    self.operator = operator
    self.operator = operator
    self.type_ = self.expression.type_
 
    self.size = expression.size
 
    self.signed = expression.signed
 
    self.allocator = allocator
 
 
 
  def generate(self, result):
        Expression.__init__(
    new_register = self.allocator.new(self.size)
            self,
    instructions = self.expression.generate(new_register)
            expression.type_(),
    instructions.extend([{"op":self.operator, "dest":result, "src":new_register}])
            expression.size(),
    self.allocator.free(new_register)
            expression.signed())
 
 
 
    def generate(self, result, allocator):
 
        new_register = allocator.new(self.size())
 
        instructions = self.expression.generate(new_register, allocator)
 
 
 
        instructions.extend([
 
            {"op":self.operator,
 
             "dest":result,
 
             "src":new_register}])
 
 
 
        allocator.free(new_register)
    return instructions
    return instructions
 
 
  def value(self):
  def value(self):
    return eval("%s%s"%(self.operator, value(self.expression)))
        return eval("%s%s"%(self.operator, self.expression.value()))
 
 
 
 
 
class FunctionCall(Expression):
 
 
 
    def __init__(self, function):
 
        self.function = function
 
 
 
        Expression.__init__(
 
            self,
 
            function.type_,
 
            function.size,
 
            function.signed)
 
 
class FunctionCall:
    def generate(self, result, allocator):
  def generate(self, result):
 
    instructions = []
    instructions = []
    for expression, argument in zip(self.arguments, self.function.arguments):
 
      instructions.extend(expression.generate(argument.register))
        for expression, argument in zip(
    instructions.append({"op"   :"jmp_and_link",
            self.arguments,
 
            self.function.arguments):
 
 
 
            temp_register = allocator.new(expression.size())
 
            instructions.extend(
 
                argument.copy(expression, temp_register, allocator))
 
            allocator.free(temp_register)
 
 
 
        instructions.append(
 
            {"op"   :"jmp_and_link",
                         "dest" :self.function.return_address,
                         "dest" :self.function.return_address,
                         "label":"function_%s"%id(self.function)})
                         "label":"function_%s"%id(self.function)})
 
 
    if hasattr(self.function, "return_value"):
    if hasattr(self.function, "return_value"):
        instructions.append({"op"   :"move",
 
                             "dest" :result,
            instructions.extend(self.function.return_value.generate(
                             "src"  :self.function.return_value})
                result,
 
                allocator))
 
 
    return instructions
    return instructions
 
 
class Output:
 
 
class Output(Expression):
 
 
  def __init__(self, name, expression):
  def __init__(self, name, expression):
    self.name = name
    self.name = name
    self.expression = expression
    self.expression = expression
    self.type_ = "int"
        Expression.__init__(self, "int", 2, True)
    self.size = expression.size
 
 
    def generate(self, result, allocator):
 
        instructions = self.expression.generate(result, allocator)
 
 
 
        instructions.append(
 
            {"op"   :"write",
 
             "src"  :result,
 
             "output":self.name})
 
 
  def generate(self, result):
 
    instructions = self.expression.generate(result);
 
    instructions.append({"op"   :"write", "src"  :result, "output":self.name})
 
    return instructions
    return instructions
 
 
class FileWrite:
 
 
class FileWrite(Expression):
 
 
  def __init__(self, name, expression):
  def __init__(self, name, expression):
    self.name = name
    self.name = name
    self.expression = expression
    self.expression = expression
    self.type_ = "int"
        Expression.__init__(
    self.size = expression.size
            self,
 
            expression.type_(),
 
            expression.size(),
 
            expression.signed())
 
 
 
    def generate(self, result, allocator):
 
        instructions = self.expression.generate(result, allocator)
 
 
 
        instructions.append(
 
            {"op"   :"file_write",
 
             "src"  :result,
 
             "type":self.expression.type_(),
 
             "file_name":self.name})
 
 
  def generate(self, result):
 
    instructions = self.expression.generate(result);
 
    instructions.append({"op"   :"file_write", "src"  :result, "file_name":self.name})
 
    return instructions
    return instructions
 
 
class Input:
 
 
class Input(Expression):
 
 
  def __init__(self, name):
  def __init__(self, name):
    self.name = name
    self.name = name
    self.type_ = "int"
        Expression.__init__(self, "int", 2, True)
    self.size = 2
 
    self.signed = True
 
 
 
  def generate(self, result):
    def generate(self, result, allocator):
      return [{"op"   :"read", "dest" :result, "input":self.name}]
      return [{"op"   :"read", "dest" :result, "input":self.name}]
 
 
class FileRead:
 
 
class FileRead(Expression):
 
 
  def __init__(self, name):
  def __init__(self, name):
    self.name = name
    self.name = name
    self.type_ = "int"
        Expression.__init__(self, "int", 2, True)
    self.size = 2
 
    self.signed = True
 
 
 
  def generate(self, result):
    def generate(self, result, allocator):
      return [{"op"   :"file_read", "dest" :result, "file_name":self.name}]
      return [{"op"   :"file_read", "dest" :result, "file_name":self.name}]
 
 
class Ready:
 
 
class Ready(Expression):
 
 
  def __init__(self, name):
  def __init__(self, name):
    self.name = name
    self.name = name
    self.type_ = "int"
        Expression.__init__(self, "int", 2, True)
    self.size = 2
 
    self.signed = True
 
 
 
  def generate(self, result):
    def generate(self, result, allocator):
      return [{"op"   :"ready", "dest" :result, "input":self.name}]
      return [{"op"   :"ready", "dest" :result, "input":self.name}]
 
 
class Array:
 
  def __init__(self, declaration, allocator):
 
    self.declaration = declaration
 
    self.allocator = allocator
 
    self.storage = "register"
 
    self.type_ = self.declaration.type_
 
    self.size = int(self.declaration.size) * 2
 
    self.signed = False
 
 
 
  def generate(self, result):
class Struct(Object):
 
 
 
    def __init__(self, instance):
 
        Object.__init__(self, instance)
 
 
 
    def generate(self, result, allocator):
    instructions = []
    instructions = []
    if result != self.declaration.register:
    if result != self.declaration.register:
      instructions.append({"op"  :"move",
 
 
            instructions.append(
 
                {"op"  :"move",
                           "dest":result,
                           "dest":result,
                           "src" :self.declaration.register})
                           "src" :self.declaration.register})
 
 
    return instructions
    return instructions
 
 
class ArrayIndex:
    def copy(self, expression, result, allocator):
  def __init__(self, declaration, index_expression, allocator):
        instructions = []
    self.declaration = declaration
 
    self.allocator = allocator
        for lvalue, rvalue in zip(
 
            self.instance.members.values(),
 
            expression.instance.members.values()):
 
 
 
            instructions.extend(
 
                lvalue.reference().copy(rvalue.reference(), result, allocator))
 
 
 
        return instructions
 
 
 
 
 
class Array(Object):
 
 
 
    def __init__(self, instance):
 
        Object.__init__(self, instance)
 
 
 
    def generate(self, result, allocator):
 
        instructions = []
 
        if result != self.instance.register:
 
 
 
            instructions.append(
 
                {"op"   : "move",
 
                 "dest" : result,
 
                 "src"  : self.instance.register})
 
 
 
        return instructions
 
 
 
    def copy(self, expression, result, allocator):
 
        instructions = expression.generate(result, allocator)
 
        if result != self.instance.register:
 
 
 
            instructions.append(
 
                {"op"   : "move",
 
                 "dest" : self.instance.register,
 
                 "src"  : result})
 
 
 
        return instructions
 
 
 
 
 
class ConstArray(Object):
 
 
 
    def __init__(self, instance):
 
        Object.__init__(self, instance)
 
 
 
    def generate(self, result, allocator):
 
        instructions = []
 
        #If initialize memory is true, the memory content will initialised (as at configuration time)
 
        #If initialize memory is false, then the memory will need to be filled by the program.
 
        if not self.instance.initialize_memory and self.instance.initializer is not None:
 
            location = self.instance.location
 
            for value in self.instance.initializer:
 
 
 
                instructions.append(
 
                    {"op":"memory_write_literal",
 
                     "address":location,
 
                     "value":value,
 
                     "element_size":self.instance.element_size})
 
 
 
                location += 1
 
 
 
        instructions.append(
 
            {"op":"literal",
 
             "literal":self.instance.location,
 
             "dest":self.instance.register})
 
 
 
        if result != self.instance.register:
 
 
 
            instructions.append(
 
                {"op"   : "move",
 
                 "dest" : result,
 
                 "src"  : self.instance.register})
 
 
 
        return instructions
 
 
 
    def copy(self, expression, result, allocator):
 
        instructions = expression.generate(result, allocator)
 
        if result != self.instance.register:
 
 
 
            instructions.append(
 
                {"op"   : "move",
 
                 "dest" : self.instance.register,
 
                 "src"  : result})
 
 
 
        return instructions
 
 
 
 
 
class ArrayIndex(Object):
 
 
 
    def __init__(self, instance, index_expression):
 
        Object.__init__(self, instance)
 
        assert self.type_var.endswith("[]")
 
        self.type_var = self.type_var[:-2]
 
        self.size_var = instance.element_size
    self.index_expression = index_expression
    self.index_expression = index_expression
    self.storage = "memory"
 
    self.type_  = self.declaration.element_type
    def generate(self, result, allocator):
    self.size   = self.declaration.element_size
        instructions = []
    self.signed = self.declaration.element_signed
        offset = allocator.new(2)
 
        address = allocator.new(2)
  def generate(self, result):
        instructions.extend(self.index_expression.generate(offset, allocator))
    instructions = []
 
    offset = self.allocator.new(2)
        instructions.append(
    address = self.allocator.new(2)
            {"op"    :"+",
    instructions.extend(self.index_expression.generate(offset))
 
    instructions.append({"op"    :"+",
 
                         "dest"  :address,
                         "dest"  :address,
                         "src"   :offset,
                         "src"   :offset,
                         "srcb"  :self.declaration.register,
             "srcb"  :self.instance.register,
                         "signed":False})
                         "signed":False})
    instructions.append({"op"    :"memory_read_request",
 
 
        instructions.append(
 
            {"op"    :"memory_read_request",
                         "src"   :address,
                         "src"   :address,
                         "sequence": id(self),
                         "sequence": id(self),
                         "element_size":self.size})
             "element_size":self.size()})
    instructions.append({"op"    :"memory_read_wait",
 
 
        instructions.append(
 
            {"op"    :"memory_read_wait",
                         "src"   :address,
                         "src"   :address,
                         "sequence": id(self),
                         "sequence": id(self),
                         "element_size":self.size})
             "element_size":self.size()})
    instructions.append({"op"    :"memory_read",
 
 
        instructions.append(
 
            {"op"    :"memory_read",
                         "src"   :address,
                         "src"   :address,
                         "dest"  :result,
                         "dest"  :result,
                         "sequence": id(self),
                         "sequence": id(self),
                         "element_size":self.size})
             "element_size":self.size()})
    self.allocator.free(address)
 
    self.allocator.free(offset)
        allocator.free(address)
 
        allocator.free(offset)
    return instructions
    return instructions
 
 
class Variable:
    def copy(self, expression, result, allocator):
  def __init__(self, declaration, allocator):
        index = allocator.new(2)
    self.declaration = declaration
        address = allocator.new(2)
    self.allocator = allocator
        instructions = expression.generate(result, allocator)
    self.storage = "register"
        instructions.extend(self.index_expression.generate(index, allocator))
    self.type_ = self.declaration.type_
 
    self.size = self.declaration.size
 
    self.signed = self.declaration.signed
 
 
 
  def generate(self, result):
        instructions.append(
 
            {"op"     :"+",
 
             "dest"   :address,
 
             "src"    :index,
 
             "srcb"   :self.instance.register,
 
             "signed" :expression.signed()})
 
 
 
        instructions.append(
 
            {"op"    :"memory_write",
 
             "src"   :address,
 
             "srcb"  :result,
 
             "element_size" :self.instance.element_size})
 
 
 
        allocator.free(index)
 
        allocator.free(address)
 
        return instructions
 
 
 
 
 
class Variable(Object):
 
    def __init__(self, instance):
 
        Object.__init__(self, instance)
 
 
 
    def generate(self, result, allocator):
    instructions = []
    instructions = []
    if result != self.declaration.register:
        if result != self.instance.register:
      instructions.append({"op"  :"move",
 
 
            instructions.append(
 
                {"op"  :"move",
                           "dest":result,
                           "dest":result,
                           "src" :self.declaration.register})
                 "src" :self.instance.register})
 
 
 
        return instructions
 
 
 
    def copy(self, expression, result, allocator):
 
        instructions = expression.generate(result, allocator)
 
        if result != self.instance.register:
 
 
 
            instructions.append(
 
                {"op"   : "move",
 
                 "dest" : self.instance.register,
 
                 "src"  : result})
 
 
    return instructions
    return instructions
 
 
class PostIncrement:
    def const(self):
 
        return self.instance.const()
 
 
 
    def value(self):
 
        if self.const():
 
            return self.instance.initializer.value()
 
        else:
 
            raise NotConstant
 
 
 
 
 
class PostIncrement(Expression):
 
 
  def  __init__(self, operator, lvalue, allocator):
  def  __init__(self, operator, lvalue, allocator):
    self.operator = operator
    self.operator = operator
    self.lvalue = lvalue
    self.lvalue = lvalue
    self.allocator = allocator
        allocator = allocator
    self.type_ = self.lvalue.declaration.type_
        Expression.__init__(self, lvalue.type_(), lvalue.size(), lvalue.signed())
    self.size = self.lvalue.declaration.size
 
    self.signed = self.lvalue.declaration.signed
 
 
 
  def generate(self, result):
    def generate(self, result, allocator):
 
 
    instructions = []
    instructions = []
 
 
    instructions.append({"op"    :"move",
        instructions.append(
                         "src"   :self.lvalue.declaration.register,
            {"op"    : "move",
 
             "src"   : self.lvalue.instance.register,
                         "dest"  :result})
                         "dest"  :result})
 
 
    instructions.append({"op"    :self.operator,
        instructions.append(
                         "dest"  :self.lvalue.declaration.register,
            {"op"    : self.operator,
 
             "dest"  : self.lvalue.instance.register,
                         "right" :1,
                         "right" :1,
                         "src"   :self.lvalue.declaration.register,
             "src"   : self.lvalue.instance.register,
                         "signed":self.signed})
             "size"  : self.size(),
 
             "signed": self.signed()})
 
 
    return instructions
    return instructions
 
 
class Assignment:
 
 
class Assignment(Expression):
 
 
  def __init__(self, lvalue, expression, allocator):
  def __init__(self, lvalue, expression, allocator):
 
        Expression.__init__(self, lvalue.type_(), lvalue.size(), lvalue.signed())
    self.lvalue = lvalue
    self.lvalue = lvalue
    self.expression = expression
    self.expression = expression
    self.allocator = allocator
    self.allocator = allocator
    self.type_ = self.lvalue.type_
 
    self.size = self.lvalue.size
 
    self.signed = self.lvalue.signed
 
 
 
  def generate(self, result):
 
    instructions = self.expression.generate(result)
 
    if self.lvalue.storage == "register":
 
      if result != self.lvalue.declaration.register:
 
        instructions.append({"op"   : "move",
 
                             "dest" : self.lvalue.declaration.register,
 
                             "src"  : result})
 
 
 
    elif self.lvalue.storage == "memory":
    def generate(self, result, allocator):
      index = self.allocator.new(2)
        return self.lvalue.copy(self.expression, result, allocator)
      address = self.allocator.new(2)
 
      instructions.extend(self.lvalue.index_expression.generate(index))
 
      instructions.append({"op"     :"+",
 
                           "dest"   :address,
 
                           "src"    :index,
 
                           "srcb"   :self.lvalue.declaration.register,
 
                           "signed" :self.signed})
 
      instructions.append({"op"    :"memory_write",
 
                           "src"   :address,
 
                           "srcb"  :result,
 
                           "element_size" :self.lvalue.declaration.element_size})
 
      self.allocator.free(index)
 
      self.allocator.free(address)
 
 
 
    return instructions
 
 
 
class Constant:
class Constant(Expression):
  def __init__(self, value, size=2, signed=True):
 
 
    def __init__(self, value, type_="int", size=2, signed=True):
    self._value = value
    self._value = value
    self.type_ = "int"
        Expression.__init__(self, type_, size, signed)
    self.size = size
 
    self.signed = signed
 
 
 
  def generate(self, result):
    def generate(self, result, allocator):
    instructions = [{"op":"literal", "dest":result, "literal":self._value}]
 
 
        instructions = [{
 
            "op":"literal",
 
            "dest":result,
 
            "size":self.size(),
 
            "signed":self.size(),
 
            "literal":self.int_value()}]
    return instructions
    return instructions
 
 
  def value(self):
  def value(self):
    return self._value
    return self._value
 
 
 No newline at end of file
 No newline at end of file
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.