Skip to content
Snippets Groups Projects
Commit 693a3f5f authored by David Sehnal's avatar David Sehnal
Browse files

wip mol-script, execute parsed/transpiled query

parent 6e17f5bb
No related branches found
No related tags found
No related merge requests found
...@@ -8,12 +8,6 @@ import Expression from './expression' ...@@ -8,12 +8,6 @@ import Expression from './expression'
const { isLiteral, isSymbol, isArgumentsArray } = Expression; const { isLiteral, isSymbol, isArgumentsArray } = Expression;
export default function format(e: Expression) {
const writer = new Writer();
_format(e, writer);
return writer.getStr();
}
class Writer { class Writer {
private value: string[] = []; private value: string[] = [];
private currentLineLength = 0; private currentLineLength = 0;
...@@ -128,4 +122,10 @@ function _format(e: Expression, writer: Writer) { ...@@ -128,4 +122,10 @@ function _format(e: Expression, writer: Writer) {
_format(e.args[a], writer); _format(e.args[a], writer);
} }
writer.pop(); writer.pop();
} }
\ No newline at end of file
export function formatMolScript(e: Expression) {
const writer = new Writer();
_format(e, writer);
return writer.getStr();
}
...@@ -20,7 +20,7 @@ namespace Expression { ...@@ -20,7 +20,7 @@ namespace Expression {
export function isArgumentsArray(e?: Arguments): e is Expression[] { return !!e && Array.isArray(e); } export function isArgumentsArray(e?: Arguments): e is Expression[] { return !!e && Array.isArray(e); }
export function isArgumentsMap(e?: Arguments): e is { [name: string]: Expression } { return !!e && !Array.isArray(e); } export function isArgumentsMap(e?: Arguments): e is { [name: string]: Expression } { return !!e && !Array.isArray(e); }
export function isLiteral(e: Expression): e is Expression.Literal { return !isApply(e); } export function isLiteral(e: Expression): e is Expression.Literal { return !isApply(e) && !isSymbol(e); }
export function isApply(e: Expression): e is Expression.Apply { return !!e && !!(e as Expression.Apply).head && typeof e === 'object'; } export function isApply(e: Expression): e is Expression.Apply { return !!e && !!(e as Expression.Apply).head && typeof e === 'object'; }
export function isSymbol(e: Expression): e is Expression.Symbol { return !!e && typeof (e as any).name === 'string' } export function isSymbol(e: Expression): e is Expression.Symbol { return !!e && typeof (e as any).name === 'string' }
} }
......
...@@ -134,8 +134,10 @@ function _compile(ctx: QueryCompilerCtx, expression: Expression): CompiledQueryF ...@@ -134,8 +134,10 @@ function _compile(ctx: QueryCompilerCtx, expression: Expression): CompiledQueryF
} }
if (Expression.isSymbol(expression)) { if (Expression.isSymbol(expression)) {
// TODO: check for "nullary symbols" and automatically apply them? const runtime = ctx.table.getRuntime(expression.name);
return CompiledQueryFn.Const(expression.name); if (!runtime) return CompiledQueryFn.Const(expression.name);
return runtime.compile(ctx);
} }
if (!Expression.isSymbol(expression.head)) { if (!Expression.isSymbol(expression.head)) {
...@@ -143,7 +145,6 @@ function _compile(ctx: QueryCompilerCtx, expression: Expression): CompiledQueryF ...@@ -143,7 +145,6 @@ function _compile(ctx: QueryCompilerCtx, expression: Expression): CompiledQueryF
} }
const compiler = ctx.table.getRuntime(expression.head.name); const compiler = ctx.table.getRuntime(expression.head.name);
if (!compiler) { if (!compiler) {
throw new Error(`Symbol '${expression.head.name}' is not implemented.`); throw new Error(`Symbol '${expression.head.name}' is not implemented.`);
} }
......
// /** /**
// * Copyright (c) 2018 Mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2018 Mol* contributors, licensed under MIT, See LICENSE file for more info.
// * *
// * @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
// */ */
// import { MSymbol, Arguments, Argument } from '../../language/symbol' import { MSymbol, Arguments, Argument } from '../../language/symbol'
// import B from '../../language/builder' import { MolScriptBuilder as B } from '../../language/builder'
// import * as M from './macro' //import * as M from './macro'
// import { MolScriptSymbolTable as MolScript } from '../../language/symbol-table' import { MolScriptSymbolTable as MolScript } from '../../language/symbol-table'
// import Type from '../../language/type' import Type from '../../language/type'
// import * as Struct from '../../language/symbol-table/structure-query' import * as Struct from '../../language/symbol-table/structure-query'
// import Expression from '../../language/expression' import Expression from '../../language/expression'
// import { UniqueArray } from 'mol-data/generic' import { UniqueArray } from 'mol-data/generic'
// export type MolScriptSymbol = export type MolScriptSymbol =
// | { kind: 'alias', aliases: string[], symbol: MSymbol } | { kind: 'alias', aliases: string[], symbol: MSymbol }
// | { kind: 'macro', aliases: string[], symbol: MSymbol, translate: (args: any) => Expression } | { kind: 'macro', aliases: string[], symbol: MSymbol, translate: (args: any) => Expression }
// function Alias(symbol: MSymbol<any>, ...aliases: string[]): MolScriptSymbol { return { kind: 'alias', aliases, symbol }; } function Alias(symbol: MSymbol<any>, ...aliases: string[]): MolScriptSymbol { return { kind: 'alias', aliases, symbol }; }
// function Macro(symbol: MSymbol<any>, translate: (args: any) => Expression, ...aliases: string[]): MolScriptSymbol { // function Macro(symbol: MSymbol<any>, translate: (args: any) => Expression, ...aliases: string[]): MolScriptSymbol {
// symbol.info.namespace = 'molscript-macro'; // symbol.info.namespace = 'molscript-macro';
// symbol.id = `molscript-macro.${symbol.info.name}`; // symbol.id = `molscript-macro.${symbol.info.name}`;
// return { kind: 'macro', symbol, translate, aliases: [symbol.info.name, ...aliases] }; // return { kind: 'macro', symbol, translate, aliases: [symbol.info.name, ...aliases] };
// } // }
// export function isMolScriptSymbol(x: any): x is MolScriptSymbol { export function isMolScriptSymbol(x: any): x is MolScriptSymbol {
// return x.kind === 'alias' || x.kind === 'macro'; return x.kind === 'alias' || x.kind === 'macro';
// } }
// export const SymbolTable = [ export const SymbolTable = [
// [ [
// 'Core symbols', 'Core symbols',
// Alias(MolScript.core.type.bool, 'bool'), Alias(MolScript.core.type.bool, 'bool'),
// Alias(MolScript.core.type.num, 'num'), Alias(MolScript.core.type.num, 'num'),
// Alias(MolScript.core.type.str, 'str'), Alias(MolScript.core.type.str, 'str'),
// Alias(MolScript.core.type.regex, 'regex'), Alias(MolScript.core.type.regex, 'regex'),
// Alias(MolScript.core.type.list, 'list'), Alias(MolScript.core.type.list, 'list'),
// Alias(MolScript.core.type.set, 'set'), Alias(MolScript.core.type.set, 'set'),
// Alias(MolScript.core.type.compositeKey, 'composite-key'), Alias(MolScript.core.type.compositeKey, 'composite-key'),
// Alias(MolScript.core.logic.not, 'not'), Alias(MolScript.core.logic.not, 'not'),
// Alias(MolScript.core.logic.and, 'and'), Alias(MolScript.core.logic.and, 'and'),
// Alias(MolScript.core.logic.or, 'or'), Alias(MolScript.core.logic.or, 'or'),
// Alias(MolScript.core.ctrl.if, 'if'), Alias(MolScript.core.ctrl.if, 'if'),
// Alias(MolScript.core.ctrl.fn, 'fn'), Alias(MolScript.core.ctrl.fn, 'fn'),
// Alias(MolScript.core.ctrl.eval, 'eval'), Alias(MolScript.core.ctrl.eval, 'eval'),
// Alias(MolScript.core.math.add, 'add', '+'), Alias(MolScript.core.math.add, 'add', '+'),
// Alias(MolScript.core.math.sub, 'sub', '-'), Alias(MolScript.core.math.sub, 'sub', '-'),
// Alias(MolScript.core.math.mult, 'mult', '*'), Alias(MolScript.core.math.mult, 'mult', '*'),
// Alias(MolScript.core.math.div, 'div', '/'), Alias(MolScript.core.math.div, 'div', '/'),
// Alias(MolScript.core.math.pow, 'pow', '**'), Alias(MolScript.core.math.pow, 'pow', '**'),
// Alias(MolScript.core.math.mod, 'mod'), Alias(MolScript.core.math.mod, 'mod'),
// Alias(MolScript.core.math.min, 'min'), Alias(MolScript.core.math.min, 'min'),
// Alias(MolScript.core.math.max, 'max'), Alias(MolScript.core.math.max, 'max'),
// Alias(MolScript.core.math.floor, 'floor'), Alias(MolScript.core.math.floor, 'floor'),
// Alias(MolScript.core.math.ceil, 'ceil'), Alias(MolScript.core.math.ceil, 'ceil'),
// Alias(MolScript.core.math.roundInt, 'round'), Alias(MolScript.core.math.roundInt, 'round'),
// Alias(MolScript.core.math.abs, 'abs'), Alias(MolScript.core.math.abs, 'abs'),
// Alias(MolScript.core.math.sqrt, 'sqrt'), Alias(MolScript.core.math.sqrt, 'sqrt'),
// Alias(MolScript.core.math.sin, 'sin'), Alias(MolScript.core.math.sin, 'sin'),
// Alias(MolScript.core.math.cos, 'cos'), Alias(MolScript.core.math.cos, 'cos'),
// Alias(MolScript.core.math.tan, 'tan'), Alias(MolScript.core.math.tan, 'tan'),
// Alias(MolScript.core.math.asin, 'asin'), Alias(MolScript.core.math.asin, 'asin'),
// Alias(MolScript.core.math.acos, 'acos'), Alias(MolScript.core.math.acos, 'acos'),
// Alias(MolScript.core.math.atan, 'atan'), Alias(MolScript.core.math.atan, 'atan'),
// Alias(MolScript.core.math.sinh, 'sinh'), Alias(MolScript.core.math.sinh, 'sinh'),
// Alias(MolScript.core.math.cosh, 'cosh'), Alias(MolScript.core.math.cosh, 'cosh'),
// Alias(MolScript.core.math.tanh, 'tanh'), Alias(MolScript.core.math.tanh, 'tanh'),
// Alias(MolScript.core.math.exp, 'exp'), Alias(MolScript.core.math.exp, 'exp'),
// Alias(MolScript.core.math.log, 'log'), Alias(MolScript.core.math.log, 'log'),
// Alias(MolScript.core.math.log10, 'log10'), Alias(MolScript.core.math.log10, 'log10'),
// Alias(MolScript.core.math.atan2, 'atan2'), Alias(MolScript.core.math.atan2, 'atan2'),
// Alias(MolScript.core.rel.eq, 'eq', '='), Alias(MolScript.core.rel.eq, 'eq', '='),
// Alias(MolScript.core.rel.neq, 'neq', '!='), Alias(MolScript.core.rel.neq, 'neq', '!='),
// Alias(MolScript.core.rel.lt, 'lt', '<'), Alias(MolScript.core.rel.lt, 'lt', '<'),
// Alias(MolScript.core.rel.lte, 'lte', '<='), Alias(MolScript.core.rel.lte, 'lte', '<='),
// Alias(MolScript.core.rel.gr, 'gr', '>'), Alias(MolScript.core.rel.gr, 'gr', '>'),
// Alias(MolScript.core.rel.gre, 'gre', '>='), Alias(MolScript.core.rel.gre, 'gre', '>='),
// Alias(MolScript.core.rel.inRange, 'in-range'), Alias(MolScript.core.rel.inRange, 'in-range'),
// Alias(MolScript.core.str.concat, 'concat'), Alias(MolScript.core.str.concat, 'concat'),
// Alias(MolScript.core.str.match, 'regex.match'), Alias(MolScript.core.str.match, 'regex.match'),
// Alias(MolScript.core.list.getAt, 'list.get'), Alias(MolScript.core.list.getAt, 'list.get'),
// Alias(MolScript.core.set.has, 'set.has'), Alias(MolScript.core.set.has, 'set.has'),
// Alias(MolScript.core.set.isSubset, 'set.subset'), Alias(MolScript.core.set.isSubset, 'set.subset'),
// ], ],
// [ [
// 'Structure', 'Structure',
// [ [
// 'Types', 'Types',
// Alias(MolScript.structureQuery.type.entityType, 'ent-type'), Alias(MolScript.structureQuery.type.entityType, 'ent-type'),
// Alias(MolScript.structureQuery.type.authResidueId, 'auth-resid'), Alias(MolScript.structureQuery.type.authResidueId, 'auth-resid'),
// Alias(MolScript.structureQuery.type.labelResidueId, 'label-resid'), Alias(MolScript.structureQuery.type.labelResidueId, 'label-resid'),
// Alias(MolScript.structureQuery.type.ringFingerprint, 'ringfp'), Alias(MolScript.structureQuery.type.ringFingerprint, 'ringfp'),
// Alias(MolScript.structureQuery.type.bondFlags, 'bond-flags'), Alias(MolScript.structureQuery.type.bondFlags, 'bond-flags'),
// ], ],
// [ [
// 'Slots', 'Slots',
// Alias(MolScript.structureQuery.slot.elementSetReduce, 'atom.set.reduce.value'), Alias(MolScript.structureQuery.slot.elementSetReduce, 'atom.set.reduce.value'),
// ], ],
// [ [
// 'Generators', 'Generators',
// Alias(MolScript.structureQuery.generator.atomGroups, 'sel.atom.atom-groups'), Alias(MolScript.structureQuery.generator.atomGroups, 'sel.atom.atom-groups'),
// Alias(MolScript.structureQuery.generator.queryInSelection, 'sel.atom.query-in-selection'), Alias(MolScript.structureQuery.generator.queryInSelection, 'sel.atom.query-in-selection'),
// Alias(MolScript.structureQuery.generator.rings, 'sel.atom.rings'), Alias(MolScript.structureQuery.generator.rings, 'sel.atom.rings'),
// Alias(MolScript.structureQuery.generator.empty, 'sel.atom.empty'), Alias(MolScript.structureQuery.generator.empty, 'sel.atom.empty'),
// Macro(MSymbol('sel.atom.atoms', Arguments.Dictionary({ // Macro(MSymbol('sel.atom.atoms', Arguments.Dictionary({
// 0: Argument(Type.Bool, { isOptional: true, defaultValue: true, description: 'Test applied to each atom.' }) // 0: Argument(Type.Bool, { isOptional: true, defaultValue: true, description: 'Test applied to each atom.' })
// }), Struct.Types.ElementSelection, 'A selection of singleton atom sets.'), // }), Struct.Types.ElementSelection, 'A selection of singleton atom sets.'),
// args => B.struct.generator.atomGroups({ 'atom-test': M.tryGetArg(args, 0, true) })), // args => B.struct.generator.atomGroups({ 'atom-test': M.tryGetArg(args, 0, true) })),
// Macro(MSymbol('sel.atom.res', Arguments.Dictionary({ // Macro(MSymbol('sel.atom.res', Arguments.Dictionary({
// 0: Argument(Type.Bool, { isOptional: true, defaultValue: true, description: 'Test applied to the 1st atom of each residue.' }) // 0: Argument(Type.Bool, { isOptional: true, defaultValue: true, description: 'Test applied to the 1st atom of each residue.' })
// }), Struct.Types.ElementSelection, 'A selection of atom sets grouped by residue.'), // }), Struct.Types.ElementSelection, 'A selection of atom sets grouped by residue.'),
// args => B.struct.generator.atomGroups({ // args => B.struct.generator.atomGroups({
// 'residue-test': M.tryGetArg(args, 0, true), // 'residue-test': M.tryGetArg(args, 0, true),
// 'group-by': B.ammp('residueKey') // 'group-by': B.ammp('residueKey')
// })), // })),
// Macro(MSymbol('sel.atom.chains', Arguments.Dictionary({ // Macro(MSymbol('sel.atom.chains', Arguments.Dictionary({
// 0: Argument(Type.Bool, { isOptional: true, defaultValue: true, description: 'Test applied to the 1st atom of each chain.' }) // 0: Argument(Type.Bool, { isOptional: true, defaultValue: true, description: 'Test applied to the 1st atom of each chain.' })
// }), Struct.Types.ElementSelection, 'A selection of atom sets grouped by chain.'), // }), Struct.Types.ElementSelection, 'A selection of atom sets grouped by chain.'),
// args => B.struct.generator.atomGroups({ // args => B.struct.generator.atomGroups({
// 'chain-test': M.tryGetArg(args, 0, true), // 'chain-test': M.tryGetArg(args, 0, true),
// 'group-by': B.ammp('chainKey') // 'group-by': B.ammp('chainKey')
// })), // })),
// ], ],
// [ [
// 'Modifiers', 'Modifiers',
// Alias(MolScript.structureQuery.modifier.queryEach, 'sel.atom.query-each'), Alias(MolScript.structureQuery.modifier.queryEach, 'sel.atom.query-each'),
// Alias(MolScript.structureQuery.modifier.intersectBy, 'sel.atom.intersect-by'), Alias(MolScript.structureQuery.modifier.intersectBy, 'sel.atom.intersect-by'),
// Alias(MolScript.structureQuery.modifier.exceptBy, 'sel.atom.except-by'), Alias(MolScript.structureQuery.modifier.exceptBy, 'sel.atom.except-by'),
// Alias(MolScript.structureQuery.modifier.unionBy, 'sel.atom.union-by'), Alias(MolScript.structureQuery.modifier.unionBy, 'sel.atom.union-by'),
// Alias(MolScript.structureQuery.modifier.union, 'sel.atom.union'), Alias(MolScript.structureQuery.modifier.union, 'sel.atom.union'),
// Alias(MolScript.structureQuery.modifier.cluster, 'sel.atom.cluster'), Alias(MolScript.structureQuery.modifier.cluster, 'sel.atom.cluster'),
// Alias(MolScript.structureQuery.modifier.includeSurroundings, 'sel.atom.include-surroundings'), Alias(MolScript.structureQuery.modifier.includeSurroundings, 'sel.atom.include-surroundings'),
// Alias(MolScript.structureQuery.modifier.includeConnected, 'sel.atom.include-connected'), Alias(MolScript.structureQuery.modifier.includeConnected, 'sel.atom.include-connected'),
// Alias(MolScript.structureQuery.modifier.expandProperty, 'sel.atom.expand-property'), Alias(MolScript.structureQuery.modifier.expandProperty, 'sel.atom.expand-property'),
// Macro(MSymbol('sel.atom.around', Arguments.Dictionary({ // Macro(MSymbol('sel.atom.around', Arguments.Dictionary({
// 0: Argument(Type.Bool, { isOptional: true, defaultValue: true, description: 'Test applied to the 1st atom of each chain.' }) // 0: Argument(Type.Bool, { isOptional: true, defaultValue: true, description: 'Test applied to the 1st atom of each chain.' })
// }), Struct.Types.ElementSelection, 'A selection of singleton atom sets with centers within "radius" of the center of any atom in the given selection.'), // }), Struct.Types.ElementSelection, 'A selection of singleton atom sets with centers within "radius" of the center of any atom in the given selection.'),
// args => B.struct.modifier.exceptBy({ // args => B.struct.modifier.exceptBy({
// '0': B.struct.filter.within({ // '0': B.struct.filter.within({
// '0': B.struct.generator.atomGroups(), target: M.tryGetArg(args, 0), 'max-radius': M.tryGetArg(args, 'radius') // '0': B.struct.generator.atomGroups(), target: M.tryGetArg(args, 0), 'max-radius': M.tryGetArg(args, 'radius')
// }), // }),
// by: M.tryGetArg(args, 0) // by: M.tryGetArg(args, 0)
// })) // }))
// ], ],
// [ [
// 'Filters', 'Filters',
// Alias(MolScript.structureQuery.filter.pick, 'sel.atom.pick'), Alias(MolScript.structureQuery.filter.pick, 'sel.atom.pick'),
// Alias(MolScript.structureQuery.filter.withSameAtomProperties, 'sel.atom.with-same-atom-properties'), Alias(MolScript.structureQuery.filter.withSameAtomProperties, 'sel.atom.with-same-atom-properties'),
// Alias(MolScript.structureQuery.filter.intersectedBy, 'sel.atom.intersected-by'), Alias(MolScript.structureQuery.filter.intersectedBy, 'sel.atom.intersected-by'),
// Alias(MolScript.structureQuery.filter.within, 'sel.atom.within'), Alias(MolScript.structureQuery.filter.within, 'sel.atom.within'),
// Alias(MolScript.structureQuery.filter.isConnectedTo, 'sel.atom.is-connected-to'), Alias(MolScript.structureQuery.filter.isConnectedTo, 'sel.atom.is-connected-to'),
// ], ],
// [ [
// 'Combinators', 'Combinators',
// Alias(MolScript.structureQuery.combinator.intersect, 'sel.atom.intersect'), Alias(MolScript.structureQuery.combinator.intersect, 'sel.atom.intersect'),
// Alias(MolScript.structureQuery.combinator.merge, 'sel.atom.merge'), Alias(MolScript.structureQuery.combinator.merge, 'sel.atom.merge'),
// Alias(MolScript.structureQuery.combinator.distanceCluster, 'sel.atom.dist-cluster'), Alias(MolScript.structureQuery.combinator.distanceCluster, 'sel.atom.dist-cluster'),
// ], ],
// [ [
// 'Atom Set Properties', 'Atom Set Properties',
// Alias(MolScript.structureQuery.atomSet.atomCount, 'atom.set.atom-count'), Alias(MolScript.structureQuery.atomSet.atomCount, 'atom.set.atom-count'),
// Alias(MolScript.structureQuery.atomSet.countQuery, 'atom.set.count-query'), Alias(MolScript.structureQuery.atomSet.countQuery, 'atom.set.count-query'),
// Alias(MolScript.structureQuery.atomSet.reduce, 'atom.set.reduce'), Alias(MolScript.structureQuery.atomSet.reduce, 'atom.set.reduce'),
// Alias(MolScript.structureQuery.atomSet.propertySet, 'atom.set.property'), Alias(MolScript.structureQuery.atomSet.propertySet, 'atom.set.property'),
// Macro(MSymbol('atom.set.max', Arguments.Dictionary({ // Macro(MSymbol('atom.set.max', Arguments.Dictionary({
// 0: Argument(Type.Num, { description: 'Numeric atom property.'}) // 0: Argument(Type.Num, { description: 'Numeric atom property.'})
// }), Type.Num, 'Maximum of the given property in the current atom set.'), // }), Type.Num, 'Maximum of the given property in the current atom set.'),
// args => M.aggregate(M.tryGetArg(args, 0), B.core.math.max)), // args => M.aggregate(M.tryGetArg(args, 0), B.core.math.max)),
// Macro(MSymbol('atom.set.sum', Arguments.Dictionary({ // Macro(MSymbol('atom.set.sum', Arguments.Dictionary({
// 0: Argument(Type.Num, { description: 'Numeric atom property.'}) // 0: Argument(Type.Num, { description: 'Numeric atom property.'})
// }), Type.Num, 'Sum of the given property in the current atom set.'), // }), Type.Num, 'Sum of the given property in the current atom set.'),
// args => M.aggregate(M.tryGetArg(args, 0), B.core.math.add, 0)), // args => M.aggregate(M.tryGetArg(args, 0), B.core.math.add, 0)),
// Macro(MSymbol('atom.set.avg', Arguments.Dictionary({ // Macro(MSymbol('atom.set.avg', Arguments.Dictionary({
// 0: Argument(Type.Num, { description: 'Numeric atom property.'}) // 0: Argument(Type.Num, { description: 'Numeric atom property.'})
// }), Type.Num, 'Average of the given property in the current atom set.'), // }), Type.Num, 'Average of the given property in the current atom set.'),
// args => B.core.math.div([ M.aggregate(M.tryGetArg(args, 0), B.core.math.add, 0), B.struct.atomSet.atomCount() ])), // args => B.core.math.div([ M.aggregate(M.tryGetArg(args, 0), B.core.math.add, 0), B.struct.atomSet.atomCount() ])),
// Macro(MSymbol('atom.set.min', Arguments.Dictionary({ // Macro(MSymbol('atom.set.min', Arguments.Dictionary({
// 0: Argument(Type.Num, { description: 'Numeric atom property.'}) // 0: Argument(Type.Num, { description: 'Numeric atom property.'})
// }), Type.Num, 'Minimum of the given property in the current atom set.'), // }), Type.Num, 'Minimum of the given property in the current atom set.'),
// args => M.aggregate(M.tryGetArg(args, 0), B.core.math.min)) // args => M.aggregate(M.tryGetArg(args, 0), B.core.math.min))
// ], ],
// [ [
// 'Atom Properties', 'Atom Properties',
// Alias(MolScript.structureQuery.atomProperty.core.elementSymbol, 'atom.el'), Alias(MolScript.structureQuery.atomProperty.core.elementSymbol, 'atom.el'),
// Alias(MolScript.structureQuery.atomProperty.core.vdw, 'atom.vdw'), Alias(MolScript.structureQuery.atomProperty.core.vdw, 'atom.vdw'),
// Alias(MolScript.structureQuery.atomProperty.core.mass, 'atom.mass'), Alias(MolScript.structureQuery.atomProperty.core.mass, 'atom.mass'),
// Alias(MolScript.structureQuery.atomProperty.core.atomicNumber, 'atom.atomic-number'), Alias(MolScript.structureQuery.atomProperty.core.atomicNumber, 'atom.atomic-number'),
// Alias(MolScript.structureQuery.atomProperty.core.x, 'atom.x'), Alias(MolScript.structureQuery.atomProperty.core.x, 'atom.x'),
// Alias(MolScript.structureQuery.atomProperty.core.y, 'atom.y'), Alias(MolScript.structureQuery.atomProperty.core.y, 'atom.y'),
// Alias(MolScript.structureQuery.atomProperty.core.z, 'atom.z'), Alias(MolScript.structureQuery.atomProperty.core.z, 'atom.z'),
// Alias(MolScript.structureQuery.atomProperty.core.atomKey, 'atom.key'), Alias(MolScript.structureQuery.atomProperty.core.atomKey, 'atom.key'),
// Alias(MolScript.structureQuery.atomProperty.core.bondCount, 'atom.bond-count'), Alias(MolScript.structureQuery.atomProperty.core.bondCount, 'atom.bond-count'),
// Alias(MolScript.structureQuery.atomProperty.topology.connectedComponentKey, 'atom.key.molecule'), Alias(MolScript.structureQuery.atomProperty.topology.connectedComponentKey, 'atom.key.molecule'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.authResidueId, 'atom.auth-resid'), Alias(MolScript.structureQuery.atomProperty.macromolecular.authResidueId, 'atom.auth-resid'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.labelResidueId, 'atom.label-resid'), Alias(MolScript.structureQuery.atomProperty.macromolecular.labelResidueId, 'atom.label-resid'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.residueKey, 'atom.key.res'), Alias(MolScript.structureQuery.atomProperty.macromolecular.residueKey, 'atom.key.res'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.chainKey, 'atom.key.chain'), Alias(MolScript.structureQuery.atomProperty.macromolecular.chainKey, 'atom.key.chain'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.entityKey, 'atom.key.entity'), Alias(MolScript.structureQuery.atomProperty.macromolecular.entityKey, 'atom.key.entity'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.isHet, 'atom.is-het'), Alias(MolScript.structureQuery.atomProperty.macromolecular.isHet, 'atom.is-het'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.id, 'atom.id'), Alias(MolScript.structureQuery.atomProperty.macromolecular.id, 'atom.id'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.label_atom_id, 'atom.label_atom_id'), Alias(MolScript.structureQuery.atomProperty.macromolecular.label_atom_id, 'atom.label_atom_id'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.label_alt_id, 'atom.label_alt_id', 'atom.altloc'), Alias(MolScript.structureQuery.atomProperty.macromolecular.label_alt_id, 'atom.label_alt_id', 'atom.altloc'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.label_comp_id, 'atom.label_comp_id'), Alias(MolScript.structureQuery.atomProperty.macromolecular.label_comp_id, 'atom.label_comp_id'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.label_asym_id, 'atom.label_asym_id'), Alias(MolScript.structureQuery.atomProperty.macromolecular.label_asym_id, 'atom.label_asym_id'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.label_entity_id, 'atom.label_entity_id'), Alias(MolScript.structureQuery.atomProperty.macromolecular.label_entity_id, 'atom.label_entity_id'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.label_seq_id, 'atom.label_seq_id'), Alias(MolScript.structureQuery.atomProperty.macromolecular.label_seq_id, 'atom.label_seq_id'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.auth_atom_id, 'atom.auth_atom_id', 'atom.name'), Alias(MolScript.structureQuery.atomProperty.macromolecular.auth_atom_id, 'atom.auth_atom_id', 'atom.name'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.auth_comp_id, 'atom.auth_comp_id', 'atom.resname'), Alias(MolScript.structureQuery.atomProperty.macromolecular.auth_comp_id, 'atom.auth_comp_id', 'atom.resname'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.auth_asym_id, 'atom.auth_asym_id', 'atom.chain'), Alias(MolScript.structureQuery.atomProperty.macromolecular.auth_asym_id, 'atom.auth_asym_id', 'atom.chain'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.auth_seq_id, 'atom.auth_seq_id', 'atom.resno'), Alias(MolScript.structureQuery.atomProperty.macromolecular.auth_seq_id, 'atom.auth_seq_id', 'atom.resno'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.pdbx_PDB_ins_code, 'atom.pdbx_PDB_ins_code', 'atom.inscode'), Alias(MolScript.structureQuery.atomProperty.macromolecular.pdbx_PDB_ins_code, 'atom.pdbx_PDB_ins_code', 'atom.inscode'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.pdbx_formal_charge, 'atom.pdbx_formal_charge'), Alias(MolScript.structureQuery.atomProperty.macromolecular.pdbx_formal_charge, 'atom.pdbx_formal_charge'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.occupancy, 'atom.occupancy'), Alias(MolScript.structureQuery.atomProperty.macromolecular.occupancy, 'atom.occupancy'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.B_iso_or_equiv, 'atom.B_iso_or_equiv', 'atom.bfactor'), Alias(MolScript.structureQuery.atomProperty.macromolecular.B_iso_or_equiv, 'atom.B_iso_or_equiv', 'atom.bfactor'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.entityType, 'atom.entity-type'), Alias(MolScript.structureQuery.atomProperty.macromolecular.entityType, 'atom.entity-type'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.secondaryStructureKey, 'atom.key.sec-struct'), Alias(MolScript.structureQuery.atomProperty.macromolecular.secondaryStructureKey, 'atom.key.sec-struct'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.isModified, 'atom.is-modified'), Alias(MolScript.structureQuery.atomProperty.macromolecular.isModified, 'atom.is-modified'),
// Alias(MolScript.structureQuery.atomProperty.macromolecular.modifiedParentName, 'atom.modified-parent'), Alias(MolScript.structureQuery.atomProperty.macromolecular.modifiedParentName, 'atom.modified-parent'),
// Macro(MSymbol('atom.sec-struct.is', Arguments.List(Struct.Types.SecondaryStructureFlag), Type.Bool, // Macro(MSymbol('atom.sec-struct.is', Arguments.List(Struct.Types.SecondaryStructureFlag), Type.Bool,
// `Test if the current atom is part of an secondary structure. Optionally specify allowed sec. struct. types: ${Type.oneOfValues(Struct.Types.SecondaryStructureFlag).join(', ')}`), // `Test if the current atom is part of an secondary structure. Optionally specify allowed sec. struct. types: ${Type.oneOfValues(Struct.Types.SecondaryStructureFlag).join(', ')}`),
// args => B.core.flags.hasAny([B.struct.atomProperty.macromolecular.secondaryStructureFlags(), B.struct.type.secondaryStructureFlags(args)])), // args => B.core.flags.hasAny([B.struct.atomProperty.macromolecular.secondaryStructureFlags(), B.struct.type.secondaryStructureFlags(args)])),
// ], ],
// [ [
// 'Bond Properties', 'Bond Properties',
// Alias(MolScript.structureQuery.bondProperty.order, 'bond.order'), Alias(MolScript.structureQuery.bondProperty.order, 'bond.order'),
// Macro(MSymbol('bond.is', Arguments.List(Struct.Types.BondFlag), Type.Bool, // Macro(MSymbol('bond.is', Arguments.List(Struct.Types.BondFlag), Type.Bool,
// `Test if the current bond has at least one (or all if partial = false) of the specified flags: ${Type.oneOfValues(Struct.Types.BondFlag).join(', ')}`), // `Test if the current bond has at least one (or all if partial = false) of the specified flags: ${Type.oneOfValues(Struct.Types.BondFlag).join(', ')}`),
// args => B.core.flags.hasAny([B.struct.bondProperty.flags(), B.struct.type.bondFlags(M.getPositionalArgs(args))])), // args => B.core.flags.hasAny([B.struct.bondProperty.flags(), B.struct.type.bondFlags(M.getPositionalArgs(args))])),
// ] ]
// ] ]
// ]; ];
// const list: MolScriptSymbol[] = []; const list: MolScriptSymbol[] = [];
// function makeList(xs: any[]) { function makeList(xs: any[]) {
// for (const x of xs) { for (const x of xs) {
// if (isMolScriptSymbol(x)) list.push(x); if (isMolScriptSymbol(x)) list.push(x);
// else if (x instanceof Array) makeList(x); else if (x instanceof Array) makeList(x);
// } }
// } }
makeList(SymbolTable);
const normalized = (function () {
const symbolList: [string, MolScriptSymbol][] = [];
const symbolMap: { [id: string]: MolScriptSymbol | undefined } = Object.create(null);
const namedArgs = UniqueArray.create<string, string>();
const constants = UniqueArray.create<string, string>();
for (const s of list) {
for (const a of s.aliases) {
symbolList.push([a, s]);
if (symbolMap[a]) throw new Error(`Alias '${a}' already in use.`);
symbolMap[a] = s;
}
const args = s.symbol.args;
if (args.kind !== 'dictionary') {
if (args.type.kind === 'oneof') {
Type.oneOfValues(args.type).forEach(v => UniqueArray.add(constants, v, v));
}
continue;
}
for (const a of Object.keys(args.map)) {
if (isNaN(a as any)) UniqueArray.add(namedArgs, a, a);
const arg = ((args.map as any)[a]) as Argument;
if (arg.type.kind === 'oneof') {
Type.oneOfValues(arg.type).forEach(v => UniqueArray.add(constants, v, v));
}
}
}
return { symbolList, symbolMap, namedArgs: namedArgs.array, constants: constants.array }
})();
export const MolScriptSymbols = list;
export const Constants = normalized.constants;
export const NamedArgs = normalized.namedArgs;
export const SymbolMap = normalized.symbolMap;
export const SymbolList = normalized.symbolList;
function substSymbols(expr: Expression): Expression {
if (Expression.isLiteral(expr)) {
return expr;
}
if (Expression.isSymbol(expr)) {
if (!SymbolMap[expr.name]) return expr;
return Expression.Symbol(SymbolMap[expr.name]!.symbol.id);
}
const head = substSymbols(expr.head);
const headChanged = head === expr.head;
if (!expr.args) {
return headChanged ? Expression.Apply(head) : expr;
}
let argsChanged = false;
if (Expression.isArgumentsArray(expr.args)) {
let newArgs: Expression[] = [];
for (let i = 0, _i = expr.args.length; i < _i; i++) {
const oldArg = expr.args[i];
const newArg = substSymbols(oldArg);
if (oldArg !== newArg) argsChanged = true;
newArgs[newArgs.length] = newArg;
}
if (!argsChanged) newArgs = expr.args;
if (!headChanged && !argsChanged) return expr;
return Expression.Apply(head, newArgs);
} else {
let newArgs: any = {}
for (const key of Object.keys(expr.args)) {
const oldArg = expr.args[key];
const newArg = substSymbols(oldArg);
if (oldArg !== newArg) argsChanged = true;
newArgs[key] = newArg;
}
if (!headChanged && !argsChanged) return expr;
if (!argsChanged) newArgs = expr.args;
return Expression.Apply(head, newArgs);
}
}
// makeList(SymbolTable); export function transpileMolScript(expr: Expression) {
return substSymbols(expr);
// const normalized = (function () { }
// const symbolList: [string, MolScriptSymbol][] = [];
// const symbolMap: { [id: string]: MolScriptSymbol | undefined } = Object.create(null);
// const namedArgs = UniqueArray.create<string, string>();
// const constants = UniqueArray.create<string, string>();
// for (const s of list) {
// for (const a of s.aliases) {
// symbolList.push([a, s]);
// if (symbolMap[a]) throw new Error(`Alias '${a}' already in use.`);
// symbolMap[a] = s;
// }
// const args = s.symbol.args;
// if (args.kind !== 'dictionary') {
// if (args.type.kind === 'oneof') {
// Type.oneOfValues(args.type).forEach(v => UniqueArray.add(constants, v, v));
// }
// continue;
// }
// for (const a of Object.keys(args.map)) {
// if (isNaN(a as any)) UniqueArray.add(namedArgs, a, a);
// const arg = ((args.map as any)[a]) as Argument;
// if (arg.type.kind === 'oneof') {
// Type.oneOfValues(arg.type).forEach(v => UniqueArray.add(constants, v, v));
// }
// }
// }
// return { symbolList, symbolMap, namedArgs: namedArgs.array, constants: constants.array }
// })();
// export const MolScriptSymbols = list;
// export const Constants = normalized.constants;
// export const NamedArgs = normalized.namedArgs;
// export const SymbolMap = normalized.symbolMap;
// export const SymbolList = normalized.symbolList;
// const sortedSymbols = SymbolList.map(s => s[0]).sort((a, b) => { // const sortedSymbols = SymbolList.map(s => s[0]).sort((a, b) => {
// if (a.length === b.length) return (a < b) as any; // if (a.length === b.length) return (a < b) as any;
// return a.length - b.length; // return a.length - b.length;
// }); // });
// export default [...sortedSymbols, ...NamedArgs.map(a => ':' + a), ...Constants]; //export default [...sortedSymbols, ...NamedArgs.map(a => ':' + a), ...Constants];
\ No newline at end of file \ No newline at end of file
...@@ -6,6 +6,8 @@ import { CustomPropSymbol } from 'mol-script/language/symbol'; ...@@ -6,6 +6,8 @@ import { CustomPropSymbol } from 'mol-script/language/symbol';
import Type from 'mol-script/language/type'; import Type from 'mol-script/language/type';
import { parseMolScript } from 'mol-script/language/parser'; import { parseMolScript } from 'mol-script/language/parser';
import * as util from 'util' import * as util from 'util'
import { transpileMolScript } from 'mol-script/script/mol-script/symbols';
import { formatMolScript } from 'mol-script/language/expression-formatter';
// import Examples from 'mol-script/script/mol-script/examples' // import Examples from 'mol-script/script/mol-script/examples'
// import { parseMolScript } from 'mol-script/script/mol-script/parser' // import { parseMolScript } from 'mol-script/script/mol-script/parser'
...@@ -15,14 +17,25 @@ import * as util from 'util' ...@@ -15,14 +17,25 @@ import * as util from 'util'
// const expr = parseMolScript(e.value)[0]; // const expr = parseMolScript(e.value)[0];
// console.log(e.name, util.inspect(expr, true, 10, true)); // console.log(e.name, util.inspect(expr, true, 10, true));
// } // }
// const exprs = parseMolScript(`(sel.atom.atom-groups
// :residue-test (= atom.auth_comp_id ALA)
// ;; ho ho ho
// :atom-test (set.has { _C _N } atom.el)) ; comm
// ;; this is a comment
// ((hi) (ho))`);
const exprs = parseMolScript(`(sel.atom.atom-groups const exprs = parseMolScript(`(sel.atom.atom-groups
:residue-test (= atom.auth_comp_id ALA) :residue-test (= atom.label_comp_id REA)
;; ho ho ho :atom-test (= atom.el _C))`);
:atom-test (set.has { _C _N } atom.el)) ; comm
;; this is a comment const tsp = transpileMolScript(exprs[0]);
((hi) (ho))`);
//console.log(util.inspect(exprs, true, 10, true));
console.log(util.inspect(exprs, true, 10, true)); console.log(util.inspect(tsp, true, 10, true));
console.log(formatMolScript);
console.log(formatMolScript(tsp));
// //console.log(expr); // //console.log(expr);
const expr = MolScriptBuilder.core.math.add([1, 2, 3]); const expr = MolScriptBuilder.core.math.add([1, 2, 3]);
...@@ -49,7 +62,7 @@ export async function testQ() { ...@@ -49,7 +62,7 @@ export async function testQ() {
const frame = await readCifFile('e:/test/quick/1cbs_updated.cif'); const frame = await readCifFile('e:/test/quick/1cbs_updated.cif');
const { structure } = await getModelsAndStructure(frame); const { structure } = await getModelsAndStructure(frame);
const expr = MolScriptBuilder.struct.generator.atomGroups({ let expr = MolScriptBuilder.struct.generator.atomGroups({
'atom-test': MolScriptBuilder.core.rel.eq([ 'atom-test': MolScriptBuilder.core.rel.eq([
MolScriptBuilder.struct.atomProperty.core.elementSymbol(), MolScriptBuilder.struct.atomProperty.core.elementSymbol(),
MolScriptBuilder.es('C') MolScriptBuilder.es('C')
...@@ -61,10 +74,12 @@ export async function testQ() { ...@@ -61,10 +74,12 @@ export async function testQ() {
'residue-test': MolScriptBuilder.core.rel.inRange([CustomProp.symbols.residueIndex.symbol(), 1, 5]) 'residue-test': MolScriptBuilder.core.rel.inRange([CustomProp.symbols.residueIndex.symbol(), 1, 5])
}); });
expr = tsp;
const compiled = compile<StructureQuery>(expr); const compiled = compile<StructureQuery>(expr);
const result = compiled(new QueryContext(structure)); const result = compiled(new QueryContext(structure));
console.log(result); console.log(result);
} }
// testQ(); testQ();
\ No newline at end of file \ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment