# 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 semantic(ast, iNES=False, cart=None):
#     if cart is None:
#         cart = Cartridge()
#     labels = get_labels(ast, cart)
#     constants = get_constants(ast, cart)
#     address = 0
#     # translate statments to opcode
#     for leaf in ast:
#         if leaf['type'] == 'S_RS':
#             labels[leaf['children'][0]['value']] = cart.rs
#             cart.rs += get_value(leaf['children'][2], labels, constants)
#         elif leaf['type'] == 'S_CONSTANT':
#             pass
#         elif leaf['type'] == 'S_DIRECTIVE':
#             directive = leaf['children'][0]['value']
#             if len(leaf['children']) == 2:
#                 argument = get_value(leaf['children'][1], labels, constants)
#             else:
#                 argument = leaf['children'][1:]
#             if directive in directive_list:
#                 directive_list[directive](argument, cart)
#             else:
#                 raise Exception('UNKNOW DIRECTIVE')
#         else:
#             if leaf['type'] in ['S_IMPLIED', 'S_ACCUMULATOR']:
#                 instruction = leaf['children'][0]['value'].upper()
#                 address = False
#             elif leaf['type'] == 'S_RELATIVE':
#                 instruction = leaf['children'][0]['value'].upper()
#                 address = get_value(leaf['children'][1], labels, constants)
#             elif leaf['type'] == 'S_IMMEDIATE_WITH_MODIFIER':
#                 instruction = leaf['children'][0]['value'].upper()
#                 modifier = leaf['children'][1]['value']
#                 address = get_value(leaf['children'][3], labels, constants)
#                 if modifier == '#LOW':
#                     address = (address & 0x00ff)
#                 elif modifier == '#HIGH':
#                     address = (address & 0xff00) >> 8
#             elif leaf['type'] in ['S_RELATIVE', 'S_IMMEDIATE', 'S_ZEROPAGE',
#                                   'S_ABSOLUTE', 'S_ZEROPAGE_X',
#                                   'S_ZEROPAGE_Y', 'S_ABSOLUTE_X',
#                                   'S_ABSOLUTE_Y']:
#                 instruction = leaf['children'][0]['value'].upper()
#                 address = get_value(leaf['children'][1], labels, constants)
#             elif leaf['type'] in ['S_INDIRECT_X', 'S_INDIRECT_Y']:
#                 instruction = leaf['children'][0]['value'].upper()
#                 address = get_value(leaf['children'][2], labels, constants)
# 
#             address_mode = address_mode_def[leaf['type']]['short']
#             opcode = opcodes[instruction][address_mode]
#             if address_mode != 'sngl' and address_mode != 'acc':
#                 if 'rel' == address_mode:
#                     address = 126 + (address - cart.pc)
#                     if address == 128:
#                         address = 0
#                     elif address < 128:
#                         address = address | 0b10000000
#                     elif address > 128:
#                         address = address & 0b01111111
# 
#                 if address_mode_def[leaf['type']]['size'] == 2:
#                     cart.append_code([opcode, address])
#                 else:
#                     arg1 = (address & 0x00ff)
#                     arg2 = (address & 0xff00) >> 8
#                     cart.append_code([opcode, arg1, arg2])
#             else:
#                 cart.append_code([opcode])
#     # nes_code = []
#     if iNES:
#         return cart.get_ines_code()
#     else:
#         return cart.get_code()


import unittest
from nesasm.compiler import lexical, syntax, semantic
# -*- coding: utf-8 -*-




class StyTest(unittest.TestCase):

    def test_sty_zp(self):
        tokens = list(lexical('STY $00'))
        self.assertEquals(2, len(tokens))
        self.assertEquals('T_INSTRUCTION', tokens[0]['type'])
        self.assertEquals('T_ADDRESS', tokens[1]['type'])
        ast = syntax(tokens)
        self.assertEquals(1, len(ast))
        self.assertEquals('S_ZEROPAGE', ast[0]['type'])
        code = semantic(ast)
        self.assertEquals(code, [0x84, 0x00])

    def test_sty_zpx(self):
        tokens = list(lexical('STY $10,X'))
        self.assertEquals(4, len(tokens))
        self.assertEquals('T_INSTRUCTION', tokens[0]['type'])
        self.assertEquals('T_ADDRESS', tokens[1]['type'])
        self.assertEquals('T_SEPARATOR', tokens[2]['type'])
        self.assertEquals('T_REGISTER', tokens[3]['type'])

# 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 semantic(ast, iNES=False, cart=None):
#     if cart is None:
#         cart = Cartridge()
#     labels = get_labels(ast, cart)
#     constants = get_constants(ast, cart)
#     address = 0
#     # translate statments to opcode
#     for leaf in ast:
#         if leaf['type'] == 'S_RS':
#             labels[leaf['children'][0]['value']] = cart.rs
#             cart.rs += get_value(leaf['children'][2], labels, constants)
#         elif leaf['type'] == 'S_CONSTANT':
#             pass
#         elif leaf['type'] == 'S_DIRECTIVE':
#             directive = leaf['children'][0]['value']
#             if len(leaf['children']) == 2:
#                 argument = get_value(leaf['children'][1], labels, constants)
#             else:
#                 argument = leaf['children'][1:]
#             if directive in directive_list:
#                 directive_list[directive](argument, cart)
#             else:
#                 raise Exception('UNKNOW DIRECTIVE')
#         else:
#             if leaf['type'] in ['S_IMPLIED', 'S_ACCUMULATOR']:
#                 instruction = leaf['children'][0]['value'].upper()
#                 address = False
#             elif leaf['type'] == 'S_RELATIVE':
#                 instruction = leaf['children'][0]['value'].upper()
#                 address = get_value(leaf['children'][1], labels, constants)
#             elif leaf['type'] == 'S_IMMEDIATE_WITH_MODIFIER':
#                 instruction = leaf['children'][0]['value'].upper()
#                 modifier = leaf['children'][1]['value']
#                 address = get_value(leaf['children'][3], labels, constants)
#                 if modifier == '#LOW':
#                     address = (address & 0x00ff)
#                 elif modifier == '#HIGH':
#                     address = (address & 0xff00) >> 8
#             elif leaf['type'] in ['S_RELATIVE', 'S_IMMEDIATE', 'S_ZEROPAGE',
#                                   'S_ABSOLUTE', 'S_ZEROPAGE_X',
#                                   'S_ZEROPAGE_Y', 'S_ABSOLUTE_X',
#                                   'S_ABSOLUTE_Y']:
#                 instruction = leaf['children'][0]['value'].upper()
#                 address = get_value(leaf['children'][1], labels, constants)
#             elif leaf['type'] in ['S_INDIRECT_X', 'S_INDIRECT_Y']:
#                 instruction = leaf['children'][0]['value'].upper()
#                 address = get_value(leaf['children'][2], labels, constants)
# 
#             address_mode = address_mode_def[leaf['type']]['short']
#             opcode = opcodes[instruction][address_mode]
#             if address_mode != 'sngl' and address_mode != 'acc':
#                 if 'rel' == address_mode:
#                     address = 126 + (address - cart.pc)
#                     if address == 128:
#                         address = 0
#                     elif address < 128:
#                         address = address | 0b10000000
#                     elif address > 128:
#                         address = address & 0b01111111
# 
#                 if address_mode_def[leaf['type']]['size'] == 2:
#                     cart.append_code([opcode, address])
#                 else:
#                     arg1 = (address & 0x00ff)
#                     arg2 = (address & 0xff00) >> 8
#                     cart.append_code([opcode, arg1, arg2])
#             else:
#                 cart.append_code([opcode])
#     # nes_code = []
#     if iNES:
#         return cart.get_ines_code()
#     else:
#         return cart.get_code()


# Path: nesasm/tests/sty_test.py
import unittest
from nesasm.compiler import lexical, syntax, semantic

# -*- coding: utf-8 -*-




class StyTest(unittest.TestCase):

    def test_sty_zp(self):
        tokens = list(lexical('STY $00'))
        self.assertEquals(2, len(tokens))
        self.assertEquals('T_INSTRUCTION', tokens[0]['type'])
        self.assertEquals('T_ADDRESS', tokens[1]['type'])
        ast = syntax(tokens)
        self.assertEquals(1, len(ast))
        self.assertEquals('S_ZEROPAGE', ast[0]['type'])
        code = semantic(ast)
        self.assertEquals(code, [0x84, 0x00])

    def test_sty_zpx(self):
        tokens = list(lexical('STY $10,X'))
        self.assertEquals(4, len(tokens))
        self.assertEquals('T_INSTRUCTION', tokens[0]['type'])
        self.assertEquals('T_ADDRESS', tokens[1]['type'])
        self.assertEquals('T_SEPARATOR', tokens[2]['type'])
        self.assertEquals('T_REGISTER', tokens[3]['type'])

        ast = syntax(tokens)