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

Subversion Repositories tcp_socket

[/] [tcp_socket/] [trunk/] [chips2/] [chips/] [compiler/] [parser.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
 
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
 
 
 
types = ["float", "signed", "unsigned", "short", "long", "char", "int", "void"]
 
numeric_types = ["float", "signed", "unsigned", "short", "long", "char", "int"]
 
storage_specifiers = ["const"]
 
 
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, initialize_memory):
    def __init__(self, input_file, reuse, initialize_memory):
Line 36... Line 43...
        return process
        return process
 
 
    def parse_type_specifier(self):
    def parse_type_specifier(self):
        type_specifiers = []
        type_specifiers = []
 
 
        while self.tokens.peek() in ["signed", "unsigned", "short", "long", "char", "int", "void"] + self.structs:
        while self.tokens.peek() in types + self.structs + storage_specifiers:
            type_specifiers.append(self.tokens.get())
            type_specifiers.append(self.tokens.get())
 
 
        signed = True
        signed = True
        if "unsigned" in type_specifiers:
        if "unsigned" in type_specifiers:
            signed = False
            signed = False
Line 58... Line 65...
            if i in self.structs:
            if i in self.structs:
                type_ = i
                type_ = i
                size = 2
                size = 2
                signed = False
                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:
        if "void" in type_specifiers:
            type_ = "void"
            type_ = "void"
            size = 2
            size = 2
            signed = False
            signed = False
 
 
 
 
        return type_, size, signed
        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_, size, signed = self.parse_type_specifier()
        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() != "(":
            return self.parse_global_declaration(type_, size, signed, name)
            return self.parse_global_declaration(type_, size, signed, const, 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.size = size
        function.size = size
        function.signed = signed
        function.signed = signed
        function.return_address = self.allocator.new(2, function.name+" return address")
 
 
        function.return_address = self.allocator.new(2,
 
            function.name+" return address")
 
 
        if type_ != "void":
        if type_ != "void":
            function.return_value = self.allocator.new(function.size, function.name+" return value")
 
        function.arguments = []
            if type_ in self.structs:
        while self.tokens.peek() != ")":
                declaration = self.scope[type_]
            argument_type, argument_size, argument_signed = self.parse_type_specifier()
            else:
            if argument_type in ["void"]:
 
                self.tokens.error("argument cannot be void")
 
            argument = self.tokens.get()
 
            element_type = None
 
            element_size = None
 
            element_signed = None
 
            if self.tokens.peek() == "[":
            if self.tokens.peek() == "[":
                self.tokens.expect("[")
                    self.tokens.error(
                self.tokens.expect("]")
                        "Functions cannot return arrays")
                element_type = argument_type
                else:
                element_size = argument_size
                    declaration = VariableDeclaration(
                element_signed = argument_signed
                        self.allocator,
                argument_type+="[]"
                        None,
                argument_size = 2
                        function.name+" return value",
                argument_signed = False
                        type_,
 
                        size,
 
                        signed,
 
                        const)
 
 
            function.arguments.append(Argument(
            function.return_value = declaration.instance().reference()
                argument,
 
                argument_type,
        function.arguments = []
                argument_size,
        while self.tokens.peek() != ")":
                argument_signed,
            function.arguments.append(self.parse_argument())
                self,
 
                element_type,
 
                element_size,
 
                element_signed))
 
            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 147... 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 190... 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 ["unsigned", "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 230... 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()
            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 not compatible(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 ["unsigned", "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()
Line 281... Line 343...
        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 ["unsigned", "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 298... 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"]:
        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 346... Line 403...
        if_ = If()
        if_ = If()
        loop.statement = 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"]:
        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
 
 
        return loop
        return loop
Line 366... 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 ["unsigned", "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 382... 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 395... 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_, size, signed = self.parse_type_specifier()
            type_, size, signed, const = self.parse_type_specifier()
            name = self.tokens.get()
            name = self.tokens.get()
            members[name] = self.parse_declaration(type_, size, signed, 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 427... 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_, size, signed, name):
    def parse_global_declaration(self, type_, size, signed, const, name):
        instances = []
        instances = []
        while True:
        while True:
            instance = self.parse_declaration(type_, size, signed, 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 442... 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_, size, signed = self.parse_type_specifier()
        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_, size, signed, 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_, size, signed, 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"]:
        elif type_ in ["int", "float"]:
            #array declaration 
            #array declaration 
            if self.tokens.peek() == "[":
            if self.tokens.peek() == "[":
                array_size = None
                array_size = None
                self.tokens.expect("[")
                self.tokens.expect("[")
                if self.tokens.peek() != "]":
                if self.tokens.peek() != "]":
                    array_size = int(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('"').decode("string_escape")] + [0]
                    initializer = [ord(i) for i in initializer.strip('"').decode("string_escape")] + [0]
                    array_size = len(initializer)
                    array_size = len(initializer)
                if array_size is None:
                if array_size is None:
                    self.tokens.error("array size must be specified if not initialized")
 
 
                    self.tokens.error(
 
                        "array size must be specified if not initialized")
 
 
                array_type=type_+"[]"
                array_type=type_+"[]"
                initialize_memory = self.initialize_memory
                initialize_memory = self.initialize_memory
                declaration = ArrayDeclaration(self.allocator,
                declaration = ArrayDeclaration(
 
                    self.allocator,
                                               array_size,
                                               array_size,
                                               array_type,
                                               array_type,
                                               type_,
                                               type_,
                                               size,
                                               size,
                                               signed,
                                               signed,
Line 494... Line 588...
            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,
                    size,
                    signed
                    signed,
 
                    const
                )
                )
 
 
        return declaration
        return declaration
 
 
    def parse_expression(self):
    def parse_expression(self):
Line 534... 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, operator, left, right):
    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
        #Some things can't be implemented in verilog, substitute them with a function
        if operator in ["/", "%"]:
        if signature in functions:
            function_call = FunctionCall()
            function = self.scope[functions[signature]]
            function_call.arguments = [left, right]
            function_call = FunctionCall(function)
            if operator == "/":
            function_call.arguments = [binary_expression.left, binary_expression.right]
                if left.signed and right.signed:
 
                    if max(left.size, right.size) == 4:
 
                        function_call.function = self.scope["long_divide_xxxx"]
 
                    else:
 
                        function_call.function = self.scope["divide_xxxx"]
 
                else:
 
                    if max(left.size, right.size) == 4:
 
                        function_call.function = self.scope["long_unsigned_divide_xxxx"]
 
                    else:
 
                        function_call.function = self.scope["unsigned_divide_xxxx"]
 
            elif operator == "%":
 
                if left.signed and right.signed:
 
                    if max(left.size, right.size) == 4:
 
                        function_call.function = self.scope["long_modulo_xxxx"]
 
                    else:
 
                        function_call.function = self.scope["modulo_xxxx"]
 
                else:
 
                    if max(left.size, right.size) == 4:
 
                        function_call.function = self.scope["long_unsigned_modulo_xxxx"]
 
                    else:
 
                        function_call.function = self.scope["unsigned_modulo_xxxx"]
 
            function_call.type_ = function_call.function.type_
 
            function_call.size = function_call.function.size
 
            function_call.signed = function_call.function.signed
 
            return function_call
            return function_call
        else:
        else:
            return Binary(
            return binary_expression
                operator,
 
                left,
    def coerce_types(self, left, right):
                right,
 
                self.allocator
        """
            )
        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 584... 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:
                operator = self.tokens.get()
                operator = self.tokens.get()
                right = self.parse_unary_expression()
                right = self.parse_unary_expression()
                expression = self.substitute_function(operator, expression, right)
                left, right = self.coerce_types(left, right)
            return expression
                left = Binary(operator, left, right)
 
                left = self.substitute_function(left)
 
            return left
        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_postfix_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_postfix_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_postfix_expression()
            expression = self.parse_postfix_expression()
            return Unary("~", expression, self.allocator)
            return Unary("~", expression)
        elif self.tokens.peek() == "sizeof":
        elif self.tokens.peek() == "sizeof":
            operator = self.tokens.get()
            operator = self.tokens.get()
            expression = self.parse_unary_expression()
            expression = self.parse_unary_expression()
            return SizeOf(expression)
            return SizeOf(expression)
        else:
        else:
Line 698... Line 830...
            return self.parse_output(name)
            return self.parse_output(name)
        if name == "file_read":
        if name == "file_read":
            return self.parse_file_read()
            return self.parse_file_read()
        if name == "file_write":
        if name == "file_write":
            return self.parse_file_write()
            return self.parse_file_write()
        function_call = FunctionCall()
        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_
 
        function_call.size = function_call.function.size
 
        function_call.signed = function_call.function.signed
 
        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 not compatible(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
        size = 2
        signed = True
        signed = True
        if token.startswith("'"):
        if token.startswith("'"):
            try:
            try:
                token = eval(token)
                token = eval(token)
Line 760... Line 896...
                    "int",
                    "int",
                    2,
                    2,
                    False,
                    False,
                    initializer,
                    initializer,
                    self.initialize_memory)
                    self.initialize_memory)
                return declaration.instance()
                return ConstArray(declaration.instance())
            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 "." 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():
                if "U" in token.upper():
                    signed = False
                    signed = False
                if "L" in token.upper():
                if "L" in token.upper():
                    size = 4
                    size = 4
Line 785... Line 939...
                    if value < 0:
                    if value < 0:
                        self.tokens.error("value too small")
                        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, size, signed)
 
 
        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 ["unsigned", "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 ["unsigned", "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):
def compatible(left, right):
    return left == right
    return left.type_() == right.type_()
 
 
 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.