import ECA from '../../../../parsers/w3x/wtg/eca' ; import Parameter from '../../../../parsers/w3x/wtg/parameter' ; import SubParameters from '../../../../parsers/w3x/wtg/subparameters' ; import WeuData from '../data' ; import { convertParameterInline } from '../conversions' ; type WEUTransformerTest = [ number , string ] ; type WEUTransformerOp = [ number , '+' | '-' | '*' | '/' , number ] ; type WEUTransformerParameter = number | string | WEUTransformerOp ; interface WEUTransformerTransformation { test ? : WEUTransformerTest ; tests ? : WEUTransformerTest [ ] ; parameters ? : WEUTransformerParameter [ ] ; } interface WEUTransformerTransformations { [ keyof ] : WEUTransformerTransformation | WEUTransformerTransformation [ ] ; } function runTests ( data , object , args , mapping , convertedParameters ) { const parameters = object . parameters ; const tests = [ ] ; if ( mapping . test ) { tests . push ( mapping . test ) ; } if ( mapping . tests ) { tests . push ( ... mapping . tests ) ; } for ( const [ index , value ] of tests ) { if ( convertedParameters [ index ] === undefined ) { convertedParameters [ index ] = convertParameterInline ( data , parameters [ index ] , args [ index ] ) ; } if ( value !== convertedParameters [ index ] ) { return false ; } } return true ; } function setNameAndType ( data , object , name ) { object . name = name ; object . type = data . triggerData . getFunctionType ( name ) ; if ( object instanceof SubParameters ) { const parameter = < Parameter > data . stack [ 1 ] ; parameter . value = name ; } } function setParameters ( data , object , args , mapping ) { if ( mapping . parameters ) { const parameters = object . parameters ; object . parameters = mapping . parameters . map ( ( value ) => { if ( typeof value === 'number' ) { return parameters [ value ] ; } else if ( typeof value === 'string' ) { const parameter = new Parameter ( ) ; if ( data . triggerData . getPreset ( value ) ) { parameter . type = 0 ; } else { parameter . type = 3 ; } parameter . value = value ; return parameter ; } else { const whichParameter = value [ 0 ] ; const whichOperator = value [ 1 ] ; const operandValue = value [ 2 ] ; const argType = args [ whichParameter ] ; let typedFunction ; let mathOp ; if ( argType === 'integer' ) { typedFunction = 'OperatorInt' ; } else if ( argType === 'real' ) { typedFunction = 'OperatorReal' ; } else { throw new Error ( `Attempted to use an operator on a non-number parameter of type "${ argType }` ) ; } if ( whichOperator === '+' ) { mathOp = 'OperatorAdd' ; } else if ( whichOperator === '-' ) { mathOp = 'OperatorSubtract' ; } else if ( whichOperator === '*' ) { mathOp = 'OperatorMultiply' ; } else { mathOp = 'OperatorDivide' ; } const parameter = new Parameter ( ) ; parameter . value = typedFunction ; parameter . type = 2 ; const subParameters = new SubParameters ( ) ; subParameters . name = typedFunction ; subParameters . type = 3 ; const operandA = parameters [ whichParameter ] ; const operator = new Parameter ( ) ; operator . type = 0 ; operator . value = mathOp ; const operandB = new Parameter ( ) ; operandB . type = 3 ; operandB . value = `${ operandValue }` ; subParameters . beginParameters = 1 ; subParameters . parameters = [ operandA , operator , operandB ] ; parameter . subParameters = subParameters ; return parameter ; } } ) ; } } export default function transformer ( transformations ) { return function ( data , object ) : boolean { const signature = data . triggerData . getFunction ( object . type , object . name ) ; if ( ! signature ) { console . warn ( `transformer failed to get the signature for the input function: ${ object . name }` ) ; return false ; } const args = signature . args ; const convertedParameters = [ ] ; for ( const [ name , mappings ] of Object . entries ( transformations ) ) { let mappingAsArray ; if ( Array . isArray ( mappings ) ) { mappingAsArray = mappings ; } else { mappingAsArray = [ mappings ] ; } for ( const mapping of mappingAsArray ) { if ( runTests ( data , object , args , mapping , convertedParameters ) ) { setNameAndType ( data , object , name ) ; setParameters ( data , object , args , mapping ) ; return true ; } } } return false ; } ; } export type Transformer = ReturnType < typeof transformer > ;