# Path: nesasm/compiler.py
# def lexical(code):
#     return analyse(code, asm65_tokens)
# 
# def syntax(tokens):
#     tokens = list(tokens)
#     ast = []
#     x = 0  # consumed
#     # debug = 0
#     labels = []
#     move = 0
#     while x < len(tokens):
#         if t_label(tokens, x):
#             labels.append(get_value(tokens[x]))
#             x += 1
#         elif t_endline(tokens, x):
#             x += 1
#         else:
#             for bnf in asm65_bnf:
#                 leaf = {}
#                 look_ahead = 0
#                 move = 0
#                 for i in bnf['bnf']:
#                     move = i(tokens, x + look_ahead)
#                     if not move:
#                         break
#                     look_ahead += 1
#                 if move:
#                     if len(labels) > 0:
#                         leaf['labels'] = labels
#                         labels = []
#                     size = 0
#                     look_ahead = 0
#                     for b in bnf['bnf']:
#                         size += b(tokens, x + look_ahead)
#                         look_ahead += 1
#                     leaf['children'] = tokens[x: x + size]
#                     leaf['type'] = bnf['type']
#                     ast.append(leaf)
#                     x += size
#                     break
#             if not move:
#                 # TODO: deal with erros like on nodeNES
#                 # walk = 0
#                 raise Exception('Invalid Syntax')
#                 # rip syntax until the end of the line
# 
#     return ast
# 
# def t_zeropage(tokens, index):
#     lh = look_ahead(tokens, index, 'T_ADDRESS')
#     if lh and len(tokens[index]['value']) == 3:
#         return 1
#     return 0
# 
# def t_address(tokens, index):
#     return look_ahead(tokens, index, 'T_ADDRESS')
# 
# def t_separator(tokens, index):
#     return look_ahead(tokens, index, 'T_SEPARATOR')
# 
# def get_labels(ast, cart=None):
#     labels = {}
#     if cart and len(cart.banks) == 1:
#         address = cart.banks[0]['start']
#     else:
#         address = 0
#     for leaf in ast:
#         if ('S_CONSTANT' == leaf['type']):
#             continue
#         if ('S_DIRECTIVE' == leaf['type']
#                 and '.org' == leaf['children'][0]['value']):
#             address = int(leaf['children'][1]['value'][1:], 16)
#         if 'labels' in leaf:
#             for label in leaf['labels']:
#                 labels[label] = address
#         if leaf['type'] != 'S_DIRECTIVE' and leaf['type'] != 'S_RS':
#             size = address_mode_def[leaf['type']]['size']
#             address += size
#         elif ('S_DIRECTIVE' == leaf['type']
#                 and '.db' == leaf['children'][0]['value']):
#             for i in leaf['children']:
#                 # TODO: better checking here
#                 if 'T_ADDRESS' == i['type'] or 'T_BINARY_NUMBER' == i['type']:
#                     address += 1
#         elif ('S_DIRECTIVE' == leaf['type']
#                 and '.incbin' == leaf['children'][0]['value']):
#             address += 4 * 1024  # TODO check file size;
#     return labels


import unittest
from types import GeneratorType
from nesasm.compiler import (lexical, syntax,
                             t_zeropage, t_address,
                             t_separator, get_labels)
        self.assertEquals('T_INSTRUCTION', tokens[1]['type'])
        self.assertEquals('T_ENDLINE', tokens[2]['type'])
        self.assertEquals('T_INSTRUCTION', tokens[3]['type'])
        self.assertEquals('T_ADDRESS', tokens[4]['type'])
        self.assertEquals('T_ENDLINE', tokens[5]['type'])
        ast = syntax(tokens)
        self.assertEquals(2, len(ast))

    def test_compile_decimal(self):
        code = '''
            LDA #128
            STA $0203
        '''
        tokens = list(lexical(code))
        self.assertEquals(7, len(tokens))
        self.assertEquals('T_ENDLINE', tokens[0]['type'])
        self.assertEquals('T_INSTRUCTION', tokens[1]['type'])
        self.assertEquals('T_DECIMAL_NUMBER', tokens[2]['type'])
        self.assertEquals('T_ENDLINE', tokens[3]['type'])
        self.assertEquals('T_INSTRUCTION', tokens[4]['type'])
        self.assertEquals('T_ADDRESS', tokens[5]['type'])
        self.assertEquals('T_ENDLINE', tokens[6]['type'])

    def test_compile_list(self):
        code = '''
        palette:
          .db $0F,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F
          .db $0F,$30,$31,$32,$33,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$0F
        '''
        tokens = list(lexical(code))

# Path: nesasm/compiler.py
# def lexical(code):
#     return analyse(code, asm65_tokens)
# 
# def syntax(tokens):
#     tokens = list(tokens)
#     ast = []
#     x = 0  # consumed
#     # debug = 0
#     labels = []
#     move = 0
#     while x < len(tokens):
#         if t_label(tokens, x):
#             labels.append(get_value(tokens[x]))
#             x += 1
#         elif t_endline(tokens, x):
#             x += 1
#         else:
#             for bnf in asm65_bnf:
#                 leaf = {}
#                 look_ahead = 0
#                 move = 0
#                 for i in bnf['bnf']:
#                     move = i(tokens, x + look_ahead)
#                     if not move:
#                         break
#                     look_ahead += 1
#                 if move:
#                     if len(labels) > 0:
#                         leaf['labels'] = labels
#                         labels = []
#                     size = 0
#                     look_ahead = 0
#                     for b in bnf['bnf']:
#                         size += b(tokens, x + look_ahead)
#                         look_ahead += 1
#                     leaf['children'] = tokens[x: x + size]
#                     leaf['type'] = bnf['type']
#                     ast.append(leaf)
#                     x += size
#                     break
#             if not move:
#                 # TODO: deal with erros like on nodeNES
#                 # walk = 0
#                 raise Exception('Invalid Syntax')
#                 # rip syntax until the end of the line
# 
#     return ast
# 
# def t_zeropage(tokens, index):
#     lh = look_ahead(tokens, index, 'T_ADDRESS')
#     if lh and len(tokens[index]['value']) == 3:
#         return 1
#     return 0
# 
# def t_address(tokens, index):
#     return look_ahead(tokens, index, 'T_ADDRESS')
# 
# def t_separator(tokens, index):
#     return look_ahead(tokens, index, 'T_SEPARATOR')
# 
# def get_labels(ast, cart=None):
#     labels = {}
#     if cart and len(cart.banks) == 1:
#         address = cart.banks[0]['start']
#     else:
#         address = 0
#     for leaf in ast:
#         if ('S_CONSTANT' == leaf['type']):
#             continue
#         if ('S_DIRECTIVE' == leaf['type']
#                 and '.org' == leaf['children'][0]['value']):
#             address = int(leaf['children'][1]['value'][1:], 16)
#         if 'labels' in leaf:
#             for label in leaf['labels']:
#                 labels[label] = address
#         if leaf['type'] != 'S_DIRECTIVE' and leaf['type'] != 'S_RS':
#             size = address_mode_def[leaf['type']]['size']
#             address += size
#         elif ('S_DIRECTIVE' == leaf['type']
#                 and '.db' == leaf['children'][0]['value']):
#             for i in leaf['children']:
#                 # TODO: better checking here
#                 if 'T_ADDRESS' == i['type'] or 'T_BINARY_NUMBER' == i['type']:
#                     address += 1
#         elif ('S_DIRECTIVE' == leaf['type']
#                 and '.incbin' == leaf['children'][0]['value']):
#             address += 4 * 1024  # TODO check file size;
#     return labels


# Path: nesasm/tests/compiler_test.py
import unittest
from types import GeneratorType
from nesasm.compiler import (lexical, syntax,
                             t_zeropage, t_address,
                             t_separator, get_labels)

        self.assertEquals('T_INSTRUCTION', tokens[1]['type'])
        self.assertEquals('T_ENDLINE', tokens[2]['type'])
        self.assertEquals('T_INSTRUCTION', tokens[3]['type'])
        self.assertEquals('T_ADDRESS', tokens[4]['type'])
        self.assertEquals('T_ENDLINE', tokens[5]['type'])
        ast = syntax(tokens)
        self.assertEquals(2, len(ast))

    def test_compile_decimal(self):
        code = '''
            LDA #128
            STA $0203
        '''
        tokens = list(lexical(code))
        self.assertEquals(7, len(tokens))
        self.assertEquals('T_ENDLINE', tokens[0]['type'])
        self.assertEquals('T_INSTRUCTION', tokens[1]['type'])
        self.assertEquals('T_DECIMAL_NUMBER', tokens[2]['type'])
        self.assertEquals('T_ENDLINE', tokens[3]['type'])
        self.assertEquals('T_INSTRUCTION', tokens[4]['type'])
        self.assertEquals('T_ADDRESS', tokens[5]['type'])
        self.assertEquals('T_ENDLINE', tokens[6]['type'])

    def test_compile_list(self):
        code = '''
        palette:
          .db $0F,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F
          .db $0F,$30,$31,$32,$33,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$0F
        '''
        tokens = list(lexical(code))

        ast = syntax(tokens)