UNPKG

teroshdl

Version:

Backend for terosHDL IDE

1,186 lines (1,090 loc) 45.9 kB
/* eslint-disable no-empty */ // Copyright 2020 Teros Technology // // Ismael Perez Rojo // Carlos Alberto Ruiz Naranjo // Alfredo Saez // // This file is part of Colibri. // // Colibri is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Colibri is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Colibri. If not, see <https://www.gnu.org/licenses/>. const path = require('path'); const ts_base_parser = require('./ts_base_parser'); const stm_parser = require('./verilog_sm'); class Parser extends ts_base_parser.Ts_base_parser { constructor(comment_symbol) { super(); this.set_symbol(comment_symbol); this.loaded = false; } async init() { try { if (this.loaded !== true) { const Tree_sitter = require('web-tree-sitter'); await Tree_sitter.init(); this.parser = new Tree_sitter(); let Lang = await Tree_sitter.Language.load(path.join(__dirname, path.sep + "parsers" + path.sep + "tree-sitter-verilog.wasm")); this.parser.setLanguage(Lang); this.loaded = true; this.stm_parser = new stm_parser.Paser_stm_verilog(this.comment_symbol, this.parser); } } catch (e) {} } async get_svg_sm(code, symbol) { return this.stm_parser.get_svg_sm(code, symbol); } async get_all(sourceCode, comment_symbol) { if (this.loaded === false) { return undefined; } let structure; let file_type; this.set_symbol(comment_symbol); try { var lines = this.fileLines(sourceCode); const tree = await this.parser.parse(sourceCode); //comments let comments = this.get_comments(tree.rootNode, lines); var module_header = this.search_multiple_in_tree(tree.rootNode, 'module_header'); if (module_header.length === 0) { let arch_body = tree; let body_elements = this.get_body_elements_and_declarations(arch_body, lines, comments, true); file_type = "package"; let package_declaration = this.get_package_declaration(tree.rootNode, lines); structure = { "package": package_declaration, // package_identifier "declarations": { 'types': body_elements.types, 'signals': body_elements.signals, 'constants': body_elements.constants, 'functions': body_elements.functions } }; } else { let arch_body = this.get_architecture_body(tree); let body_elements = this.get_body_elements_and_declarations(arch_body, lines, comments); file_type = "entity"; structure = { 'libraries': this.get_libraries(tree.rootNode, lines, comments), // includes "entity": this.get_entityName(tree.rootNode, lines), // module "generics": body_elements.generics, // parameters "ports": body_elements.ports, "body": { 'processes': body_elements.processes, 'instantiations': body_elements.instantiations, }, "declarations": { 'types': body_elements.types, 'signals': body_elements.signals, 'constants': body_elements.constants, 'functions': body_elements.functions } }; } structure = this.parse_doxy(structure, file_type); structure = this.parse_mermaid(structure, file_type); if (file_type === "entity") { structure = this.parse_ports_group(structure); structure = this.parse_virtual_bus(structure); structure.entity.description = this.normalize_description(structure.entity.description); } return structure; } catch (error) { return undefined; } } ////////////////////////////////////////////////////////////////////////////// get_body_elements_and_declarations(arch_body, lines, general_comments, enable_package) { let last_element_position = -1; //Elements array let process_array = []; let signals_array = []; let constants_array = []; let functions_array = []; let types_array = []; let instantiations_array = []; let ports_array = []; let generics_array = []; let cursor = arch_body.walk(); let comments = ''; // Process cursor.gotoFirstChild(); do { if (cursor.nodeType === 'module_or_generate_item' || cursor.nodeType === 'package_item') { cursor.gotoFirstChild(); do { if (cursor.nodeType === 'always_construct') { last_element_position = cursor.startPosition.row; let new_processes = this.get_processes(cursor.currentNode(), lines, general_comments); comments = comments.replace(/fsm_extract/g, ''); new_processes = this.set_description_to_array(new_processes, comments, general_comments); process_array = process_array.concat(new_processes); comments = ''; } else if (cursor.nodeType === 'net_declaration' || cursor.nodeType === 'data_declaration') { last_element_position = cursor.startPosition.row; let new_signals = this.get_signals(cursor.currentNode(), lines, general_comments); new_signals = this.set_description_to_array(new_signals, comments, general_comments); signals_array = signals_array.concat(new_signals); if (new_signals.length === 0 && enable_package === true || enable_package === undefined) { let new_types = this.get_types_pkg(cursor.currentNode(), lines, general_comments); new_types = this.set_description_to_array(new_types, comments, general_comments); types_array = types_array.concat(new_types); } comments = ''; } else if (cursor.nodeType === 'function_identifier' || cursor.nodeType === 'function_declaration') { last_element_position = cursor.startPosition.row; let new_functions = this.get_functions(cursor.currentNode(), lines, general_comments); new_functions = this.set_description_to_array(new_functions, comments, general_comments); functions_array = functions_array.concat(new_functions); comments = ''; } else if (cursor.nodeType === 'any_parameter_declaration') { last_element_position = cursor.startPosition.row; let new_constants = this.get_constants(cursor.currentNode(), lines, general_comments); new_constants = this.set_description_to_array(new_constants, comments, general_comments); constants_array = constants_array.concat(new_constants); if (new_constants.length === 0) { let new_generics = this.get_generics(cursor.currentNode(), lines, general_comments, 0); new_generics = this.set_description_to_array(new_generics, comments, general_comments); generics_array = generics_array.concat(new_generics); } if (new_constants.length === 0 && enable_package === true) { new_constants = this.get_generics(cursor.currentNode(), lines, general_comments, 0); new_constants = this.set_description_to_array(new_constants, comments, general_comments); constants_array = constants_array.concat(new_constants); } comments = ''; } else if (cursor.nodeType === 'type_declaration') { last_element_position = cursor.startPosition.row; let new_types = this.get_types_pkg(cursor.currentNode(), lines, general_comments); new_types = this.set_description_to_array(new_types, comments, general_comments); types_array = types_array.concat(new_types); comments = ''; } else if (cursor.nodeType === 'module_instantiation') { last_element_position = cursor.startPosition.row; let new_instantiations = this.get_instantiations(cursor.currentNode(), lines, general_comments); new_instantiations = this.set_description_to_array(new_instantiations, comments, general_comments); instantiations_array = instantiations_array.concat(new_instantiations); comments = ''; } else { comments = ''; } } while (cursor.gotoNextSibling() !== false); cursor.gotoParent(); } else if (cursor.nodeType === 'module_ansi_header') { let new_ports = this.get_ansi_ports(cursor.currentNode(), lines, general_comments); ports_array = ports_array.concat(new_ports); let new_generics = this.get_ansi_generics(cursor.currentNode(), lines, general_comments); generics_array = generics_array.concat(new_generics); let new_constants = this.get_ansi_constants(cursor.currentNode(), lines, general_comments); constants_array = constants_array.concat(new_constants); comments = ''; } else if (cursor.nodeType === 'port_declaration') { last_element_position = cursor.startPosition.row; let new_ports = this.get_ports(cursor.currentNode(), lines, general_comments); new_ports = this.set_description_to_array(new_ports, comments, general_comments); ports_array = ports_array.concat(new_ports); comments = ''; last_element_position = cursor.startPosition.row; let new_signals = this.get_types(cursor.currentNode(), lines, general_comments); new_signals = this.set_description_to_array(new_signals, comments, general_comments); signals_array = signals_array.concat(new_signals); comments = ''; } else if (cursor.nodeType === 'parameter_declaration') { last_element_position = cursor.startPosition.row; let new_generics = this.get_generics(cursor.currentNode(), lines, general_comments, 0); new_generics = this.set_description_to_array(new_generics, comments, general_comments); generics_array = generics_array.concat(new_generics); comments = ''; } else if (cursor.nodeType === 'comment') { let comment_position = cursor.startPosition.row; if (last_element_position !== comment_position) { comments += this.get_comment_with_break(cursor.nodeText); } else { comments = ''; } } else { comments = ''; } } while (cursor.gotoNextSibling() !== false); return { processes: process_array, signals: signals_array, instantiations: instantiations_array, ports: ports_array, generics: generics_array, constants: constants_array, functions: functions_array, types: types_array }; } get_ansi_ports(p, lines, general_comments) { let last_comments = ''; let last_element_position = -1; let ports_types = ['input_declaration', 'output_declaration', 'ansi_port_declaration', 'inout_declaration' ]; let ports = []; let comments = ''; let ports_list = this.get_item_from_childs(p, 'list_of_port_declarations'); if (ports_list === undefined) { return ports; } let cursor = ports_list.walk(); cursor.gotoFirstChild(); do { if (ports_types.includes(cursor.nodeType) === true) { if (last_element_position === cursor.startPosition.row) { comments = last_comments; } else { last_comments = comments; } last_element_position = cursor.startPosition.row; let new_ports = this.get_ports(cursor.currentNode(), lines, general_comments); new_ports = this.set_description_to_array(new_ports, comments, general_comments); ports = ports.concat(new_ports); comments = ''; } else if (cursor.nodeType === 'comment') { let comment_position = cursor.startPosition.row; if (last_element_position !== comment_position) { comments += this.get_comment_with_break(cursor.nodeText); } else { comments = ''; } } else { comments = ''; } } while (cursor.gotoNextSibling() !== false); return ports; } get_ansi_generics(p, lines, general_comments) { let last_element_position = -1; let generics_types = ['parameter_port_declaration']; let last_comments = ''; let generics = []; let comments = ''; let generics_list = this.get_item_from_childs(p, 'parameter_port_list'); if (generics_list === undefined) { return generics; } let cursor = generics_list.walk(); cursor.gotoFirstChild(); do { if (generics_types.includes(cursor.nodeType) === true) { if (last_element_position === cursor.startPosition.row) { comments = last_comments; } else { last_comments = comments; } last_element_position = cursor.startPosition.row; let new_generics = this.get_generics(cursor.currentNode(), lines, general_comments, 1); new_generics = this.set_description_to_array(new_generics, comments, general_comments); generics = generics.concat(new_generics); comments = ''; } else if (cursor.nodeType === 'comment') { let comment_position = cursor.startPosition.row; if (last_element_position !== comment_position) { comments += this.get_comment_with_break(cursor.nodeText); } else { comments = ''; } } else { comments = ''; } } while (cursor.gotoNextSibling() !== false); return generics; } get_ansi_constants(p, lines, general_comments) { let last_element_position = -1; let constants_types = ['parameter_port_declaration']; let last_comments = ''; let constants = []; let comments = ''; let constants_list = this.get_item_from_childs(p, 'parameter_port_list'); if (constants_list === undefined) { return constants; } let cursor = constants_list.walk(); cursor.gotoFirstChild(); do { if (constants_types.includes(cursor.nodeType) === true) { if (last_element_position === cursor.startPosition.row) { comments = last_comments; } else { last_comments = comments; } last_element_position = cursor.startPosition.row; let new_constants = this.get_constants(cursor.currentNode(), lines, general_comments, 1); new_constants = this.set_description_to_array(new_constants, comments, general_comments); constants = constants.concat(new_constants); comments = ''; } else if (cursor.nodeType === 'comment') { let comment_position = cursor.startPosition.row; if (last_element_position !== comment_position) { comments += this.get_comment_with_break(cursor.nodeText); } else { comments = ''; } } else { comments = ''; } } while (cursor.gotoNextSibling() !== false); return constants; } get_architecture_body(p) { let break_p = false; let arch_body = undefined; let cursor = p.walk(); cursor.gotoFirstChild(); do { if (cursor.nodeType === 'module_declaration') { arch_body = cursor.currentNode(); break_p = true; } } while (cursor.gotoNextSibling() === true && break_p === false); if (arch_body === undefined) { arch_body = p.walk().currentNode(); } return arch_body; } set_description_to_array(arr, txt, general_comments) { for (let i = 0; i < arr.length; ++i) { let comment_candidate = general_comments[arr[i].start_line]; if (comment_candidate !== undefined) { let result = this.check_comment(comment_candidate); if (result.check === true) { arr[i].description = result.comment; } } if (arr[i].description === '') { arr[i].description = txt; } } return arr; } check_comment(comment) { let check = false; let result = ''; comment = comment.slice(2); if (this.comment_symbol === '') { result = comment.trim() + '\n'; check = true; } else if (comment[0] === this.comment_symbol) { result = comment.slice(1).trim() + '\n'; check = true; } return { check: check, comment: result }; } ////////////////////////////////////////////////////////////////////////////// get_process_label(p) { let label_txt = ''; let label = this.get_item_from_childs(p, "block_identifier"); if (label === undefined) { label_txt = 'unnamed'; } else { label_txt = label.text; } return label_txt; } get_deep_process(p) { let statement = this.get_item_from_childs(p, 'statement'); let statement_item = this.get_item_from_childs(statement, 'statement_item'); let procedural_timing_control_statement = this.get_item_from_childs(statement_item, 'procedural_timing_control_statement'); if (procedural_timing_control_statement !== undefined) { let statement_or_null = this.get_item_from_childs(procedural_timing_control_statement, 'statement_or_null'); let statement_2 = this.get_item_from_childs(statement_or_null, 'statement'); let statement_item_2 = this.get_item_from_childs(statement_2, 'statement_item'); let seq_block = this.get_item_from_childs(statement_item_2, 'seq_block'); return seq_block; } else { let seq_block = this.get_item_from_childs(statement_item, 'seq_block'); return seq_block; } } getPortName(port, lines) { var arr = this.search_multiple_in_tree(port, 'list_of_port_identifiers'); var port_name; if (arr.length === 0) { arr = this.search_multiple_in_tree(port, 'list_of_variable_identifiers'); } if (arr.length === 0) { arr = this.search_multiple_in_tree(port, 'port_identifier'); } for (var x = 0; x < arr.length; ++x) { if (x === 0) { port_name = this.extract_data(arr[x], lines); } else { port_name = port_name + ',' + this.extract_data(arr[x], lines); } } return port_name; } getPortNameAnsi(port, lines) { let arr = this.search_multiple_in_tree(port, 'port_identifier'); if (arr.length === 0) { arr = this.search_multiple_in_tree(port, 'simple_identifier'); let port_name = this.extract_data(arr[0], lines); return port_name; } else { let port_name = this.extract_data(arr[0], lines); let split_port_name = port_name.split(','); for (let x = 0; x < split_port_name.length; ++x) { return port_name; } } } getPortType(port, lines) { var arr = this.search_multiple_in_tree(port, 'net_port_type1'); if (arr[0] == null) { arr = this.search_multiple_in_tree(port, 'packed_dimension'); } if (arr[0] == null) { return ""; } let port_type = this.extract_data(arr[0], lines); return port_type; } getPortKind(port, lines) { var arr = this.search_multiple_in_tree(port, 'port_direction'); if (arr[0] == null) { return; } var port_type = this.extract_data(arr[0], lines); return port_type; } add_port(element, key, name, direction, type, ansi, items, comments, lines) { let directionVar = undefined; let start_line = element.startPosition.row; var item = {}; var inputs = []; var arr = this.search_multiple_in_tree(element, key); inputs = arr; for (var x = 0; x < inputs.length; ++x) { var port_name; switch (name) { case 'getPortName': port_name = this.getPortName(inputs[x], lines); break; case 'getPortNameAnsi': port_name = this.getPortNameAnsi(inputs[x], lines); break; default: name = this.getPortName; } port_name = port_name.split(','); directionVar = this.getPortKind(inputs[x], lines); if (directionVar !== undefined) { this.last_direction = directionVar; } var typeVar; switch (type) { case 'getPortType': typeVar = this.getPortType(inputs[x], lines); break; default: typeVar = this.getPortType(inputs[x], lines); } var port_ref = this.search_multiple_in_tree(element, 'port_reference'); var comment = ""; var comment_str = comments[inputs[x].startPosition.row]; for (var i = 0; i < port_name.length; i++) { if (comment_str === undefined) { for (var z = 0; z < port_ref.length; z++) { var port_ref_name = this.extract_data(port_ref[z], lines); if (port_ref_name === port_name[i].trim()) { var pre_comment = comments[port_ref[z].startPosition.row]; if (pre_comment !== undefined) { comment = this.get_comment_with_break(pre_comment); } } } } let comment_check = this.get_comment_with_break(comment_str); if (comment_check !== '') { comment = comment_check; } if (directionVar === undefined) { directionVar = this.last_direction; } item = { 'name': port_name[i], 'direction': ((ansi === true) ? directionVar : direction), 'type': typeVar, "default_value": "", "description": comment, "start_line": start_line }; items.push(item); } } return items; } get_ports(tree, lines, comments) { var items = []; var element = tree; //Inputs items = this.add_port(element, 'input_declaration', 'getPortName', 'input', 'getPortType', false, items, comments, lines); //Outputs items = this.add_port(element, 'output_declaration', 'getPortName', 'output', 'getPortType', false, items, comments, lines); //ansi_port_declaration items = this.add_port(element, 'ansi_port_declaration', 'getPortNameAnsi', 'getPortKind', 'getPortType', true, items, comments, lines); //inouts items = this.add_port(element, 'inout_declaration', 'getPortName', "inout", 'getPortType', false, items, comments, lines); return items; } get_comments(tree, lines) { var item = {}; var inputs = []; var arr = this.search_multiple_in_tree(tree, 'comment'); inputs = arr; for (var x = 0; x < inputs.length; ++x) { item[inputs[x].startPosition.row] = this.extract_data(inputs[x], lines); } return item; } get_libraries() { return []; } get_generics(tree, lines, comments, ansi) { let items = []; let inputs = []; let item = {}; let element = tree; let arr = []; //Inputs if (ansi === 0) { arr = this.search_multiple_in_tree(element, 'parameter_declaration'); } else { arr = this.search_multiple_in_tree(element, 'parameter_declaration'); } if (arr.length === 0) { arr = this.search_multiple_in_tree(element, 'parameter_port_declaration'); } inputs = arr; for (let x = 0; x < inputs.length; ++x) { let comment = ""; let pre_comment = comments[inputs[x].startPosition.row]; if (pre_comment !== undefined) { comment = this.get_comment_with_break(pre_comment); } item = { "name": this.get_generic_name(inputs[x], lines), "type": this.get_generic_kind(inputs[x], lines), "default_value": this.get_generic_default(inputs[x], lines), "description": comment }; items.push(item); } return items; } get_library_name(port, lines) { let arr = this.search_multiple_in_tree(port, 'double_quoted_string'); if (arr.length === 0) { let lib = this.extract_data(arr[0], lines); return lib; } else { let lib = this.extract_data(arr[0], lines).substr(1, this.extract_data(arr[0], lines).length - 2); let split_lib = lib.split(','); for (let x = 0; x < split_lib.length; ++x) { return lib; } } } get_generic_name(port, lines) { let arr = this.search_multiple_in_tree(port, 'parameter_identifier'); if (arr.length === 1) { arr = this.search_multiple_in_tree(port, 'simple_identifier'); let port_name = this.extract_data(arr[0], lines); return port_name; } else { let port_name = this.extract_data(arr[0], lines); let split_port_name = port_name.split(','); for (let x = 0; x < split_port_name.length; ++x) { return port_name; } } } get_generic_default(input, lines) { var arr = this.search_multiple_in_tree(input, 'constant_param_expression'); if (arr.length === 0) { var name = "undefined"; return name; } var input_value = this.extract_data(arr[0], lines); return input_value; } get_always_name(always, lines) { var arr = this.search_multiple_in_tree(always, 'block_identifier'); if (arr.length === 0) { var name = "unnamed"; return name; } var always_name = this.extract_data(arr[0], lines); return always_name; } get_always_sens_list(always, lines) { var arr = this.search_multiple_in_tree(always, 'event_control'); if (arr.length === 0) { var name = ''; return name; } var always_name = this.extract_data(arr[0], lines); return always_name; } get_always_type_list(always, lines) { let type = ''; let arr = this.search_multiple_in_tree(always, 'always_keyword'); if (arr.length !== 0) { type = this.extract_data(arr[0], lines); } return type; } get_instantiation_name(always, lines) { var arr = this.search_multiple_in_tree(always, 'name_of_instance'); if (arr.length === 0) { var name = "undefined"; return name; } var always_name = this.extract_data(arr[0], lines); return always_name; } get_type_type(input, lines) { var arr = this.search_multiple_in_tree(input, 'interface_identifier'); if (arr.length === 0) { var name = "undefined"; return name; } var always_name = this.extract_data(arr[0], lines); return always_name; } get_type_type_pkg(input) { let arr = this.search_multiple_in_tree(input, 'data_type'); if (arr.length === 0) { let name = "undefined"; return name; } let name = arr[0].text.replace(/\/\/(.+)/gi, ''); return name; } get_signal_type(input, lines, command) { let arr = this.search_multiple_in_tree(input, command); if (arr.length === 0) { arr = this.search_multiple_in_tree(input, 'net_type_identifier'); } if (arr.length === 0) { let name = "undefined"; return name; } let always_name = this.extract_data(arr[0], lines); return always_name; } get_type_name(input, lines) { let arr = this.search_multiple_in_tree(input, 'list_of_interface_identifiers'); if (arr.length === 0) { let name = "undefined"; return name; } let input_name = this.extract_data(arr[0], lines); return input_name; } get_type_name_pkg(input, lines) { let arr = this.search_multiple_in_tree(input, 'type_identifier'); if (arr.length === 0) { let name = "undefined"; return name; } let input_name = this.extract_data(arr[0], lines); return input_name; } get_port_default(input, lines) { let arr = this.search_multiple_in_tree(input, 'list_of_interface_identifiers'); if (arr.length === 0) { let name = "undefined"; return name; } let input_name = this.extract_data(arr[0], lines); return input_name; } get_signal_name(input, lines) { let arr = this.search_multiple_in_tree(input, 'net_identifier'); let names = []; let name; if (arr.length === 0) { name = "undefined"; } else { for (let i = 0; i < arr.length; ++i) { let input_name = this.extract_data(arr[i], lines); names.push(input_name); } } let arr2 = this.search_multiple_in_tree(input, 'variable_identifier'); if (arr2.length === 0 && name === "undefined") { name = "undefined"; return name; } for (let i = 0; i < arr2.length; ++i) { let input_name = this.extract_data(arr2[i], lines); names.push(input_name); } return names; } get_constant_name(input, lines) { let arr = this.search_multiple_in_tree(input, 'parameter_identifier'); if (arr.length === 0) { let name = "undefined"; return name; } let input_name = this.extract_data(arr[0], lines); return input_name; } get_constant_type(input, lines) { let arr = this.search_multiple_in_tree(input, 'data_type_or_implicit1'); if (arr.length === 0) { let name = ''; return name; } let input_name = this.extract_data(arr[0], lines); return input_name; } get_constant_default(input, lines) { let arr = this.search_multiple_in_tree(input, 'constant_param_expression'); if (arr.length === 0) { let name = "undefined"; return name; } let input_name = this.extract_data(arr[0], lines); return input_name; } get_function_name(input, lines) { let arr = this.search_multiple_in_tree(input, 'function_identifier'); if (arr.length === 0) { let name = "undefined"; return name; } let input_name = this.extract_data(arr[0], lines); return input_name; } get_function_arguments(input, lines) { let arr = this.search_multiple_in_tree(input, 'tf_port_list'); if (arr.length === 0) { let name = ""; return name; } let input_name = '(' + this.extract_data(arr[0], lines) + ')'; return input_name; } get_function_return(input, lines) { let arr = this.search_multiple_in_tree(input, 'function_data_type_or_implicit1'); if (arr.length === 0) { let name = ""; return name; } let input_name = 'return (' + this.extract_data(arr[0], lines) + ')'; return input_name; } get_instantiation_type(always, lines) { let arr = this.search_multiple_in_tree(always, 'simple_identifier'); if (arr.length === 0) { let name = "undefined"; return name; } let always_name = this.extract_data(arr[0], lines); return always_name; } get_generic_kind(port, lines) { let arr = this.search_multiple_in_tree(port, 'data_type_or_implicit1'); if (arr.length === 0) { return ""; } else { let port_name = this.extract_data(arr[0], lines); let split_port_name = port_name.split(','); for (let x = 0; x < split_port_name.length; ++x) { return port_name; } } } async get_only_entity_name(code) { if (this.loaded === false) { return undefined; } const tree = await this.parser.parse(code); let cursor = tree.walk(); let arr = this.search_multiple_in_tree(cursor.currentNode(), 'module_identifier'); if (arr === undefined) { return ''; } else { return arr[0].text; } } async get_entity_or_package_name(code) { let entity_name = await this.get_only_entity_name(code); return { name: entity_name, type: 'entity' }; } get_entityName(tree, lines) { let element = tree; let arr = this.search_multiple_in_tree(element, 'module_header'); element = arr; arr = this.search_multiple_in_tree(element[0], 'simple_identifier'); let module_index = this.index(arr[0]); let item = { "name": this.extract_data(arr[0], lines), "description": "" }; let description = ""; let comments = this.search_multiple_in_tree(tree, 'comment'); for (let x = 0; x < comments.length; ++x) { if (comments[x].startPosition.row >= module_index[0]) { break; } let comment_str = this.extract_data(comments[x], lines); description += this.get_comment(comment_str) + '\n'; } description += '\n'; item["description"] = description; return item; } get_package_declaration(tree, lines) { var element = tree; var arr = this.search_multiple_in_tree(element, 'package_identifier'); element = arr; if (arr.length === 0) { return { 'name': '', 'description': '' }; } arr = this.search_multiple_in_tree(element[0], 'simple_identifier'); var module_index = this.index(arr[0]); let item = { "name": this.extract_data(arr[0], lines), "description": "" }; var description = ""; var comments = this.search_multiple_in_tree(tree, 'comment'); for (var x = 0; x < comments.length; ++x) { if (comments[x].startPosition.row >= module_index[0]) { break; } var comment_str = this.extract_data(comments[x], lines); description += this.get_comment_with_break(comment_str); } description += '\n'; item["description"] = description; return item; } get_processes(tree, lines) { var items = []; var inputs = []; var item = {}; var element = tree; let start_line = element.startPosition.row; //Inputs var arr = this.search_multiple_in_tree(element, 'always_construct'); inputs = arr; for (var x = 0; x < inputs.length; ++x) { let comment = ""; var arr1 = this.get_deep_process(inputs[x]); item = { "name": this.get_process_label(arr1), "sens_list": this.get_always_sens_list(inputs[x], lines), "type": this.get_always_type_list(inputs[x], lines), "description": comment, 'start_line': start_line }; items.push(item); } return items; } get_instantiations(tree, lines) { var items = []; var inputs = []; var item = {}; var element = tree; let start_line = element.startPosition.row; //Inputs var arr = this.search_multiple_in_tree(element, 'module_instantiation'); inputs = arr; for (var x = 0; x < inputs.length; ++x) { let comment = ""; item = { "name": this.get_instantiation_name(inputs[x], lines), "type": this.get_instantiation_type(inputs[x], lines), "description": comment, 'start_line': start_line }; items.push(item); } return items; } get_types(tree, lines) { var items = []; var inputs = []; var item = {}; var element = tree; let start_line = element.startPosition.row; //Inputs var arr = this.search_multiple_in_tree(element, 'interface_port_declaration'); //port_declaration inputs = arr; for (var x = 0; x < inputs.length; ++x) { let comment = ""; var arr_types = this.get_type_name(inputs[x], lines); var split_arr_types = arr_types.split(','); for (var s = 0; s < split_arr_types.length; ++s) { var name_type = split_arr_types[s]; item = { "name": name_type.trim(), "type": this.get_type_type(inputs[x], lines), "description": comment, 'start_line': start_line }; items.push(item); } } return items; } get_types_pkg(tree, lines) { var items = []; var inputs = []; var item = {}; var element = tree; let start_line = element.startPosition.row; //Inputs var arr = this.search_multiple_in_tree(element, 'type_declaration'); //port_declaration inputs = arr; for (var x = 0; x < inputs.length; ++x) { let comment = ""; let type = this.get_type_type_pkg(inputs[x], lines); var arr_types = this.get_type_name_pkg(inputs[x], lines); var split_arr_types = arr_types.split(','); for (var s = 0; s < split_arr_types.length; ++s) { var name_type = split_arr_types[s]; item = { "name": name_type.trim(), "type": type, "description": comment, 'start_line': start_line }; if (type !== '') { items.push(item); } } } return items; } get_signals(tree, lines, comments) { let items = []; let inputs = []; let inputs2 = []; let element = tree; let start_line = element.startPosition.row; //Inputs let arr = this.search_multiple_in_tree(element, 'net_declaration'); let arr2 = this.search_multiple_in_tree(element, 'data_declaration'); inputs = arr; inputs2 = arr2; this.get_signal_array(inputs, comments, items, lines, 'list_of_net_decl_assignments', 'net_type', 'packed_dimension', start_line); this.get_signal_array(inputs2, comments, items, lines, 'list_of_variable_decl_assignments', 'data_type_or_implicit1', 0, start_line); return items; } get_signal_array(inputs, comments, items, lines, name_command, type_command, type_dim, start_line) { var item = {}; for (var x = 0; x < inputs.length; ++x) { let comment = ""; var arr_signals = this.get_signal_name(inputs[x], lines, name_command); if (arr_signals !== 'undefined') { let signal_type = this.get_signal_type(inputs[x], lines, type_command); let signal_type_dim = this.get_signal_type(inputs[x], lines, type_dim); if (signal_type_dim !== 'undefined') { if (signal_type !== signal_type_dim) { signal_type = signal_type + ' ' + signal_type_dim; } } for (var s = 0; s < arr_signals.length; ++s) { var name_signal = arr_signals[s]; item = { "name": name_signal.trim(), "type": signal_type, "description": comment, "start_line": start_line }; if (signal_type !== 'undefined') { items.push(item); } } } } return items; } get_constants(tree, lines) { var items = []; var inputs = []; var item = {}; var element = tree; let start_line = element.startPosition.row; //Inputs var arr = this.search_multiple_in_tree(element, 'local_parameter_declaration'); inputs = arr; for (var x = 0; x < inputs.length; ++x) { let comment = ""; var arr2 = this.search_multiple_in_tree(inputs[x], 'param_assignment'); for (var x2 = 0; x2 < arr2.length; ++x2) { item = { "name": this.get_constant_name(arr2[x2], lines), "type": this.get_constant_type(inputs[x], lines), "default_value": this.get_constant_default(arr2[x2], lines), // constant_param_expression "description": comment, "start_line": start_line }; items.push(item); } } return items; } get_functions(tree, lines) { var items = []; var inputs = []; var item = {}; var element = tree; let start_line = element.startPosition.row; //Inputs var arr = this.search_multiple_in_tree(element, 'function_body_declaration'); inputs = arr; for (var x = 0; x < inputs.length; ++x) { let comment = ""; item = { "name": this.get_function_name(inputs[x], lines), "description": comment, "arguments": this.get_function_arguments(inputs[x], lines), "return": this.get_function_return(inputs[x], lines), "start_line": start_line }; items.push(item); } return items; } extract_data(node, lines) { return lines[node.startPosition.row].substr(node.startPosition.column, node.endPosition.column - node.startPosition.column); } index(node) { return [node.startPosition.row, node.startPosition.column]; } fileLines(source) { var array = source.toString().split("\n"); return array; } } module.exports = Parser;