UNPKG

nixfilter-logicsignal

Version:

Filters for handling (compressing/uncompressing etc.) logic signals

158 lines (136 loc) 5.4 kB
'use strict'; var Logic_Signal, first_valid_value, get_number_of_repetitions_in_array, greatest_common_divisor, greatest_common_divisor_in_array, is_array, is_object_type, is_of_type, is_string_type, is_valid_value, logic_signal_pattern, logic_signal_regexp, repeat_array; // Returns true if the passed argument <value> is neither null nor undefined is_valid_value = function(value) { return (value !== void 0) && (value !== null); }; // Returns the first value in <values...> that is neither null nor undefined first_valid_value = function(...values) { var i, len, value; for (i = 0, len = values.length; i < len; i++) { value = values[i]; if (is_valid_value(value)) { return value; } } }; // Assuming that array <array> can be constructed by repeating another array n times, returns the largest n get_number_of_repetitions_in_array = function(array) { var i, index, j, number_of_repetitions, ref, ref1, ref2, repeated_array_length; for (number_of_repetitions = i = ref = array.length; i >= 2; number_of_repetitions = i += -1) { if ((array.length % number_of_repetitions) === 0) { repeated_array_length = Math.floor(array.length / number_of_repetitions); for (index = j = ref1 = repeated_array_length, ref2 = array.length; j < ref2; index = j += 1) { if (array[index] !== array[index % repeated_array_length]) { break; } } if (index === array.length) { return number_of_repetitions; } } } return 1; }; // Returns the greatest common divisor (GCD) of <first_number> and <second_number> greatest_common_divisor = function(first_number, second_number) { return (first_number ? greatest_common_divisor(second_number % first_number, first_number) : second_number); }; // Returns the greatest_common_divisor (GCD) of all numbers in array <numbers_array> greatest_common_divisor_in_array = function(numbers_array) { return numbers_array.reduce(greatest_common_divisor); }; // Returns true if <value> is an array is_array = function(value) { return Array.isArray(value); }; // Returns a function with <value> argument that returns true if <value> is of type <type_string> is_of_type = function(type_string) { return function(value) { return typeof value === type_string; }; }; // Returns true if <value> is of type "string" is_object_type = is_of_type('object'); // Returns true if <value> is of type "string" is_string_type = is_of_type('string'); // The regular expression pattern of a valid logic signal, as a string logic_signal_pattern = '^\\s*\\[?(\\s*[+-]?\\d+?(?:,\\s*[+-]?\\d+)*)\\]?(?:\\s*@\\s*(\\d+))?(?:\\s*\\*\\s*(\\d+))?\\s*$'; // The regular expression pattern of a valid logic signal, as a RegExp logic_signal_regexp = new RegExp(logic_signal_pattern); // Repeat array <array> <number_of_repetitions> times repeat_array = function(array, number_of_repetitions) { var i, index, ref, results; results = []; for (index = i = 0, ref = array.length * number_of_repetitions; i < ref; index = i += 1) { results.push(array[index % array.length]); } return results; }; // This class represents a logic/binary signal Logic_Signal = class { constructor(data, cycle_time, repetitions) { var cycle_string; if (is_array(data)) { this.cycles = data; this.cycle_time = cycle_time; this.repetitions = repetitions; } else if (is_object_type(data)) { this.cycles = data.cycles; this.cycle_time = data.cycle_time; this.repetitions = data.repetitions; } else if (is_string_type(data)) { data = logic_signal_regexp.exec(data); this.cycles = (function() { var i, len, ref, results; ref = data[1].split(','); results = []; for (i = 0, len = ref.length; i < len; i++) { cycle_string = ref[i]; results.push(parseInt(cycle_string)); } return results; })(); this.cycle_time = data[2]; this.repetitions = data[3]; } else { throw new Error('Logic signal constructor called with invalid arguments'); } this.cycle_time = first_valid_value(this.cycle_time, 1); this.repetitions = first_valid_value(this.repetitions, 1); } get_unrepeated_timings() { return this.cycles.map((cycle) => { return cycle * this.cycle_time; }); } get_timings() { return repeat_array(this.get_unrepeated_timings(), this.repetitions); } compress() { var cycle_time, cycles, repetitions, timing, timings, unrepeated_timings; timings = this.get_timings(); repetitions = get_number_of_repetitions_in_array(timings); unrepeated_timings = timings.slice(0, Math.floor(timings.length / repetitions)); cycle_time = greatest_common_divisor_in_array(unrepeated_timings); cycles = (function() { var i, len, results; results = []; for (i = 0, len = unrepeated_timings.length; i < len; i++) { timing = unrepeated_timings[i]; results.push(Math.floor(timing / cycle_time)); } return results; })(); return new Logic_Signal(cycles, cycle_time, repetitions); } to_string() { return `${this.cycles.join(',')}@${this.cycle_time}*${this.repetitions}`; } to_timings_string() { return this.get_timings().join(','); } }; // What this module exports module.exports = Logic_Signal; //# sourceMappingURL=logic_signal.js.map