Instruction:
Can you create a Python 3 function that
returns a string representation of the operands in the tree.

Response:
def _str_oper(op1, op2=None, reversed=False, no_exaf=False):
    ''' Returns pop sequence for 16 bits operands
    1st operand in HL, 2nd operand in DE

    You can swap operators extraction order
    by setting reversed to True.

    If no_exaf = True => No bits flags in A' will be used.
                        This saves two bytes.
    '''
    output = []

    if op2 is not None and reversed:
        op1, op2 = op2, op1

    tmp2 = False
    if op2 is not None:
        val = op2
        if val[0] == '*':
            indirect = True
            val = val[1:]
        else:
            indirect = False

        if val[0] == '_':  # Direct
            output.append('ld de, (%s)' % val)
        elif val[0] == '#':  # Direct
            output.append('ld de, %s' % val[1:])
        elif val[0] == '$':  # Direct in the stack
            output.append('pop de')
        else:
            output.append('pop de')
            tmp2 = True

        if indirect:
            output.append('call __LOAD_DE_DE')
            REQUIRES.add('lddede.asm')  # TODO: This is never used??

    if reversed:
        tmp = output
        output = []

    val = op1
    tmp1 = False
    if val[0] == '*':
        indirect = True
        val = val[1:]
    else:
        indirect = False

    if val[0] == '_':  # Direct
        output.append('ld hl, (%s)' % val)
    elif val[0] == '#':  # Inmmediate
        output.append('ld hl, %s' % val[1:])
    elif val[0] == '$':  # Direct in the stack
        output.append('pop hl')
    else:
        output.append('pop hl')
        tmp1 = True

    if indirect:
        output.append('ld hl, %s' % val[1:])
        output.append('ld c, (hl)')
        output.append('inc hl')
        output.append('ld h, (hl)')
        output.append('ld l, c')

    if reversed:
        output.extend(tmp)

    if not no_exaf:
        if tmp1 and tmp2:
            output.append('ld a, 3')  # Marks both strings to be freed
        elif tmp1:
            output.append('ld a, 1')  # Marks str1 to be freed
        elif tmp2:
            output.append('ld a, 2')  # Marks str2 to be freed
        else:
            output.append('xor a')  # Marks no string to be freed

    if op2 is not None:
        return (tmp1, tmp2, output)

    return (tmp1, output)


Instruction:
How would you implement a function in Python 3 that
outputs a FREEMEM sequence for 1 or 2 ops

Response:
def _free_sequence(tmp1, tmp2=False):
    ''' Outputs a FREEMEM sequence for 1 or 2 ops
    '''
    if not tmp1 and not tmp2:
        return []

    output = []
    if tmp1 and tmp2:
        output.append('pop de')
        output.append('ex (sp), hl')
        output.append('push de')
        output.append('call __MEM_FREE')
        output.append('pop hl')
        output.append('call __MEM_FREE')
    else:
        output.append('ex (sp), hl')
        output.append('call __MEM_FREE')

    output.append('pop hl')
    REQUIRES.add('alloc.asm')
    return output


Instruction:
Create a Python 3 function for
comparing & pops top 2 strings out of the stack.

Response:
def _nestr(ins):
    ''' Compares & pops top 2 strings out of the stack.
    Temporal values are freed from memory. (a$ != b$)
    '''
    (tmp1, tmp2, output) = _str_oper(ins.quad[2], ins.quad[3])
    output.append('call __STRNE')
    output.append('push af')
    REQUIRES.add('string.asm')
    return output


Instruction:
Can you tell what is the following Python 3 function doing
def make_node(cls, lineno, fname, func=None, type_=None, *operands):
        if func is not None and len(operands) == 1:  # Try constant-folding
            if is_number(operands[0]) or is_string(operands[0]):  # e.g. ABS(-5)
                return SymbolNUMBER(func(operands[0].value), type_=type_, lineno=lineno)

        return cls(lineno, fname, type_, *operands)

Response: Creates a node for a unary operation.


Instruction:
How would you explain what the following Python 3 function does
def _8bit_oper(op1, op2=None, reversed_=False):
    output = []

    if op2 is not None and reversed_:
        tmp = op1
        op1 = op2
        op2 = tmp

    op = op1
    indirect = (op[0] == '*')
    if indirect:
        op = op[1:]

    immediate = (op[0] == '#')
    if immediate:
        op = op[1:]

    if is_int(op):
        op = int(op)

        if indirect:
            output.append('ld a, (%i)' % op)
        else:
            if op == 0:
                output.append('xor a')
            else:
                output.append('ld a, %i' % int8(op))
    else:
        if immediate:
            if indirect:
                output.append('ld a, (%s)' % op)
            else:
                output.append('ld a, %s' % op)
        elif op[0] == '_':
            if indirect:
                idx = 'bc' if reversed_ else 'hl'
                output.append('ld %s, (%s)' % (idx, op))  # can't use HL
                output.append('ld a, (%s)' % idx)
            else:
                output.append('ld a, (%s)' % op)
        else:
            if immediate:
                output.append('ld a, %s' % op)
            elif indirect:
                idx = 'bc' if reversed_ else 'hl'
                output.append('pop %s' % idx)
                output.append('ld a, (%s)' % idx)
            else:
                output.append('pop af')

    if op2 is None:
        return output

    if not reversed_:
        tmp = output
        output = []

    op = op2
    indirect = (op[0] == '*')
    if indirect:
        op = op[1:]

    immediate = (op[0] == '#')
    if immediate:
        op = op[1:]

    if is_int(op):
        op = int(op)

        if indirect:
            output.append('ld hl, (%i - 1)' % op)
        else:
            output.append('ld h, %i' % int8(op))
    else:
        if immediate:
            if indirect:
                output.append('ld hl, %s' % op)
                output.append('ld h, (hl)')
            else:
                output.append('ld h, %s' % op)
        elif op[0] == '_':
            if indirect:
                output.append('ld hl, (%s)' % op)
                output.append('ld h, (hl)' % op)
            else:
                output.append('ld hl, (%s - 1)' % op)
        else:
            output.append('pop hl')

        if indirect:
            output.append('ld h, (hl)')

    if not reversed_:
        output.extend(tmp)

    return output

Response: Returns a pop sequence for 8 bits operands op1 and op2.


Instruction:
Implement a Python 3 function for
adding an 8 - bit integer to the stack and returns the result.

Response:
def _add8(ins):
    """ Pops last 2 bytes from the stack and adds them.
    Then push the result onto the stack.

    Optimizations:
      * If any of the operands is ZERO,
        then do NOTHING: A + 0 = 0 + A = A

      * If any of the operands is 1, then
        INC is used

      * If any of the operands is -1 (255), then
        DEC is used
    """
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 0:  # Nothing to add: A + 0 = A
            output.append('push af')
            return output

        op2 = int8(op2)

        if op2 == 1:  # Adding 1 is just an inc
            output.append('inc a')
            output.append('push af')
            return output

        if op2 == 0xFF:  # Adding 255 is just a dec
            output.append('dec a')
            output.append('push af')
            return output

        output.append('add a, %i' % int8(op2))
        output.append('push af')
        return output

    if op2[0] == '_':  # stack optimization
        op1, op2 = op2, op1

    output = _8bit_oper(op1, op2)
    output.append('add a, h')
    output.append('push af')

    return output


Instruction:
Can you implement a function in Python 3 that
subs function for internal use only.

Response:
def _sub8(ins):
    """ Pops last 2 bytes from the stack and subtract them.
    Then push the result onto the stack. Top-1 of the stack is
    subtracted Top
    _sub8 t1, a, b === t1 <-- a - b

    Optimizations:
      * If 2nd op is ZERO,
        then do NOTHING: A - 0 = A

      * If 1st operand is 0, then
        just do a NEG

      * If any of the operands is 1, then
        DEC is used

      * If any of the operands is -1 (255), then
        INC is used
    """

    op1, op2 = tuple(ins.quad[2:])
    if is_int(op2):  # 2nd operand
        op2 = int8(op2)
        output = _8bit_oper(op1)

        if op2 == 0:
            output.append('push af')
            return output  # A - 0 = A

        op2 = int8(op2)

        if op2 == 1:  # A - 1 == DEC A
            output.append('dec a')
            output.append('push af')
            return output

        if op2 == 0xFF:  # A - (-1) == INC A
            output.append('inc a')
            output.append('push af')
            return output

        output.append('sub %i' % op2)
        output.append('push af')
        return output

    if is_int(op1):  # 1st operand is numeric?
        if int8(op1) == 0:  # 0 - A = -A ==> NEG A
            output = _8bit_oper(op2)
            output.append('neg')
            output.append('push af')
            return output

    # At this point, even if 1st operand is numeric, proceed
    # normally

    if op2[0] == '_':  # Optimization when 2nd operand is an id
        rev = True
        op1, op2 = op2, op1
    else:
        rev = False

    output = _8bit_oper(op1, op2, rev)
    output.append('sub h')
    output.append('push af')

    return output


Instruction:
Explain what the following Python 3 code does
def _mul8(ins):

    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 1:  # A * 1 = 1 * A = A
            output.append('push af')
            return output

        if op2 == 0:
            output.append('xor a')
            output.append('push af')
            return output

        if op2 == 2:  # A * 2 == A SLA 1
            output.append('add a, a')
            output.append('push af')
            return output

        if op2 == 4:  # A * 4 == A SLA 2
            output.append('add a, a')
            output.append('add a, a')
            output.append('push af')
            return output

        output.append('ld h, %i' % int8(op2))
    else:
        if op2[0] == '_':  # stack optimization
            op1, op2 = op2, op1

        output = _8bit_oper(op1, op2)

    output.append('call __MUL8_FAST')  # Inmmediate
    output.append('push af')
    REQUIRES.add('mul8.asm')
    return output

Response: Multiplies 2 las values from the stack.


Instruction:
Here you have a function in Python 3, explain what it does
def _divu8(ins):
    op1, op2 = tuple(ins.quad[2:])
    if is_int(op2):
        op2 = int8(op2)

        output = _8bit_oper(op1)
        if op2 == 1:
            output.append('push af')
            return output

        if op2 == 2:
            output.append('srl a')
            output.append('push af')
            return output

        output.append('ld h, %i' % int8(op2))
    else:
        if op2[0] == '_':  # Optimization when 2nd operand is an id
            if is_int(op1) and int(op1) == 0:
                output = list()  # Optimization: Discard previous op if not from the stack
                output.append('xor a')
                output.append('push af')
                return output

            rev = True
            op1, op2 = op2, op1
        else:
            rev = False

        output = _8bit_oper(op1, op2, rev)

    output.append('call __DIVU8_FAST')
    output.append('push af')
    REQUIRES.add('div8.asm')
    return output

Response: Divides 2 8bit unsigned integers.


Instruction:
Given the following Python 3 function, write the documentation
def _ltu8(ins):
    output = _8bit_oper(ins.quad[2], ins.quad[3])
    output.append('cp h')
    output.append('sbc a, a')
    output.append('push af')

    return output

Response:
Compares top 2 operands and pushes them out of the stack and checks
        if the 1st operand < 2nd operand.


Instruction:
Write a Python 3 script to
compare top 2 operands out of the stack and checks if the 1st operand < 2nd operand. Returns a list of 8 bit signed version of the tree.

Response:
def _lti8(ins):
    """ Compares & pops top 2 operands out of the stack, and checks
        if the 1st operand < 2nd operand (top of the stack).
        Pushes 0 if False, 1 if True.

        8 bit signed version
    """
    output = []
    output.extend(_8bit_oper(ins.quad[2], ins.quad[3]))
    output.append('call __LTI8')
    output.append('push af')
    REQUIRES.add('lti8.asm')

    return output


Instruction:
Can you generate the documentation for the following Python 3 function
def _gtu8(ins):
    output = _8bit_oper(ins.quad[2], ins.quad[3], reversed_=True)
    output.append('cp h')
    output.append('sbc a, a')
    output.append('push af')

    return output

Response:
Compares top 2 operands and pushes them out of the stack and checks
        if the 1st operand > 2nd operand.


Instruction:
Write a Python 3 function that can
compare top 2 operands out of the stack and checks if they are equal.

Response:
def _eq8(ins):
    """ Compares & pops top 2 operands out of the stack, and checks
        if the 1st operand == 2nd operand (top of the stack).
        Pushes 0 if False, 1 if True.

        8 bit un/signed version
    """
    if is_int(ins.quad[3]):
        output = _8bit_oper(ins.quad[2])
        n = int8(ins.quad[3])
        if n:
            if n == 1:
                output.append('dec a')
            else:
                output.append('sub %i' % n)
    else:
        output = _8bit_oper(ins.quad[2], ins.quad[3])
        output.append('sub h')

    output.append('sub 1')  # Sets Carry only if 0
    output.append('sbc a, a')
    output.append('push af')

    return output


Instruction:
Explain what the following Python 3 code does
def _leu8(ins):
    output = _8bit_oper(ins.quad[2], ins.quad[3], reversed_=True)
    output.append('sub h')  # Carry if H > A
    output.append('ccf')  # Negates => Carry if H <= A
    output.append('sbc a, a')
    output.append('push af')

    return output

Response:
Compares top 2 operands and pops top 3 operands out of the stack and checks
        if the 1st operand < 2nd operand.


Instruction:
How would you explain what the following Python 3 function does
def _lei8(ins):
    output = _8bit_oper(ins.quad[2], ins.quad[3])
    output.append('call __LEI8')
    output.append('push af')
    REQUIRES.add('lei8.asm')

    return output

Response:
Compares top 2 operands and pushes them out of the stack and checks
        if the 1st operand < 2nd operand. Returns the new stack.


Instruction:
Can you generate the documentation for the following Python 3 function
def _gei8(ins):
    output = _8bit_oper(ins.quad[2], ins.quad[3], reversed_=True)
    output.append('call __LEI8')
    output.append('push af')
    REQUIRES.add('lei8.asm')

    return output

Response:
Compares top 2 operands and pushes them out of the stack and checks
        if the 1st operand > 2nd operand.


Instruction:
Explain what the following Python 3 code does
def _and8(ins):
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)  # Pops the stack (if applicable)
        if op2 != 0:  # X and True = X
            output.append('push af')
            return output

        # False and X = False
        output.append('xor a')
        output.append('push af')
        return output

    output = _8bit_oper(op1, op2)
    # output.append('call __AND8')
    lbl = tmp_label()
    output.append('or a')
    output.append('jr z, %s' % lbl)
    output.append('ld a, h')
    output.append('%s:' % lbl)
    output.append('push af')
    # REQUIRES.add('and8.asm')

    return output

Response: Internal function to produce an AND instruction.


Instruction:
How would you code a function in Python 3 to
pop top 2 operands out of the stack and pushes the result.

Response:
def _band8(ins):
    """ Pops top 2 operands out of the stack, and does
        1st AND (bitwise) 2nd operand (top of the stack),
        pushes the result.

        8 bit un/signed version
    """
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)
        if op2 == 0xFF:  # X & 0xFF = X
            output.append('push af')
            return output

        if op2 == 0:  # X and 0 = 0
            output.append('xor a')
            output.append('push af')
            return output

        op1, op2 = tuple(ins.quad[2:])

    output = _8bit_oper(op1, op2)
    output.append('and h')
    output.append('push af')

    return output


Instruction:
How would you implement a function in Python 3 that
pops top 2 operands out of the stack, and checks if 1st operand XOR (logical) 2nd operand (top of the stack), pushes 0 if False, 1 if True. 8 bit un/signed version

Response:
def _xor8(ins):
    """ Pops top 2 operands out of the stack, and checks
        if 1st operand XOR (logical) 2nd operand (top of the stack),
        pushes 0 if False, 1 if True.

        8 bit un/signed version
    """
    op1, op2 = tuple(ins.quad[2:])
    if _int_ops(op1, op2) is not None:
        op1, op2 = _int_ops(op1, op2)

        output = _8bit_oper(op1)  # True or X = not X
        if op2 == 0:  # False xor X = X
            output.append('push af')
            return output

        output.append('sub 1')
        output.append('sbc a, a')
        output.append('push af')
        return output

    output = _8bit_oper(op1, op2)
    output.append('call __XOR8')
    output.append('push af')
    REQUIRES.add('xor8.asm')

    return output


Instruction:
How would you explain what the following Python 3 function does
def _not8(ins):
    output = _8bit_oper(ins.quad[2])
    output.append('sub 1')  # Gives carry only if A = 0
    output.append('sbc a, a')  # Gives FF only if Carry else 0
    output.append('push af')

    return output

Response: Negates top of the stack


Instruction:
Can you write a function in Python 3 where it
negates (BITWISE NOT) top of the stack (8 bits in AF)

Response:
def _bnot8(ins):
    """ Negates (BITWISE NOT) top of the stack (8 bits in AF)
    """
    output = _8bit_oper(ins.quad[2])
    output.append('cpl')  # Gives carry only if A = 0
    output.append('push af')

    return output


Instruction:
How would you code a function in Python 3 to
negate top of the stack.

Response:
def _neg8(ins):
    """ Negates top of the stack (8 bits in AF)
    """
    output = _8bit_oper(ins.quad[2])
    output.append('neg')
    output.append('push af')

    return output


Instruction:
How would you explain what the following Python 3 function does
def _abs8(ins):
    output = _8bit_oper(ins.quad[2])
    output.append('call __ABS8')
    output.append('push af')
    REQUIRES.add('abs8.asm')
    return output

Response: Returns the absolute value of top of the stack.


Instruction:
Can you write a function in Python 3 where it
shifts 8bit unsigned integer to the right.

Response:
def _shru8(ins):
    """ Shift 8bit unsigned integer to the right. The result is pushed onto the stack.

    Optimizations:
      * If 1nd or 2nd op is 0 then
        do nothing

      * If 2nd op is < 4 then
        unroll loop
    """
    op1, op2 = tuple(ins.quad[2:])

    if is_int(op2):
        op2 = int8(op2)

        output = _8bit_oper(op1)
        if op2 == 0:
            output.append('push af')
            return output

        if op2 < 4:
            output.extend(['srl a'] * op2)
            output.append('push af')
            return output

        label = tmp_label()
        output.append('ld b, %i' % int8(op2))
        output.append('%s:' % label)
        output.append('srl a')
        output.append('djnz %s' % label)
        output.append('push af')
        return output

    if is_int(op1) and int(op1) == 0:
        output = _8bit_oper(op2)
        output.append('xor a')
        output.append('push af')
        return output

    output = _8bit_oper(op1, op2, True)
    label = tmp_label()
    label2 = tmp_label()
    output.append('or a')
    output.append('ld b, a')
    output.append('ld a, h')
    output.append('jr z, %s' % label2)
    output.append('%s:' % label)
    output.append('srl a')
    output.append('djnz %s' % label)
    output.append('%s:' % label2)
    output.append('push af')
    return output


Instruction:
Create a Python 3 function to
true if this macro is defined in the given symbol

Response:
def is_defined(self, symbolTable=None):
        """ True if this macro has been defined
        """
        if symbolTable is None:
            symbolTable = self.table

        return symbolTable.defined(self.id_)


Instruction:
Write a Python 3 script to
create an array BOUND LIST. node. children are appended to the node.

Response:
def make_node(cls, node, *args):
        ''' Creates an array BOUND LIST.
        '''
        if node is None:
            return cls.make_node(SymbolBOUNDLIST(), *args)

        if node.token != 'BOUNDLIST':
            return cls.make_node(None, node, *args)

        for arg in args:
            if arg is None:
                continue
            node.appendChild(arg)

        return node


Instruction:
Can you implement a function in Python 3 that
initializes the parser state

Response:
def init():
    """ Initializes parser state
    """
    global LABELS
    global LET_ASSIGNMENT
    global PRINT_IS_USED
    global SYMBOL_TABLE

    global ast
    global data_ast
    global optemps
    global OPTIONS
    global last_brk_linenum

    LABELS = {}
    LET_ASSIGNMENT = False
    PRINT_IS_USED = False
    last_brk_linenum = 0

    ast = None
    data_ast = None  # Global Variables AST
    optemps = OpcodesTemps()

    gl.INITS.clear()
    del gl.FUNCTION_CALLS[:]
    del gl.FUNCTION_LEVEL[:]
    del gl.FUNCTIONS[:]
    SYMBOL_TABLE = gl.SYMBOL_TABLE = api.symboltable.SymbolTable()
    OPTIONS = api.config.OPTIONS

    # DATAs info
    gl.DATA_LABELS.clear()
    gl.DATA_IS_USED = False
    del gl.DATAS[:]
    gl.DATA_PTR_CURRENT = api.utils.current_data_label()
    gl.DATA_FUNCTIONS = []
    gl.error_msg_cache.clear()


Instruction:
Here you have a function in Python 3, explain what it does
def make_number(value, lineno, type_=None):
    return symbols.NUMBER(value, type_=type_, lineno=lineno)

Response: Creates a number node.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def make_typecast(type_, node, lineno):
    assert isinstance(type_, symbols.TYPE)
    return symbols.TYPECAST.make_node(type_, node, lineno)

Response: Wrapper for a Typecast node


Instruction:
How would you explain what the following Python 3 function does
def make_binary(lineno, operator, left, right, func=None, type_=None):
    return symbols.BINARY.make_node(operator, left, right, lineno, func, type_)

Response: Wrapper for creating a Binary node


Instruction:
Given the following Python 3 function, write the documentation
def make_unary(lineno, operator, operand, func=None, type_=None):
    return symbols.UNARY.make_node(lineno, operator, operand, func, type_)

Response: Wrapper for making a Unary node


Instruction:
Can you tell what is the following Python 3 function doing
def make_builtin(lineno, fname, operands, func=None, type_=None):
    if operands is None:
        operands = []
    assert isinstance(operands, Symbol) or isinstance(operands, tuple) or isinstance(operands, list)
    # TODO: In the future, builtin functions will be implemented in an external library, like POINT or ATTR
    __DEBUG__('Creating BUILTIN "{}"'.format(fname), 1)
    if not isinstance(operands, collections.Iterable):
        operands = [operands]
    return symbols.BUILTIN.make_node(lineno, fname, func, type_, *operands)

Response: Wrapper for creating a Builtin function node.


Instruction:
Implement a Python 3 function for
wrapping for creating a String Slice node

Response:
def make_strslice(lineno, s, lower, upper):
    """ Wrapper: returns String Slice node
    """
    return symbols.STRSLICE.make_node(lineno, s, lower, upper)


Instruction:
Can you tell what is the following Python 3 function doing
def make_sentence(sentence, *args, **kwargs):
    return symbols.SENTENCE(*([sentence] + list(args)), **kwargs)

Response: Wrapper for creating a Sentence node


Instruction:
Make a summary of the following Python 3 code
def make_argument(expr, lineno, byref=None):
    if expr is None:
        return  # There were a syntax / semantic error

    if byref is None:
        byref = OPTIONS.byref.value
    return symbols.ARGUMENT(expr, lineno=lineno, byref=byref)

Response: Wrapper for creating an ARGUMENT node


Instruction:
Given the following Python 3 function, write the documentation
def make_array_access(id_, lineno, arglist):
    return symbols.ARRAYACCESS.make_node(id_, arglist, lineno)

Response: Creates an array access node.


Instruction:
How would you explain what the following Python 3 function does
def make_call(id_, lineno, args):
    assert isinstance(args, symbols.ARGLIST)

    entry = SYMBOL_TABLE.access_call(id_, lineno)
    if entry is None:
        return None

    if entry.class_ is CLASS.unknown and entry.type_ == TYPE.string and len(args) == 1 and is_numeric(args[0]):
        entry.class_ = CLASS.var  # A scalar variable. e.g a$(expr)

    if entry.class_ == CLASS.array:  # An already declared array
        arr = symbols.ARRAYLOAD.make_node(id_, args, lineno)
        if arr is None:
            return None

        if arr.offset is not None:
            offset = make_typecast(TYPE.uinteger,
                                   make_number(arr.offset, lineno=lineno),
                                   lineno)
            arr.appendChild(offset)
        return arr

    if entry.class_ == CLASS.var:  # An already declared/used string var
        if len(args) > 1:
            api.errmsg.syntax_error_not_array_nor_func(lineno, id_)
            return None

        entry = SYMBOL_TABLE.access_var(id_, lineno)
        if entry is None:
            return None

        if len(args) == 1:
            return symbols.STRSLICE.make_node(lineno, entry, args[0].value, args[0].value)

        entry.accessed = True
        return entry

    return make_func_call(id_, lineno, args)

Response: This function will return an AST node for a function call or array access.


Instruction:
Can you generate the documentation for the following Python 3 function
def make_type(typename, lineno, implicit=False):
    assert isinstance(typename, str)
    if not SYMBOL_TABLE.check_is_declared(typename, lineno, 'type'):
        return None

    type_ = symbols.TYPEREF(SYMBOL_TABLE.get_entry(typename), lineno, implicit)
    return type_

Response: Converts a typename identifier to a type usage symbol


Instruction:
Explain what the following Python 3 code does
def make_bound(lower, upper, lineno):
    return symbols.BOUND.make_node(lower, upper, lineno)

Response: Wrapper for creating an array bound node


Instruction:
Explain what the following Python 3 code does
def make_label(id_, lineno):
    entry = SYMBOL_TABLE.declare_label(id_, lineno)
    if entry:
        gl.DATA_LABELS[id_] = gl.DATA_PTR_CURRENT  # This label points to the current DATA block index
    return entry

Response: Creates a label entry. Returns None on error.


Instruction:
Explain what the following Python 3 code does
def make_break(lineno, p):
    global last_brk_linenum

    if not OPTIONS.enableBreak.value or lineno == last_brk_linenum or is_null(p):
        return None

    last_brk_linenum = lineno
    return make_sentence('CHKBREAK', make_number(lineno, lineno, TYPE.uinteger))

Response: Make a BREAK instruction.


Instruction:
Create a Python 3 function to
program that starts the program.

Response:
def p_start(p):
    """ start : program
    """
    global ast, data_ast

    user_data = make_label('.ZXBASIC_USER_DATA', 0)
    make_label('.ZXBASIC_USER_DATA_LEN', 0)

    if PRINT_IS_USED:
        zxbpp.ID_TABLE.define('___PRINT_IS_USED___', 1)
        # zxbasmpp.ID_TABLE.define('___PRINT_IS_USED___', 1)

    if zxblex.IN_STATE:
        p.type = 'NEWLINE'
        p_error(p)
        sys.exit(1)

    ast = p[0] = p[1]
    __end = make_sentence('END', make_number(0, lineno=p.lexer.lineno))

    if not is_null(ast):
        ast.appendChild(__end)
    else:
        ast = __end

    SYMBOL_TABLE.check_labels()
    SYMBOL_TABLE.check_classes()

    if gl.has_errors:
        return

    __DEBUG__('Checking pending labels', 1)
    if not api.check.check_pending_labels(ast):
        return

    __DEBUG__('Checking pending calls', 1)
    if not api.check.check_pending_calls():
        return

    data_ast = make_sentence('BLOCK', user_data)

    # Appends variable declarations at the end.
    for var in SYMBOL_TABLE.vars_:
        data_ast.appendChild(make_var_declaration(var))

    # Appends arrays declarations at the end.
    for var in SYMBOL_TABLE.arrays:
        data_ast.appendChild(make_array_declaration(var))


Instruction:
Write a Python 3 function that can
program : program program_line

Response:
def p_program(p):
    """ program : program program_line
    """
    p[0] = make_block(p[1], p[2], make_break(p.lineno(2), p[2]))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def p_program_line_label(p):
    lbl = make_label(p[1], p.lineno(1))
    p[0] = make_block(lbl, p[2]) if len(p) == 3 else lbl

Response: Label line with block if it is not already in the program line.


Instruction:
Can you tell what is the following Python 3 function doing
def p_var_decl(p):
    for vardata in p[2]:
        SYMBOL_TABLE.declare_variable(vardata[0], vardata[1], p[3])

    p[0] = None

Response: declare variable in sequence


Instruction:
Make a summary of the following Python 3 code
def p_bound(p):
    p[0] = make_bound(make_number(OPTIONS.array_base.value,
                                  lineno=p.lineno(1)), p[1], p.lexer.lineno)

Response: parse an array element bound


Instruction:
Explain what the following Python 3 code does
def p_const_vector_elem_list(p):
    if p[1] is None:
        return

    if not is_static(p[1]):
        if isinstance(p[1], symbols.UNARY):
            tmp = make_constexpr(p.lineno(1), p[1])
        else:
            api.errmsg.syntax_error_not_constant(p.lexer.lineno)
            p[0] = None
            return
    else:
        tmp = p[1]

    p[0] = [tmp]

Response: p = parser. parse_const_vector_elem_list


Instruction:
Make a summary of the following Python 3 code
def p_const_vector_elem_list_list(p):
    if p[1] is None or p[3] is None:
        return

    if not is_static(p[3]):
        if isinstance(p[3], symbols.UNARY):
            tmp = make_constexpr(p.lineno(2), p[3])
        else:
            api.errmsg.syntax_error_not_constant(p.lineno(2))
            p[0] = None
            return
    else:
        tmp = p[3]

    if p[1] is not None:
        p[1].append(tmp)
    p[0] = p[1]

Response: parse a const vector elem list list


Instruction:
Can you tell what is the following Python 3 function doing
def p_const_vector_vector_list(p):
    if len(p[3]) != len(p[1][0]):
        syntax_error(p.lineno(2), 'All rows must have the same number of elements')
        p[0] = None
        return

    p[0] = p[1] + [p[3]]

Response: A function to parse a const_vector_list.


Instruction:
Make a summary of the following Python 3 code
def p_statement_border(p):
    p[0] = make_sentence('BORDER',
                         make_typecast(TYPE.ubyte, p[2], p.lineno(1)))

Response: statement : BORDER expr


Instruction:
Given the following Python 3 function, write the documentation
def p_statement_plot(p):
    p[0] = make_sentence('PLOT',
                         make_typecast(TYPE.ubyte, p[2], p.lineno(3)),
                         make_typecast(TYPE.ubyte, p[4], p.lineno(3)))

Response: statement : PLOT expr COMMA expr


Instruction:
Can you generate a brief explanation for the following Python 3 code
def p_statement_plot_attr(p):
    p[0] = make_sentence('PLOT',
                         make_typecast(TYPE.ubyte, p[3], p.lineno(4)),
                         make_typecast(TYPE.ubyte, p[5], p.lineno(4)), p[2])

Response: statement : PLOT attr_list expr COMMA expr


Instruction:
Can you generate the documentation for the following Python 3 function
def p_statement_draw(p):
    p[0] = make_sentence('DRAW',
                         make_typecast(TYPE.integer, p[2], p.lineno(3)),
                         make_typecast(TYPE.integer, p[4], p.lineno(3)))

Response: statement : DRAW expr COMMA expr


Instruction:
Can you generate the documentation for the following Python 3 function
def p_statement_draw_attr(p):
    p[0] = make_sentence('DRAW',
                         make_typecast(TYPE.integer, p[3], p.lineno(4)),
                         make_typecast(TYPE.integer, p[5], p.lineno(4)), p[2])

Response: Statement draw attr list expr COMMA expr


Instruction:
Can you generate a brief explanation for the following Python 3 code
def p_statement_circle(p):
    p[0] = make_sentence('CIRCLE',
                         make_typecast(TYPE.byte_, p[2], p.lineno(3)),
                         make_typecast(TYPE.byte_, p[4], p.lineno(5)),
                         make_typecast(TYPE.byte_, p[6], p.lineno(5)))

Response: statement : CIRCLE expr COMMA expr COMMA expr


Instruction:
Here you have a function in Python 3, explain what it does
def p_statement_beep(p):
    p[0] = make_sentence('BEEP', make_typecast(TYPE.float_, p[2], p.lineno(1)),
                         make_typecast(TYPE.float_, p[4], p.lineno(3)))

Response: statement : BEEP expr COMMA expr


Instruction:
Write a Python 3 script for
parsing an assignment statement.

Response:
def p_assignment(p):
    """ statement : lexpr expr
    """
    global LET_ASSIGNMENT

    LET_ASSIGNMENT = False  # Mark we're no longer using LET
    p[0] = None
    q = p[1:]
    i = 1

    if q[1] is None:
        return

    if isinstance(q[1], symbols.VAR) and q[1].class_ == CLASS.unknown:
        q[1] = SYMBOL_TABLE.access_var(q[1].name, p.lineno(i))

    q1class_ = q[1].class_ if isinstance(q[1], symbols.VAR) else CLASS.unknown
    variable = SYMBOL_TABLE.access_id(q[0], p.lineno(i), default_type=q[1].type_, default_class=q1class_)
    if variable is None:
        return  # HINT: This only happens if variable was not declared with DIM and --strict flag is in use

    if variable.class_ == CLASS.unknown:  # The variable is implicit
        variable.class_ = CLASS.var

    if variable.class_ not in (CLASS.var, CLASS.array):
        api.errmsg.syntax_error_cannot_assing_not_a_var(p.lineno(i), variable.name)
        return

    if variable.class_ == CLASS.var and q1class_ == CLASS.array:
        syntax_error(p.lineno(i), 'Cannot assign an array to an scalar variable')
        return

    if variable.class_ == CLASS.array:
        if q1class_ != variable.class_:
            syntax_error(p.lineno(i), 'Cannot assign an scalar to an array variable')
            return

        if q[1].type_ != variable.type_:
            syntax_error(p.lineno(i), 'Arrays must have the same element type')
            return

        if variable.memsize != q[1].memsize:
            syntax_error(p.lineno(i), "Arrays '%s' and '%s' must have the same size" %
                         (variable.name, q[1].name))
            return

        if variable.count != q[1].count:
            warning(p.lineno(i), "Arrays '%s' and '%s' don't have the same number of dimensions" %
                    (variable.name, q[1].name))
        else:
            for b1, b2 in zip(variable.bounds, q[1].bounds):
                if b1.count != b2.count:
                    warning(p.lineno(i), "Arrays '%s' and '%s' don't have the same dimensions" %
                            (variable.name, q[1].name))
                    break
        # Array copy
        p[0] = make_sentence('ARRAYCOPY', variable, q[1])
        return

    expr = make_typecast(variable.type_, q[1], p.lineno(i))
    p[0] = make_sentence('LET', variable, expr)


Instruction:
Given the following Python 3 function, write the documentation
def p_lexpr(p):
    global LET_ASSIGNMENT

    LET_ASSIGNMENT = True  # Mark we're about to start a LET sentence

    if p[1] == 'LET':
        p[0] = p[2]
        i = 2
    else:
        p[0] = p[1]
        i = 1

    SYMBOL_TABLE.access_id(p[i], p.lineno(i))

Response:
lexpr : ID EQ
              | LET ID EQ
              | ARRAY_ID EQ
              | LET ARRAY_ID EQ


Instruction:
Make a summary of the following Python 3 code
def p_arr_assignment(p):
    i = 2 if p[1].upper() == 'LET' else 1
    id_ = p[i]
    arg_list = p[i + 1]
    expr = p[i + 3]

    p[0] = None
    if arg_list is None or expr is None:
        return  # There were errors

    entry = SYMBOL_TABLE.access_call(id_, p.lineno(i))
    if entry is None:
        return

    if entry.type_ == TYPE.string:
        variable = gl.SYMBOL_TABLE.access_array(id_, p.lineno(i))
        if len(variable.bounds) + 1 == len(arg_list):
            ss = arg_list.children.pop().value
            p[0] = make_array_substr_assign(p.lineno(i), id_, arg_list, (ss, ss), expr)
            return

    arr = make_array_access(id_, p.lineno(i), arg_list)
    if arr is None:
        return

    expr = make_typecast(arr.type_, expr, p.lineno(i))
    if entry is None:
        return

    p[0] = make_sentence('LETARRAY', arr, expr)

Response: A statement for assignment of ARRAY_ID arg_list EQ expr


Instruction:
Make a summary of the following Python 3 code
def p_substr_assignment_no_let(p):
    # This can be only a substr assignment like a$(i + 3) = ".", since arrays
    # have ARRAY_ID already
    entry = SYMBOL_TABLE.access_call(p[1], p.lineno(1))
    if entry is None:
        return

    if entry.class_ == CLASS.unknown:
        entry.class_ = CLASS.var

    if p[6].type_ != TYPE.string:
        api.errmsg.syntax_error_expected_string(p.lineno(5), p[6].type_)

    lineno = p.lineno(2)
    base = make_number(OPTIONS.string_base.value, lineno, _TYPE(gl.STR_INDEX_TYPE))
    substr = make_typecast(_TYPE(gl.STR_INDEX_TYPE), p[3], lineno)
    p[0] = make_sentence('LETSUBSTR', entry,
                         make_binary(lineno, 'MINUS', substr, base, func=lambda x, y: x - y),
                         make_binary(lineno, 'MINUS', substr, base, func=lambda x, y: x - y),
                         p[6])

Response: A substr assignment statement.


Instruction:
Here you have a function in Python 3, explain what it does
def p_substr_assignment(p):
    if p[3] is None or p[5] is None:
        return  # There were errors

    p[0] = None
    entry = SYMBOL_TABLE.access_call(p[2], p.lineno(2))
    if entry is None:
        return

    if entry.class_ == CLASS.unknown:
        entry.class_ = CLASS.var

    assert entry.class_ == CLASS.var and entry.type_ == TYPE.string

    if p[5].type_ != TYPE.string:
        api.errmsg.syntax_error_expected_string(p.lineno(4), p[5].type_)

    if len(p[3]) > 1:
        syntax_error(p.lineno(2), "Accessing string with too many indexes. Expected only one.")
        return

    if len(p[3]) == 1:
        substr = (
            make_typecast(_TYPE(gl.STR_INDEX_TYPE), p[3][0].value, p.lineno(2)),
            make_typecast(_TYPE(gl.STR_INDEX_TYPE), p[3][0].value, p.lineno(2)))
    else:
        substr = (make_typecast(_TYPE(gl.STR_INDEX_TYPE),
                                make_number(gl.MIN_STRSLICE_IDX,
                                            lineno=p.lineno(2)),
                                p.lineno(2)),
                  make_typecast(_TYPE(gl.STR_INDEX_TYPE),
                                make_number(gl.MAX_STRSLICE_IDX,
                                            lineno=p.lineno(2)),
                                p.lineno(2)))

    lineno = p.lineno(2)
    base = make_number(OPTIONS.string_base.value, lineno, _TYPE(gl.STR_INDEX_TYPE))
    p[0] = make_sentence('LETSUBSTR', entry,
                         make_binary(lineno, 'MINUS', substr[0], base, func=lambda x, y: x - y),
                         make_binary(lineno, 'MINUS', substr[1], base, func=lambda x, y: x - y),
                         p[5])

Response: Statement for substr assignment.


Instruction:
Make a summary of the following Python 3 code
def p_str_assign(p):
    if p[1].upper() != 'LET':
        q = p[1]
        r = p[4]
        s = p[2]
        lineno = p.lineno(3)
    else:
        q = p[2]
        r = p[5]
        s = p[3]
        lineno = p.lineno(4)

    if q is None or s is None:
        p[0] = None
        return

    if r.type_ != TYPE.string:
        api.errmsg.syntax_error_expected_string(lineno, r.type_)

    entry = SYMBOL_TABLE.access_var(q, lineno, default_type=TYPE.string)
    if entry is None:
        p[0] = None
        return

    p[0] = make_sentence('LETSUBSTR', entry, s[0], s[1], r)

Response: A string assignment statement.


Instruction:
Can you tell what is the following Python 3 function doing
def p_if_sentence(p):
    cond_ = p[1]
    if len(p) == 6:
        lbl = make_label(p[3], p.lineno(3))
        stat_ = make_block(lbl, p[4])
        endif_ = p[5]
    elif len(p) == 5:
        stat_ = p[3]
        endif_ = p[4]
    else:
        stat_ = make_nop()
        endif_ = p[3]

    p[0] = make_sentence('IF', cond_, make_block(stat_, endif_), lineno=p.lineno(2))

Response: P an if statement.


Instruction:
How would you implement a function in Python 3 that
processes single - line IF statements.

Response:
def p_single_line_if(p):
    """ if_inline : if_then_part statements %prec ID
                  | if_then_part co_statements_co %prec NEWLINE
                  | if_then_part statements_co %prec NEWLINE
                  | if_then_part co_statements %prec ID
    """
    cond_ = p[1]
    stat_ = p[2]
    p[0] = make_sentence('IF', cond_, stat_, lineno=p.lineno(1))


Instruction:
Can you write a function in Python 3 where it
processes the else - if - part of a statement.

Response:
def p_elseif_part(p):
    """ elseif_expr : ELSEIF expr then
                    | LABEL ELSEIF expr then
    """
    if p[1] == 'ELSEIF':
        label_ = make_nop()  # No label
        cond_ = p[2]
    else:
        label_ = make_label(p[1], p.lineno(1))
        cond_ = p[3]

    p[0] = label_, cond_


Instruction:
How would you explain what the following Python 3 function does
def p_elseif_list(p):
    label_, cond_ = p[1]
    then_ = p[2]
    else_ = p[3]

    if isinstance(else_, list):  # it's an else part
        else_ = make_block(*else_)
    else:
        then_ = make_block(then_, else_)
        else_ = None

    p[0] = make_block(label_, make_sentence('IF', cond_, then_, else_, lineno=p.lineno(1)))

Response: P 3. 1. 3. elseiflist


Instruction:
Here you have a function in Python 3, explain what it does
def p_elseif_elseiflist(p):
    label_, cond_ = p[1]
    then_ = p[2]
    else_ = p[3]
    p[0] = make_block(label_, make_sentence('IF', cond_, then_, else_, lineno=p.lineno(1)))

Response: P 3. 1. 6. If list


Instruction:
Can you generate the documentation for the following Python 3 function
def p_else_part_endif(p):
    if p[2] == '\n':
        if len(p) == 4:
            p[0] = [make_nop(), p[3]]
        elif len(p) == 6:
            p[0] = [make_label(p[3], p.lineno(3)), p[4], p[5]]
        else:
            p[0] = [p[3], p[4]]
    else:
        p[0] = [p[2], p[3]]

Response: P [ 1 ] else_part_inline


Instruction:
Can you generate the documentation for the following Python 3 function
def p_else_part_label(p):
    lbl = make_label(p[1], p.lineno(1))
    p[0] = [make_block(lbl, p[3]), p[4]]

Response: Label the else part of a block.


Instruction:
Here you have a function in Python 3, explain what it does
def p_if_then_part(p):
    if is_number(p[2]):
        api.errmsg.warning_condition_is_always(p.lineno(1), bool(p[2].value))

    p[0] = p[2]

Response: If expr then part


Instruction:
Can you tell what is the following Python 3 function doing
def p_next1(p):
    if p[1] == 'NEXT':
        p1 = make_nop()
        p3 = p[2]
    else:
        p1 = make_label(p[1], p.lineno(1))
        p3 = p[3]

    if p3 != gl.LOOPS[-1][1]:
        api.errmsg.syntax_error_wrong_for_var(p.lineno(2), gl.LOOPS[-1][1], p3)
        p[0] = make_nop()
        return

    p[0] = p1

Response: A function to be used in the loop loop.


Instruction:
Can you create a Python 3 function that
handles FOR start and FOR statements.

Response:
def p_for_sentence_start(p):
    """ for_start : FOR ID EQ expr TO expr step
    """
    gl.LOOPS.append(('FOR', p[2]))
    p[0] = None

    if p[4] is None or p[6] is None or p[7] is None:
        return

    if is_number(p[4], p[6], p[7]):
        if p[4].value != p[6].value and p[7].value == 0:
            warning(p.lineno(5), 'STEP value is 0 and FOR might loop forever')

        if p[4].value > p[6].value and p[7].value > 0:
            warning(p.lineno(5), 'FOR start value is greater than end. This FOR loop is useless')

        if p[4].value < p[6].value and p[7].value < 0:
            warning(p.lineno(2), 'FOR start value is lower than end. This FOR loop is useless')

    id_type = common_type(common_type(p[4], p[6]), p[7])
    variable = SYMBOL_TABLE.access_var(p[2], p.lineno(2), default_type=id_type)
    if variable is None:
        return

    variable.accessed = True
    expr1 = make_typecast(variable.type_, p[4], p.lineno(3))
    expr2 = make_typecast(variable.type_, p[6], p.lineno(5))
    expr3 = make_typecast(variable.type_, p[7], p.lexer.lineno)

    p[0] = make_sentence('FOR', variable, expr1, expr2, expr3)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def p_error_raise(p):
    q = make_number(1, lineno=p.lineno(2))
    r = make_binary(p.lineno(1), 'MINUS',
                    make_typecast(TYPE.ubyte, p[2], p.lineno(1)), q,
                    lambda x, y: x - y)
    p[0] = make_sentence('ERROR', r)

Response: A statement that can be used to raise an error.


Instruction:
Explain what the following Python 3 code does
def p_stop_raise(p):
    q = make_number(9, lineno=p.lineno(1)) if len(p) == 2 else p[2]
    z = make_number(1, lineno=p.lineno(1))
    r = make_binary(p.lineno(1), 'MINUS',
                    make_typecast(TYPE.ubyte, q, p.lineno(1)), z,
                    lambda x, y: x - y)
    p[0] = make_sentence('STOP', r)

Response: A stop raise statement.


Instruction:
Can you generate the documentation for the following Python 3 function
def p_do_loop(p):
    if len(p) == 4:
        q = make_block(p[2], p[3])
    else:
        q = p[2]

    if p[1] == 'DO':
        gl.LOOPS.append(('DO',))

    if q is None:
        warning(p.lineno(1), 'Infinite empty loop')

    # An infinite loop and no warnings
    p[0] = make_sentence('DO_LOOP', q)
    gl.LOOPS.pop()

Response: A do loop statement.


Instruction:
Can you generate the documentation for the following Python 3 function
def p_read(p):
    gl.DATA_IS_USED = True
    reads = []

    if p[2] is None:
        return

    for arg in p[2]:
        entry = arg.value
        if entry is None:
            p[0] = None
            return

        if isinstance(entry, symbols.VARARRAY):
            api.errmsg.syntax_error(p.lineno(1), "Cannot read '%s'. It's an array" % entry.name)
            p[0] = None
            return

        if isinstance(entry, symbols.VAR):
            if entry.class_ != CLASS.var:
                api.errmsg.syntax_error_cannot_assing_not_a_var(p.lineno(2), entry.name)
                p[0] = None
                return

            entry.accessed = True
            if entry.type_ == TYPE.auto:
                entry.type_ = _TYPE(gl.DEFAULT_TYPE)
                api.errmsg.warning_implicit_type(p.lineno(2), p[2], entry.type_)

            reads.append(make_sentence('READ', entry))
            continue

        if isinstance(entry, symbols.ARRAYLOAD):
            reads.append(make_sentence('READ', symbols.ARRAYACCESS(entry.entry, entry.args, entry.lineno)))
            continue

        api.errmsg.syntax_error(p.lineno(1), "Syntax error. Can only read a variable or an array element")
        p[0] = None
        return

    p[0] = make_block(*reads)

Response: parse a READ statement


Instruction:
Given the following Python 3 function, write the documentation
def p_do_loop_while(p):
    if len(p) == 6:
        q = make_block(p[2], p[3])
        r = p[5]
    else:
        q = p[2]
        r = p[4]

    if p[1] == 'DO':
        gl.LOOPS.append(('DO',))

    p[0] = make_sentence('DO_WHILE', r, q)
    gl.LOOPS.pop()

    if is_number(r):
        api.errmsg.warning_condition_is_always(p.lineno(3), bool(r.value))
    if q is None:
        api.errmsg.warning_empty_loop(p.lineno(3))

Response: parse a DO loop while statement


Instruction:
Given the following Python 3 function, write the documentation
def p_do_while_loop(p):
    r = p[1]
    q = p[2]
    if q == 'LOOP':
        q = None

    p[0] = make_sentence('WHILE_DO', r, q)
    gl.LOOPS.pop()

    if is_number(r):
        api.errmsg.warning_condition_is_always(p.lineno(2), bool(r.value))

Response: Process a while loop statement.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def p_while_sentence(p):
    gl.LOOPS.pop()
    q = make_block(p[2], p[3])

    if is_number(p[1]) and p[1].value:
        if q is None:
            warning(p[1].lineno, "Condition is always true and leads to an infinite loop.")
        else:
            warning(p[1].lineno, "Condition is always true and might lead to an infinite loop.")

    p[0] = make_sentence('WHILE', p[1], q)

Response: Process a WHILE statement.


Instruction:
Can you generate the documentation for the following Python 3 function
def p_exit(p):
    q = p[2]
    p[0] = make_sentence('EXIT_%s' % q)

    for i in gl.LOOPS:
        if q == i[0]:
            return

    syntax_error(p.lineno(1), 'Syntax Error: EXIT %s out of loop' % q)

Response: EXIT WHILE DOCOME WHILE DOCOME FOR FOREXIT


Instruction:
Write a Python 3 function that can
parse an ATTR_LIST statement.

Response:
def p_attr(p):
    """ attr : OVER expr
             | INVERSE expr
             | INK expr
             | PAPER expr
             | BRIGHT expr
             | FLASH expr
    """
    # ATTR_LIST are used by drawing commands: PLOT, DRAW, CIRCLE
    # BOLD and ITALIC are ignored by them, so we put them out of the
    # attr definition so something like DRAW BOLD 1; .... will raise
    # a syntax error
    p[0] = make_sentence(p[1] + '_TMP',
                         make_typecast(TYPE.ubyte, p[2], p.lineno(1)))


Instruction:
Can you generate the documentation for the following Python 3 function
def p_print_list(p):
    p[0] = p[1]
    p[0].eol = (p[3] is not None)

    if p[3] is not None:
        p[0].appendChild(p[3])

Response: print_list is a list of lists of lists of dicts


Instruction:
Make a summary of the following Python 3 code
def p_print_list_comma(p):
    p[0] = p[1]
    p[0].eol = (p[3] is not None)
    p[0].appendChild(make_sentence('PRINT_COMMA'))

    if p[3] is not None:
        p[0].appendChild(p[3])

Response: A function to parse the print_list_comma.


Instruction:
How would you explain what the following Python 3 function does
def p_on_goto(p):
    expr = make_typecast(TYPE.ubyte, p[2], p.lineno(1))
    p[0] = make_sentence('ON_' + p[3], expr, *p[4])

Response: statement : ON expr goto label_list


Instruction:
Create a Python 3 function to
parse a RETURN statement.

Response:
def p_return(p):
    """ statement : RETURN
    """
    if not FUNCTION_LEVEL:  # At less one level, otherwise, this return is from a GOSUB
        p[0] = make_sentence('RETURN')
        return

    if FUNCTION_LEVEL[-1].kind != KIND.sub:
        syntax_error(p.lineno(1), 'Syntax Error: Functions must RETURN a value, or use EXIT FUNCTION instead.')
        p[0] = None
        return

    p[0] = make_sentence('RETURN', FUNCTION_LEVEL[-1])


Instruction:
Here you have a function in Python 3, explain what it does
def p_return_expr(p):
    if not FUNCTION_LEVEL:  # At less one level
        syntax_error(p.lineno(1), 'Syntax Error: Returning value out of FUNCTION')
        p[0] = None
        return

    if FUNCTION_LEVEL[-1].kind is None:  # This function was not correctly declared.
        p[0] = None
        return

    if FUNCTION_LEVEL[-1].kind != KIND.function:
        syntax_error(p.lineno(1), 'Syntax Error: SUBs cannot return a value')
        p[0] = None
        return

    if is_numeric(p[2]) and FUNCTION_LEVEL[-1].type_ == TYPE.string:
        syntax_error(p.lineno(2), 'Type Error: Function must return a string, not a numeric value')
        p[0] = None
        return

    if not is_numeric(p[2]) and FUNCTION_LEVEL[-1].type_ != TYPE.string:
        syntax_error(p.lineno(2), 'Type Error: Function must return a numeric value, not a string')
        p[0] = None
        return

    p[0] = make_sentence('RETURN', FUNCTION_LEVEL[-1],
                         make_typecast(FUNCTION_LEVEL[-1].type_, p[2],
                                       p.lineno(1)))

Response: Parse a RETURN statement.


Instruction:
Given the following Python 3 function, write the documentation
def p_poke2(p):
    i = 2 if isinstance(p[2], Symbol) or p[2] is None else 3
    if p[i + 1] is None or p[i + 3] is None:
        p[0] = None
        return
    p[0] = make_sentence('POKE',
                         make_typecast(TYPE.uinteger, p[i + 1], p.lineno(i + 2)),
                         make_typecast(p[i], p[i + 3], p.lineno(i + 3))
                         )

Response:
statement : POKE numbertype expr COMMA expr
                   | POKE LP numbertype expr COMMA expr RP


Instruction:
Can you write a function in Python 3 where it
parses a simple instruction.

Response:
def p_simple_instruction(p):
    """ statement : ITALIC expr
                   | BOLD expr
                   | INK expr
                   | PAPER expr
                   | BRIGHT expr
                   | FLASH expr
                   | OVER expr
                   | INVERSE expr
    """
    p[0] = make_sentence(p[1], make_typecast(TYPE.ubyte, p[2], p.lineno(1)))


Instruction:
Write a Python 3 script for
parsing load code statement

Response:
def p_load_code(p):
    """ statement : load_or_verify expr ID
                  | load_or_verify expr CODE
                  | load_or_verify expr CODE expr
                  | load_or_verify expr CODE expr COMMA expr
    """
    if p[2].type_ != TYPE.string:
        api.errmsg.syntax_error_expected_string(p.lineno(3), p[2].type_)

    if len(p) == 4:
        if p[3].upper() not in ('SCREEN', 'SCREEN$', 'CODE'):
            syntax_error(p.lineno(3), 'Unexpected "%s" ID. Expected "SCREEN$" instead' % p[3])
            return None
        else:
            if p[3].upper() == 'CODE':  # LOAD "..." CODE
                start = make_number(0, lineno=p.lineno(3))
                length = make_number(0, lineno=p.lineno(3))
            else:  # SCREEN$
                start = make_number(16384, lineno=p.lineno(3))
                length = make_number(6912, lineno=p.lineno(3))
    else:
        start = make_typecast(TYPE.uinteger, p[4], p.lineno(3))

        if len(p) == 5:
            length = make_number(0, lineno=p.lineno(3))
        else:
            length = make_typecast(TYPE.uinteger, p[6], p.lineno(5))

    p[0] = make_sentence(p[1], p[2], start, length)


Instruction:
Can you generate the documentation for the following Python 3 function
def p_expr_div_expr(p):
    p[0] = make_binary(p.lineno(2), 'DIV', p[1], p[3], lambda x, y: x / y)

Response: expr : expr DIV expr


Instruction:
Explain what the following Python 3 code does
def p_expr_mod_expr(p):
    p[0] = make_binary(p.lineno(2), 'MOD', p[1], p[3], lambda x, y: x % y)

Response: expr : expr MOD expr


Instruction:
Given the following Python 3 function, write the documentation
def p_expr_pow_expr(p):
    p[0] = make_binary(p.lineno(2), 'POW',
                       make_typecast(TYPE.float_, p[1], p.lineno(2)),
                       make_typecast(TYPE.float_, p[3], p.lexer.lineno),
                       lambda x, y: x ** y)

Response: expr = expr POW expr


Instruction:
Can you generate a brief explanation for the following Python 3 code
def p_expr_shl_expr(p):
    if p[1] is None or p[3] is None:
        p[0] = None
        return

    if p[1].type_ in (TYPE.float_, TYPE.fixed):
        p[1] = make_typecast(TYPE.ulong, p[1], p.lineno(2))

    p[0] = make_binary(p.lineno(2), 'SHL', p[1],
                       make_typecast(TYPE.ubyte, p[3], p.lineno(2)),
                       lambda x, y: x << y)

Response: P expr SHL expr


Instruction:
Can you tell what is the following Python 3 function doing
def p_expr_LT_expr(p):
    p[0] = make_binary(p.lineno(2), 'LT', p[1], p[3], lambda x, y: x < y)

Response: expr : expr LT expr


Instruction:
Can you generate a brief explanation for the following Python 3 code
def p_expr_GT_expr(p):
    p[0] = make_binary(p.lineno(2), 'GT', p[1], p[3], lambda x, y: x > y)

Response: expr : expr GT expr


Instruction:
Make a summary of the following Python 3 code
def p_expr_GE_expr(p):
    p[0] = make_binary(p.lineno(2), 'GE', p[1], p[3], lambda x, y: x >= y)

Response: expr : expr GE expr


Instruction:
Make a summary of the following Python 3 code
def p_expr_NE_expr(p):
    p[0] = make_binary(p.lineno(2), 'NE', p[1], p[3], lambda x, y: x != y)

Response: expr : expr NE expr


Instruction:
Given the following Python 3 function, write the documentation
def p_expr_OR_expr(p):
    p[0] = make_binary(p.lineno(2), 'OR', p[1], p[3], lambda x, y: x or y)

Response: expr : expr OR expr


Instruction:
How would you explain what the following Python 3 function does
def p_expr_BOR_expr(p):
    p[0] = make_binary(p.lineno(2), 'BOR', p[1], p[3], lambda x, y: x | y)

Response: expr : expr BOR expr


Instruction:
How would you explain what the following Python 3 function does
def p_expr_XOR_expr(p):
    p[0] = make_binary(p.lineno(2), 'XOR', p[1], p[3], lambda x, y: (x and not y) or (not x and y))

Response: expr : expr XOR expr


Instruction:
Can you tell what is the following Python 3 function doing
def p_expr_AND_expr(p):
    p[0] = make_binary(p.lineno(2), 'AND', p[1], p[3], lambda x, y: x and y)

Response: expr : expr AND expr


Instruction:
Here you have a function in Python 3, explain what it does
def p_expr_BAND_expr(p):
    p[0] = make_binary(p.lineno(2), 'BAND', p[1], p[3], lambda x, y: x & y)

Response: expr : expr BAND expr


Instruction:
Here you have a function in Python 3, explain what it does
def p_expr_PI(p):
    p[0] = make_number(PI, lineno=p.lineno(1), type_=TYPE.float_)

Response: A function to generate the PI expression.


Instruction:
Given the following Python 3 function, write the documentation
def p_expr_id_substr(p):
    entry = SYMBOL_TABLE.access_var(p[1], p.lineno(1), default_type=TYPE.string)
    p[0] = None
    if entry is None:
        return

    entry.accessed = True
    p[0] = make_strslice(p.lineno(1), entry, p[2][0], p[2][1])

Response: string : ID substr


Instruction:
How would you code a function in Python 3 to
string : LP expr RP substr

Response:
def p_string_expr_lp(p):
    """ string : LP expr RP substr
    """
    if p[2].type_ != TYPE.string:
        syntax_error(p.lexer.lineno,
                     "Expected a string type expression. "
                     "Got %s type instead" % TYPE.to_string(p[2].type_))
        p[0] = None
    else:
        p[0] = make_strslice(p.lexer.lineno, p[2], p[4][0], p[4][1])


Instruction:
Can you generate the documentation for the following Python 3 function
def p_subind_str(p):
    p[0] = (make_typecast(TYPE.uinteger, p[2], p.lineno(1)),
            make_typecast(TYPE.uinteger, p[4], p.lineno(3)))

Response: substr : LP expr TO expr RP


Instruction:
Can you tell what is the following Python 3 function doing
def p_subind_TO(p):
    p[0] = (make_typecast(TYPE.uinteger,
                          make_number(0, lineno=p.lineno(2)),
                          p.lineno(1)),
            make_typecast(TYPE.uinteger,
                          make_number(gl.MAX_STRSLICE_IDX, lineno=p.lineno(3)),
                          p.lineno(2)))

Response: Subind to LP TO RP


Instruction:
Explain what the following Python 3 code does
def p_addr_of_id(p):
    entry = SYMBOL_TABLE.access_id(p[2], p.lineno(2))
    if entry is None:
        p[0] = None
        return

    entry.accessed = True
    result = make_unary(p.lineno(1), 'ADDRESS', entry, type_=_TYPE(gl.PTR_TYPE))

    if is_dynamic(entry):
        p[0] = result
    else:
        p[0] = make_constexpr(p.lineno(1), result)

Response:
bexpr : ADDRESSOF ID
             | ADDRESSOF ARRAY_ID


Instruction:
Write a Python 3 function that can
handle the ID call expression.

Response:
def p_idcall_expr(p):
    """ func_call : ID arg_list %prec UMINUS
    """  # This can be a function call or a string index
    p[0] = make_call(p[1], p.lineno(1), p[2])
    if p[0] is None:
        return

    if p[0].token in ('STRSLICE', 'VAR', 'STRING'):
        entry = SYMBOL_TABLE.access_call(p[1], p.lineno(1))
        entry.accessed = True
        return

    # TODO: Check that arrays really needs kind=function to be set
    # Both array accesses and functions are tagged as functions
    # functions also has the class_ attribute set to 'function'
    p[0].entry.set_kind(KIND.function, p.lineno(1))
    p[0].entry.accessed = True


Instruction:
How would you explain what the following Python 3 function does
def p_let_arr_substr(p):
    i = 2 if p[1].upper() == 'LET' else 1

    id_ = p[i]
    arg_list = p[i + 1]
    substr = p[i + 2]
    expr_ = p[i + 4]
    p[0] = make_array_substr_assign(p.lineno(i), id_, arg_list, substr, expr_)

Response:
P_let_arr_substr is a helper function for inserting a substr statement in a LET ARRAY_ID arg_list substr EQ expr
                  | ARRAY_ID substr EQ expr


Instruction:
Can you tell what is the following Python 3 function doing
def p_let_arr_substr_in_args4(p):
    i = 2 if p[1].upper() == 'LET' else 1

    id_ = p[i]
    arg_list = p[i + 2]
    substr = (arg_list.children.pop().value, p[i + 4])
    expr_ = p[i + 7]
    p[0] = make_array_substr_assign(p.lineno(i), id_, arg_list, substr, expr_)

Response: A let arr substr in args 4.


Instruction:
Can you tell what is the following Python 3 function doing
def p_addr_of_array_element(p):
    p[0] = None

    if p[3] is None:
        return

    result = make_array_access(p[2], p.lineno(2), p[3])
    if result is None:
        return

    result.entry.accessed = True
    p[0] = make_unary(p.lineno(1), 'ADDRESS', result, type_=_TYPE(gl.PTR_TYPE))

Response: A function to create an array access.


Instruction:
Make a summary of the following Python 3 code
def p_bexpr_func(p):
    args = make_arg_list(make_argument(p[2], p.lineno(2)))
    p[0] = make_call(p[1], p.lineno(1), args)
    if p[0] is None:
        return

    if p[0].token in ('STRSLICE', 'VAR', 'STRING'):
        entry = SYMBOL_TABLE.access_call(p[1], p.lineno(1))
        entry.accessed = True
        return

    # TODO: Check that arrays really needs kind=function to be set
    # Both array accesses and functions are tagged as functions
    # functions also has the class_ attribute set to 'function'
    p[0].entry.set_kind(KIND.function, p.lineno(1))
    p[0].entry.accessed = True

Response: A function is a function call.


Instruction:
How would you explain what the following Python 3 function does
def p_funcdecl(p):
    if p[1] is None:
        p[0] = None
        return

    p[0] = p[1]
    p[0].local_symbol_table = SYMBOL_TABLE.table[SYMBOL_TABLE.current_scope]
    p[0].locals_size = SYMBOL_TABLE.leave_scope()
    FUNCTION_LEVEL.pop()
    p[0].entry.body = p[2]

    entry = p[0].entry
    entry.forwarded = False

Response: function_declaration : function_header function_body


Instruction:
Can you generate a brief explanation for the following Python 3 code
def p_funcdeclforward(p):
    if p[2] is None:
        if FUNCTION_LEVEL:
            FUNCTION_LEVEL.pop()
        return

    if p[2].entry.forwarded:
        syntax_error(p.lineno(1), "duplicated declaration for function '%s'" % p[2].name)

    p[2].entry.forwarded = True
    SYMBOL_TABLE.leave_scope()
    FUNCTION_LEVEL.pop()

Response: function declaration is forward


Instruction:
Given the following Python 3 function, write the documentation
def p_param_definition(p):
    p[0] = p[1]
    if p[0] is not None:
        p[0].byref = OPTIONS.byref.value

Response: param_definition is a param_definition object that is passed to the API.


Instruction:
Explain what the following Python 3 code does
def p_function_body(p):
    if not FUNCTION_LEVEL:
        syntax_error(p.lineno(3), "Unexpected token 'END %s'. No Function or Sub has been defined." % p[2])
        p[0] = None
        return

    a = FUNCTION_LEVEL[-1].kind
    if a not in (KIND.sub, KIND.function):  # This function/sub was not correctly declared, so exit now
        p[0] = None
        return

    i = 2 if p[1] == 'END' else 3
    b = p[i].lower()

    if a != b:
        syntax_error(p.lineno(i), "Unexpected token 'END %s'. Should be 'END %s'" % (b.upper(), a.upper()))
        p[0] = None
    else:
        p[0] = None if p[1] == 'END' else p[1]

Response: Parse the function body.


Instruction:
Given the following Python 3 function, write the documentation
def p_expr_usr(p):
    if p[2].type_ == TYPE.string:
        p[0] = make_builtin(p.lineno(1), 'USR_STR', p[2], type_=TYPE.uinteger)
    else:
        p[0] = make_builtin(p.lineno(1), 'USR',
                            make_typecast(TYPE.uinteger, p[2], p.lineno(1)),
                            type_=TYPE.uinteger)

Response: bexpr : USR bexpr %prec UMINUS


Instruction:
How would you explain what the following Python 3 function does
def p_expr_peek(p):
    p[0] = make_builtin(p.lineno(1), 'PEEK',
                        make_typecast(TYPE.uinteger, p[2], p.lineno(1)),
                        type_=TYPE.ubyte)

Response: bexpr : PEEK bexpr %prec UMINUS


Instruction:
Can you tell what is the following Python 3 function doing
def p_expr_lbound(p):
    entry = SYMBOL_TABLE.access_array(p[3], p.lineno(3))
    if entry is None:
        p[0] = None
        return

    entry.accessed = True

    if p[1] == 'LBOUND':
        p[0] = make_number(entry.bounds[OPTIONS.array_base.value].lower,
                           p.lineno(3), TYPE.uinteger)
    else:
        p[0] = make_number(entry.bounds[OPTIONS.array_base.value].upper,
                           p.lineno(3), TYPE.uinteger)

Response: A function to handle LBOUND and UBOUND expressions.


Instruction:
Can you tell what is the following Python 3 function doing
def p_expr_lbound_expr(p):
    entry = SYMBOL_TABLE.access_array(p[3], p.lineno(3))
    if entry is None:
        p[0] = None
        return

    entry.accessed = True
    num = make_typecast(TYPE.uinteger, p[5], p.lineno(6))

    if is_number(num):
        if num.value == 0:  # 0 => Number of dims
            p[0] = make_number(len(entry.bounds), p.lineno(3), TYPE.uinteger)
            return

        val = num.value - 1
        if val < 0 or val >= len(entry.bounds):
            syntax_error(p.lineno(6), "Dimension out of range")
            p[0] = None
            return

        if p[1] == 'LBOUND':
            p[0] = make_number(entry.bounds[val].lower, p.lineno(3), TYPE.uinteger)
        else:
            p[0] = make_number(entry.bounds[val].upper, p.lineno(3), TYPE.uinteger)
        return

    if p[1] == 'LBOUND':
        entry.lbound_used = True
    else:
        entry.ubound_used = True

    p[0] = make_builtin(p.lineno(1), p[1], [entry, num], type_=TYPE.uinteger)

Response: p = parse_expr_lbound_expr ( p )


Instruction:
Can you tell what is the following Python 3 function doing
def p_len(p):
    arg = p[2]
    if arg is None:
        p[0] = None
    elif isinstance(arg, symbols.VAR) and arg.class_ == CLASS.array:
        p[0] = make_number(len(arg.bounds), lineno=p.lineno(1))  # Do constant folding
    elif arg.type_ != TYPE.string:
        api.errmsg.syntax_error_expected_string(p.lineno(1), TYPE.to_string(arg.type_))
        p[0] = None
    elif is_string(arg):  # Constant string?
        p[0] = make_number(len(arg.value), lineno=p.lineno(1))  # Do constant folding
    else:
        p[0] = make_builtin(p.lineno(1), 'LEN', arg, type_=TYPE.uinteger)

Response: Parse the LEN expression.


Instruction:
How would you explain what the following Python 3 function does
def p_str(p):
    if is_number(p[2]):  # A constant is converted to string directly
        p[0] = symbols.STRING(str(p[2].value), p.lineno(1))
    else:
        p[0] = make_builtin(p.lineno(1), 'STR',
                            make_typecast(TYPE.float_, p[2], p.lineno(1)),
                            type_=TYPE.string)

Response:
%prec UMINUS
    string expr %prec UMINUS
    string


Instruction:
Given the following Python 3 function, write the documentation
def p_chr_one(p):
    arg_list = make_arg_list(make_argument(p[2], p.lineno(1)))
    arg_list[0].value = make_typecast(TYPE.ubyte, arg_list[0].value, p.lineno(1))
    p[0] = make_builtin(p.lineno(1), 'CHR', arg_list, type_=TYPE.string)

Response: \ x1b [ 1mNAME \ x1b [ 0m chr - 1 - > CHR


Instruction:
Can you create a Python 3 function that
strings : CHR arg_list

Response:
def p_chr(p):
    """ string : CHR arg_list
    """
    if len(p[2]) < 1:
        syntax_error(p.lineno(1), "CHR$ function need at less 1 parameter")
        p[0] = None
        return

    for i in range(len(p[2])):  # Convert every argument to 8bit unsigned
        p[2][i].value = make_typecast(TYPE.ubyte, p[2][i].value, p.lineno(1))

    p[0] = make_builtin(p.lineno(1), 'CHR', p[2], type_=TYPE.string)


Instruction:
Explain what the following Python 3 code does
def p_code(p):

    def asc(x):
        if len(x):
            return ord(x[0])

        return 0

    if p[2] is None:
        p[0] = None
        return

    if p[2].type_ != TYPE.string:
        api.errmsg.syntax_error_expected_string(p.lineno(1), TYPE.to_string(p[2].type_))
        p[0] = None
    else:
        p[0] = make_builtin(p.lineno(1), 'CODE', p[2], lambda x: asc(x), type_=TYPE.ubyte)

Response: Code parser for internal use.


Instruction:
Here you have a function in Python 3, explain what it does
def make_node(lower, upper, lineno):
        if not is_static(lower, upper):
            syntax_error(lineno, 'Array bounds must be constants')
            return None

        if isinstance(lower, SymbolVAR):
            lower = lower.value
        if isinstance(upper, SymbolVAR):
            upper = upper.value

        lower.value = int(lower.value)
        upper.value = int(upper.value)

        if lower.value < 0:
            syntax_error(lineno, 'Array bounds must be greater than 0')
            return None

        if lower.value > upper.value:
            syntax_error(lineno, 'Lower array bound must be less or equal to upper one')
            return None

        return SymbolBOUND(lower.value, upper.value)

Response: Creates a node that is a range of the array.


Instruction:
Can you implement a function in Python 3 that
returns a number for a BASIC program. That is the number of the BASIC log file.

Response:
def number(self, number):
        """ Returns a floating point (or integer) number for a BASIC
        program. That is: It's ASCII representation followed by 5 bytes
        in floating point or integer format (if number in (-65535 + 65535)
        """
        s = [ord(x) for x in str(number)] + [14]  # Bytes of string representation in bytes

        if number == int(number) and abs(number) < 65536:  # integer form?
            sign = 0xFF if number < 0 else 0
            b = [0, sign] + self.numberLH(number) + [0]
        else:  # Float form
            (C, ED, LH) = fp.immediate_float(number)
            C = C[:2]  # Remove 'h'
            ED = ED[:4]  # Remove 'h'
            LH = LH[:4]  # Remove 'h'

            b = [int(C, 16)]  # Convert to BASE 10
            b += [int(ED[:2], 16), int(ED[2:], 16)]
            b += [int(LH[:2], 16), int(LH[2:], 16)]

        return s + b


Instruction:
Can you write a function in Python 3 where it
parses a given string into a list of BASIC commands and the remaining strings.

Response:
def parse_sentence(self, string):
        """ Parses the given sentence. BASIC commands must be
        types UPPERCASE and as SEEN in ZX BASIC. e.g. GO SUB for gosub, etc...
        """

        result = []

        def shift(string_):
            """ Returns first word of a string, and remaining
            """
            string_ = string_.strip()  # Remove spaces and tabs

            if not string_:  # Avoid empty strings
                return '', ''

            i = string_.find(' ')
            if i == -1:
                command_ = string_
                string_ = ''
            else:
                command_ = string_[:i]
                string_ = string_[i:]

            return command_, string_

        command, string = shift(string)
        while command != '':
            result += self.token(command)


Instruction:
Implement a function in Python 3 to
return the bytes of a sentence.

Response:
def sentence_bytes(self, sentence):
        """ Return bytes of a sentence.
        This is a very simple parser. Sentence is a list of strings and numbers.
        1st element of sentence MUST match a token.
        """
        result = [TOKENS[sentence[0]]]

        for i in sentence[1:]:  # Remaining bytes
            if isinstance(i, str):
                result.extend(self.literal(i))
            elif isinstance(i, float) or isinstance(i, int):  # A number?
                result.extend(self.number(i))
            else:
                result.extend(i)  # Must be another thing

        return result


Instruction:
Write a Python 3 script for
returning the bytes for a basic line.

Response:
def line(self, sentences, line_number=None):
        """ Return the bytes for a basic line.
        If no line number is given, current one + 10 will be used
        Sentences if a list of sentences
        """
        if line_number is None:
            line_number = self.current_line + 10
        self.current_line = line_number

        sep = []
        result = []
        for sentence in sentences:
            result.extend(sep)
            result.extend(self.sentence_bytes(sentence))
            sep = [ord(':')]

        result.extend([ENTER])
        result = self.line_number(line_number) + self.numberLH(len(result)) + result

        return result


Instruction:
Write a Python 3 script for
adding a line to the output.

Response:
def add_line(self, sentences, line_number=None):
        """ Add current line to the output.
        See self.line() for more info
        """
        self.bytes += self.line(sentences, line_number)


Instruction:
Create a Python 3 function to
return the offset in bytes of the base memory of the current object.

Response:
def offset(self):
        """ If this is a constant access (e.g. A(1))
        return the offset in bytes from the beginning of the
        variable in memory.

        Otherwise, if it's not constant (e.g. A(i))
        returns None
        """
        offset = 0
        # Now we must typecast each argument to a u16 (POINTER) type
        # i is the dimension ith index, b is the bound
        for i, b in zip(self.arglist, self.entry.bounds):
            tmp = i.children[0]
            if is_number(tmp) or is_const(tmp):
                if offset is not None:
                    offset = offset * b.count + tmp.value
            else:
                offset = None
                break

        if offset is not None:
            offset = TYPE.size(gl.SIZE_TYPE) + TYPE.size(gl.BOUND_TYPE) * len(self.arglist) + offset * self.type_.size

        return offset


Instruction:
How would you implement a function in Python 3 that
creates an array access. A node.

Response:
def make_node(cls, id_, arglist, lineno):
        """ Creates an array access. A(x1, x2, ..., xn)
        """
        assert isinstance(arglist, SymbolARGLIST)
        variable = gl.SYMBOL_TABLE.access_array(id_, lineno)
        if variable is None:
            return None

        if len(variable.bounds) != len(arglist):
            syntax_error(lineno, "Array '%s' has %i dimensions, not %i" %
                         (variable.name, len(variable.bounds), len(arglist)))
            return None

        # Checks for array subscript range if the subscript is constant
        # e.g. A(1) is a constant subscript access
        for i, b in zip(arglist, variable.bounds):
            btype = gl.SYMBOL_TABLE.basic_types[gl.BOUND_TYPE]
            lower_bound = NUMBER(b.lower, type_=btype, lineno=lineno)
            i.value = BINARY.make_node('MINUS',
                                       TYPECAST.make_node(btype, i.value, lineno),
                                       lower_bound, lineno, func=lambda x, y: x - y,
                                       type_=btype)
            if is_number(i.value) or is_const(i.value):
                val = i.value.value
                if val < 0 or val > b.count:
                    warning(lineno, "Array '%s' subscript out of range" % id_)

        # Returns the variable entry and the node
        return cls(variable, arglist, lineno)


Instruction:
Make a summary of the following Python 3 code
def t_INITIAL_COMMENT(self, t):
        r';'
        t.lexer.push_state('asmcomment')
        t.type = 'TOKEN'
        t.value = ';'
        return t

Response: r This is the initial comment token.


Instruction:
Write a Python 3 script to
look for preprocessor ID directives and set the type to ID

Response:
def t_prepro_ID(self, t):
        r'[_a-zA-Z][_a-zA-Z0-9]*'  # preprocessor directives
        t.type = reserved_directives.get(t.value.lower(), 'ID')
        if t.type == 'DEFINE':
            t.lexer.begin('define')
        elif t.type == 'PRAGMA':
            t.lexer.begin('pragma')
        return t


Instruction:
Can you tell what is the following Python 3 function doing
def put_current_line(self, prefix=''):
        return '%s#line %i "%s"\n' % (prefix, self.lex.lineno, os.path.basename(self.filestack[-1][0]))

Response: Returns line and file for include sequences.


Instruction:
Write a Python 3 script for
including a file into the internal state.

Response:
def include(self, filename):
        """ Changes FILENAME and line count
        """
        if filename != STDIN and filename in [x[0] for x in self.filestack]:  # Already included?
            self.warning(' Recursive inclusion')

        self.filestack.append([filename, 1, self.lex, self.input_data])
        self.lex = lex.lex(object=self)
        result = self.put_current_line()  # First #line start with \n (EOL)

        try:
            if filename == STDIN:
                self.input_data = sys.stdin.read()
            else:
                self.input_data = api.utils.read_txt_file(filename)

            if len(self.input_data) and self.input_data[-1] != EOL:
                self.input_data += EOL
        except IOError:
            self.input_data = EOL

        self.lex.input(self.input_data)
        return result


Instruction:
Can you tell what is the following Python 3 function doing
def add_alias(self, entry):
        assert isinstance(entry, SymbolVAR)
        self.aliased_by.append(entry)

Response: Adds an alias to the current list aliased_by


Instruction:
Given the following Python 3 function, write the documentation
def make_alias(self, entry):
        entry.add_alias(self)
        self.alias = entry
        self.scope = entry.scope  # Local aliases can be "global" (static)
        self.byref = entry.byref
        self.offset = entry.offset
        self.addr = entry.addr

Response: Make this variable an alias of another one.


Instruction:
Create a Python 3 function to
convert a var_instance to a label one

Response:
def to_label(var_instance):
        """ Converts a var_instance to a label one
        """
        # This can be done 'cause LABEL is just a dummy descent of VAR
        assert isinstance(var_instance, SymbolVAR)
        from symbols import LABEL
        var_instance.__class__ = LABEL
        var_instance.class_ = CLASS.label
        var_instance._scope_owner = []
        return var_instance


Instruction:
Create a Python 3 function to
convert a var_instance to a function one

Response:
def to_function(var_instance, lineno=None):
        """ Converts a var_instance to a function one
        """
        assert isinstance(var_instance, SymbolVAR)
        from symbols import FUNCTION
        var_instance.__class__ = FUNCTION
        var_instance.class_ = CLASS.function
        var_instance.reset(lineno=lineno)
        return var_instance


Instruction:
Explain what the following Python 3 code does
def to_vararray(var_instance, bounds):
        assert isinstance(var_instance, SymbolVAR)
        from symbols import BOUNDLIST
        from symbols import VARARRAY
        assert isinstance(bounds, BOUNDLIST)
        var_instance.__class__ = VARARRAY
        var_instance.class_ = CLASS.array
        var_instance.bounds = bounds
        return var_instance

Response: Converts a var_instance to a var array one


Instruction:
How would you explain what the following Python 3 function does
def _paddr(ins):
    output = []

    oper = ins.quad[1]
    indirect = (oper[0] == '*')
    if indirect:
        oper = oper[1:]

    I = int(oper)
    if I >= 0:
        I += 4  # Return Address + "push IX"

    output.append('push ix')
    output.append('pop hl')
    output.append('ld de, %i' % I)
    output.append('add hl, de')

    if indirect:
        output.append('ld e, (hl)')
        output.append('inc hl')
        output.append('ld h, (hl)')
        output.append('ld l, e')

    output.append('push hl')
    return output

Response:
Returns code sequence which points to
    local variable or parameter HL


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _pload(offset, size):
    output = []

    indirect = offset[0] == '*'
    if indirect:
        offset = offset[1:]

    I = int(offset)
    if I >= 0:  # If it is a parameter, round up to even bytes
        I += 4 + (size % 2 if not indirect else 0)  # Return Address + "push IX"

    ix_changed = (indirect or size < 5) and (abs(I) + size) > 127  # Offset > 127 bytes. Need to change IX
    if ix_changed:  # more than 1 byte
        output.append('push ix')
        output.append('ld de, %i' % I)
        output.append('add ix, de')
        I = 0
    elif size == 5:  # For floating point numbers we always use DE as IX offset
        output.append('push ix')
        output.append('pop hl')
        output.append('ld de, %i' % I)
        output.append('add hl, de')
        I = 0

    if indirect:
        output.append('ld h, (ix%+i)' % (I + 1))
        output.append('ld l, (ix%+i)' % I)

        if size == 1:
            output.append('ld a, (hl)')
        elif size == 2:
            output.append('ld c, (hl)')
            output.append('inc hl')
            output.append('ld h, (hl)')
            output.append('ld l, c')
        elif size == 4:
            output.append('call __ILOAD32')
            REQUIRES.add('iload32.asm')
        else:  # Floating point
            output.append('call __ILOADF')
            REQUIRES.add('iloadf.asm')
    else:
        if size == 1:
            output.append('ld a, (ix%+i)' % I)
        else:
            if size <= 4:  # 16/32bit integer, low part
                output.append('ld l, (ix%+i)' % I)
                output.append('ld h, (ix%+i)' % (I + 1))

                if size > 2:  # 32 bit integer, high part
                    output.append('ld e, (ix%+i)' % (I + 2))
                    output.append('ld d, (ix%+i)' % (I + 3))

            else:  # Floating point
                output.append('call __PLOADF')
                REQUIRES.add('ploadf.asm')

    if ix_changed:
        output.append('pop ix')

    return output

Response:
Generic parameter loading.
    Emmits output code for setting IX at the right location.
    size = Number of bytes to load:
        1 => 8 bit value
        2 => 16 bit value / string
        4 => 32 bit value / f16 value
        5 => 40 bit value


Instruction:
Here you have a function in Python 3, explain what it does
def _pload32(ins):
    output = _pload(ins.quad[2], 4)
    output.append('push de')
    output.append('push hl')
    return output

Response: Loads from stack pointer X 2nd parameter.


Instruction:
How would you explain what the following Python 3 function does
def _ploadf(ins):
    output = _pload(ins.quad[2], 5)
    output.extend(_fpush())
    return output

Response: Loads from stack pointer SP + X 2nd parameter.


Instruction:
How would you explain what the following Python 3 function does
def _ploadstr(ins):
    output = _pload(ins.quad[2], 2)
    if ins.quad[1][0] != '$':
        output.append('call __LOADSTR')
        REQUIRES.add('loadstr.asm')

    output.append('push hl')
    return output

Response:
Loads from stack pointer X 2nd parameter X being
    X 2nd operand X being
    X 2nd parameter X being
    X 2nd operand X 2nd operand X


Instruction:
Write a Python 3 function for
loading from stack pointer SP + X 2nd parameter.

Response:
def _fploadstr(ins):
    """ Loads from stack pointer (SP) + X, being
    X 2st parameter.

    1st operand must be a SIGNED integer.
    Unlike ploadstr, this version does not push the result
    back into the stack.
    """
    output = _pload(ins.quad[2], 2)
    if ins.quad[1][0] != '$':
        output.append('call __LOADSTR')
        REQUIRES.add('loadstr.asm')

    return output


Instruction:
Create a Python 3 function to
store 2nd parameter at stack pointer X 1st parameter.

Response:
def _pstore8(ins):
    """ Stores 2nd parameter at stack pointer (SP) + X, being
    X 1st parameter.

    1st operand must be a SIGNED integer.
    """
    value = ins.quad[2]
    offset = ins.quad[1]
    indirect = offset[0] == '*'
    size = 0
    if indirect:
        offset = offset[1:]
        size = 1

    I = int(offset)
    if I >= 0:
        I += 4  # Return Address + "push IX"
        if not indirect:
            I += 1  # F flag ignored

    if is_int(value):
        output = []
    else:
        output = _8bit_oper(value)

    ix_changed = not (-128 + size <= I <= 127 - size)  # Offset > 127 bytes. Need to change IX
    if ix_changed:  # more than 1 byte
        output.append('push ix')
        output.append('pop hl')
        output.append('ld de, %i' % I)
        output.append('add hl, de')

    if indirect:
        if ix_changed:
            output.append('ld c, (hl)')
            output.append('inc hl')
            output.append('ld h, (hl)')
            output.append('ld l, c')
        else:
            output.append('ld h, (ix%+i)' % (I + 1))
            output.append('ld l, (ix%+i)' % I)

        if is_int(value):
            output.append('ld (hl), %i' % int8(value))
        else:
            output.append('ld (hl), a')

        return output

    # direct store
    if ix_changed:
        if is_int(value):
            output.append('ld (hl), %i' % int8(value))
        else:
            output.append('ld (hl), a')

        return output

    if is_int(value):
        output.append('ld (ix%+i), %i' % (I, int8(value)))
    else:
        output.append('ld (ix%+i), a' % I)

    return output


Instruction:
Can you generate the documentation for the following Python 3 function
def _pstore16(ins):
    value = ins.quad[2]
    offset = ins.quad[1]
    indirect = offset[0] == '*'
    size = 1
    if indirect:
        offset = offset[1:]

    I = int(offset)
    if I >= 0:
        I += 4  # Return Address + "push IX"

    if is_int(value):
        output = []
    else:
        output = _16bit_oper(value)

    ix_changed = not (-128 + size <= I <= 127 - size)  # Offset > 127 bytes. Need to change IX

    if indirect:
        if is_int(value):
            output.append('ld hl, %i' % int16(value))

        output.append('ld bc, %i' % I)
        output.append('call __PISTORE16')
        REQUIRES.add('istore16.asm')
        return output

    # direct store
    if ix_changed:  # more than 1 byte
        if not is_int(value):
            output.append('ex de, hl')

        output.append('push ix')
        output.append('pop hl')
        output.append('ld bc, %i' % I)
        output.append('add hl, bc')

        if is_int(value):
            v = int16(value)
            output.append('ld (hl), %i' % (v & 0xFF))
            output.append('inc hl')
            output.append('ld (hl), %i' % (v >> 8))
            return output
        else:
            output.append('ld (hl), e')
            output.append('inc hl')
            output.append('ld (hl), d')
            return output

    if is_int(value):
        v = int16(value)
        output.append('ld (ix%+i), %i' % (I, v & 0xFF))
        output.append('ld (ix%+i), %i' % (I + 1, v >> 8))
    else:
        output.append('ld (ix%+i), l' % I)
        output.append('ld (ix%+i), h' % (I + 1))

    return output

Response: Stores 2nd parameter at stack pointer X 1st parameter.


Instruction:
Write a Python 3 function that can
store 2nd parameter at stack pointer X 1st parameter being X 1st operand must be a SIGNED integer. Returns Address + push IX

Response:
def _pstore32(ins):
    """ Stores 2nd parameter at stack pointer (SP) + X, being
    X 1st parameter.

    1st operand must be a SIGNED integer.
    """
    value = ins.quad[2]
    offset = ins.quad[1]
    indirect = offset[0] == '*'
    if indirect:
        offset = offset[1:]

    I = int(offset)
    if I >= 0:
        I += 4  # Return Address + "push IX"

    output = _32bit_oper(value)

    if indirect:
        output.append('ld bc, %i' % I)
        output.append('call __PISTORE32')
        REQUIRES.add('pistore32.asm')
        return output

    # direct store
    output.append('ld bc, %i' % I)
    output.append('call __PSTORE32')
    REQUIRES.add('pstore32.asm')

    return output


Instruction:
Implement a Python 3 function for
storing 2nd parameter at stack pointer X 1st parameter being X 1st operand must be a SIGNED integer.

Response:
def _pstoref16(ins):
    """ Stores 2nd parameter at stack pointer (SP) + X, being
    X 1st parameter.

    1st operand must be a SIGNED integer.
    """
    value = ins.quad[2]
    offset = ins.quad[1]
    indirect = offset[0] == '*'
    if indirect:
        offset = offset[1:]

    I = int(offset)
    if I >= 0:
        I += 4  # Return Address + "push IX"

    output = _f16_oper(value)

    if indirect:
        output.append('ld bc, %i' % I)
        output.append('call __PISTORE32')
        REQUIRES.add('pistore32.asm')
        return output

    # direct store
    output.append('ld bc, %i' % I)
    output.append('call __PSTORE32')
    REQUIRES.add('pstore32.asm')

    return output


Instruction:
Can you tell what is the following Python 3 function doing
def _pstoref(ins):
    value = ins.quad[2]
    offset = ins.quad[1]
    indirect = offset[0] == '*'
    if indirect:
        offset = offset[1:]

    I = int(offset)
    if I >= 0:
        I += 4  # Return Address + "push IX"

    output = _float_oper(value)

    if indirect:
        output.append('ld hl, %i' % I)
        output.append('call __PISTOREF')
        REQUIRES.add('storef.asm')
        return output

    # direct store
    output.append('ld hl, %i' % I)
    output.append('call __PSTOREF')
    REQUIRES.add('pstoref.asm')

    return output

Response:
Stores 2nd parameter at stack pointer X 1st parameter being
    X 1st operand must be a SIGNED integer.


Instruction:
How would you code a function in Python 3 to
return a list of strings representing the store string.

Response:
def _pstorestr(ins):
    """ Stores 2nd parameter at stack pointer (SP) + X, being
    X 1st parameter.

    1st operand must be a SIGNED integer.

    Note: This procedure proceeds as _pstore16, since STRINGS are 16bit pointers.
    """
    output = []
    temporal = False

    # 2nd operand first, because must go into the stack
    value = ins.quad[2]

    if value[0] == '*':
        value = value[1:]
        indirect = True
    else:
        indirect = False

    if value[0] == '_':
        output.append('ld de, (%s)' % value)

        if indirect:
            output.append('call __LOAD_DE_DE')
            REQUIRES.add('lddede.asm')

    elif value[0] == '#':
        output.append('ld de, %s' % value[1:])
    else:
        output.append('pop de')
        temporal = value[0] != '$'
        if indirect:
            output.append('call __LOAD_DE_DE')
            REQUIRES.add('lddede.asm')

    # Now 1st operand
    value = ins.quad[1]
    if value[0] == '*':
        value = value[1:]
        indirect = True
    else:
        indirect = False

    I = int(value)
    if I >= 0:
        I += 4  # Return Address + "push IX"

    output.append('ld bc, %i' % I)

    if not temporal:
        if indirect:
            output.append('call __PISTORE_STR')
            REQUIRES.add('storestr.asm')
        else:
            output.append('call __PSTORE_STR')
            REQUIRES.add('pstorestr.asm')
    else:
        if indirect:
            output.append('call __PISTORE_STR2')
            REQUIRES.add('storestr2.asm')
        else:
            output.append('call __PSTORE_STR2')
            REQUIRES.add('pstorestr2.asm')

    return output


Instruction:
Implement a function in Python 3 to
create a node for a unary operation.

Response:
def make_node(cls, lineno, operator, operand, func=None, type_=None):
        """ Creates a node for a unary operation. E.g. -x or LEN(a$)

        Parameters:
            -func: lambda function used on constant folding when possible
            -type_: the resulting type (by default, the same as the argument).
                For example, for LEN (str$), result type is 'u16'
                and arg type is 'string'
        """
        assert type_ is None or isinstance(type_, SymbolTYPE)

        if func is not None:  # Try constant-folding
            if is_number(operand):  # e.g. ABS(-5)
                return SymbolNUMBER(func(operand.value), lineno=lineno)
            elif is_string(operand):  # e.g. LEN("a")
                return SymbolSTRING(func(operand.text), lineno=lineno)

        if type_ is None:
            type_ = operand.type_

        if operator == 'MINUS':
            if not type_.is_signed:
                type_ = type_.to_signed()
                operand = SymbolTYPECAST.make_node(type_, operand, lineno)
        elif operator == 'NOT':
            type_ = TYPE.ubyte

        return cls(operator, operand, lineno, type_)


Instruction:
Here you have a function in Python 3, explain what it does
def to_signed(cls, type_):
        if type_ in cls.unsigned:
            return {TYPE.ubyte: TYPE.byte_,
                    TYPE.uinteger: TYPE.integer,
                    TYPE.ulong: TYPE.long_}[type_]
        if type_ in cls.decimals or type_ in cls.signed:
            return type_
        return cls.unknown

Response: Return signed type or equivalent


Instruction:
Given the following Python 3 function, write the documentation
def to_type(cls, typename):
        NAME_TYPES = {cls.TYPE_NAMES[x]: x for x in cls.TYPE_NAMES}
        return NAME_TYPES.get(typename, None)

Response: Converts a type ID to name. On error returns None. On error returns None.


Instruction:
Write a Python 3 function for
returning a floating point operand converted to 32 bits unsigned int.

Response:
def f16(op):
    """ Returns a floating point operand converted to 32 bits unsigned int.
    Negative numbers are returned in 2 complement.

    The result is returned in a tuple (DE, HL) => High16 (Int part), Low16 (Decimal part)
    """
    op = float(op)

    negative = op < 0
    if negative:
        op = -op

    DE = int(op)
    HL = int((op - DE) * 2**16) & 0xFFFF
    DE &= 0xFFFF

    if negative:  # Do C2
        DE ^= 0xFFFF
        HL ^= 0xFFFF

        DEHL = ((DE << 16) | HL) + 1
        HL = DEHL & 0xFFFF
        DE = (DEHL >> 16) & 0xFFFF

    return (DE, HL)