-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser_suffixparselets.lua
110 lines (90 loc) · 2.72 KB
/
parser_suffixparselets.lua
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
local infixOperators = require("parser_infixoperators")
local function newSubscript(left)
return {
type = "subscript",
left = left,
exprs = {}
}
end
local function newFunctionCall(funcExpr)
return {
type = "function-call",
funcExpr = funcExpr,
args = {}
}
end
local function newUnaryPostfix(left, symbol)
return {
type = "unary-postfix",
left = left,
symbol = symbol
}
end
local function newBinaryOperator(symbol, left, right)
return {
type = "binary-operator",
symbol = symbol,
left = left,
right = right
}
end
local function newTernaryOperator(condExpr, thenExpr, elseExpr)
return {
type = "ternary-operator",
condExpr = condExpr,
thenExpr = thenExpr,
elseExpr = elseExpr
}
end
return {
{
token = { type = TokenType.OPERATOR },
func = function(parser, left, token)
if (token.contents == "--" or token.contents == "++") then
return newUnaryPostfix(left, token.contents)
end
local operator = infixOperators[token.contents]
assert(operator ~= nil, "Invalid infix operator " .. tostring(token.contents))
local right = parser:parseExpression(math.max(0, operator.precedence - (operator.rightAssociative and 1 or 0)))
if (token.contents == '?') then
parser:expect(TokenType.OPERATOR, ':')
local elseExpr = parser:parseExpression(0)
return newTernaryOperator(left, right, elseExpr)
end
return newBinaryOperator(token.contents, left, right)
end
},
{
token = { type = TokenType.BRK_PAREN, contents = '(' },
func = function(parser, left, token)
local funcCall = newFunctionCall(left)
if (not parser:eos() and not (parser.currentToken.type == TokenType.BRK_PAREN and parser.currentToken.contents == ')')) then
repeat
table.insert(funcCall.args, parser:parseExpression(0))
until (parser:eos() or parser.currentToken.type ~= TokenType.COMMA)
end
parser:expect(TokenType.BRK_PAREN, ')')
return funcCall
end
},
{
token = { type = TokenType.BRK_SQUARE, contents == '[' },
func = function(parser, left, token)
local subscript = newSubscript(left)
if (parser:eos() or parser.currentToken.type == TokenType.BRK_SQUARE and parser.currentToken.contents == ']') then
error("[Parser] expected expression")
end
repeat
table.insert(subscript.exprs, parser:parseExpression(0))
until (parser:eos() or parser.currentToken.type ~= TokenType.COMMA)
parser:expect(TokenType.BRK_SQUARE, ']')
return subscript
end
},
{
token = { type = TokenType.DOT },
func = function(parser, left, token)
return newBinaryOperator('.', left, { type = "identifier", identifier = parser:expect(TokenType.IDENTIFIER) })
end
}
}