-
Notifications
You must be signed in to change notification settings - Fork 83
/
HexColor.js
73 lines (60 loc) · 1.92 KB
/
HexColor.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
var isHex = require('../../tokenizer').isHex;
var TYPE = require('../../tokenizer').TYPE;
var IDENTIFIER = TYPE.Identifier;
var NUMBER = TYPE.Number;
var NUMBERSIGN = TYPE.NumberSign;
function consumeHexSequence(scanner, required) {
if (!isHex(scanner.source.charCodeAt(scanner.tokenStart))) {
if (required) {
scanner.error('Unexpected input', scanner.tokenStart);
} else {
return;
}
}
for (var pos = scanner.tokenStart + 1; pos < scanner.tokenEnd; pos++) {
var code = scanner.source.charCodeAt(pos);
// break on non-hex char
if (!isHex(code)) {
// break token, exclude symbol
scanner.tokenStart = pos;
return;
}
}
// token is full hex sequence, go to next token
scanner.next();
}
// # ident
module.exports = {
name: 'HexColor',
structure: {
value: String
},
parse: function() {
var start = this.scanner.tokenStart;
this.scanner.eat(NUMBERSIGN);
scan:
switch (this.scanner.tokenType) {
case NUMBER:
consumeHexSequence(this.scanner, true);
// if token is identifier then number consists of hex only,
// try to add identifier to result
if (this.scanner.tokenType === IDENTIFIER) {
consumeHexSequence(this.scanner, false);
}
break;
case IDENTIFIER:
consumeHexSequence(this.scanner, true);
break;
default:
this.scanner.error('Number or identifier is expected');
}
return {
type: 'HexColor',
loc: this.getLocation(start, this.scanner.tokenStart),
value: this.scanner.substrToCursor(start + 1) // skip #
};
},
generate: function(processChunk, node) {
processChunk('#', node.value);
}
};