예제 #1
0
 def inlinePass(self, allow_inline):
     """Run inline pass. Return list of merged names if no inlining could be done."""
     # Collect identifiers. First pass - collect from generic sources and append from non-generic.
     collected = []
     for ii in self.__sources:
         if not ii.getType():
             collect_pass = ii.collect()
             for jj in self.__sources:
                 if jj.getType():
                     for kk in collect_pass:
                         jj.collectAppend(kk)
             collected += collect_pass
     # Second pass - collect from non-generic sources. Do not append.
     for ii in self.__sources:
         if ii.getType():
             collected += ii.collect()
     # Merge multiple matching inout names.
     merged = sorted(merge_collected_names(collected),
                     key=len,
                     reverse=True)
     # Collect all member accesses for members and set them to the blocks.
     for ii in merged:
         block = ii[0]
         if is_listing(block):
             block = block[0]
         if not (is_glsl_block_inout_struct(block)
                 or is_glsl_block_struct(block)):
             continue
         lst = collect_member_accesses(ii[0], ii[1:])
         block.setMemberAccesses(lst)
     # If inlining is not allowed, just return merged block.
     if not allow_inline:
         return merged
     # Perform inlining if possible.
     for ii in range(len(merged)):
         vv = merged[ii]
         block = vv[0]
         if is_listing(block) or (not is_glsl_block_declaration(block)):
             continue
         names = vv[1:]
         if not is_inline_name(names[0]):
             continue
         # If no inline conflict, perform inline and return nothing to signify another pass can be done.
         if not self.hasInlineConflict(block, names):
             self.inline(block, names)
             return None
     # Return merged list.
     return merged
예제 #2
0
 def deconstruct(self):
     """Deconstruct into byte stream."""
     lst = []
     if is_listing(self.__value):
         for ii in self.__value:
             if not is_deconstructable(ii):
                 break
             lst += self.deconstruct_single(int(ii))
     elif is_deconstructable(self.__value):
         lst = self.deconstruct_single(int(self.__value))
     if 0 >= len(lst):
         return None
     if 1 >= len(lst):
         return [self]
     ret = []
     for ii in range(len(lst)):
         struct_elem = lst[ii]
         if isinstance(struct_elem, str):
             var = AssemblerVariable(("", 1, ord(struct_elem)))
         else:
             var = AssemblerVariable(("", 1, int(struct_elem)))
         if 0 == ii:
             var.__desc = self.__desc
             var.__name = self.__name
             var.__original_size = self.__size
             var.__label_pre = self.__label_pre
         elif len(lst) - 1 == ii:
             var.__label_post = self.__label_post
         ret += [var]
     return ret
예제 #3
0
 def deconstruct(self):
     """Deconstruct into byte stream."""
     lst = []
     if is_listing(self.__value):
         for ii in self.__value:
             if not is_deconstructable(ii):
                 break
             lst += self.deconstruct_single(int(ii))
     elif is_deconstructable(self.__value):
         lst = self.deconstruct_single(int(self.__value))
     if 0 >= len(lst):
         return None
     if 1 >= len(lst):
         return [self]
     ret = []
     for ii in range(len(lst)):
         struct_elem = lst[ii]
         if isinstance(struct_elem, str):
             var = AssemblerVariable(("", 1, ord(struct_elem)))
         else:
             var = AssemblerVariable(("", 1, int(struct_elem)))
         if 0 == ii:
             var.__desc = self.__desc
             var.__name = self.__name
             var.__original_size = self.__size
             var.__label_pre = self.__label_pre
         elif len(lst) - 1 == ii:
             var.__label_post = self.__label_post
         ret += [var]
     return ret
예제 #4
0
def merge_collected_names_inout(lst):
    """Merge inout blocks from given list of names."""
    ret = []
    for ii in lst:
        if is_glsl_block_inout(ii[0]):
            found = False
            for jj in range(len(ret)):
                vv = ret[jj]
                block = vv[0]
                if is_listing(block):
                    block = block[0]
                if is_glsl_block_inout(block) and block.isMergableWith(ii[0]):
                    if ii[1] != ii[0].getName():
                        raise RuntimeError(
                            "inout block inconsistency: '%s' vs. '%s'" %
                            (ii[1], ii[0].getName()))
                    if vv[1] != block.getName():
                        raise RuntimeError(
                            "inout block inconsistency: '%s' vs. '%s'" %
                            (vv[1], vv[0].getName()))
                    ret[jj] = merge_collected_name_lists(vv, ii)
                    found = True
                    break
            if found:
                continue
        ret += [ii]
    return ret
예제 #5
0
파일: glsl_block.py 프로젝트: mikalv/dnload
 def addAccesses(self, op):
     if is_listing(op):
         for ii in op:
             self.addAccesses(ii)
         return
     if not is_glsl_access(op):
         return
     self.__accesses += [op]
예제 #6
0
 def addExtraFlags(self, op):
     """Add extra flags to use when linking."""
     if is_listing(op):
         for ii in op:
             self.addExtraFlags(ii)
         return
     if not (op in self.__linker_flags_extra):
         self.__linker_flags_extra += [op]
예제 #7
0
 def addAccesses(self, op):
     if is_listing(op):
         for ii in op:
             self.addAccesses(ii)
         return
     if not is_glsl_access(op):
         return
     self.__accesses += [op]
예제 #8
0
 def addExtraFlags(self, op):
     """Add extra flags to use when assembling."""
     if is_listing(op):
         for ii in op:
             self.addExtraFlags(ii)
         return
     if not (op in self.__assembler_flags_extra):
         self.__assembler_flags_extra += [op]
예제 #9
0
파일: compiler.py 프로젝트: faemiyah/dnload
 def add_extra_compiler_flags(self, op):
     """Add extra compiler flags."""
     if is_listing(op):
         for ii in op:
             self.add_extra_compiler_flags(ii)
         return
     if not (op in self._compiler_flags_extra):
         if (not (op in self._include_directories)) and (not (op in self._definitions)):
             self._compiler_flags_extra += [op]
예제 #10
0
 def addNamesUsed(self, op):
     """Add given names as names used by this block."""
     if is_listing(op):
         for ii in op:
             self.addNamesUsed(ii)
         return
     if not is_glsl_name(op):
         return
     self.__names_used += [op]
예제 #11
0
파일: compiler.py 프로젝트: faemiyah/dnload
 def add_extra_compiler_flags(self, op):
     """Add extra compiler flags."""
     if is_listing(op):
         for ii in op:
             self.add_extra_compiler_flags(ii)
         return
     if not (op in self._compiler_flags_extra):
         if (not (op in self._include_directories)) and (not (op in self._definitions)):
             self._compiler_flags_extra += [op]
예제 #12
0
파일: glsl_block.py 프로젝트: mikalv/dnload
 def addNamesUsed(self, op):
     """Add given names as names used by this block."""
     if is_listing(op):
         for ii in op:
             self.addNamesUsed(ii)
         return
     if not is_glsl_name(op):
         return
     self.__names_used += [op]
예제 #13
0
 def addAccesses(self, op):
     """Adds access elements in the block to the block's access list."""
     if is_listing(op):
         for ii in op:
             self.addAccesses(ii)
         return
     if not is_glsl_access(op):
         return
     self.__accesses += [op]
예제 #14
0
 def __init__(self, lst, terminator = ""):
   """Constructor."""
   GlslBlock.__init__(self)
   self.__content = lst
   self.__terminator = terminator
   if (not is_listing(self.__content)) or (None in self.__content):
     raise RuntimeError("content must be a listing")
   # Hierarchy.
   self.addAccesses(lst)
   self.addNamesUsed(lst)
예제 #15
0
 def __init__(self, lst, terminator=""):
     """Constructor."""
     GlslBlock.__init__(self)
     self.__content = lst
     self.__terminator = terminator
     if (not is_listing(self.__content)) or (None in self.__content):
         raise RuntimeError("content must be a listing")
     # Hierarchy.
     self.addAccesses(lst)
     self.addNamesUsed(lst)
예제 #16
0
파일: glsl_block.py 프로젝트: mikalv/dnload
 def addNamesDeclared(self, op):
     """Add given names as names declared by this block."""
     if is_listing(op):
         for ii in op:
             self.addNamesDeclared(ii)
         return
     if not is_glsl_name(op):
         return
     if op in self.__names_declared:
         raise RuntimeError("declaring name '%s' twice" % (op))
     self.__names_declared.add(op)
예제 #17
0
 def format_label(self, op):
     """Generate name labels."""
     if not op:
         return ""
     ret = ""
     if is_listing(op):
         for ii in op:
             ret += format_label(ii)
     else:
         ret += ".globl %s\n%s:\n" % (op, op)
     return ret
예제 #18
0
 def __init__(self, op):
   """Constructor."""
   self.__name = None
   self.__desc = None
   self.__data = []
   if isinstance(op, str):
     self.__name = op
     self.__desc = None
   elif is_listing(op):
     for ii in op:
       if is_listing(ii):
         self.add_data(ii)
       elif not self.__name:
         self.__name = ii
       elif not self.__desc:
         self.__desc = ii
       else:
         raise RuntimeError("too many string arguments for list constructor")
   self.refresh_name_label()
   self.refresh_name_end_label()
예제 #19
0
 def addNamesDeclared(self, op):
     """Add given names as names declared by this block."""
     if is_listing(op):
         for ii in op:
             self.addNamesDeclared(ii)
         return
     if not is_glsl_name(op):
         return
     if op in self.__names_declared:
         raise RuntimeError("declaring name '%s' twice" % (op))
     self.__names_declared.add(op)
예제 #20
0
 def __init__(self, op):
     """Constructor."""
     self.__name = None
     self.__desc = None
     self.__data = []
     if isinstance(op, str):
         self.__name = op
         self.__desc = None
     elif is_listing(op):
         for ii in op:
             if is_listing(ii):
                 self.add_data(ii)
             elif not self.__name:
                 self.__name = ii
             elif not self.__desc:
                 self.__desc = ii
             else:
                 raise RuntimeError("too many string arguments for list constructor")
     self.refresh_name_label()
     self.refresh_name_end_label()
예제 #21
0
 def format_label(self, op):
     """Generate name labels."""
     if not op:
         return ""
     ret = ""
     if is_listing(op):
         for ii in op:
             ret += format_label(ii)
     else:
         ret += ".globl %s\n%s:\n" % (op, op)
     return ret
예제 #22
0
 def addRight(self, op):
     """Add right child token."""
     # List case.
     if is_listing(op):
         for ii in op:
             self.addRight(ii)
         return
     # Single case.
     if not is_glsl_token(op):
         raise RuntimeError("trying to add right non-token '%s'" % (str(left)))
     self.__right += [op]
     op.setParent(self)
예제 #23
0
def merge_collected_name_lists(lst1, lst2):
    """Merge two collected names lists."""
    if is_listing(lst2[0]):
        raise RuntimeError(
            "expected non-listing as first element of collected name list 2, got: %s"
            % (str(lst2[0])))
    if is_listing(lst1[0]):
        ret = [lst1[0] + [lst2[0]]]
    else:
        ret = [[lst1[0], lst2[0]]]
    ret += lst1[1:]
    # It is possible both listings contain some exact same following values, do not simply catenate.
    for ii in lst2[1:]:
        found = False
        for jj in ret[1:]:
            if ii is jj:
                found = True
                break
        if not found:
            ret += [ii]
    return ret
예제 #24
0
 def __init__(self, op, name=None):
     """Constructor."""
     if not is_listing(op):
         raise RuntimeError("only argument passed is not a list")
     self.__desc = op[0]
     self.__size = op[1]
     self.__value = op[2]
     self.__name = name
     self.__original_size = -1
     self.__label_pre = []
     self.__label_post = []
     if 3 < len(op):
         self.add_label_pre(op[3])
예제 #25
0
 def __init__(self, op, name=None):
     """Constructor."""
     if not is_listing(op):
         raise RuntimeError("only argument passed is not a list")
     self.__desc = op[0]
     self.__size = op[1]
     self.__value = op[2]
     self.__name = name
     self.__original_size = -1
     self.__label_pre = []
     self.__label_post = []
     if 3 < len(op):
         self.add_label_pre(op[3])
예제 #26
0
 def addRight(self, op):
     """Add right child token."""
     # List case.
     if is_listing(op):
         for ii in op:
             self.addRight(ii)
         return
     # Single case.
     if not is_glsl_token(op):
         raise RuntimeError("trying to add right non-token '%s'" %
                            (str(left)))
     self.__right += [op]
     op.setParent(self)
예제 #27
0
파일: glsl_block.py 프로젝트: mikalv/dnload
def check_token(token, req):
    """Check if token is acceptable but do not compare against types."""
    # Check against list, any option is ok.
    if is_listing(req):
        for ii in req:
            if check_token(token, ii):
                return True
        return False
    if not isinstance(req, str):
        raise RuntimeError("request '%s' is not a string" % (str(req)))
    # Tokens are converted to strings for comparison.
    if isinstance(token, str) and (token == req):
        return True
    return (token.format(False) == req)
예제 #28
0
 def addMiddle(self, op):
     """Add middle child token."""
     # List case.
     if is_listing(op):
         for ii in op:
             self.addMiddle(ii)
         return
     # Tokens added normally.
     if is_glsl_token(op):
         self.__middle += [op]
         op.setParent(self)
     # Non-tokens added as-is.
     else:
         self.__middle += [op]
예제 #29
0
def check_token(token, req):
    """Check if token is acceptable but do not compare against types."""
    # Check against list, any option is ok.
    if is_listing(req):
        for ii in req:
            if check_token(token, ii):
                return True
        return False
    if not isinstance(req, str):
        raise RuntimeError("request '%s' is not a string" % (str(req)))
    # Tokens are converted to strings for comparison.
    if isinstance(token, str) and (token == req):
        return True
    return (token.format(False) == req)
예제 #30
0
 def addMiddle(self, op):
     """Add middle child token."""
     # List case.
     if is_listing(op):
         for ii in op:
             self.addMiddle(ii)
         return
     # Tokens added normally.
     if is_glsl_token(op):
         self.__middle += [op]
         op.setParent(self)
     # Non-tokens added as-is.
     else:
         self.__middle += [op]
예제 #31
0
def collect_member_uses(op, uses):
    """Collect member uses from inout struct blocks."""
    # List case.
    if is_listing(op):
        for ii in op:
            collect_member_uses(ii, uses)
        return
    # Actual inout block.
    for ii in op.getMembers():
        name_object = ii.getName()
        name_string = name_object.getName()
        if name_string in uses:
            uses[name_string] += [name_object]
        else:
            uses[name_string] = [name_object]
예제 #32
0
 def __init__(self, typeid, name, lst, scope):
     """Constructor."""
     GlslBlock.__init__(self)
     self.__typeid = typeid
     self.__name = name
     self.__parameters = lst
     self.__scope = scope
     if not is_listing(self.__parameters):
         raise RuntimeError("parameters must be a listing")
     # Hierarchy.
     name.setType(typeid)
     self.addNamesDeclared(name)
     self.addNamesUsed(name)
     self.addChildren(lst)
     self.addChildren(scope)
예제 #33
0
def glsl_parse_parameter_list(source):
    """Parse list of parameters."""
    # Empty parameter list is ok.
    if is_listing(source) and (0 >= len(source)):
        return []
    ret = []
    parameters = glsl_split_parameter_list(source)
    for ii in parameters:
        (parameter, remaining) = glsl_parse_parameter(ii)
        if not parameter:
            raise RuntimeError("could not parse parameter from '%s'" % (str(map(str, ii))))
        if remaining:
            raise RuntimeError("extra content after parameter: '%s'" % (str(map(str, remaining))))
        ret += [parameter]
    return ret
예제 #34
0
 def __init__(self, typeid, name, lst, scope):
     """Constructor."""
     GlslBlock.__init__(self)
     self.__typeid = typeid
     self.__name = name
     self.__parameters = lst
     self.__scope = scope
     if not is_listing(self.__parameters):
         raise RuntimeError("parameters must be a listing")
     # Hierarchy.
     name.setType(typeid)
     self.addNamesDeclared(name)
     self.addNamesUsed(name)
     self.addChildren(lst)
     self.addChildren(scope)
예제 #35
0
 def addChildren(self, lst, prepend=False):
     """Add another block as a child of this."""
     if not is_listing(lst):
         self.addChildren([lst], prepend)
         return
     for ii in lst:
         if not is_glsl_block(ii):
             raise RuntimeError("element '%s' to be added is not of type GlslBlock" % (str(ii)))
         if ii.getParent():
             raise RuntimeError("block '%s' to be added already has parent '%s'" % (str(ii), str(ii.getParent())))
         if prepend:
             self._children = [ii] + self._children
         else:
             self._children += [ii]
         ii.setParent(self)
예제 #36
0
 def addChildren(self, lst, prepend=False):
     """Add another block as a child of this."""
     if not is_listing(lst):
         self.addChildren([lst], prepend)
         return
     for ii in lst:
         if not is_glsl_block(ii):
             raise RuntimeError("element '%s' to be added is not of type GlslBlock" % (str(ii)))
         if ii.getParent():
             raise RuntimeError("block '%s' to be added already has parent '%s'" % (str(ii), str(ii.getParent())))
         if prepend:
             self._children = [ii] + self._children
         else:
             self._children += [ii]
         ii.setParent(self)
예제 #37
0
def glsl_parse_member_list(source):
    """Parse list of members."""
    # Empty member list is ok.
    if is_listing(source) and (0 >= len(source)):
        return []
    (member, content) = glsl_parse_member(source)
    if not member:
        raise RuntimeError("error parsing members: %s" % (str(map(str, source))))
    ret = [member]
    while content:
        (member, remaining) = glsl_parse_member(content)
        if not member:
            raise RuntimeError("error parsing members: %s" % (str(map(str, content))))
        ret += [member]
        content = remaining
    return ret
예제 #38
0
def glsl_parse_member_list(source):
    """Parse list of members."""
    # Empty member list is ok.
    if is_listing(source) and (0 >= len(source)):
        return []
    (member, content) = glsl_parse_member(source)
    if not member:
        raise RuntimeError("error parsing members: %s" % (str(map(str, source))))
    ret = [member]
    while content:
        (member, remaining) = glsl_parse_member(content)
        if not member:
            raise RuntimeError("error parsing members: %s" % (str(map(str, content))))
        ret += [member]
        content = remaining
    return ret
예제 #39
0
 def getSingleChild(self):
     """Degeneration preventation. If token only has a single child, return that instead."""
     lr = len(self.__left) + len(self.__right)
     # If left and right exist, return node itself - there is no single child here.
     if 0 < lr:
         if not self.__middle and ((not self.__left) or (not self.__right)):
             raise RuntimeError("empty middle only allowed if bothe left and right exist")
         return self
     # If left and right did not exist, return middle.
     elif self.__middle:
         if is_listing(self.__middle):
             if 1 >= len(self.__middle):
                 return self.__middle[0]
         return self.__middle
     # Should never happen.
     raise RuntimeError("token has no content")
예제 #40
0
 def hasInlineConflict(self, block, names):
     """Tell if given block has an inlining conflict."""
     # If block is a listing, just go over all options.
     if is_listing(block):
         for ii in block:
             if self.hasInlineConflict(ii, names):
                 return True
         return False
     # Check for inline conflicts within this block.
     parent = find_parent_scope(block)
     if is_glsl_block_source(parent):
         for ii in self.__sources:
             if (ii != parent) and ((not parent.getType()) or (not ii.getType())):
                 if has_inline_conflict(ii, block, names):
                     return True
     return has_inline_conflict(parent, block, names)
예제 #41
0
def extract_tokens(tokens, required):
    """Require tokens from token string, return selected elements and the rest of tokens."""
    # If required is just a string, make it a listing of length one.
    if not is_listing(required):
        required = (required,)
    # Generate array for returning on failure.
    failure_array = []
    for ii in required:
        if "?" == ii[:1]:
            failure_array += [None]
    failure_array += [tokens]
    # For straight-out incompatible request, get out immediately.
    if len(required) > len(tokens):
        return failure_array
    # Iterate over requests.
    content = tokens[:]
    required = list(required)
    ret = []
    success = True
    while content and required:
        curr = content.pop(0)
        req = required.pop(0)
        # Token request.
        if "?" == req[:1]:
            desc = req[1:]
            # Extracting scope.
            if desc in ("{", "[", "("):
                if curr.format(False) == desc:
                    (scope, remaining) = extract_scope(content, curr)
                    if not (scope is None):
                        ret += [scope]
                        content = remaining
                        continue
                # Scope not found.
                return failure_array
            # Extracting singular element.
            validated = validate_token(curr, desc)
            if validated:
                ret += [validated]
            else:
                return failure_array
        # Not a request, compare verbatim. Names can be compared verbatim.
        elif not check_token(curr, req):
            return failure_array
    # Successful, return the remaining elements.
    return ret + [content]
예제 #42
0
파일: glsl_block.py 프로젝트: mikalv/dnload
def extract_tokens(tokens, required):
    """Require tokens from token string, return selected elements and the rest of tokens."""
    # If required is just a string, make it a listing of length one.
    if not is_listing(required):
        required = (required, )
    # Generate array for returning on failure.
    failure_array = []
    for ii in required:
        if "?" == ii[:1]:
            failure_array += [None]
    failure_array += [tokens]
    # For straight-out incompatible request, get out immediately.
    if len(required) > len(tokens):
        return failure_array
    # Iterate over requests.
    content = tokens[:]
    required = list(required)
    ret = []
    success = True
    while content and required:
        curr = content.pop(0)
        req = required.pop(0)
        # Token request.
        if "?" == req[:1]:
            desc = req[1:]
            # Extracting scope.
            if desc in ("{", "[", "("):
                if curr.format(False) == desc:
                    (scope, remaining) = extract_scope(content, curr)
                    if not (scope is None):
                        ret += [scope]
                        content = remaining
                        continue
                # Scope not found.
                return failure_array
            # Extracting singular element.
            validated = validate_token(curr, desc)
            if validated:
                ret += [validated]
            else:
                return failure_array
        # Not a request, compare verbatim. Names can be compared verbatim.
        elif not check_token(curr, req):
            return failure_array
    # Successful, return the remaining elements.
    return ret + [content]
예제 #43
0
 def hasNameConflict(self, block, name):
     """Tell if given block would have a conflict if renamed into given name."""
     # If block is a listing, just go over all options.
     if is_listing(block):
         for ii in block:
             if self.hasNameConflict(ii, name):
                 return True
         return False
     # Check for conflicts within this block.
     parent = find_parent_scope(block)
     if is_glsl_block_source(parent):
         for ii in self.__sources:
             if (ii != parent) and ((not parent.getType()) or
                                    (not ii.getType())):
                 if has_name_conflict(ii, block, name):
                     return True
     return has_name_conflict(parent, block, name)
예제 #44
0
 def getSingleChild(self):
     """Degeneration preventation. If token only has a single child, return that instead."""
     lr = len(self.__left) + len(self.__right)
     # If left and right exist, return node itself - there is no single child here.
     if 0 < lr:
         if not self.__middle and ((not self.__left) or (not self.__right)):
             raise RuntimeError(
                 "empty middle only allowed if bothe left and right exist")
         return self
     # If left and right did not exist, return middle.
     elif self.__middle:
         if is_listing(self.__middle):
             if 1 >= len(self.__middle):
                 return self.__middle[0]
         return self.__middle
     # Should never happen.
     raise RuntimeError("token has no content")
예제 #45
0
def token_descend(token):
    """Descend token or token list."""
    # Single element case.
    if is_glsl_token(token):
        token.setParent(None)
        single = token.getSingleChild()
        if single == token:
            return token
        return token_descend(single)
    # Listing case.
    if is_listing(token):
        for ii in token:
            ii.setParent(None)
            if not is_glsl_token(ii):
                raise RuntimeError("non-token '%s' found in descend" % (str(ii)))
        if len(token) == 1:
            return token_descend(token[0])
    # Could not descend.
    return token
예제 #46
0
def merge_collected_names_function(lst):
    """Merge inout blocks from given list of names."""
    ret = []
    for ii in lst:
        if is_glsl_block_function(ii[0]):
            found = False
            for jj in range(len(ret)):
                vv = ret[jj]
                block = vv[0]
                if is_listing(block):
                    block = block[0]
                if is_glsl_block_function(block) and (block.getName()
                                                      == ii[0].getName()):
                    ret[jj] = merge_collected_name_lists(vv, ii)
                    found = True
                    break
            if found:
                continue
        ret += [ii]
    return ret
예제 #47
0
 def renameBlockType(self, block):
     """Rename block type for given name strip."""
     # Select name to rename to.
     if not target_name:
         counted = self.countSorted()
         # Single-character names first.
         for letter in counted:
             if not self.hasNameConflict(block, letter):
                 target_name = letter
                 break
         # None of the letters was free, invent new one.
         if not target_name:
             target_name = self.inventName(block, counted)
     # Listing case.
     if is_listing(block):
         for ii in block:
             self.renameBlock(ii, target_name)
         return
     # Just select first name.
     block.getTypeName().lock(target_name)
예제 #48
0
def token_descend(token):
    """Descend token or token list."""
    # Single element case.
    if is_glsl_token(token):
        token.setParent(None)
        single = token.getSingleChild()
        if single == token:
            return token
        return token_descend(single)
    # Listing case.
    if is_listing(token):
        for ii in token:
            ii.setParent(None)
            if not is_glsl_token(ii):
                raise RuntimeError("non-token '%s' found in descend" %
                                   (str(ii)))
        if len(token) == 1:
            return token_descend(token[0])
    # Could not descend.
    return token
예제 #49
0
 def add_label_pre(self, op):
     """Add pre-label(s)."""
     if is_listing(op):
         self.__label_pre += op
     else:
         self.__label_pre += [op]
예제 #50
0
 def add_label_post(self, op):
     """Add post-label(s)."""
     if is_listing(op):
         self.__label_post += op
     else:
         self.__label_post += [op]
예제 #51
0
 def crunch(self,
            mode="full",
            max_inlines=-1,
            max_renames=-1,
            max_simplifys=-1):
     """Crunch the source code to smaller state."""
     combines = None
     inlines = None
     renames = None
     simplifys = None
     # Expand unless crunching completely disabled.
     if "none" != mode:
         for ii in self.__sources:
             ii.expandRecursive()
         # Perform inlining passes.
         inlines = 0
         while True:
             inline_pass_rv = self.inlinePass((max_inlines < 0)
                                              or (inlines < max_inlines))
             # Last pass will return a listing of merged variable names.
             if is_listing(inline_pass_rv):
                 merged = inline_pass_rv
                 break
             # Inlining was done, another round.
             inlines += 1
         # Perform simplification passes.
         simplifys = 0
         for ii in self.__sources:
             if (0 <= max_simplifys) and (simplifys >= max_simplifys):
                 break
             simplifys += simplify_pass(ii, max_simplifys - simplifys)
         # After all names have been collected, it's possible to select the best swizzle.
         swizzle = self.selectSwizzle()
         for ii in self.__sources:
             ii.selectSwizzle(swizzle)
         # Print number of inout merges.
         if is_verbose():
             inout_merges = []
             for ii in merged:
                 block = ii[0]
                 if is_listing(block):
                     inout_merges += [block[0]]
             if inout_merges:
                 print("GLSL inout connections found: %s" %
                       (str(map(str, inout_merges))))
         # Run rename passes until done.
         renames = 0
         for ii in merged:
             if (0 <= max_renames) and (renames >= max_renames):
                 break
             self.renamePass(ii[0], ii[1:])
             renames += 1
         # Run member rename passes until done.
         for ii in merged:
             block = ii[0]
             if is_listing(block):
                 block = block[0]
             if not is_glsl_block_inout_struct(block):
                 continue
             renames += self.renameMembers(block, max_renames - renames)
             # Also rename block type.
             if (0 > max_renames) or (renames < max_renames):
                 self.renameBlock(ii[0])
                 renames += 1
         # Perform recombine passes.
         for ii in self.__sources:
             combines = ii.collapseRecursive(mode)
     # Print summary of operations.
     if is_verbose():
         operations = []
         if inlines:
             operations += ["%i inlines" % (inlines)]
         if simplifys:
             operations += ["%i simplifys" % (simplifys)]
         if renames:
             operations += ["%i renames" % (renames)]
         if combines:
             operations += ["%i combines" % (combines)]
         if operations:
             print("GLSL processing done: %s" % (", ".join(operations)))