nope/modules/net-analyzer/registry/javascript.parser.ts
Martin Karkowski 838d910c2f adding gojs
2020-12-01 13:05:35 +01:00

391 lines
10 KiB
TypeScript

/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-02-20 19:46:19
* @modify date 2020-11-25 07:36:44
* @desc [description]
*/
import * as handlebars from "handlebars";
import { IParseableTransitionDescription, IParsedLogic } from "../types/interface";
import { AbstractParser } from "./default.parser";
export class JsParser extends AbstractParser {
public variableDefinition(context: IParsedLogic): string {
throw new Error("Method not implemented.");
}
/**
* Function which will generate Parameters for the desired Function
* @param task The Taskobject.
*/
protected _generateParameters(task: IParseableTransitionDescription) {
// Only Adapt a Copy
const ret = deepClone(task.params);
const pair = new Map<string, string>();
// Adapt the Parameters.
for (const updateDefinition of task.dynamicParams) {
pair.set(updateDefinition.usedVariable, "\"" + updateDefinition.usedVariable + "\"");
rsetattr(
ret,
updateDefinition.parameterPointer,
updateDefinition.usedVariable
);
}
const obj = JSON.stringify(ret, undefined, 4);
// Create The Text which will be used for the Parameters
for (const [key, value] of pair.entries()) {
replaceAll(obj, value, key);
}
return obj;
}
// Array, containing all Elements which should be replaced.
protected _replace: {
regex: RegExp;
replacer: string;
}[] = [
{
regex: /(?<=[ \]\)])or(?=[ \[\(])/g,
replacer: "||"
},
{
regex: /(?<=[ \]\)])and(?=[ \[\(])/g,
replacer: "&&"
},
{
regex: /(?<=[ \]\)])sin(?=[ \[\(])/g,
replacer: "Math.sin"
},
{
regex: /(?<=[ \]\)])cos(?=[ \[\(])/g,
replacer: "Math.cos"
},
{
// (?<=[ \]\)])
regex: /not(?=[ \[\(])/g,
replacer: "!"
},
{
regex: /(?<=[ \]\)])\|(?=[ \[\(])/g,
replacer: "||"
},
{
regex: /(?<=[ \]\)])\&(?=[ \[\(])/g,
replacer: "&&"
}
];
/**
* Function, which will be used to adapt the Path.
* @param value
*/
protected _adaptGuard(guard: string,
simplifiedGuard: string,
OriginalScope: {
[index: string]: {
source: string;
schema: IJsonSchema;
};
},
simplifiedScope: {
[index: string]: {
source: string;
schema: IJsonSchema;
};
},
mappingOriginalToSimplified: Map<string, string>,
mappingSimplifiedToOriginal: Map<string, string>,
mappingSimplifiedToAdapted: Map<string, string>,
mappingAdaptedToSimplified: Map<string, string>,
mappingVariableToRoot: Map<string, string>) {
let adaptedGuard = simplifiedGuard;
// Firstly get rid off the Elements (Chars, ot replace in the Equation)
for (const data of this._replace) {
adaptedGuard = adaptedGuard.replace(data.regex, data.replacer);
}
// Adapt the used Names
for (const [simple, adapted] of mappingSimplifiedToAdapted) {
adaptedGuard = replaceAll(adaptedGuard, simple, adapted);
}
return adaptedGuard;
}
/**
* Function, which will be used to adapt a Variable Name.
* @param value The original Variable Name
*/
protected _adaptVariableName(
variable: string,
simplifiedName: string,
path: string
) {
return "vars['" + simplifiedName + "']";
}
/**
* Function, which will be used to generate Function Code.
* @param taskData
*/
protected _getFunctionTriggerCode(_taskData: IParseableTransitionDescription) {
const taskData = deepClone(_taskData);
taskData.params = this._generateParameters(taskData);
const updateTaskResult =
"" +
`
_memoryInterface.set('{{id}}.function.output', {
done: false,
error: false,
result: null,
errorObject: null
});
_broker.performTask('{{functionName}}', {{{params}}}, '{{id}}', 'async', (error, parameters, result) => {
_memoryInterface.set('{{id}}.function.output', {
result: result,
done: error ? false : true,
error: error ? true : false,
errorObject: error
});
});
`;
const render = handlebars.compile(updateTaskResult);
return render(taskData);
}
protected _convertInput(definition: {
// Amount of Tokens that will be consumed (Result must be greater the minTokens)
consumed: IArcExpression;
placeId: string;
type:
| "expression"
| "inhibitor"
| "multiexpression"
| "test"
| "value"
| "variable";
minTokens: number;
}) {
return {
placeId: definition.placeId,
minTokens: definition.minTokens,
tokensToRemove: 1,
};
}
protected _convertOutput(definition: {
// Amount of Tokens that will be produced
produced: IArcExpression;
placeId: string;
type:
| "expression"
| "inhibitor"
| "multiexpression"
| "test"
| "value"
| "variable";
maxTokens: number;
}): {
// Amount of Tokens that will be produced
placeId: string;
maxTokens: number;
tokensToAdd: number;
} {
return {
placeId: definition.placeId,
maxTokens: definition.maxTokens,
tokensToAdd: 1,
};
}
protected _templates: {
[index: string]: string;
} = {
ifHeaderTemplate: "{{#unless isFirst}}else {{/unless}}if ({{> testPrePlaces}}{{> testPostPlaces}}{{> testGuard}}) {",
testPrePlaces: "{{#each inputs}} ((tokens['{{placeId}}']{{#if minTokens}} - {{minTokens}}{{/if}}) >= {{tokensToRemove}}) &&{{/each}}",
testPostPlaces: "{{#each testOutputs}} ((tokens['{{placeId}}'] + {{tokensToAdd}}) <= {{maxTokens}}) &&{{/each}}",
testGuard: " {{{ externalGuard }}}",
removeTokens: "{{#each inputs}}tokens['{{placeId}}'] -= {{tokensToRemove}};{{/each}}",
addTokens: "{{#each outputs}}tokens['{{placeId}}'] += {{tokensToAdd}};{{/each}}",
mainTemplate:
"" +
`
import { ZISSLogger, DEFAULT_LOGGER } from '../modules/ZISS-Logger/src/Unique.Logger';
const _logger = ZISSLogger.logger.getLogger();
/** Add Console Logger. */
ZISSLogger.logger.addStream(DEFAULT_LOGGER);
_logger.info('started');
import 'reflect-metadata';
import * as BROKERFILEBASE from '../modules/ZISS-Broker/assembly/manual-assembly';
import * as BROKER from '../modules/ZISS-Broker/assembly/manual-assembly';
import * as MEMORYINTERFACE from '../modules/ZISS-Memory-Interface/assembly/manual-assembly';
import * as PUBSUB from '../modules/ZISS-Publish-And-Subscribe-System/assembly/manual-assembly';
import { Builder } from '../modules/ZISS-Assembly-Builder/src/Container-Builder.FileLoader';
import { ArgumentParser } from 'argparse';
const parser = new ArgumentParser({
version: '1.0.0',
addHelp: true,
description: 'Main Starter For the Kernel Tool'
});
parser.addArgument(
['-l', '--level'],
{
help: 'The Loglevel. Defaults to Debug',
defaultValue: 'info',
choices: ['debug', 'error', 'fatal', 'info', 'trace', 'warn'],
dest: 'level',
}
);
const args = parser.parseArgs();
ZISSLogger.logger.level = args.level;
Builder.load();
Builder.on('loaded', () => {
const _loader = Builder.instance.container.get<BROKERFILEBASE.FilebasedBroker>(BROKERFILEBASE.TYPES.BrokerFilebased);
const _broker = Builder.instance.container.get<BROKER.Broker>(BROKER.TYPES.Broker);
const _memoryInterface = Builder.instance.container.get<MEMORYINTERFACE.BaseStorage>(MEMORYINTERFACE.TYPES.Storage);
const _pubSub = Builder.instance.container.get<PUBSUB.PubSubSystem>(PUBSUB.TYPES.PubSubSystem);
const vars: {[index:string]:any} = {
'true':true
};
const tokens: {[index:string]:number} = {
{{#each places}}
'{{id}}' : {{tokens.length}},
{{/each}}
};
function mainLoop(){
let checkTransitions = true;
// Main Loop, which will iterate, until no action is left.
while (checkTransitions) {
checkTransitions = false;
{{#each transitions}}
// Test Transtion {{{label}}}
{{> ifHeaderTemplate}}
{{#if inputs}}
// Removing Tokens from Pre-Places.
{{> removeTokens}}
{{/if}}
{{#if outputs}}
// Adding Tokens to the Post-Places.
{{> addTokens}}
{{/if}}
{{#if functionName}}
// Execute the desired Function
{{#getFunctionCode this}}{{/getFunctionCode}}
{{/if}}
// Make shure the System Loops over again.
checkTransitions = true;
}
{{/each}}
}
}
// Define the Variables
{{#each subscribedVariables}}
Object.defineProperty(vars, '{{simplifiedName}}', {
get: () => _memoryInterface.get('{{path}}'),
set: (value) => _memoryInterface.set('{{path}}', value),
enumerable: true
});
_pubSub.createSubscription('{{path}}', (data) => {
mainLoop();
});
{{/each}}
{{#each variables}}
{{#if hasValue}}
_memoryInterface.set('{{path}}', {{data}});
{{/if}}
{{/each}}
const _func = async function () {
try {
await _loader.loadModules();
// Perform autostart
await _loader.performAutostartConfig();
ZISSLogger.logger.level = args.level;
ZISSLogger.logger.setLoglevel('delimiter', 'info');
ZISSLogger.logger.setLoglevel('logic.functions', 'info');
// Start the Task
mainLoop();
} catch (e) {
_logger.error(e, 'Error during Loading the Content');
}
};
_func();
});
`
};
/**
* Function, which will generate the MainLoop.
* @param network
*/
mainLoop(network: ILogicNetwork): string {
// Reference to the Own Object.
const _this = this;
handlebars.registerHelper("getFunctionCode", (taskData) =>
_this._getFunctionTriggerCode(taskData)
);
this.linkTemplates();
const render = handlebars.compile(this._templates.mainTemplate);
return render(this.getParseableLogic(network));
}
instanceCreation(context: IParsedLogic): string {
throw new Error("Method not implemented.");
}
}