import { CommandInterface } from '../Commands' ; import * as Constants from '../Constants' ; import { Variables } from './Variables' ; import { Variable } from './Variable' ; export class ScalarStruct extends Variable { private _fields : Array < string > ; private _children : Array < Variable > ; constructor ( name = '' , fields = [ ] ) { super ( ) ; this . _name = name ; this . _value = fields . join ( Constants . FIELDS_SEPARATOR ) ; this . _fields = fields ; this . _numberOfChildren = this . _fields . length ; if ( this . _numberOfChildren !== 0 ) { this . _children = new Array < Variable > ( ) ; Variables . addReferenceTo ( this ) ; } } public typename ( ) { return 'scalar struct' ; } public extendedTypename ( ) { return this . typename ( ) ; } public loads ( type ) { return type === this . typename ( ) ; } public createConcreteType ( name , fields ) { return new ScalarStruct ( name , fields ) ; } public loadNew ( name , type , runtime , callback ) { ScalarStruct . getFields ( name , runtime , ( fields ) => { const struct = this . createConcreteType ( name , fields ) ; callback ( struct ) ; } ) ; } public listChildren ( runtime , count , start , callback ) { const self = this ; this . _fields . forEach ( name => { Variables . loadVariable ( name , runtime , ( v ) => { self . _children . push ( v ) ; if ( self . _children . length === self . _numberOfChildren ) { callback ( self . _children . slice ( start , start + count ) ) ; } } ) ; } ) ; } public static setSplitStyle ( splitFieldnamesOctaveStyle ) { if ( splitFieldnamesOctaveStyle ) { ScalarStruct . split = ScalarStruct . splitOctaveStyle ; } else { ScalarStruct . split = ScalarStruct . splitMatlabStyle ; } } private static split : ( value : string ) => string [ ] = ScalarStruct . splitMatlabStyle ; public static getFields ( name , runtime , callback ) { let fieldnames = new Array < string > ( ) ; runtime . evaluateAsLine ( `fieldnames(${ name })` , ( output ) => { const fields = ScalarStruct . split ( output ) ; fields . forEach ( field => { fieldnames . push ( `${ name }.${ field }` ) ; } ) ; callback ( fieldnames ) ; } ) ; } private static readonly CLEAN_REGEX = /^\{\n((?:.*|\s*)*)\n\}$/ ; private static readonly FIELDS_REGEX = /\n?  \[\d+,1\] = / ; private static readonly NON_WORD_REGEX = /\W/ ; private static splitOctaveStyle ( value ) { value = Variables . clean ( value ) ; const match = value . match ( ScalarStruct . CLEAN_REGEX ) ; if ( match !== null && match . length === 2 ) { value = match [ 1 ] ; } const fields = value . split ( ScalarStruct . FIELDS_REGEX ) ; fields . shift ( ) ; for ( let i = 0 ; i !== fields . length ; ++ i ) { const field = fields [ i ] ; if ( field . length === 0 || ScalarStruct . NON_WORD_REGEX . test ( field ) ) { fields [ i ] = `('${ field }')` ; } } return fields ; } private static readonly FIELD_REGEX = /^[a-zA-Z]\w*$/ ; private static splitMatlabStyle ( value ) { value = Variables . clean ( value ) ; const match = value . match ( ScalarStruct . CLEAN_REGEX ) ; if ( match !== null && match . length === 2 ) { value = match [ 1 ] ; } let fields = value . split ( ScalarStruct . FIELDS_REGEX ) ; fields . shift ( ) ; fields = fields . filter ( field => field . length !== 0 && ScalarStruct . FIELD_REGEX . test ( field ) ) ; return fields ; } }