示例#1
0
def list(self, parent, cur):
    """
A list (both comma or space delimited)

Args:
    self (Builder): Code constructor
    parent (Node): Parent node
    cur (int): Current position in code

Returns:
	int : End of list

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "[2 -3]")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  '[2 -3]'
       0     Expression  expression.create    '[2 -3]'
       0     Matrix      misc.matrix          '[2 -3]'
       1     Vector      misc.matrix          '2 -3'
       1     Expression  expression.create    '2'
       1     Int         misc.number          '2'
       3     Expression  expression.create    '-3'
       4     Int         misc.number          '3'
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
     1  1Block      code_block   TYPE
     1  1| Statement  code_block   TYPE
     1  1| | Matrix     matrix       irowvec
     1  2| | | Vector     matrix       irowvec
     1  2| | | | Int        int          int
     1  4| | | | Neg        expression   int
     1  5| | | | | Int        int          int
    """

    if self.code[cur] not in "({":
        self.syntaxerror(cur, "start of list character")

    end = cur
    for vector in iterate.comma_list(self, cur):
        for start, end in vector:
            self.create_expression(parent, start, end)

    end += 1
    while self.code[end] in " \t":
        end += 1

    if self.code[end] not in ")}":
        self.syntaxerror(cur, "end of list character")

    return end
示例#2
0
def list(self, parent, cur):
    """
A list (both comma or space delimited)

Args:
    self (Builder): Code constructor
    parent (Node): Parent node
    cur (int): Current position in code

Returns:
	int : End of list

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "[2 -3]")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  '[2 -3]'
       0     Expression  expression.create    '[2 -3]'
       0     Matrix      misc.matrix          '[2 -3]'
       1     Vector      misc.matrix          '2 -3'
       1     Expression  expression.create    '2'
       1     Int         misc.number          '2'
       3     Expression  expression.create    '-3'
       4     Int         misc.number          '3'
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
     1  1Block      code_block   TYPE
     1  1| Statement  code_block   TYPE
     1  1| | Matrix     matrix       irowvec
     1  2| | | Vector     matrix       irowvec
     1  2| | | | Int        int          int
     1  4| | | | Neg        expression   int
     1  5| | | | | Int        int          int
    """

    if self.code[cur] not in "({":
        self.syntaxerror(cur, "start of list character")

    end = cur
    for vector in iterate.comma_list(self, cur):
        for start, end in vector:
            self.create_expression(parent, start, end)

    end += 1
    while self.code[end] in " \t":
        end += 1

    if self.code[end] not in ")}":
        self.syntaxerror(cur, "end of list character")

    return end
示例#3
0
def cell(self, node, cur):
    """
Verbatim cells

Args:
    self (Builder): Code constructor
    node (Node): Parent node
    cur (int): Current position in code

Returns:
	int : End of cell

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "{1, 2}")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  '{1, 2}'
       0     Expression  expression.create    '{1, 2}'
       0     Cell        misc.cell            '{1, 2}'
       1     Expression  expression.create    '1'
       1     Int         misc.number          '1'
       4     Expression  expression.create    '2'
       4     Int         misc.number          '2'
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
    1 1Block      code_block   TYPE
    1 1| Statement  code_block   TYPE
    1 1| | Cell       cell         TYPE
    1 2| | | Int        int          int
    1 5| | | Int        int          int
    """

    if self.code[cur] != "{":
        self.syntaxerror(cur, "curly braces")

    end = findend.cell(self, cur)
    if self.disp:
        print "%4d     Cell       " % cur,
        print "%-20s" % "misc.cell",
        print repr(self.code[cur : end + 1])

    if identify.space_delimited(self, cur):
        L = iterate.space_list(self, cur)
    else:
        L = iterate.comma_list(self, cur)
    cell = mc.collection.Cell(node, cur=cur, code=self.code[cur : end + 1])

    for array in L:

        if array:
            start = array[0][0]
            end = array[-1][-1]
        else:
            start = cur

        for start, end in array:

            self.create_expression(cell, start, end)

    return findend.cell(self, cur)
示例#4
0
def matrix(self, node, cur):
    """
Verbatim matrices

Args:
    self (Builder): Code constructor
    node (Node): Parent node
    cur (int): Current position in code

Returns:
	int : End of matrix

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "[[1 2] [3 4]]")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  '[[1 2] [3 4]]'
       0     Expression  expression.create    '[[1 2] [3 4]]'
       0     Matrix      misc.matrix          '[[1 2] [3 4]]'
       1     Vector      misc.matrix          '[1 2] [3 4]'
       1     Expression  expression.create    '[1 2]'
       1     Matrix      misc.matrix          '[1 2]'
       2     Vector      misc.matrix          '1 2'
       2     Expression  expression.create    '1'
       2     Int         misc.number          '1'
       4     Expression  expression.create    '2'
       4     Int         misc.number          '2'
       7     Expression  expression.create    '[3 4]'
       7     Matrix      misc.matrix          '[3 4]'
       8     Vector      misc.matrix          '3 4'
       8     Expression  expression.create    '3'
       8     Int         misc.number          '3'
      10     Expression  expression.create    '4'
      10     Int         misc.number          '4'
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
     1   1Block      code_block   TYPE
     1   1| Statement  code_block   TYPE
     1   1| | Matrix     matrix       irowvec
     1   2| | | Vector     matrix       irowvec
     1   2| | | | Matrix     matrix       irowvec
     1   3| | | | | Vector     matrix       irowvec
     1   3| | | | | | Int        int          int
     1   5| | | | | | Int        int          int
     1   8| | | | Matrix     matrix       irowvec
     1   9| | | | | Vector     matrix       irowvec
     1   9| | | | | | Int        int          int
     1  11| | | | | | Int        int          int
    """

    if self.code[cur] != "[":
        self.syntaxerror(cur, "bracket start")

    end = findend.matrix(self, cur)
    if self.disp:
        print "%4d     Matrix     " % cur,
        print "%-20s" % "misc.matrix",
        print repr(self.code[cur : end + 1])

    if identify.space_delimited(self, cur):
        L = iterate.space_list(self, cur)
    else:
        L = iterate.comma_list(self, cur)
    matrix = mc.collection.Matrix(node, cur=cur, code=self.code[cur : end + 1])

    for array in L:

        if array:
            start = array[0][0]
            end = array[-1][-1]
        else:
            start = cur

        vector = mc.collection.Vector(matrix, cur=start, code=self.code[start : end + 1])

        if self.disp:
            print "%4d     Vector     " % (start),
            print "%-20s" % "misc.matrix",
            print repr(self.code[start : end + 1])

        for start, end in array:

            self.create_expression(vector, start, end)

    if not L:

        if self.disp:
            print "%4d     Vector     " % cur,
            print "%-20s" % "misc.matrix",
            print repr("")
        vector = mc.collection.Vector(matrix, cur=cur, code="")

    return findend.matrix(self, cur)
示例#5
0
def cell(self, node, cur):
    """
Verbatim cells

Args:
    self (Builder): Code constructor
    node (Node): Parent node
    cur (int): Current position in code

Returns:
	int : End of cell

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "{1, 2}")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  '{1, 2}'
       0     Expression  expression.create    '{1, 2}'
       0     Cell        misc.cell            '{1, 2}'
       1     Expression  expression.create    '1'
       1     Int         misc.number          '1'
       4     Expression  expression.create    '2'
       4     Int         misc.number          '2'
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
    1 1Block      code_block   TYPE
    1 1| Statement  code_block   TYPE
    1 1| | Cell       cell         TYPE
    1 2| | | Int        int          int
    1 5| | | Int        int          int
    """

    if self.code[cur] != "{":
        self.syntaxerror(cur, "curly braces")

    end = findend.cell(self, cur)
    if self.disp:
        print "%4d     Cell       " % cur,
        print "%-20s" % "misc.cell",
        print repr(self.code[cur:end + 1])

    if identify.space_delimited(self, cur):
        L = iterate.space_list(self, cur)
    else:
        L = iterate.comma_list(self, cur)
    cell = mc.collection.Cell(node, cur=cur, code=self.code[cur:end + 1])

    for array in L:

        if array:
            start = array[0][0]
            end = array[-1][-1]
        else:
            start = cur

        for start, end in array:

            self.create_expression(cell, start, end)

    return findend.cell(self, cur)
示例#6
0
def matrix(self, node, cur):
    """
Verbatim matrices

Args:
    self (Builder): Code constructor
    node (Node): Parent node
    cur (int): Current position in code

Returns:
	int : End of matrix

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "[[1 2] [3 4]]")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Statement     codeblock.codeblock  '[[1 2] [3 4]]'
       0     Expression  expression.create    '[[1 2] [3 4]]'
       0     Matrix      misc.matrix          '[[1 2] [3 4]]'
       1     Vector      misc.matrix          '[1 2] [3 4]'
       1     Expression  expression.create    '[1 2]'
       1     Matrix      misc.matrix          '[1 2]'
       2     Vector      misc.matrix          '1 2'
       2     Expression  expression.create    '1'
       2     Int         misc.number          '1'
       4     Expression  expression.create    '2'
       4     Int         misc.number          '2'
       7     Expression  expression.create    '[3 4]'
       7     Matrix      misc.matrix          '[3 4]'
       8     Vector      misc.matrix          '3 4'
       8     Expression  expression.create    '3'
       8     Int         misc.number          '3'
      10     Expression  expression.create    '4'
      10     Int         misc.number          '4'
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
     1   1Block      code_block   TYPE
     1   1| Statement  code_block   TYPE
     1   1| | Matrix     matrix       irowvec
     1   2| | | Vector     matrix       irowvec
     1   2| | | | Matrix     matrix       irowvec
     1   3| | | | | Vector     matrix       irowvec
     1   3| | | | | | Int        int          int
     1   5| | | | | | Int        int          int
     1   8| | | | Matrix     matrix       irowvec
     1   9| | | | | Vector     matrix       irowvec
     1   9| | | | | | Int        int          int
     1  11| | | | | | Int        int          int
    """

    if self.code[cur] != "[":
        self.syntaxerror(cur, "bracket start")

    end = findend.matrix(self, cur)
    if self.disp:
        print "%4d     Matrix     " % cur,
        print "%-20s" % "misc.matrix",
        print repr(self.code[cur:end + 1])

    if identify.space_delimited(self, cur):
        L = iterate.space_list(self, cur)
    else:
        L = iterate.comma_list(self, cur)
    matrix = mc.collection.Matrix(node, cur=cur, code=self.code[cur:end + 1])

    for array in L:

        if array:
            start = array[0][0]
            end = array[-1][-1]
        else:
            start = cur

        vector = mc.collection.Vector(matrix,
                                      cur=start,
                                      code=self.code[start:end + 1])

        if self.disp:
            print "%4d     Vector     " % (start),
            print "%-20s" % "misc.matrix",
            print repr(self.code[start:end + 1])

        for start, end in array:

            self.create_expression(vector, start, end)

    if not L:

        if self.disp:
            print "%4d     Vector     " % cur,
            print "%-20s" % "misc.matrix",
            print repr("")
        vector = mc.collection.Vector(matrix, cur=cur, code="")

    return findend.matrix(self, cur)
示例#7
0
def function(self, parent, cur):
    """
Explicit functions

Args:
    self (Builder): Code constructor
    parent (Node): Parent node
    cur (int): Current position in code

Returns:
	int : Index to end of function

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "function f(); end")
    loading unnamed
         Program     functions.program
       0 Function        functions.function   'function f()'
      12 Codeblock   codeblock.codeblock 
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
    1  1Funcs      program      TYPE    unnamed
    1  1| Func       func_returns TYPE    f
    1  1| | Declares   func_returns TYPE
    1  1| | Returns    func_returns TYPE
    1 11| | Params     func_returns TYPE
    1 13| | Block      code_block   TYPE
    """

    if self.code[cur:cur+8] != "function":
        self.syntaxerror(cur, "function start")
    if self.code[cur+8] not in c.k_end+"[":
        self.syntaxerror(cur, "function name or return values")

    START = cur
    k = cur + 8

    while self.code[k] in " \t":
        k += 1

    if  self.code[k] not in c.letters+"[":
        self.syntaxerror(k, "function name or return values")
    start = k

    k = findend.expression(self, k)
    end = k

    k += 1
    while self.code[k] in " \t":
        k += 1

    # with return values
    if self.code[k] == "=":

        k += 1
        while self.code[k] in " \t.":
            if self.code[k:k+3] == "...":
                k = findend.dots(self, k)+1
            else:
                k += 1

        l = k
        if  self.code[l] not in c.letters:
            self.syntaxerror(l, "function name")

        while self.code[l+1] in c.letters+c.digits+"_":
            l += 1

        m = l+1

        while self.code[m] in " \t":
            m += 1

        if self.code[m] == "(":
            m = findend.paren(self, m)
        else:
            m = l

        if self.disp:
            print "%4d Function       " % cur,
            print "%-20s" % "functions.function",
            print repr(self.code[START:m+1])

        name = self.code[k:l+1]
        func = mc.collection.Func(parent, name, cur=cur)
        mc.collection.Declares(func, code="")
        returns = mc.collection.Returns(func, code=self.code[start:end+1])

        # multi-return
        if self.code[start] == "[":
            if identify.space_delimited(self, start):
                L = iterate.space_list(self, start)
            else:
                L = iterate.comma_list(self, start)
            end = START
            for array in L:
                for s,e in array:
                    end = s

                    if self.disp:
                        print "%4d   Return       " % cur,
                        print "%-20s" % "functions.function",
                        print repr(self.code[s:e+1])

                    if not any([a in c.letters+c.digits+"_@" \
                            for a in self.code[s:e+1]]):
                        self.syntaxerror(s, "return value")

                    mc.collection.Var(returns, self.code[s:e+1], cur=s,
                            code=self.code[s:e+1])

        # single return
        else:
            end = findend.expression(self, start)

            if self.disp:
                print "%4d   Return       " % cur,
                print repr(self.code[start:end+1])

            mc.collection.Var(returns, self.code[start:end+1], cur=start,
                    code=self.code[start:end+1])


        cur = l+1
        while self.code[cur] in " \t":
            cur += 1

    # No returns
    else:
        m = k
        if self.code[m] == "(":
            m = findend.paren(self, m)
        else:
            m = end


        if self.disp:
            print "%4d Function       " % cur,
            print "%-20s" % "functions.function",
            print repr(self.code[START:m+1])

        end = start+1
        while self.code[end] in c.letters+"_":
            end += 1

        name = self.code[start:end]
        func = mc.collection.Func(parent, name, cur=cur)

        mc.collection.Declares(func)
        returns = mc.collection.Returns(func)

        cur = end

    # Parameters
    params = mc.collection.Params(func, cur=cur)
    if self.code[cur] == "(":

        end = findend.paren(self, cur)
        params.code = self.code[cur+1:end]

        L = iterate.comma_list(self, cur)
        for array in L:
            for s,e in array:

                if self.disp:
                    print "%4d   Param        " % cur,
                    print "%-20s" % "functions.function",
                    print repr(self.code[s:e+1])

                var = mc.collection.Var(params, self.code[s:e+1], cur=s,
                        code=self.code[s:e+1])

        cur = end

    cur += 1

    cur = self.create_codeblock(func, cur)

    # Postfix
    for var in returns:
        var.create_declare()

    end = cur
    func.code = self.code[START:end+1]

    mc.collection.Header(func.program[4], func.name)

    return cur
示例#8
0
def multi(self, parent, cur, eq_loc):
    """
Assignment with multiple return

Args:
    self (Builder): Code constructor.
    parent (Node): Parent node
    cur (int): Current position in code
    eq_loc (int): position of the assignment marker ('='-sign)

Returns:
	int: Index to end of assignment

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "[a,b] = c")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Assigns     assign.multi         '[a,b] = c'
       1     Var         variables.assign     'a'
       3     Var         variables.assign     'b'
       8     Expression  expression.create    'c'
       8     Var         variables.variable   'c'
    >>> builder.configure()
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
     1  1Block      code_block   TYPE
     1  1| Assigns    unknown      TYPE    c
     1  2| | Var        unknown      TYPE    a
     1  4| | Var        unknown      TYPE    b
     1  9| | Var        unknown      TYPE    c
    """

    if self.code[cur] != "[":
        self.syntaxerror(cur, "multi-assign start")
    if self.code[eq_loc] != "=":
        self.syntaxerror(cur, "assignment sign (=)")

    j = eq_loc + 1
    while self.code[j] in " \t.":
        if self.code[j] == ".":
            j = findend.dots(self, j) + 1
        else:
            j += 1
    end = findend.expression(self, j)

    if self.disp:
        print "%4d   Assigns    " %\
                cur,
        print "%-20s" % "assign.multi",
        print repr(self.code[cur:end + 1])

    if identify.space_delimited(self, cur):
        l = iterate.space_list(self, cur)
    else:
        l = iterate.comma_list(self, cur)

    if len(l[0]) == 1:
        return self.create_assign(parent, l[0][0][0], eq_loc)

    assigns = mc.collection.Assigns(parent,
                                    cur=cur,
                                    code=self.code[cur:end + 1])

    for vector in l:
        for start, stop in vector:
            self.create_assign_variable(assigns, start, end=stop)

    cur = eq_loc + 1
    while self.code[cur] in " \t":
        cur += 1

    cur_ = self.create_expression(assigns, cur)

    assigns.name = assigns[-1].name

    return cur_
示例#9
0
def function(self, parent, cur):
    """
Explicit functions

Args:
    self (Builder): Code constructor
    parent (Node): Parent node
    cur (int): Current position in code

Returns:
	int : Index to end of function

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "function f(); end")
    loading unnamed
         Program     functions.program
       0 Function        functions.function   'function f()'
      12 Codeblock   codeblock.codeblock 
    >>> builder.configure(suggest=False)
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
    1  1Funcs      program      TYPE    unnamed
    1  1| Func       func_returns TYPE    f
    1  1| | Declares   func_returns TYPE
    1  1| | Returns    func_returns TYPE
    1 11| | Params     func_returns TYPE
    1 13| | Block      code_block   TYPE
    """

    if self.code[cur:cur + 8] != "function":
        self.syntaxerror(cur, "function start")
    if self.code[cur + 8] not in c.k_end + "[":
        self.syntaxerror(cur, "function name or return values")

    START = cur
    k = cur + 8

    while self.code[k] in " \t":
        k += 1

    if self.code[k] not in c.letters + "[":
        self.syntaxerror(k, "function name or return values")
    start = k

    k = findend.expression(self, k)
    end = k

    k += 1
    while self.code[k] in " \t":
        k += 1

    # with return values
    if self.code[k] == "=":

        k += 1
        while self.code[k] in " \t.":
            if self.code[k:k + 3] == "...":
                k = findend.dots(self, k) + 1
            else:
                k += 1

        l = k
        if self.code[l] not in c.letters:
            self.syntaxerror(l, "function name")

        while self.code[l + 1] in c.letters + c.digits + "_":
            l += 1

        m = l + 1

        while self.code[m] in " \t":
            m += 1

        if self.code[m] == "(":
            m = findend.paren(self, m)
        else:
            m = l

        if self.disp:
            print "%4d Function       " % cur,
            print "%-20s" % "functions.function",
            print repr(self.code[START:m + 1])

        name = self.code[k:l + 1]
        func = mc.collection.Func(parent, name, cur=cur)
        mc.collection.Declares(func, code="")
        returns = mc.collection.Returns(func, code=self.code[start:end + 1])

        # multi-return
        if self.code[start] == "[":
            if identify.space_delimited(self, start):
                L = iterate.space_list(self, start)
            else:
                L = iterate.comma_list(self, start)
            end = START
            for array in L:
                for s, e in array:
                    end = s

                    if self.disp:
                        print "%4d   Return       " % cur,
                        print "%-20s" % "functions.function",
                        print repr(self.code[s:e + 1])

                    if not any([a in c.letters+c.digits+"_@" \
                            for a in self.code[s:e+1]]):
                        self.syntaxerror(s, "return value")

                    mc.collection.Var(returns,
                                      self.code[s:e + 1],
                                      cur=s,
                                      code=self.code[s:e + 1])

        # single return
        else:
            end = findend.expression(self, start)

            if self.disp:
                print "%4d   Return       " % cur,
                print repr(self.code[start:end + 1])

            mc.collection.Var(returns,
                              self.code[start:end + 1],
                              cur=start,
                              code=self.code[start:end + 1])

        cur = l + 1
        while self.code[cur] in " \t":
            cur += 1

    # No returns
    else:
        m = k
        if self.code[m] == "(":
            m = findend.paren(self, m)
        else:
            m = end

        if self.disp:
            print "%4d Function       " % cur,
            print "%-20s" % "functions.function",
            print repr(self.code[START:m + 1])

        end = start + 1
        while self.code[end] in c.letters + "_":
            end += 1

        name = self.code[start:end]
        func = mc.collection.Func(parent, name, cur=cur)

        mc.collection.Declares(func)
        returns = mc.collection.Returns(func)

        cur = end

    # Parameters
    params = mc.collection.Params(func, cur=cur)
    if self.code[cur] == "(":

        end = findend.paren(self, cur)
        params.code = self.code[cur + 1:end]

        L = iterate.comma_list(self, cur)
        for array in L:
            for s, e in array:

                if self.disp:
                    print "%4d   Param        " % cur,
                    print "%-20s" % "functions.function",
                    print repr(self.code[s:e + 1])

                var = mc.collection.Var(params,
                                        self.code[s:e + 1],
                                        cur=s,
                                        code=self.code[s:e + 1])

        cur = end

    cur += 1

    cur = self.create_codeblock(func, cur)

    # Postfix
    for var in returns:
        var.create_declare()

    end = cur
    func.code = self.code[START:end + 1]

    mc.collection.Header(func.program[4], func.name)

    return cur
示例#10
0
def multi(self, parent, cur, eq_loc):
    """
Assignment with multiple return

Args:
    self (Builder): Code constructor.
    parent (Node): Parent node
    cur (int): Current position in code
    eq_loc (int): position of the assignment marker ('='-sign)

Returns:
	int: Index to end of assignment

Example:
    >>> builder = mc.Builder(True)
    >>> builder.load("unnamed", "[a,b] = c")
    loading unnamed
         Program     functions.program
       0 Main        functions.main
       0 Codeblock   codeblock.codeblock 
       0   Assigns     assign.multi         '[a,b] = c'
       1     Var         variables.assign     'a'
       3     Var         variables.assign     'b'
       8     Expression  expression.create    'c'
       8     Var         variables.variable   'c'
    >>> builder.configure()
    >>> print mc.qtree(builder, core=True) # doctest: +NORMALIZE_WHITESPACE
     1  1Block      code_block   TYPE
     1  1| Assigns    unknown      TYPE    c
     1  2| | Var        unknown      TYPE    a
     1  4| | Var        unknown      TYPE    b
     1  9| | Var        unknown      TYPE    c
    """

    if self.code[cur] != "[":
        self.syntaxerror(cur, "multi-assign start")
    if self.code[eq_loc] != "=":
        self.syntaxerror(cur, "assignment sign (=)")

    j = eq_loc + 1
    while self.code[j] in " \t.":
        if self.code[j] == ".":
            j = findend.dots(self, j) + 1
        else:
            j += 1
    end = findend.expression(self, j)

    if self.disp:
        print "%4d   Assigns    " % cur,
        print "%-20s" % "assign.multi",
        print repr(self.code[cur : end + 1])

    if identify.space_delimited(self, cur):
        l = iterate.space_list(self, cur)
    else:
        l = iterate.comma_list(self, cur)

    if len(l[0]) == 1:
        return self.create_assign(parent, l[0][0][0], eq_loc)

    assigns = mc.collection.Assigns(parent, cur=cur, code=self.code[cur : end + 1])

    for vector in l:
        for start, stop in vector:
            self.create_assign_variable(assigns, start, end=stop)

    cur = eq_loc + 1
    while self.code[cur] in " \t":
        cur += 1

    cur_ = self.create_expression(assigns, cur)

    assigns.name = assigns[-1].name

    return cur_