#!/usr/bin/env python3

# Copyright (C) 2016 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:n
#
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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.

# This tool has a couple of helpful macros to process Wasm files from the wasm.json.

from generateWasm import *
import optparse
import sys
import re

parser = optparse.OptionParser(usage="usage: %prog <wasm.json> <WasmOps.h>")
(options, args) = parser.parse_args(sys.argv[0:])
if len(args) != 3:
    parser.error(parser.usage)

wasm = Wasm(args[0], args[1])
opcodes = wasm.opcodes
wasmB3IRGeneratorHFile = open(args[2], "w")

opcodeRegex = re.compile('([a-zA-Z0-9]+)')
argumentRegex = re.compile(r'(\@[0-9]+)')
decimalRegex = re.compile('([-]?[0-9]+)')
whitespaceRegex = re.compile(r'\s+')
commaRegex = re.compile('(,)')
oparenRegex = re.compile(r'(\()')
cparenRegex = re.compile(r'(\))')


class Source:
    def __init__(self, contents, offset=0):
        self.contents = contents
        self.offset = offset


def read(regex, source):
    match = regex.match(source.contents, source.offset)
    if not match:
        return None
    source.offset = match.end()
    return match.group()


def lex(source):
    result = []
    while source.offset != len(source.contents):
        read(whitespaceRegex, source)
        opcode = read(opcodeRegex, source)
        if opcode:
            result.append(opcode)
            continue

        argument = read(argumentRegex, source)
        if argument:
            result.append(argument)
            continue

        number = read(decimalRegex, source)
        if number:
            result.append(int(number))
            continue

        oparen = read(oparenRegex, source)
        if oparen:
            result.append(oparen)
            continue

        cparen = read(cparenRegex, source)
        if cparen:
            result.append(cparen)
            continue

        comma = read(commaRegex, source)
        if comma:
            # Skip commas
            continue

        raise Exception("Lexing Error: could not lex token from: " + source.contents + " at offset: " + str(source.offset) + " (" + source.contents[source.offset:] + "). With tokens: [" + ", ".join(result) + "]")
    return result


class CodeGenerator:
    def __init__(self, tokens):
        self.tokens = tokens
        self.index = 0
        self.code = []

    def advance(self):
        self.index += 1

    def token(self):
        return self.tokens[self.index]

    def parseError(self, string):
        raise Exception("Parse error " + string)

    def consume(self, string):
        if self.token() != string:
            self.parseError("Expected " + string + " but got " + self.token())
        self.advance()

    def generateParameters(self):
        self.advance()
        params = []
        tokens = self.tokens
        while self.index < len(tokens):
            if self.token() == ")":
                self.advance()
                return params
            params.append(self.generateOpcode())
        self.parseError("Parsing arguments fell off end")

    def generateOpcode(self):
        result = None
        if self.token() == "i32" or self.token() == "i64":
            type = "Int32"
            if self.token() == "i64":
                type = "Int64"
            self.advance()
            self.consume("(")
            self.code.append(generateConstCode(self.index, self.token(), type))
            result = temp(self.index)
            self.advance()
            self.consume(")")
        elif argumentRegex.match(self.token()):
            result = "get(arg" + self.token()[1:] + ")"
            self.advance()
        else:
            op = self.token()
            index = self.index
            self.advance()
            params = self.generateParameters()
            self.code.append(generateB3OpCode(index, op, params))
            result = temp(index)

        return result

    def makeResult(self, resultValue):
        return resultValue + ";\n" + "result = push(resultValue->type());\n" + "m_currentBlock->appendNew<VariableValue>(m_proc, Set, origin(), result, resultValue);"

    def generate(self, wasmOp):
        if len(self.tokens) == 1:
            params = ["get(arg" + str(param) + ")" for param in range(len(wasmOp["parameter"]))]
            return self.makeResult("    Value* resultValue = m_currentBlock->appendNew<Value>(m_proc, B3::" + self.token() + ", origin(), " + ", ".join(params) + ")")
        result = self.generateOpcode()
        self.code.append("Value* resultValue = " + result)
        return self.makeResult("    " + "    \n".join(self.code))


def temp(index):
    return "temp" + str(index)


def generateB3OpCode(index, op, params):
    return "Value* " + temp(index) + " = m_currentBlock->appendNew<Value>(m_proc, B3::" + op + ", origin(), " + ", ".join(params) + ");"


def generateConstCode(index, value, type):
    return "Value* " + temp(index) + " = constant(" + type + ", " + value + ");"


def generateB3Code(wasmOp, source):
    tokens = lex(Source(source))
    parser = CodeGenerator(tokens)
    return parser.generate(wasmOp)


def generateSimpleCode(op):
    opcode = op["opcode"]
    b3op = opcode["b3op"]
    args = ["ExpressionType arg" + str(param) for param in range(len(opcode["parameter"]))]
    args.append("ExpressionType& result")
    return """
template<> auto B3IRGenerator::addOp<OpType::""" + wasm.toCpp(op["name"]) + ">(" + ", ".join(args) + """) -> PartialResult
{
""" + generateB3Code(opcode, b3op) + """
    return { };
}
"""


definitions = [generateSimpleCode(op) for op in wasm.opcodeIterator(lambda op: isSimple(op) and (isBinary(op) or isUnary(op)))]
contents = wasm.header + """

#pragma once

#if ENABLE(WEBASSEMBLY)

namespace JSC { namespace Wasm {

""" + "".join(definitions) + """

} } // namespace JSC::Wasm

#endif // ENABLE(WEBASSEMBLY)

"""

wasmB3IRGeneratorHFile.write(contents)
wasmB3IRGeneratorHFile.close()
