-
Notifications
You must be signed in to change notification settings - Fork 0
/
semantics.js
111 lines (111 loc) · 4.19 KB
/
semantics.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
var grammar = require('./grammar');
var Expression = require('./Expression');
var Declaration = require('./Declaration');
var semantics = grammar.createSemantics().addOperation('parse', {
number: (integer, dot, decimal) => new Expression.Literal(+(integer.sourceString + dot.sourceString)),
string: (open, x, close) => new Expression.Literal(x.children.map(char => char.parse()).join('')),
char_literal: x => x.sourceString,
char_escaped: (backslash, x) => escape[x.sourceString],
identifier: (_, x) => x.sourceString,
ExpressionName: (global, identifier) => new Expression.Name(identifier.parse(), global.sourceString ? Infinity : null),
ExpressionThis: (_this, identifier) => new Expression.This(identifier.parse()),
ExpressionObjectProperty: (name, colon, value) => ({ name: name.parse(), value: value.parse() }),
ExpressionObject: (open, property, close) => new Expression.Object(property.asIteration().parse()),
ExpressionArray: (open, element, close) => new Expression.Array(element.asIteration().parse()),
ExpressionTuple: (open, element, close) => new Expression.Tuple(element.asIteration().parse()),
ExpressionAtom_parentheses: (open, expression, close) => expression.parse(),
ExpressionAtom_placeholder: (open, name, close) => new Expression.Placeholder(name.parse()),
ExpressionId_id: (table, sharp, id) => new Expression.Id(table.parse(), id.parse()),
ExpressionCall_call: (expression, argument) => new Expression.Call(expression.parse(), argument.parse()),
ExpressionMember_property: (expression, dot, property) => new Expression.Property(expression.parse(), property.parse()),
ExpressionMember_element: (expression, at, index) => new Expression.Element(expression.parse(), index.parse()),
ExpressionCount_count: unary,
ExpressionAdd_add: binary,
ExpressionMultiply_multiply: binary,
ExpressionAddUnary_add: unary,
ExpressionRelation_relation: binary,
ExpressionNot_not: unary,
ExpressionAnd_and: binary,
ExpressionOr_or: binary,
ExpressionConditional_conditional: (condition, question, _true, colon, _false) => new Expression.Conditional(
condition.parse(),
_true.parse(),
_false.parse()
),
ExpressionQuery_filter: (expression, where, filter) => new Expression.Filter(
expression.parse(),
filter.parse()
),
ExpressionQuery_which: (expression, which, filter) => new Expression.Which(
expression.parse(),
filter.parse()
),
ExpressionQuery_map: (expression, map, mapper) => new Expression.Map(
expression.parse(),
mapper.parse()
),
ExpressionQuery_limit: (expression, limit, limiter) => new Expression.Limit(
expression.parse(),
limiter.parse()
),
ExpressionQuery_order: (expression, order, orderer, direction) => new Expression.Order(
expression.parse(),
orderer.parse(),
{ asc: false, desc: true }[direction.sourceString]
),
ExpressionQuery_group: (expression, group, grouper) => new Expression.Group(
expression.parse(),
grouper.parse()
),
ExpressionQuery_distinct: (distinct, expression) => new Expression.Distinct(
expression.parse()
),
ExpressionComma_comma: (name, equal, value, comma, body) => new Expression.Comma(
{
name: name.parse(),
value: value.parse()
},
body.parse()
),
Declaration: (name, open, statement, close) => new Declaration(
name.parse(),
statement.children.map(p => p.parse())
),
DeclarationPropertyType: (identifier, colon, type, semicolon) => new Declaration.Statement.Property(identifier.parse(), { type: type.parse() }),
DeclarationPropertyValue: (identifier, equal, value, semicolon) => new Declaration.Statement.Property(identifier.parse(), { value: value.parse() }),
DeclarationId: (id, identifier, semicolon) => new Declaration.Statement.Id(identifier.parse())
});
function binary(left, operator, right) {
return new Expression.Operation(
operator.sourceString,
left.parse(),
right.parse()
);
}
function unary(operator, operand) {
if (operator.isTerminal())
return new Expression.Operation(
operator.sourceString,
undefined,
operand.parse()
);
else {
[operator, operand] = [operand, operator];
return new Expression.Operation(
operator.sourceString,
operand.parse(),
undefined
);
}
}
var escape = {
'"': '"',
'\\': '\\',
b: '\b',
f: '\f',
n: '\n',
r: '\r',
t: '\t',
v: '\v'
};
module.exports = semantics;