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

Subversion Repositories tcp_socket

[/] [tcp_socket/] [trunk/] [chips2/] [chips/] [compiler/] [parser.py,cover] - 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
 
> from copy import copy
 
 
> from parse_tree import *
> from parse_tree import *
> from tokens import Tokens
> from tokens import Tokens
> from allocator import Allocator
> from allocator import Allocator
 
 
> def optimise_if(if_statement):
> types = ["float", "signed", "unsigned", "short", "long", "char", "int", "void"]
>     try:
> numeric_types = ["float", "signed", "unsigned", "short", "long", "char", "int"]
>         if value(if_statement.expression):
> storage_specifiers = ["const"]
>             return if_statement.true_statement
 
>         elif if_statement.false_statement:
 
>             return if_statement.false_statement
 
>         else:
 
>             null_instruction = Block()
 
>             null_instruction.statements = []
 
>             return null_instruction
 
>     except NotConstant:
 
>         return if_statement
 
 
 
> class Parser:
> class Parser:
 
 
>     """Turn the C input file into a tree of expressions and statements."""
>     """Turn the C input file into a tree of expressions and statements."""
 
 
>     def __init__(self, input_file, reuse):
>     def __init__(self, input_file, reuse, initialize_memory):
>         self.scope = {}
>         self.scope = {}
>         self.function = None
>         self.function = None
>         self.loop = None
>         self.loop = None
>         self.tokens = Tokens(input_file)
>         self.tokens = Tokens(input_file)
>         self.allocator = Allocator(reuse)
>         self.allocator = Allocator(reuse)
>         self.structs = []
>         self.structs = []
 
>         self.initialize_memory = initialize_memory
 
 
>     def parse_process(self):
>     def parse_process(self):
>         process = Process()
>         process = Process()
>         process.allocator = self.allocator
>         process.allocator = self.allocator
>         process.inputs = []
>         process.inputs = []
Line 45... Line 40...
>             else:
>             else:
>                 process.functions.append(self.parse_function())
>                 process.functions.append(self.parse_function())
>         process.main = self.main
>         process.main = self.main
>         return process
>         return process
 
 
 
>     def parse_type_specifier(self):
 
>         type_specifiers = []
 
 
 
>         while self.tokens.peek() in types + self.structs + storage_specifiers:
 
>             type_specifiers.append(self.tokens.get())
 
 
 
>         signed = True
 
>         if "unsigned" in type_specifiers:
 
>             signed = False
 
>             if "signed" in type_specifiers:
 
!                 self.tokens.error("Cannot be signed and unsigned")
 
 
 
>         size = 2
 
>         if "long" in type_specifiers:
 
>             if "short" in type_specifiers:
 
!                 self.tokens.error("Cannot be long and short")
 
>             size = 4
 
 
 
>         type_ = "int"
 
>         for i in type_specifiers:
 
>             if i in self.structs:
 
>                 type_ = i
 
>                 size = 2
 
>                 signed = False
 
 
 
>         if "float" in type_specifiers:
 
>             if "short" in type_specifiers:
 
!                 self.tokens.error("Float cannot be short")
 
>             if "long" in type_specifiers:
 
!                 self.tokens.error("Float cannot be long (but double can)")
 
>             if "unsigned" in type_specifiers:
 
!                 self.tokens.error("Float cannot be unsigned")
 
>             type_ = "float"
 
>             size = 4
 
>             signed = True
 
 
 
>         const = False
 
>         if "const" in type_specifiers:
 
>             const = True
 
 
 
>         if "void" in type_specifiers:
 
>             type_ = "void"
 
>             size = 2
 
>             signed = False
 
 
 
 
 
>         return type_, size, signed, const
 
 
 
>     def parse_argument(self):
 
>         type_, size, signed, const = self.parse_type_specifier()
 
 
 
>         if type_ in ["void"]:
 
!             self.tokens.error("argument cannot be void")
 
>         else:
 
>             argument = self.tokens.get()
 
>             if type_ in self.structs:
 
>                 declaration = self.scope[type_]
 
>             else:
 
>                 if self.tokens.peek() == "[":
 
>                     self.tokens.expect("[")
 
>                     self.tokens.expect("]")
 
>                     declaration = ArrayDeclaration(
 
>                         self.allocator,
 
>                         2,
 
>                         type_+"[]",
 
>                         type_,
 
>                         size,
 
>                         signed,
 
>                         None,
 
>                         self.initialize_memory)
 
>                 else:
 
>                     declaration = VariableDeclaration(
 
>                         self.allocator,
 
>                         None,
 
>                         argument,
 
>                         type_,
 
>                         size,
 
>                         signed,
 
>                         const)
 
>         instance = declaration.instance()
 
>         self.scope[argument] = instance
 
>         return instance.reference()
 
 
>     def parse_function(self):
>     def parse_function(self):
>         function = Function()
>         function = Function()
>         function.allocator = self.allocator
>         function.allocator = self.allocator
>         stored_scope = self.scope
>         stored_scope = copy(self.scope)
>         type_ = self.tokens.get()
>         type_, size, signed, const = self.parse_type_specifier()
>         name = self.tokens.get()
>         name = self.tokens.get()
 
 
          #check if it is a global declaration
          #check if it is a global declaration
>         if self.tokens.peek() != "(":
>         if self.tokens.peek() != "(":
>             if type_ not in ["int", "short", "long", "char"] + self.structs:
>             return self.parse_global_declaration(type_, size, signed, const, name)
!                 self.tokens.error("unknown type")
 
>             return self.parse_global_declaration(type_, name)
 
 
 
          #otherwise continue parsing a function
          #otherwise continue parsing a function
>         self.tokens.expect("(")
>         self.tokens.expect("(")
>         function.name = name
>         function.name = name
>         function.type_ = type_
>         function.type_ = type_
>         function.return_address = self.allocator.new(function.name+" return address")
>         function.size = size
>         if type_ not in ["int", "short", "long", "char", "void"]:
>         function.signed = signed
!             self.tokens.error("unknown type")
 
 
>         function.return_address = self.allocator.new(2,
 
>             function.name+" return address")
 
 
>         if type_ != "void":
>         if type_ != "void":
>             function.return_value = self.allocator.new(function.name+" return value")
 
 
>             if type_ in self.structs:
 
!                 declaration = self.scope[type_]
 
>             else:
 
>                 if self.tokens.peek() == "[":
 
!                     self.tokens.error(
 
!                         "Functions cannot return arrays")
 
>                 else:
 
>                     declaration = VariableDeclaration(
 
>                         self.allocator,
 
>                         None,
 
>                         function.name+" return value",
 
>                         type_,
 
>                         size,
 
>                         signed,
 
>                         const)
 
 
 
>             function.return_value = declaration.instance().reference()
 
 
>         function.arguments = []
>         function.arguments = []
>         while self.tokens.peek() != ")":
>         while self.tokens.peek() != ")":
>             type_ = self.tokens.get()
>             function.arguments.append(self.parse_argument())
>             if type_ not in ["int", "short", "long", "char"]:
 
!                 self.tokens.error("unknown type")
 
>             argument = self.tokens.get()
 
>             if self.tokens.peek() == "[":
 
>                 self.tokens.expect("[")
 
>                 self.tokens.expect("]")
 
>                 type_+="[]"
 
>             function.arguments.append(Argument(argument, type_, self))
 
>             if self.tokens.peek() == ",":
>             if self.tokens.peek() == ",":
>                 self.tokens.expect(",")
>                 self.tokens.expect(",")
>             else:
>             else:
>                 break
>                 break
 
 
>         self.tokens.expect(")")
>         self.tokens.expect(")")
>         self.function = function
>         self.function = function
>         function.statement = self.parse_statement()
>         function.statement = self.parse_statement()
>         if type_ != "void" and not hasattr(function, "return_statement"):
>         if type_ != "void" and not hasattr(function, "return_statement"):
>             self.tokens.error("Function must have a return statement")
>             self.tokens.error("Function must have a return statement")
Line 111... Line 201...
>         return continue_
>         return continue_
 
 
>     def parse_return(self):
>     def parse_return(self):
>         return_ = Return()
>         return_ = Return()
>         return_.function = self.function
>         return_.function = self.function
 
>         return_.allocator = self.allocator
>         self.function.return_statement = return_
>         self.function.return_statement = return_
>         self.tokens.expect("return")
>         self.tokens.expect("return")
>         if hasattr(self.function, "return_value"):
>         if hasattr(self.function, "return_value"):
>             return_.expression = self.parse_expression()
>             return_.expression = self.parse_expression()
>         self.tokens.expect(";")
>         self.tokens.expect(";")
Line 154... Line 245...
>         self.tokens.expect(";")
>         self.tokens.expect(";")
>         wait_clocks.line = self.tokens.lineno
>         wait_clocks.line = self.tokens.lineno
>         return wait_clocks
>         return wait_clocks
 
 
>     def parse_statement(self):
>     def parse_statement(self):
>         if self.tokens.peek() in ["int", "short", "long", "char"] + self.structs:
>         if self.tokens.peek() in numeric_types + self.structs + storage_specifiers:
>             return self.parse_compound_declaration()
>             return self.parse_compound_declaration()
>         elif self.tokens.peek() == "struct":
>         elif self.tokens.peek() == "struct":
>             return self.parse_struct_declaration()
>             return self.parse_struct_declaration()
>         elif self.tokens.peek() == "if":
>         elif self.tokens.peek() == "if":
>             return self.parse_if()
>             return self.parse_if()
Line 194... Line 285...
>     def parse_discard(self):
>     def parse_discard(self):
>         return DiscardExpression(self.parse_expression(), self.allocator)
>         return DiscardExpression(self.parse_expression(), self.allocator)
 
 
>     def parse_assignment(self):
>     def parse_assignment(self):
>         assignment_operators = [
>         assignment_operators = [
>             "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "<<=", ">>=",
>             "=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "<<=", ">>="
>             "++", "--"
 
>         ]
>         ]
>         lvalue = self.parse_ternary_expression()
>         lvalue = self.parse_ternary_expression()
>         if self.tokens.peek() in assignment_operators:
>         if self.tokens.peek() in assignment_operators:
>             if not hasattr(lvalue, "declaration"):
>             if lvalue.const():
 
 
>                 self.tokens.error(
>                 self.tokens.error(
>                     "left hand operand of assignment is not modifiable"
>                     "left hand operand of assignment is not modifiable")
>                 )
 
>             operator = self.tokens.get()
>             operator = self.tokens.get()
>             if operator == "=":
>             if operator == "=":
>                 expression = self.parse_ternary_expression()
>                 expression = self.parse_ternary_expression()
>             elif operator in ["++", "--"]:
 
>                 expression = Binary(
 
>                     operator[:-1],
 
>                     lvalue,
 
>                     Constant(1),
 
>                     self.allocator
 
>                 )
 
>             else:
>             else:
>                 expression = Binary(
 
>                     operator[:-1],
>                 expression = self.parse_ternary_expression()
>                     lvalue,
>                 left = lvalue
>                     self.parse_ternary_expression(),
>                 left, expression = self.coerce_types(left, expression)
>                     self.allocator
>                 expression = Binary(operator[:-1], left, expression)
>                 )
 
>             if lvalue.type_ != expression.type_:
>             if expression.type_() != lvalue.type_():
 
>                 if expression.type_() == "int" and lvalue.type_() == "float":
 
!                     expression = IntToFloat(expression)
 
>                 elif expression.type_() == "float" and lvalue.type_() == "int":
 
>                     expression = FloatToInt(expression)
 
>                 else:
>                 self.tokens.error(
>                 self.tokens.error(
>                     "type mismatch in assignment"
>                         "type mismatch in assignment expected: %s actual: %s"%(
>                 )
>                             lvalue.type_(),
 
>                             expression.type_()))
 
 
>             return Assignment(lvalue, expression, self.allocator)
>             return Assignment(lvalue, expression, self.allocator)
>         else:
>         else:
>             return lvalue
>             return lvalue
 
 
 
 
>     def parse_if(self):
>     def parse_if(self):
>         if_ = If()
>         if_ = If()
>         if_.allocator = self.allocator
>         if_.allocator = self.allocator
>         self.tokens.expect("if")
>         self.tokens.expect("if")
>         self.tokens.expect("(")
>         self.tokens.expect("(")
>         if_.expression = self.parse_expression()
>         if_.expression = self.parse_expression()
>         if if_.expression.type_ not in ["int", "short", "long", "char"]:
>         if if_.expression.type_() not in ["unsigned", "int", "short", "long", "char"]:
>             self.tokens.error(
>             self.tokens.error(
>                 "if statement conditional must be an integer like expression"
>                 "if statement conditional must be an integer like expression")
>             )
 
>         self.tokens.expect(")")
>         self.tokens.expect(")")
>         if_.true_statement = self.parse_statement()
>         if_.true_statement = self.parse_statement()
>         if self.tokens.peek() == "else":
>         if self.tokens.peek() == "else":
>             self.tokens.expect("else")
>             self.tokens.expect("else")
>             if_.false_statement = self.parse_statement()
>             if_.false_statement = self.parse_statement()
>         else:
>         else:
>             if_.false_statement = None
>             if_.false_statement = None
>         return optimise_if(if_)
>         return if_
 
 
>     def parse_switch(self):
>     def parse_switch(self):
>         switch = Switch()
>         switch = Switch()
>         switch.cases = {}
>         switch.cases = {}
>         self.tokens.expect("switch")
>         self.tokens.expect("switch")
>         self.tokens.expect("(")
>         self.tokens.expect("(")
>         expression = self.parse_expression()
>         expression = self.parse_expression()
>         if expression.type_ not in ["int", "short", "long", "char"]:
>         if expression.type_() not in ["unsigned", "int", "short", "long", "char"]:
>             self.tokens.error(
>             self.tokens.error(
>                 "switch statement expression must be an integer like expression"
>                 "switch statement expression must be an integer like expression")
>             )
 
>         self.tokens.expect(")")
>         self.tokens.expect(")")
>         stored_loop = self.loop
>         stored_loop = self.loop
>         self.loop = switch
>         self.loop = switch
>         statement = self.parse_statement()
>         statement = self.parse_statement()
>         self.loop = stored_loop
>         self.loop = stored_loop
Line 271... Line 359...
>         return switch
>         return switch
 
 
>     def parse_case(self):
>     def parse_case(self):
>         self.tokens.expect("case")
>         self.tokens.expect("case")
>         expression = self.parse_expression()
>         expression = self.parse_expression()
>         if expression.type_ not in ["int", "short", "long", "char"]:
>         if expression.type_() not in ["int"]:
>             self.tokens.error(
>             self.tokens.error(
>                 "case expression must be an integer like expression"
>                 "case expression must be an integer like expression")
>             )
 
>         self.tokens.expect(":")
>         self.tokens.expect(":")
>         try:
>         try:
>             expression = value(expression)
>             expression = expression.value()
>             case = Case()
>             case = Case()
>             self.loop.cases[expression] =    case
>             self.loop.cases[expression] =    case
>         except NotConstant:
>         except NotConstant:
>             self.tokens.error("case expression must be constant")
>             self.tokens.error("case expression must be constant")
>         except AttributeError:
>         except AttributeError:
>             self.tokens.error(
>             self.tokens.error(
>                 "case statements may only be use inside a switch statment"
>                 "case statements may only be use inside a switch statment")
>             )
 
>         return case
>         return case
 
 
>     def parse_default(self):
>     def parse_default(self):
>         self.tokens.expect("default")
>         self.tokens.expect("default")
>         self.tokens.expect(":")
>         self.tokens.expect(":")
>         default = Default()
>         default = Default()
>         if not hasattr(self.loop, "cases"):
>         if not hasattr(self.loop, "cases"):
>             self.tokens.error(
>             self.tokens.error(
>                 "default statements may only be used inside a switch statment"
>                 "default statements may only be used inside a switch statment")
>             )
 
>         if hasattr(self.loop, "default"):
>         if hasattr(self.loop, "default"):
>             self.tokens.error(
>             self.tokens.error(
>                 "A switch statement may only have one default statement"
>                 "A switch statement may only have one default statement")
>             )
 
>         self.loop.default=default
>         self.loop.default=default
>         return default
>         return default
 
 
>     def parse_while(self):
>     def parse_while(self):
>         loop = Loop()
>         loop = Loop()
Line 315... Line 399...
>         self.loop = loop
>         self.loop = loop
>         statement = self.parse_statement()
>         statement = self.parse_statement()
>         self.loop = stored_loop
>         self.loop = stored_loop
 
 
>         if_ = If()
>         if_ = If()
 
>         loop.statement = if_
>         break_ = Break()
>         break_ = Break()
>         break_.loop = loop
>         break_.loop = loop
>         if_.allocator = self.allocator
>         if_.allocator = self.allocator
>         if expression.type_ not in ["int", "short", "long", "char"]:
>         if expression.type_() not in ["int"]:
>             self.tokens.error(
>             self.tokens.error(
>                 "if statement conditional must be an integer like expression"
>                 "while statement conditional must be an integer like expression")
>             )
 
>         if_.expression = expression
>         if_.expression = expression
>         if_.false_statement = break_
>         if_.false_statement = break_
>         if_.true_statement = statement
>         if_.true_statement = statement
 
 
>         loop.statement = optimise_if(if_)
 
>         return loop
>         return loop
 
 
>     def parse_for(self):
>     def parse_for(self):
>         for_ = For()
>         for_ = For()
>         for_.allocator = self.allocator
>         for_.allocator = self.allocator
Line 339... Line 422...
>         if self.tokens.peek() != ";":
>         if self.tokens.peek() != ";":
>             for_.statement1 = self.parse_discard()
>             for_.statement1 = self.parse_discard()
>         self.tokens.expect(";")
>         self.tokens.expect(";")
>         if self.tokens.peek() != ";":
>         if self.tokens.peek() != ";":
>             for_.expression = self.parse_expression()
>             for_.expression = self.parse_expression()
>             if for_.expression.type_ not in ["int", "short", "long", "char"]:
>             if for_.expression.type_() not in [
 
>                 "unsigned",
 
>                 "int",
 
>                 "short",
 
>                 "long",
 
>                 "char"]:
 
 
>                 self.tokens.error(
>                 self.tokens.error(
>                     "for statement conditional must be an integer like expression"
>             "For statement conditional must be an integer like expression")
>                 )
 
>         self.tokens.expect(";")
>         self.tokens.expect(";")
>         if self.tokens.peek() != ")":
>         if self.tokens.peek() != ")":
>             for_.statement2 = self.parse_discard()
>             for_.statement2 = self.parse_discard()
>         self.tokens.expect(")")
>         self.tokens.expect(")")
>         stored_loop = self.loop
>         stored_loop = self.loop
Line 355... Line 444...
>         self.loop = stored_loop
>         self.loop = stored_loop
>         return for_
>         return for_
 
 
>     def parse_block(self):
>     def parse_block(self):
>         block = Block()
>         block = Block()
>         stored_scope = self.scope
>         stored_scope = copy(self.scope)
>         self.tokens.expect("{")
>         self.tokens.expect("{")
>         block.statements = []
>         block.statements = []
>         while self.tokens.peek() != "}":
>         while self.tokens.peek() != "}":
>             block.statements.append(self.parse_statement())
>             block.statements.append(self.parse_statement())
>         self.tokens.expect("}")
>         self.tokens.expect("}")
Line 368... Line 457...
 
 
>     def parse_struct_body(self):
>     def parse_struct_body(self):
>         self.tokens.expect("{")
>         self.tokens.expect("{")
>         members = {}
>         members = {}
>         while self.tokens.peek() != "}":
>         while self.tokens.peek() != "}":
>             type_ = self.tokens.get()
>             type_, size, signed, const = self.parse_type_specifier()
>             name = self.tokens.get()
>             name = self.tokens.get()
>             members[name] = self.parse_declaration(type_, name)
 
 
>             members[name] = self.parse_declaration(
 
>                 type_,
 
>                 size,
 
>                 signed,
 
>                 const,
 
>                 name)
 
 
>             self.tokens.expect(";")
>             self.tokens.expect(";")
>         self.tokens.expect("}")
>         self.tokens.expect("}")
>         return members
>         return members
 
 
>     def parse_typedef_struct(self):
>     def parse_typedef_struct(self):
Line 400... Line 496...
>         self.tokens.expect(";")
>         self.tokens.expect(";")
>         instance = self.scope[struct_name].instance()
>         instance = self.scope[struct_name].instance()
>         self.scope[name] = instance
>         self.scope[name] = instance
>         return instance
>         return instance
 
 
>     def parse_global_declaration(self, type_, name):
>     def parse_global_declaration(self, type_, size, signed, const, name):
>         instances = []
>         instances = []
>         while True:
>         while True:
>             instance = self.parse_declaration(type_, name).instance()
 
 
>             instance = self.parse_declaration(
 
>                 type_,
 
>                 size,
 
>                 signed,
 
>                 const,
 
>                 name).instance()
 
 
>             self.scope[name] = instance
>             self.scope[name] = instance
>             instances.append(instance)
>             instances.append(instance)
>             if self.tokens.peek() == ",":
>             if self.tokens.peek() == ",":
>                 self.tokens.expect(",")
>                 self.tokens.expect(",")
>             else:
>             else:
Line 415... Line 518...
>             name = self.tokens.get()
>             name = self.tokens.get()
>         self.tokens.expect(";")
>         self.tokens.expect(";")
>         return CompoundDeclaration(instances)
>         return CompoundDeclaration(instances)
 
 
>     def parse_compound_declaration(self):
>     def parse_compound_declaration(self):
>         type_ = self.tokens.get()
>         type_, size, signed, const = self.parse_type_specifier()
>         instances = []
>         instances = []
>         while True:
>         while True:
>             name = self.tokens.get()
>             name = self.tokens.get()
>             instance = self.parse_declaration(type_, name).instance()
 
 
>             instance = self.parse_declaration(
 
>                 type_,
 
>                 size,
 
>                 signed,
 
>                 const,
 
>                 name).instance()
 
 
>             self.scope[name] = instance
>             self.scope[name] = instance
>             instances.append(instance)
>             instances.append(instance)
>             if self.tokens.peek() == ",":
>             if self.tokens.peek() == ",":
>                 self.tokens.expect(",")
>                 self.tokens.expect(",")
>             else:
>             else:
>                 break
>                 break
>             name = None
>             name = None
>         self.tokens.expect(";")
>         self.tokens.expect(";")
>         return CompoundDeclaration(instances)
>         return CompoundDeclaration(instances)
 
 
>     def parse_declaration(self, type_, name):
>     def parse_declaration(self, type_, size, signed, const, name):
          #struct declaration
          #struct declaration
>         if type_ in self.structs:
>         if type_ in self.structs:
>             declaration = self.scope[type_]
>             declaration = self.scope[type_]
>         elif type_ in ["int", "short", "long", "char"]:
>         elif type_ in ["int", "float"]:
              #array declaration
              #array declaration
>             if self.tokens.peek() == "[":
>             if self.tokens.peek() == "[":
>                 size = None
>                 array_size = None
>                 self.tokens.expect("[")
>                 self.tokens.expect("[")
>                 if self.tokens.peek() != "]":
>                 if self.tokens.peek() != "]":
>                     size = self.tokens.get()
>                     size_expression = self.parse_ternary_expression()
 
>                     if size_expression.type_() != "int":
 
!                         self.tokens.error("Array size must be an integer like expression")
 
>                     try:
 
>                         array_size = size_expression.value()
 
>                     except NotConstant:
 
>                         self.tokens.error("Array size must be constant")
 
 
>                 self.tokens.expect("]")
>                 self.tokens.expect("]")
>                 initializer = None
>                 initializer = None
>                 if self.tokens.peek() == "=":
>                 if self.tokens.peek() == "=":
>                     self.tokens.expect("=")
>                     self.tokens.expect("=")
>                     initializer = self.tokens.get()
>                     initializer = self.tokens.get()
>                     initializer = [ord(i) for i in initializer.strip('"')] + [0]
>                     initializer = [ord(i) for i in initializer.strip('"').decode("string_escape")] + [0]
>                     size = len(initializer)
>                     array_size = len(initializer)
>                 if size is None:
>                 if array_size is None:
>                     self.tokens.error("array size must be specified if not initialized")
 
>                 type_+="[]"
>                     self.tokens.error(
>                 declaration = ArrayDeclaration(self.allocator, size, type_, initializer)
>                         "array size must be specified if not initialized")
 
 
 
>                 array_type=type_+"[]"
 
>                 initialize_memory = self.initialize_memory
 
>                 declaration = ArrayDeclaration(
 
>                     self.allocator,
 
>                     array_size,
 
>                     array_type,
 
>                     type_,
 
>                     size,
 
>                     signed,
 
>                     initializer,
 
>                     self.initialize_memory)
 
 
              #simple variable declaration
              #simple variable declaration
>             else:
>             else:
>                 if self.tokens.peek() == "=":
>                 if self.tokens.peek() == "=":
>                     self.tokens.expect("=")
>                     self.tokens.expect("=")
>                     initializer = self.parse_ternary_expression()
>                     initializer = self.parse_ternary_expression()
>                 else:
>                 else:
>                     initializer = Constant(0)
>                     initializer = Constant(0, type_, size, signed)
 
 
 
>                 if type_ != initializer.type_():
 
 
 
>                     if type_ == "int" and initializer.type_() == "float":
 
>                         initializer = FloatToInt(initializer)
 
>                     elif type_ == "float" and initializer.type_() == "int":
 
>                         initializer = IntToFloat(initializer)
 
>                     else:
 
>                         self.tokens.error(
 
>                             "type mismatch in intializer expected: %s actual: %s"%(
 
>                                 type_,
 
>                                 intitializer.type_()))
>                 declaration = VariableDeclaration(
>                 declaration = VariableDeclaration(
>                     self.allocator,
>                     self.allocator,
>                     initializer,
>                     initializer,
>                     name,
>                     name,
>                     type_
>                     type_,
 
>                     size,
 
>                     signed,
 
>                     const
>                 )
>                 )
 
 
>         return declaration
>         return declaration
 
 
>     def parse_expression(self):
>     def parse_expression(self):
Line 497... Line 641...
>         while self.tokens.peek() in ["&&"]:
>         while self.tokens.peek() in ["&&"]:
>             self.tokens.expect("&&")
>             self.tokens.expect("&&")
>             expression = AND(expression, self.parse_binary_expression(["|"]))
>             expression = AND(expression, self.parse_binary_expression(["|"]))
>         return expression
>         return expression
 
 
 
>     def substitute_function(self, binary_expression):
 
 
 
>         """
 
>         For some operations are more easily implemented in sofftware.
 
>         This function substitutes a call to the builtin library function.
 
>         """
 
 
 
>         functions = {
 
>            "False,int,int,4,/" : "long_unsigned_divide_xxxx",
 
>            "True,int,int,4,/" : "long_divide_xxxx",
 
>            "False,int,int,2,/" : "unsigned_divide_xxxx",
 
>            "True,int,int,2,/" : "divide_xxxx",
 
>            "False,int,int,4,%" : "long_unsigned_modulo_xxxx",
 
>            "True,int,int,4,%" : "long_modulo_xxxx",
 
>            "False,int,int,2,%" : "unsigned_modulo_xxxx",
 
>            "True,int,int,2,%" : "modulo_xxxx",
 
>            "True,float,float,4,==" : "float_equal_xxxx",
 
>            "True,float,float,4,!=" : "float_ne_xxxx",
 
>            "True,float,float,4,<" : "float_lt_xxxx",
 
>            "True,float,float,4,>" : "float_gt_xxxx",
 
>            "True,float,float,4,<=" : "float_le_xxxx",
 
>            "True,float,float,4,>=" : "float_ge_xxxx",
 
>         }
 
 
 
          #select a function that matches the template.
 
>         signature = ",".join([
 
>             str(binary_expression.signed()),
 
>             binary_expression.left.type_(),
 
>             binary_expression.right.type_(),
 
>             str(binary_expression.size()),
 
>             binary_expression.operator])
 
 
 
          #Some things can't be implemented in verilog, substitute them with a function
 
>         if signature in functions:
 
>             function = self.scope[functions[signature]]
 
>             function_call = FunctionCall(function)
 
>             function_call.arguments = [binary_expression.left, binary_expression.right]
 
>             return function_call
 
>         else:
 
>             return binary_expression
 
 
 
>     def coerce_types(self, left, right):
 
 
 
>         """
 
>         Convert numeric types in expressions.
 
>         """
 
 
 
>         if left.type_() != right.type_():
 
>             if left.type_() == "float" and right.type_() == "int":
 
>                 return left, IntToFloat(right)
 
>             elif left.type_() == "int" and right.type_() == "float":
 
>                 return IntToFloat(left), right
 
>             else:
 
>                 self.tokens.error("Incompatible types : %s %s"%(
 
>                     left.type_(),
 
>                     right.type_()))
 
 
 
>         return left, right
 
 
>     def parse_binary_expression(self, operators):
>     def parse_binary_expression(self, operators):
>         operator_precedence = {
>         operator_precedence = {
>                 "|": ["^"],
>                 "|": ["^"],
>                 "^": ["&"],
>                 "^": ["&"],
>                 "&": ["==", "!="],
>                 "&": ["==", "!="],
Line 508... Line 711...
>                 "<": ["<<", ">>"],
>                 "<": ["<<", ">>"],
>                 "<<": ["+", "-"],
>                 "<<": ["+", "-"],
>                 "+": ["*", "/", "%"],
>                 "+": ["*", "/", "%"],
>         }
>         }
>         if operators[0] not in operator_precedence:
>         if operators[0] not in operator_precedence:
>             expression = self.parse_unary_expression()
>             left = self.parse_unary_expression()
>             while self.tokens.peek() in operators:
>             while self.tokens.peek() in operators:
>                 expression = Binary(
>                 operator = self.tokens.get()
>                     self.tokens.get(),
>                 right = self.parse_unary_expression()
>                     expression,
>                 left, right = self.coerce_types(left, right)
>                     self.parse_unary_expression(),
>                 left = Binary(operator, left, right)
>                     self.allocator
>                 left = self.substitute_function(left)
>                 )
>             return left
>             return expression
 
>         else:
>         else:
>             next_operators = operator_precedence[operators[0]]
>             next_operators = operator_precedence[operators[0]]
>             expression = self.parse_binary_expression(next_operators)
>             left = self.parse_binary_expression(next_operators)
>             while self.tokens.peek() in operators:
>             while self.tokens.peek() in operators:
>                 expression = Binary(
>                 operator = self.tokens.get()
>                     self.tokens.get(),
>                 right = self.parse_binary_expression(next_operators)
>                     expression,
>                 left, right = self.coerce_types(left, right)
>                     self.parse_binary_expression(next_operators),
>                 left = Binary(operator, left, right)
>                     self.allocator
>                 left = self.substitute_function(left)
>                 )
>             return left
>             return expression
 
 
 
>     def parse_unary_expression(self):
>     def parse_unary_expression(self):
>         if self.tokens.peek() == "!":
>         if self.tokens.peek() == "!":
>             operator = self.tokens.get()
>             operator = self.tokens.get()
>             expression = self.parse_paren_expression()
>             expression = self.parse_postfix_expression()
>             return Binary("==", expression, Constant(0), self.allocator)
>             return Binary("==", expression, Constant(0))
>         elif self.tokens.peek() == "-":
>         elif self.tokens.peek() == "-":
>             operator = self.tokens.get()
>             operator = self.tokens.get()
>             expression = self.parse_paren_expression()
>             expression = self.parse_postfix_expression()
>             return Binary("-", Constant(0), expression, self.allocator)
>             return Binary("-", Constant(0,
 
>                 expression.type_(),
 
>                 expression.size(),
 
>                 expression.signed()),
 
>                 expression)
>         elif self.tokens.peek() == "~":
>         elif self.tokens.peek() == "~":
>             operator = self.tokens.get()
>             operator = self.tokens.get()
>             expression = self.parse_paren_expression()
>             expression = self.parse_postfix_expression()
>             return Unary("~", expression)
>             return Unary("~", expression)
 
>         elif self.tokens.peek() == "sizeof":
 
>             operator = self.tokens.get()
 
>             expression = self.parse_unary_expression()
 
>             return SizeOf(expression)
>         else:
>         else:
>             return self.parse_paren_expression()
>             return self.parse_postfix_expression()
 
 
 
>     def parse_postfix_expression(self):
 
>         expression = self.parse_paren_expression()
 
>         while self.tokens.peek() in ["++", "--"]:
 
>             operator = self.tokens.get()
 
>             expression = PostIncrement(
 
>                 operator[:-1],
 
>                 expression,
 
>                 self.allocator
 
>             )
 
>         return expression
 
 
>     def parse_paren_expression(self):
>     def parse_paren_expression(self):
>         if self.tokens.peek() == "(":
>         if self.tokens.peek() == "(":
>             self.tokens.expect("(")
>             self.tokens.expect("(")
>             expression = self.parse_expression()
>             expression = self.parse_expression()
Line 564... Line 784...
>             else:
>             else:
>                 return self.parse_variable(name)
>                 return self.parse_variable(name)
>         else:
>         else:
>             return self.parse_number()
>             return self.parse_number()
 
 
 
>     def parse_file_read(self):
 
!         self.tokens.expect("(")
 
!         file_name = self.tokens.get()
 
>         file_name = file_name.strip('"').decode("string_escape")
 
>         self.tokens.expect(")")
 
!         return FileRead(file_name)
 
 
 
>     def parse_file_write(self):
 
>         self.tokens.expect("(")
 
>         expression = self.parse_expression()
 
>         self.tokens.expect(",")
 
>         file_name = self.tokens.get()
 
>         file_name = file_name.strip('"').decode("string_escape")
 
>         self.tokens.expect(")")
 
>         return FileWrite(file_name, expression)
 
 
>     def parse_input(self, name):
>     def parse_input(self, name):
>         input_name = name.replace("input_", "")
>         input_name = name.replace("input_", "")
>         self.tokens.expect("(")
>         self.tokens.expect("(")
>         self.tokens.expect(")")
>         self.tokens.expect(")")
>         return Input(input_name)
>         return Input(input_name)
Line 590... Line 826...
>             return self.parse_input(name)
>             return self.parse_input(name)
>         if name.startswith("ready_"):
>         if name.startswith("ready_"):
>             return self.parse_ready(name)
>             return self.parse_ready(name)
>         if name.startswith("output_"):
>         if name.startswith("output_"):
>             return self.parse_output(name)
>             return self.parse_output(name)
>         function_call = FunctionCall()
>         if name == "file_read":
 
>             return self.parse_file_read()
 
>         if name == "file_write":
 
>             return self.parse_file_write()
 
>         if name not in self.scope:
 
>             self.tokens.error("Unknown function: %s"%name)
 
>         function = self.scope[name]
 
>         function_call = FunctionCall(function)
>         function_call.arguments = []
>         function_call.arguments = []
>         self.tokens.expect("(")
>         self.tokens.expect("(")
>         while self.tokens.peek() != ")":
>         while self.tokens.peek() != ")":
>             function_call.arguments.append(self.parse_expression())
>             function_call.arguments.append(self.parse_expression())
>             if self.tokens.peek() == ",":
>             if self.tokens.peek() == ",":
>                 self.tokens.expect(",")
>                 self.tokens.expect(",")
>             else:
>             else:
>                 break
>                 break
>         self.tokens.expect(")")
>         self.tokens.expect(")")
 
 
>         if name not in self.scope:
 
>             self.tokens.error("Unknown function: %s"%name)
 
 
 
>         function_call.function = self.scope[name]
 
>         function_call.type_ = function_call.function.type_
 
>         required_arguments = len(function_call.function.arguments)
>         required_arguments = len(function_call.function.arguments)
>         actual_arguments = len(function_call.arguments)
>         actual_arguments = len(function_call.arguments)
>         if required_arguments != actual_arguments:
>         if required_arguments != actual_arguments:
>             self.tokens.error("Function %s takes %s arguments %s given."%(
>             self.tokens.error("Function %s takes %s arguments %s given."%(
>                 name,
>                 name,
>                 len(function_call.function.arguments),
>                 len(function_call.function.arguments),
>                 len(function_call.arguments)
>                 len(function_call.arguments)))
>             ))
 
>         required_arguments = function_call.function.arguments
>         required_arguments = function_call.function.arguments
>         actual_arguments = function_call.arguments
>         actual_arguments = function_call.arguments
 
>         corrected_arguments = []
>         for required, actual in zip(required_arguments, actual_arguments):
>         for required, actual in zip(required_arguments, actual_arguments):
>             if required.type_ != actual.type_:
>             if not compatible(required, actual):
>                 self.tokens.error("Type mismatch expected type : %s got: %s."%(
>                 if actual.type_() == "int" and required.type_() == "float":
>                     required.type_,
>                     actual = IntToFloat(actual)
>                     actual.type_
>                 elif actual.type_() == "float" and required.type_() == "int":
>                 ))
!                     actual = FloatToInt(actual)
 
>                 else:
 
>                     self.tokens.error(
 
>                         "type mismatch in assignment expected: %s actual: %s"%(
 
>                             required.type_(),
 
>                             actual.type_()))
 
>             corrected_arguments.append(actual)
 
>         function_call.arguments = corrected_arguments
 
 
>         return function_call
>         return function_call
 
 
>     def parse_number(self):
>     def parse_number(self):
>         token = self.tokens.get()
>         token = self.tokens.get()
 
>         type_ = "int"
 
>         size = 2
 
>         signed = True
>         if token.startswith("'"):
>         if token.startswith("'"):
>             try:
>             try:
>                 token = eval(token)
>                 token = eval(token)
>                 value = ord(token)
>                 value = ord(token)
!             except SyntaxError:
!             except SyntaxError:
!                 self.tokens.error("%s is not a character literal"%token)
!                 self.tokens.error("%s is not a character literal"%token)
 
>         elif token.startswith('"'):
 
>             try:
 
>                 initializer = [ord(i) for i in token.strip('"').decode("string_escape")] + [0]
 
>                 size = len(initializer)
 
>                 initialize_memory = self.initialize_memory
 
>                 declaration = ArrayDeclaration(
 
>                     self.allocator,
 
>                     size,
 
>                     "int[]",
 
>                     "int",
 
>                     2,
 
>                     False,
 
>                     initializer,
 
>                     self.initialize_memory)
 
>                 return ConstArray(declaration.instance())
 
!             except SyntaxError:
 
!                 self.tokens.error("%s is not a character literal"%token)
 
>         elif "." in token:
 
              #float literal
 
>             try:
 
>                 type_ = "float"
 
>                 signed = True
 
>                 size = 4
 
>                 token = token.upper().replace("F", "")
 
>                 token = token.upper().replace("L", "")
 
>                 value = float(eval(token))
 
 
 
>                 try:
 
>                     byte_value = struct.pack(">f", value)
 
>                 except OverflowError:
 
>                     self.tokens.error("value too large")
 
 
 
>             except SyntaxError:
 
>                 self.tokens.error("%s is not a floating point literal"%token)
>         else:
>         else:
 
              #integer literal
>             try:
>             try:
 
>                 if "U" in token.upper():
 
>                     signed = False
 
>                 if "L" in token.upper():
 
>                     size = 4
 
>                 token = token.upper().replace("U", "")
>                 value = int(eval(token))
>                 value = int(eval(token))
 
 
 
>                 if signed:
 
>                     if value > 2**((size * 8)-1) - 1:
 
>                         self.tokens.error("value too large")
 
>                     if value < -(2**((size * 8)-1)):
 
>                         self.tokens.error("value too small")
 
>                 else:
 
>                     if value > 2**(size * 8) - 1:
 
!                         self.tokens.error("value too large")
 
>                     if value < 0:
 
>                         self.tokens.error("value too small")
 
 
>             except SyntaxError:
>             except SyntaxError:
>                 self.tokens.error("%s is not an integer literal"%token)
>                 self.tokens.error("%s is not an integer literal"%token)
>         return Constant(value)
 
 
>         return Constant(value, type_, size, signed)
 
 
>     def parse_variable(self, name):
>     def parse_variable(self, name):
>         if name not in self.scope:
>         if name not in self.scope:
>             self.tokens.error("Unknown variable: %s"%name)
>             self.tokens.error("Unknown variable: %s"%name)
>         instance = self.scope[name]
>         instance = self.scope[name]
>         return self.parse_variable_array_struct(instance)
>         return self.parse_variable_array_struct(instance)
 
 
>     def parse_variable_array_struct(self, instance):
>     def parse_variable_array_struct(self, instance):
>         if instance.type_ in ["int", "short", "long", "char"]:
>         if instance.type_() in numeric_types:
>             return Variable(instance, self.allocator)
 
>         elif instance.type_.endswith("[]"):
>             if not hasattr(instance, "reference"):
 
 
 
>                 self.tokens.error(
 
>                     "Not an expression")
 
 
 
>             return Variable(instance)
 
>         elif instance.type_().endswith("[]"):
>             if self.tokens.peek() == "[":
>             if self.tokens.peek() == "[":
>                 self.tokens.expect("[")
>                 self.tokens.expect("[")
>                 index_expression = self.parse_expression()
>                 index_expression = self.parse_expression()
>                 self.tokens.expect("]")
>                 self.tokens.expect("]")
>                 if index_expression.type_ not in ["int", "short", "long", "char"]:
>                 if index_expression.type_() not in ["int"]:
 
 
>                     self.tokens.error(
>                     self.tokens.error(
>                         "array indices must be an integer like expression"
>                         "Array indices must be an integer like expression")
>                     )
 
>                 return ArrayIndex(instance, index_expression, self.allocator)
>                 return ArrayIndex(instance, index_expression)
>             else:
>             else:
>                 return Array(instance, self.allocator)
>                 return Array(instance)
>         elif instance.type_ == "struct":
>         elif instance.type_().startswith("struct"):
 
>             if self.tokens.peek() == ".":
>             self.tokens.expect(".")
>             self.tokens.expect(".")
>             member = self.tokens.get()
>             member = self.tokens.get()
>             instance = instance.members[member]
>             instance = instance.members[member]
>             return self.parse_variable_array_struct(instance)
>             return self.parse_variable_array_struct(instance)
 
>             else:
 
>                 return Struct(instance)
 
 
 
> def compatible(left, right):
 
>     return left.type_() == right.type_()

powered by: WebSVN 2.1.0

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