61 lines
1.5 KiB
Lua
61 lines
1.5 KiB
Lua
local util = require "core:bitwise/util"
|
|
|
|
local tokenizer = require "core:bitwise/tokenizer"
|
|
|
|
local types = tokenizer.types
|
|
|
|
local priorities =
|
|
{
|
|
[types.bnot] = 4,
|
|
[types.lshift] = 3,
|
|
[types.rshift] = 3,
|
|
[types.band] = 2,
|
|
[types.bxor] = 1,
|
|
[types.bor] = 0
|
|
}
|
|
|
|
local function parse(str)
|
|
local stack = { }
|
|
local output = { }
|
|
|
|
for _, token in ipairs(tokenizer.get_tokens(str)) do
|
|
if table.has(tokenizer.numTypes, token.type) or token.type == types.id then
|
|
table.insert(output, token)
|
|
elseif table.has(tokenizer.operatorTypes, token.type) then
|
|
local firstOp = util.stack.top(stack)
|
|
|
|
if firstOp and table.has(tokenizer.operatorTypes, firstOp.type) and priorities[firstOp.type] >= priorities[token.type] then
|
|
table.insert(output, util.stack.pop(stack))
|
|
end
|
|
|
|
util.stack.push(stack, token)
|
|
elseif token.type == types.openingBracket then
|
|
util.stack.push(stack, token)
|
|
elseif token.type == types.closingBracket then
|
|
while true do
|
|
local topToken = util.stack.top(stack)
|
|
|
|
if not topToken then util.throw(token.column, "unexpected closing bracket")
|
|
elseif topToken.type == types.openingBracket then break end
|
|
|
|
table.insert(output, util.stack.pop(stack))
|
|
end
|
|
|
|
util.stack.pop(stack)
|
|
end
|
|
end
|
|
|
|
while #stack > 0 do
|
|
local token = util.stack.pop(stack)
|
|
|
|
if token.type == types.openingBracket then
|
|
util.throw(token.column, "unclosed bracket")
|
|
end
|
|
|
|
table.insert(output, token)
|
|
end
|
|
|
|
return output
|
|
end
|
|
|
|
return parse |