#!/usr/bin/env python
# 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"""

from __future__ import print_function

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')
    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'])
    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'])

    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'])

    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()
