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
|
/* <copyright>
This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
</copyright> */
var Montage = require("montage").Montage;
var AbstractSemantics = exports.AbstractSemantics = Montage.create(Montage, {
create: {
value: function (prototype, descriptor) {
var self = Montage.create(prototype, descriptor);
var operators = self.operators;
self.evaluatorArgumentLengths = {};
// convert the declared operators into evaluators
Object.keys(operators).forEach(function (name) {
var operate = operators[name];
self.evaluators[name] = function () { // ...args
var args = Array.prototype.slice.call(
arguments,
0,
operate.length
);
return function (value, parameters, visitor) {
return operate.apply(
operators,
args.map(function (argument) {
return argument(value, parameters, visitor);
})
);
};
};
self.evaluatorArgumentLengths[name] = operate.length;
});
return self;
}
},
evaluatorArgumentLengths: {
value: null
},
compile: {
value: function (syntax, parents) {
var self = this;
parents = {
syntax: syntax,
parents: parents
};
if (syntax.type === 'value') {
return function (value) {
return value;
};
} else if (syntax.type === 'parameters') {
return function (value, parameters) {
return parameters;
};
} else if (syntax.type === 'literal') {
return function () {
return syntax.value;
};
} else if (self.evaluators[syntax.type]) {
var evaluator = self.evaluators[syntax.type];
var length =
self.evaluatorArgumentLengths[syntax.type] ||
evaluator.length;
var args = syntax.args.map(function (child) {
return self.compile(child, parents);
});
if (syntax.insensitive) {
args = args.map(function (evaluate) {
return function (value, parameters, visitor) {
return evaluate.call(
self,
value,
parameters,
visitor
).toLowerCase();
};
})
}
return evaluator.apply(self, args.concat([parents]));
} else {
throw new Error("Unknown evaluator " + syntax.type);
}
}
},
evaluate: {
value: function (syntax, value, parameters, visitor) {
return this.compile(syntax)(value, parameters, visitor);
}
}
});
|