# Copyright (c) 2003-2005 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os
import sys
import re
import traceback
# get type names
from types import *

from ply import lex
from ply import yacc

##########################################################################
#
# Base classes for use outside of the assembler
#
##########################################################################

class Micro_Container(object):
    def __init__(self, name):
        self.microops = []
        self.name = name
        self.directives = {}
        self.micro_classes = {}
        self.labels = {}

    def add_microop(self, mnemonic, microop):
        self.microops.append(microop)

    def __str__(self):
        string = "%s:\n" % self.name
        for microop in self.microops:
            string += "  %s\n" % microop
        return string

class Combinational_Macroop(Micro_Container):
    pass

class Rom_Macroop(object):
    def __init__(self, name, target):
        self.name = name
        self.target = target

    def __str__(self):
        return "%s: %s\n" % (self.name, self.target)

class Rom(Micro_Container):
    def __init__(self, name):
        super(Rom, self).__init__(name)
        self.externs = {}

##########################################################################
#
# Support classes
#
##########################################################################

class Label(object):
    def __init__(self):
        self.extern = False
        self.name = ""

class Block(object):
    def __init__(self):
        self.statements = []

class Statement(object):
    def __init__(self):
        self.is_microop = False
        self.is_directive = False
        self.params = ""

class Microop(Statement):
    def __init__(self):
        super(Microop, self).__init__()
        self.mnemonic = ""
        self.labels = []
        self.is_microop = True

class Directive(Statement):
    def __init__(self):
        super(Directive, self).__init__()
        self.name = ""
        self.is_directive = True

##########################################################################
#
# Functions that handle common tasks
#
##########################################################################

def print_error(message):
    print()
    print("*** %s" % message)
    print()

def handle_statement(parser, container, statement):
    if statement.is_microop:
        if statement.mnemonic not in parser.microops.keys():
            raise Exception("Unrecognized mnemonic: {}".format(
                statement.mnemonic))
        parser.symbols["__microopClassFromInsideTheAssembler"] = \
            parser.microops[statement.mnemonic]
        try:
            microop = eval('__microopClassFromInsideTheAssembler(%s)' %
                    statement.params, {}, parser.symbols)
        except:
            print_error("Error creating microop object with mnemonic %s." % \
                    statement.mnemonic)
            raise
        try:
            for label in statement.labels:
                container.labels[label.text] = microop
                if label.is_extern:
                    container.externs[label.text] = microop
            container.add_microop(statement.mnemonic, microop)
        except:
            print_error("Error adding microop.")
            raise
    elif statement.is_directive:
        if statement.name not in container.directives.keys():
            raise Exception("Unrecognized directive: {}".format(
                statement.name))
        parser.symbols["__directiveFunctionFromInsideTheAssembler"] = \
            container.directives[statement.name]
        try:
            eval('__directiveFunctionFromInsideTheAssembler(%s)' %
                    statement.params, {}, parser.symbols)
        except:
            print_error("Error executing directive.")
            print(container.directives)
            raise
    else:
        raise Exception("Didn't recognize the type of statement {}".format(
            statement))

##########################################################################
#
# Lexer specification
#
##########################################################################

# Error handler.  Just call exit.  Output formatted to work under
# Emacs compile-mode.  Optional 'print_traceback' arg, if set to True,
# prints a Python stack backtrace too (can be handy when trying to
# debug the parser itself).
def error(lineno, string, print_traceback = False):
    # Print a Python stack backtrace if requested.
    if (print_traceback):
        traceback.print_exc()
    if lineno != 0:
        line_str = "%d:" % lineno
    else:
        line_str = ""
    sys.exit("%s %s" % (line_str, string))

reserved = ('DEF', 'MACROOP', 'ROM', 'EXTERN')

tokens = reserved + (
        # identifier
        'ID',
        # arguments for microops and directives
        'PARAMS',

        'LPAREN', 'RPAREN',
        'LBRACE', 'RBRACE',
        'COLON', 'SEMI', 'DOT',
        'NEWLINE'
        )

# New lines are ignored at the top level, but they end statements in the
# assembler
states = (
    ('asm', 'exclusive'),
    ('params', 'exclusive'),
)

reserved_map = { }
for r in reserved:
    reserved_map[r.lower()] = r

# Ignore comments
def t_ANY_COMMENT(t):
    r'\#[^\n]*(?=\n)'

def t_ANY_MULTILINECOMMENT(t):
    r'/\*([^/]|((?<!\*)/))*\*/'

# A colon marks the end of a label. It should follow an ID which will
# put the lexer in the "params" state. Seeing the colon will put it back
# in the "asm" state since it knows it saw a label and not a mnemonic.
def t_params_COLON(t):
    r':'
    t.lexer.begin('asm')
    return t

# Parameters are a string of text which don't contain an unescaped statement
# statement terminator, ie a newline or semi colon.
def t_params_PARAMS(t):
    r'([^\n;\\]|(\\[\n;\\]))+'
    t.lineno += t.value.count('\n')
    unescapeParamsRE = re.compile(r'(\\[\n;\\])')
    def unescapeParams(mo):
        val = mo.group(0)
        return val[1]
    t.value = unescapeParamsRE.sub(unescapeParams, t.value)
    t.lexer.begin('asm')
    return t

# An "ID" in the micro assembler is either a label, directive, or mnemonic
# If it's either a directive or a mnemonic, it will be optionally followed by
# parameters. If it's a label, the following colon will make the lexer stop
# looking for parameters.
def t_asm_ID(t):
    r'[A-Za-z_]\w*'
    t.type = reserved_map.get(t.value, 'ID')
    # If the ID is really "extern", we shouldn't start looking for parameters
    # yet. The real ID, the label itself, is coming up.
    if t.type != 'EXTERN':
        t.lexer.begin('params')
    return t

# If there is a label and you're -not- in the assembler (which would be caught
# above), don't start looking for parameters.
def t_ANY_ID(t):
    r'[A-Za-z_]\w*'
    t.type = reserved_map.get(t.value, 'ID')
    return t

# Braces enter and exit micro assembly
def t_INITIAL_LBRACE(t):
    r'\{'
    t.lexer.begin('asm')
    return t

def t_asm_RBRACE(t):
    r'\}'
    t.lexer.begin('INITIAL')
    return t

# At the top level, keep track of newlines only for line counting.
def t_INITIAL_NEWLINE(t):
    r'\n+'
    t.lineno += t.value.count('\n')

# In the micro assembler, do line counting but also return a token. The
# token is needed by the parser to detect the end of a statement.
def t_asm_NEWLINE(t):
    r'\n+'
    t.lineno += t.value.count('\n')
    return t

# A newline or semi colon when looking for params signals that the statement
# is over and the lexer should go back to looking for regular assembly.
def t_params_NEWLINE(t):
    r'\n+'
    t.lineno += t.value.count('\n')
    t.lexer.begin('asm')
    return t

def t_params_SEMI(t):
    r';'
    t.lexer.begin('asm')
    return t

# Basic regular expressions to pick out simple tokens
t_ANY_LPAREN = r'\('
t_ANY_RPAREN = r'\)'
t_ANY_SEMI   = r';'
t_ANY_DOT    = r'\.'

t_ANY_ignore = ' \t\x0c'

def t_ANY_error(t):
    error(t.lineno, "illegal character '%s'" % t.value[0])
    t.skip(1)

##########################################################################
#
# Parser specification
#
##########################################################################

# Start symbol for a file which may have more than one macroop or rom
# specification.
def p_file(t):
    'file : opt_rom_or_macros'

def p_opt_rom_or_macros_0(t):
    'opt_rom_or_macros : '

def p_opt_rom_or_macros_1(t):
    'opt_rom_or_macros : rom_or_macros'

def p_rom_or_macros_0(t):
    'rom_or_macros : rom_or_macro'

def p_rom_or_macros_1(t):
    'rom_or_macros : rom_or_macros rom_or_macro'

def p_rom_or_macro_0(t):
    '''rom_or_macro : rom_block
                    | macroop_def'''

# Defines a section of microcode that should go in the current ROM
def p_rom_block(t):
    'rom_block : DEF ROM block SEMI'
    if not t.parser.rom:
        print_error("Rom block found, but no Rom object specified.")
        raise TypeError("Rom block found, but no Rom object was specified.")
    for statement in t[3].statements:
        handle_statement(t.parser, t.parser.rom, statement)
    t[0] = t.parser.rom

# Defines a macroop that jumps to an external label in the ROM
def p_macroop_def_0(t):
    'macroop_def : DEF MACROOP ID LPAREN ID RPAREN SEMI'
    if not t.parser.rom_macroop_type:
        print_error("ROM based macroop found, but no ROM macroop " +
            "class was specified.")
        raise TypeError("ROM based macroop found, but no ROM macroop " +
            "class was specified.")
    macroop = t.parser.rom_macroop_type(t[3], t[5])
    t.parser.macroops[t[3]] = macroop


# Defines a macroop that is combinationally generated
def p_macroop_def_1(t):
    'macroop_def : DEF MACROOP ID block SEMI'
    try:
        curop = t.parser.macro_type(t[3])
    except TypeError:
        print_error("Error creating macroop object.")
        raise
    for statement in t[4].statements:
        handle_statement(t.parser, curop, statement)
    t.parser.macroops[t[3]] = curop

# A block of statements
def p_block(t):
    'block : LBRACE statements RBRACE'
    block = Block()
    block.statements = t[2]
    t[0] = block

def p_statements_0(t):
    'statements : statement'
    if t[1]:
        t[0] = [t[1]]
    else:
        t[0] = []

def p_statements_1(t):
    'statements : statements statement'
    if t[2]:
        t[1].append(t[2])
    t[0] = t[1]

def p_statement(t):
    'statement : content_of_statement end_of_statement'
    t[0] = t[1]

# A statement can be a microop or an assembler directive
def p_content_of_statement_0(t):
    '''content_of_statement : microop
                            | directive'''
    t[0] = t[1]

# Ignore empty statements
def p_content_of_statement_1(t):
    'content_of_statement : '
    pass

# Statements are ended by newlines or a semi colon
def p_end_of_statement(t):
    '''end_of_statement : NEWLINE
                        | SEMI'''
    pass

# Different flavors of microop to avoid shift/reduce errors
def p_microop_0(t):
    'microop : labels ID'
    microop = Microop()
    microop.labels = t[1]
    microop.mnemonic = t[2]
    t[0] = microop

def p_microop_1(t):
    'microop : ID'
    microop = Microop()
    microop.mnemonic = t[1]
    t[0] = microop

def p_microop_2(t):
    'microop : labels ID PARAMS'
    microop = Microop()
    microop.labels = t[1]
    microop.mnemonic = t[2]
    microop.params = t[3]
    t[0] = microop

def p_microop_3(t):
    'microop : ID PARAMS'
    microop = Microop()
    microop.mnemonic = t[1]
    microop.params = t[2]
    t[0] = microop

# Labels in the microcode
def p_labels_0(t):
    'labels : label'
    t[0] = [t[1]]

def p_labels_1(t):
    'labels : labels label'
    t[1].append(t[2])
    t[0] = t[1]

# labels on lines by themselves are attached to the following instruction.
def p_labels_2(t):
    'labels : labels NEWLINE'
    t[0] = t[1]

def p_label_0(t):
    'label : ID COLON'
    label = Label()
    label.is_extern = False
    label.text = t[1]
    t[0] = label

def p_label_1(t):
    'label : EXTERN ID COLON'
    label = Label()
    label.is_extern = True
    label.text = t[2]
    t[0] = label

# Directives for the macroop
def p_directive_0(t):
    'directive : DOT ID'
    directive = Directive()
    directive.name = t[2]
    t[0] = directive

def p_directive_1(t):
    'directive : DOT ID PARAMS'
    directive = Directive()
    directive.name = t[2]
    directive.params = t[3]
    t[0] = directive

# Parse error handler.  Note that the argument here is the offending
# *token*, not a grammar symbol (hence the need to use t.value)
def p_error(t):
    if t:
        error(t.lineno, "syntax error at '%s'" % t.value)
    else:
        error(0, "unknown syntax error", True)

class MicroAssembler(object):

    def __init__(self, macro_type, microops,
            rom = None, rom_macroop_type = None):
        self.lexer = lex.lex()
        self.parser = yacc.yacc()
        self.parser.macro_type = macro_type
        self.parser.macroops = {}
        self.parser.microops = microops
        self.parser.rom = rom
        self.parser.rom_macroop_type = rom_macroop_type
        self.parser.symbols = {}
        self.symbols = self.parser.symbols

    def assemble(self, asm):
        self.parser.parse(asm, lexer=self.lexer)
        macroops = self.parser.macroops
        self.parser.macroops = {}
        return macroops
