#!/usr/bin/env python3
# Copyright (c) 2016 Google Inc.

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generates Vim syntax rules for SPIR-V assembly (.spvasm) files"""

import json

PREAMBLE="""" Vim syntax file
" Language:   spvasm
" Generated by SPIRV-Tools

if version < 600
  syntax clear
elseif exists("b:current_syntax")
  finish
endif

syn case match
"""

POSTAMBLE="""

syntax keyword spvasmTodo TODO FIXME contained

syn match   spvasmIdNumber /%\d\+\>/

" The assembler treats the leading minus sign as part of the number token.
" This applies to integers, and to floats below.
syn match   spvasmNumber /-\?\<\d\+\>/

" Floating point literals.
" In general, C++ requires at least digit in the mantissa, and the
" floating point is optional.  This applies to both the regular decimal float
" case and the hex float case.

" First case: digits before the optional decimal, no trailing digits.
syn match   spvasmFloat  /-\?\d\+\.\?\(e[+-]\d\+\)\?/
" Second case: optional digits before decimal, trailing digits
syn match   spvasmFloat  /-\?\d*\.\d\+\(e[+-]\d\+\)\?/

" First case: hex digits before the optional decimal, no trailing hex digits.
syn match   spvasmFloat  /-\?0[xX]\\x\+\.\?p[-+]\d\+/
" Second case: optional hex digits before decimal, trailing hex digits
syn match   spvasmFloat  /-\?0[xX]\\x*\.\\x\+p[-+]\d\+/

syn match   spvasmComment /;.*$/ contains=spvasmTodo
syn region  spvasmString start=/"/ skip=/\\\\"/ end=/"/
syn match   spvasmId /%[a-zA-Z_][a-zA-Z_0-9]*/

" Highlight unknown constants and statements as errors
syn match   spvasmError /[a-zA-Z][a-zA-Z_0-9]*/


if version >= 508 || !exists("did_c_syn_inits")
  if version < 508
    let did_c_syn_inits = 1
    command -nargs=+ HiLink hi link <args>
  else
    command -nargs=+ HiLink hi def link <args>
  endif

  HiLink spvasmStatement Statement
  HiLink spvasmNumber Number
  HiLink spvasmComment Comment
  HiLink spvasmString String
  HiLink spvasmFloat Float
  HiLink spvasmConstant Constant
  HiLink spvasmIdNumber Identifier
  HiLink spvasmId Identifier
  HiLink spvasmTodo Todo

  delcommand HiLink
endif

let b:current_syntax = "spvasm"
"""

# This list is taken from the description of OpSpecConstantOp in SPIR-V 1.1.
# TODO(dneto): Propose that this information be embedded in the grammar file.
SPEC_CONSTANT_OP_OPCODES = """
        OpSConvert, OpFConvert
        OpSNegate, OpNot
        OpIAdd, OpISub
        OpIMul, OpUDiv, OpSDiv, OpUMod, OpSRem, OpSMod
        OpShiftRightLogical, OpShiftRightArithmetic, OpShiftLeftLogical
        OpBitwiseOr, OpBitwiseXor, OpBitwiseAnd
        OpVectorShuffle, OpCompositeExtract, OpCompositeInsert
        OpLogicalOr, OpLogicalAnd, OpLogicalNot,
        OpLogicalEqual, OpLogicalNotEqual
        OpSelect
        OpIEqual, OpINotEqual
        OpULessThan, OpSLessThan
        OpUGreaterThan, OpSGreaterThan
        OpULessThanEqual, OpSLessThanEqual
        OpUGreaterThanEqual, OpSGreaterThanEqual

        OpQuantizeToF16

        OpConvertFToS, OpConvertSToF
        OpConvertFToU, OpConvertUToF
        OpUConvert
        OpConvertPtrToU, OpConvertUToPtr
        OpGenericCastToPtr, OpPtrCastToGeneric
        OpBitcast
        OpFNegate
        OpFAdd, OpFSub
        OpFMul, OpFDiv
        OpFRem, OpFMod
        OpAccessChain, OpInBoundsAccessChain
        OpPtrAccessChain, OpInBoundsPtrAccessChain"""


def EmitAsStatement(name):
    """Emits the given name as a statement token"""
    print('syn keyword spvasmStatement', name)


def EmitAsEnumerant(name):
    """Emits the given name as an named operand token"""
    print('syn keyword spvasmConstant', name)


def main():
    """Parses arguments, then generates the Vim syntax rules for SPIR-V assembly
    on stdout."""
    import argparse
    parser = argparse.ArgumentParser(description='Generate SPIR-V info tables')
    parser.add_argument('--spirv-core-grammar', metavar='<path>',
                        type=str, required=True,
                        help='input JSON grammar file for core SPIR-V '
                        'instructions')
    parser.add_argument('--extinst-glsl-grammar', metavar='<path>',
                        type=str, required=False, default=None,
                        help='input JSON grammar file for GLSL extended '
                        'instruction set')
    parser.add_argument('--extinst-opencl-grammar', metavar='<path>',
                        type=str, required=False, default=None,
                        help='input JSON grammar file for OpenGL extended '
                        'instruction set')
    parser.add_argument('--extinst-debuginfo-grammar', metavar='<path>',
                        type=str, required=False, default=None,
                        help='input JSON grammar file for DebugInfo extended '
                        'instruction set')
    args = parser.parse_args()

    # Generate the syntax rules.
    print(PREAMBLE)

    core = json.loads(open(args.spirv_core_grammar).read())
    print('\n" Core instructions')
    for inst in core["instructions"]:
        EmitAsStatement(inst['opname'])
        aliases = inst.get('aliases', [])
        for alias in aliases:
            EmitAsStatement(alias)
    print('\n" Core operand enums')
    for operand_kind in core["operand_kinds"]:
        if 'enumerants' in operand_kind:
            for e in operand_kind['enumerants']:
                EmitAsEnumerant(e['enumerant'])
                aliases = e.get('aliases', [])
                for a in aliases:
                    EmitAsEnumerant(a)

    if args.extinst_glsl_grammar is not None:
        print('\n" GLSL.std.450 extended instructions')
        glsl = json.loads(open(args.extinst_glsl_grammar).read())
        # These opcodes are really enumerant operands for the OpExtInst
        # instruction.
        for inst in glsl["instructions"]:
            EmitAsEnumerant(inst['opname'])

    if args.extinst_opencl_grammar is not None:
        print('\n" OpenCL.std extended instructions')
        opencl = json.loads(open(args.extinst_opencl_grammar).read())
        for inst in opencl["instructions"]:
            EmitAsEnumerant(inst['opname'])

    if args.extinst_debuginfo_grammar is not None:
        print('\n" DebugInfo extended instructions')
        debuginfo = json.loads(open(args.extinst_debuginfo_grammar).read())
        for inst in debuginfo["instructions"]:
            EmitAsEnumerant(inst['opname'])
        print('\n" DebugInfo operand enums')
        for operand_kind in debuginfo["operand_kinds"]:
            if 'enumerants' in operand_kind:
                for e in operand_kind['enumerants']:
                    EmitAsEnumerant(e['enumerant'])

    print('\n" OpSpecConstantOp opcodes')
    for word in SPEC_CONSTANT_OP_OPCODES.split(' '):
        stripped = word.strip('\n,')
        if stripped != "":
            # Treat as an enumerant, but without the leading "Op"
            EmitAsEnumerant(stripped[2:])
    print(POSTAMBLE)


if __name__ == '__main__':
    main()
