Skip to content

Commit 4a006ac

Browse files
committed
More examples
1 parent fea5b55 commit 4a006ac

File tree

3 files changed

+219
-1
lines changed

3 files changed

+219
-1
lines changed

JavaScript/8-method.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ const obj1 = {
1313
max: (a, b) => {
1414
return a > b ? a : b;
1515
},
16-
min: (a, b) => (a < b ? a : b)
16+
min: (a, b) => (a < b ? a : b),
17+
dec: a => --a
1718
};
1819

1920
console.log('obj1.f1.name = ' + obj1.f1.name);

JavaScript/c-comments.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
3+
const fs = require('fs');
4+
5+
const printLine = (
6+
// Print specified line from a file
7+
fileName, // file to parse
8+
lineNumber // number, line starting from 1
9+
// Returns: boolean, success status
10+
) => {
11+
const content = fs.readFileSync(fileName).toString();
12+
const lines = content.split('\n');
13+
const line = lines[lineNumber - 1];
14+
if (line === undefined) return false;
15+
console.dir({
16+
fileName, lineNumber, line
17+
});
18+
return true;
19+
};
20+
21+
printLine('./c-comments.js', 5);

JavaScript/d-decompose.js

+196
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
'use strict';
2+
3+
const merge = (
4+
// Distinct merge miltiple arrays
5+
...args // array of array
6+
// Returns: array
7+
) => {
8+
const array = args[0];
9+
let i, ilen, j, jlen, arr, val;
10+
for (i = 1, ilen = args.length; i < ilen; i++) {
11+
arr = args[i];
12+
for (j = 0, jlen = arr.length; j < jlen; j++) {
13+
val = arr[j];
14+
if (!array.includes(val)) array.push(val);
15+
}
16+
}
17+
return array;
18+
};
19+
20+
const section = (
21+
// Splits string by the first occurrence of separator
22+
s, // string
23+
separator // string, or char
24+
// Example: rsection('All you need is JavaScript', 'is')
25+
// Returns: ['All you need ', ' JavaScript']
26+
) => {
27+
const i = s.indexOf(separator);
28+
if (i < 0) return [s, ''];
29+
return [s.slice(0, i), s.slice(i + separator.length)];
30+
};
31+
32+
const SCALAR_TYPES = ['string', 'number', 'boolean', 'undefined'];
33+
const OBJECT_TYPES = ['function', 'array', 'object', 'null', 'symbol'];
34+
const META_TYPES = ['char', 'hash', 'record', 'set', 'map'];
35+
const ALL_TYPES = merge(SCALAR_TYPES, OBJECT_TYPES, META_TYPES);
36+
37+
const FUNC_TERMS = [') {', ') => {', ') => ('];
38+
const NAMED_LINES = ['Example:', 'Returns:', 'Hint:', 'Result:'];
39+
40+
const indexing = s => term => s.indexOf(term);
41+
42+
const last = arr => arr[arr.length - 1];
43+
44+
const parseLines = (
45+
// Parse signature lines
46+
s, // string, signature lines
47+
signature // record, { title, description, parameters, comments }
48+
// Returns: array of string
49+
) => {
50+
let lines = s.split('\n');
51+
lines.pop();
52+
signature.title = (lines.shift() || '').replace('//', '').trim();
53+
lines = lines.map(
54+
d => d.trim().replace(/^(.*) \/\//, '$1:').replace(',:', ':')
55+
);
56+
for (let line of lines) {
57+
if (line.startsWith('//')) {
58+
line = line.replace(/^\/\/ /, '').trim();
59+
if (NAMED_LINES.find(s => line.startsWith(s))) {
60+
const [name, comment] = section(line, ': ');
61+
signature.comments.push({ name, comment });
62+
} else if (signature.parameters.length === 0) {
63+
if (signature.description.length > 0) {
64+
signature.description += '\n';
65+
}
66+
signature.description += line;
67+
} else {
68+
const par = last(signature.parameters);
69+
par.comment += '\n' + line;
70+
}
71+
} else {
72+
const [name, text] = section(line, ': ');
73+
let [type, comment] = section(text, ', ');
74+
if (!ALL_TYPES.find(s => type.startsWith(s))) {
75+
comment = type;
76+
type = '';
77+
}
78+
signature.parameters.push({ name, type, comment });
79+
}
80+
}
81+
};
82+
83+
const parseSignature = (
84+
// Parse function signature
85+
fn // function, method
86+
// Returns: { title, description, parameters, comments }
87+
) => {
88+
const signature = {
89+
title: '', description: '',
90+
parameters: [], comments: []
91+
};
92+
let s = fn.toString();
93+
let pos = FUNC_TERMS.map(indexing(s))
94+
.filter(k => k !== -1)
95+
.reduce((prev, cur) => (prev < cur ? prev : cur), s.length);
96+
if (pos !== -1) {
97+
s = s.substring(0, pos);
98+
pos = s.indexOf('\n');
99+
s = s.substring(pos + 1);
100+
parseLines(s, signature);
101+
}
102+
return signature;
103+
};
104+
105+
const introspect = (
106+
// Introspect interface
107+
namespace // hash of interfaces
108+
// Returns: hash of hash of record, { method, title, parameters }
109+
) => {
110+
const inventory = {};
111+
let name, iface, methods, method, fn, signature;
112+
for (name in namespace) {
113+
iface = namespace[name];
114+
methods = {};
115+
inventory[name] = methods;
116+
for (method in iface) {
117+
fn = iface[method];
118+
signature = parseSignature(fn);
119+
signature = Object.assign({
120+
method: name + '.' + method
121+
}, signature);
122+
methods[method] = signature;
123+
}
124+
}
125+
return inventory;
126+
};
127+
128+
const badIntrospect = (
129+
// Introspect interface
130+
namespace // hash of interfaces
131+
// Returns: hash of hash of record, { method, title, parameters }
132+
) => {
133+
const inventory = {};
134+
let name, iface, methods, method, fn, signature;
135+
for (name in namespace) {
136+
iface = namespace[name];
137+
methods = {};
138+
inventory[name] = methods;
139+
for (method in iface) {
140+
fn = iface[method];
141+
signature = {
142+
title: '', description: '',
143+
parameters: [], comments: []
144+
};
145+
let s = fn.toString();
146+
let pos = FUNC_TERMS.map(indexing(s))
147+
.filter(k => k !== -1)
148+
.reduce((prev, cur) => (prev < cur ? prev : cur), s.length);
149+
if (pos !== -1) {
150+
s = s.substring(0, pos);
151+
pos = s.indexOf('\n');
152+
s = s.substring(pos + 1);
153+
let lines = s.split('\n');
154+
lines.pop();
155+
signature.title = (lines.shift() || '').replace('//', '').trim();
156+
lines = lines.map(
157+
d => d.trim().replace(/^(.*) \/\//, '$1:').replace(',:', ':')
158+
);
159+
for (let line of lines) {
160+
if (line.startsWith('//')) {
161+
line = line.replace(/^\/\/ /, '').trim();
162+
if (NAMED_LINES.find(s => line.startsWith(s))) {
163+
const [name, comment] = section(line, ': ');
164+
signature.comments.push({ name, comment });
165+
} else if (signature.parameters.length === 0) {
166+
if (signature.description.length > 0) {
167+
signature.description += '\n';
168+
}
169+
signature.description += line;
170+
} else {
171+
const par = last(signature.parameters);
172+
par.comment += '\n' + line;
173+
}
174+
} else {
175+
const [name, text] = section(line, ': ');
176+
let [type, comment] = section(text, ', ');
177+
if (!ALL_TYPES.find(s => type.startsWith(s))) {
178+
comment = type;
179+
type = '';
180+
}
181+
signature.parameters.push({ name, type, comment });
182+
}
183+
}
184+
}
185+
signature = Object.assign({
186+
method: name + '.' + method
187+
}, signature);
188+
methods[method] = signature;
189+
}
190+
}
191+
return inventory;
192+
};
193+
194+
const iface = { common: { merge, section } };
195+
console.dir(introspect(iface));
196+
console.dir(badIntrospect(iface));

0 commit comments

Comments
 (0)