-
Notifications
You must be signed in to change notification settings - Fork 1
/
parser.js
114 lines (96 loc) · 2.93 KB
/
parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
'use strict';
function range(start, end, increment) {
const result = [];
const b = start <= end;
for (let i = start; b ? i <= end : i >= end; i+=increment) {
result.push(i);
}
return result;
}
function parse(text) {
let circuit = {
wires: 0, gates: 0,
inputs: [], outputs: [],
gate: [],
inputLine: '',
outputLine: ''
};
const bristol = text.split('\n').map(function (line) {
const i = line.indexOf('#');
if (i > -1) {
line = line.substring(0, i-1);
}
line = line.trim();
if (line.length === 0) {
return [];
}
line = line.split(' ').filter(function (word) {
return word.length > 0
});
for (let j = 0; j < line.length; j++) {
const word = line[j];
const i1 = word.indexOf('[');
const i2 = word.indexOf(']');
if (i1 < i2 && i1 > -1 && i2 > -1) {
let range_ = word.substring(i1+1, i2);
if (range_.indexOf(':') > -1) {
range_ = range_.split(':');
range_ = range(+range_[0], +range_[1], +range_[2] || 1);
line = line.splice(0, j).concat(range_, line.slice(1));
j += range_.length - 1;
} else if (range_.indexOf('|>') > -1) {
range_ = range_.split('|>');
range_ = range(+range_[0], +range_[0] + +range_[1] - 1, 1);
line = line.splice(0, j).concat(range_, line.slice(1));
j += range_.length - 1;
}
}
}
return line;
}).filter(function (line) {
return line.length > 0;
});
circuit.wires = +bristol[0][1];
const inputsCount = bristol[1].slice(1).reduce((a, v) => parseInt(v) + a, 0);
for (let i = 0; i < inputsCount; i++) {
circuit.inputs.push(i);
}
for (let i = 0; i < bristol.length-3; i++) {
let args = bristol[i+3];
let gate = {inputs: [], outputs: [], type: args[2+(+args[0])+(+args[1])]};
for (let j = 0; j < parseInt(args[0]); j++) {
gate.inputs.push(+args[2+j]);
}
for (let j = 0; j < parseInt(args[1]); j++) {
gate.outputs.push(+args[2+(+args[0])+j]);
}
circuit.gate.push(gate);
}
circuit.gates = circuit.gate.length;
const outputsCount = bristol[2].slice(1).reduce((a, v) => parseInt(v) + a, 0);
for (let i = circuit.wires - outputsCount; i < circuit.wires; i++) {
circuit.outputs.push(i);
}
circuit.inputLine = bristol[1];
circuit.outputLine = bristol[2];
return circuit;
}
function stringify(circuit) {
const bristol = [];
// Encode header information and gates
bristol[0] = [circuit.gates, circuit.wires];
bristol[1] = circuit.inputLine;
bristol[2] = circuit.outputLine;
for (let i = 0; i < circuit.gate.length; i++) {
const gate = circuit.gate[i];
bristol[i+3] = gate.inputs.concat(gate.outputs);
bristol[i+3].unshift(gate.inputs.length, gate.outputs.length);
bristol[i+3].push(gate.type);
}
// Stringify
return bristol.map(line => line.join(' ')).join('\n');
}
module.exports = {
parse: parse,
stringify: stringify
};