UNPKG

hdl-js

Version:

Hardware definition language (HDL) and Hardware simulator

143 lines (121 loc) 3.19 kB
/** * The MIT License (MIT) * Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com> */ 'use strict'; /** * Helper `gen` function calls node type handler. */ function gen(node) { return node ? generator[node.type](node) : ''; } /** * Generates input pins. */ function genInputs(inputs) { return 'IN ' + inputs.map(gen).join(', ') + ';'; } /** * Generates output pins. */ function genOutputs(outputs) { return 'OUT ' + outputs.map(gen).join(', ') + ';'; } /** * Generates parts implementation. */ function genParts(parts) { if (!parts || parts.length === 0) { return ''; } return '\n\n PARTS:\n\n ' + parts.map(gen).join(';\n') + ';'; } /** * Generates builtin chips list. */ function genBuiltins(builtins) { if (!builtins || builtins.length === 0) { return ''; } return '\n\n BUILTIN ' + builtins.map(gen).join(', ') + ';'; } /** * Generates clocked pins. */ function genClocked(clocked) { if (!clocked || clocked.length === 0) { return ''; } return '\n\n CLOCKED ' + clocked.map(gen).join(', ') + ';'; } /** * AST handler. */ var generator = { Chip: function Chip(node) { return '\n CHIP ' + node.name + ' {\n ' + genInputs(node.inputs) + '\n ' + genOutputs(node.outputs) + // Optional parts: genParts(node.parts) + genBuiltins(node.builtins) + genClocked(node.clocked) + '\n }\n '; }, Name: function Name(node) { var name = node.value; // a[1] if (node.hasOwnProperty('index')) { return name + '[' + node.index + ']'; } // a[1] if (node.hasOwnProperty('size')) { return name + '[' + node.size + ']'; } // a[0..3] if (node.hasOwnProperty('range')) { return name + '[' + node.range.from + '..' + node.range.to + ']'; } // a return name; }, ChipCall: function ChipCall(node) { var args = node.arguments.map(gen).join(', '); return node.name + '(' + args + ')'; }, Argument: function Argument(node) { return gen(node.name) + '=' + gen(node.value); }, Constant: function Constant(node) { return node.raw; } }; /** * Reformats the code according to options. */ function reformat(code) { var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref$indent = _ref.indent, indent = _ref$indent === undefined ? 2 : _ref$indent; return code.trim().split('\n').map(function (line, index, arr) { line = line.trim(); if (line && index > 0 && index < arr.length - 1) { line = ' '.repeat(indent) + line; } return line; }).join('\n'); } module.exports = { /** * Generates an HDL code from AST. * * options: {indent = 2} */ fromAST: function fromAST(node, options) { var hdl = reformat(gen(node), options); return ['/**', ' * Automatically generated by hdl-js "' + node.name + '" gate.', ' */', hdl].join('\n'); }, /** * Generates an HDL code from a CompositeGate instance. * * options: see `generateFromAST`. */ fromCompositeGate: function fromCompositeGate(compositeGate, options) { return this.fromAST(compositeGate.toAST(), options); } };