# 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().__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().__init__()
        self.mnemonic = ""
        self.labels = []
        self.is_microop = True

class Directive(Statement):
    def __init__(self):
        super().__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
