UNPKG

jsmf-jstl

Version:

Model transformation for JSTL

103 lines (74 loc) 3 kB
'use strict' const _ = require('lodash') const JSMF = require('jsmf-core') let Class, Model, Enum (function() { Model = JSMF.Model Class = JSMF.Class Enum = JSMF.Enum }).call() const App = Class.newInstance('App') const IO = new Enum('IO', ['INPUT', 'OUTPUT']) const Signal = new Enum('Signal', ['LOW', 'HIGH']) const StructuralConcerns = Class.newInstance('StructuralConcerns') App.setReference('structural', StructuralConcerns, 1) const BrickAlias = Class.newInstance('BrickAlias', [], {name: String, pin: JSMF.Range(0,13)}) StructuralConcerns.setReference('alias', BrickAlias, -1) const PinMode = Class.newInstance('PinMode', [], {name: String, mode: IO}) StructuralConcerns.setReference('pinMode', PinMode, -1) const BehaviouralConcerns = Class.newInstance('BehaviouralConcerns') App.setReference('behavioural', BehaviouralConcerns, 1) const TimeConfig = Class.newInstance('TimeConfig', [], {initialTime: Number, debounce: Number}) BehaviouralConcerns.setReference('timeConfig', TimeConfig, 1) const StateFunction = Class .newInstance( 'StateFunction', [], {name: String, readOn: String, read: Signal, next: String} ) BehaviouralConcerns.setReference('stateFunction', StateFunction, -1) const Write = Class.newInstance('Write', [], {on: String, value: Signal}) StateFunction.setReference('write', Write, -1) const MainLoop = Class.newInstance('MainLoop', [], {init: String}) BehaviouralConcerns.setReference('mainLoop', MainLoop, 1) const AbstractCode = new Model('AbstractCode', [], App, true) /** * Code Generation */ function toCode(xs, n) { return _.map(xs, x => x.toCode()).join(n) } App.prototype.toCode = () => toCode(this.structural) + '\n\n' + toCode(this.behavioural) StructuralConcerns.prototype.toCode = () => toCode(this.alias, '\n') + '\n\n' + 'void setup() {\n' + toCode(this.pinMode, '\n') + '\n}' BrickAlias.prototype.toCode = () => 'int ' + this.name + ' = ' + this.pin + ';' PinMode.prototype.toCode = () => ' pinMode(' + this.name + ', ' + IO.getName(this.mode) + ');' BehaviouralConcerns.prototype.toCode = () => toCode(this.timeConfig) + '\n\n' + toCode(this.stateFunction, '\n\n') + '\n\n' + toCode(this.mainLoop) TimeConfig.prototype.toCode = () => 'long time = ' + this.initialTime + '; long debounce = ' + this.debounce + ';' StateFunction.prototype.toCode = () => 'void state_' + this.name + '() {\n' + toCode(this.write, '\n\n') + ' boolean guard = millis() - time > debounce;\n' + ' if (digitalRead(' + this.readOn + ') == ' + Signal.getName(this.read) + ' && guard) {\n' + ' time = millis(); state_' +this.next + '();\n' + ' } else {\n' + ' state_' + this.name + '();\n' + ' }\n' + '}' Write.prototype.toCode = () => ' digitalWrite(' + this.on + ', ' + Signal.getName(this.value) + ');\n' MainLoop.prototype.toCode = () => 'void loop() { state_' + this.init + '(); }' module.exports = JSMF.modelExport(AbstractCode)