about summary refs log blame commit diff stats
path: root/lua/chupacabra/chupacabra.lua
blob: 645d3277b26921fde95fc562ec0be3e546848c65 (plain) (tree)














































































                                                                                                                     
local chupacabra = {}

-- TODO: add the ability to push and pop arrays from the stack

-- Parse a string into a list of tokens
function chupacabra.tokenize(str)
    local tokens = {}
    for token in string.gmatch(str, "%S+") do
        table.insert(tokens, token)
    end
    return tokens
end

function chupacabra.evaluate(tokens, context)
    local stack = {}

    for _, token in ipairs(tokens) do
        if tonumber(token) then
            table.insert(stack, tonumber(token))
        elseif token == "pop" then
            table.remove(stack) -- testing is fun
        elseif token == "+" then
            local b = table.remove(stack)
            local a = table.remove(stack)
            table.insert(stack, a + b)
        elseif token == "-" then
            local b = table.remove(stack)
            local a = table.remove(stack)
            table.insert(stack, a - b)
        elseif token == "*" then
            local b = table.remove(stack)
            local a = table.remove(stack)
            table.insert(stack, a * b)
        elseif token == "/" then
            local b = table.remove(stack)
            local a = table.remove(stack)
            table.insert(stack, a / b)
        elseif token == "map+" then
            -- If the token is "map+", pop an array from the stack, add 1 to each element, and push the result
            local a = table.remove(stack)
            for i, v in ipairs(a) do
                a[i] = v + 1
            end
            table.insert(stack, a)
        elseif token == "map*" then
            -- If the token is "map*", pop an array from the stack, multiply each element by 2, and push the result
            local a = table.remove(stack)
            for i, v in ipairs(a) do
                a[i] = v * 2
            end
            table.insert(stack, a)
        elseif token == "map-" then
            -- If the token is "map-", pop an array from the stack, subtract 1 from each element, and push the result
            local a = table.remove(stack)
            for i, v in ipairs(a) do
                a[i] = v - 1
            end
            table.insert(stack, a)
        elseif token == "map/" then
            -- If the token is "map/", pop an array from the stack, divide each element by 2, and push the result
            local a = table.remove(stack)
            for i, v in ipairs(a) do
                a[i] = v / 2
            end
            table.insert(stack, a)
        else
            error("invalid token: " .. token)
        end
    end

    return table.remove(stack)
end

function chupacabra.run(str, context)
    local tokens = chupacabra.tokenize(str)
    return chupacabra.evaluate(tokens, context)
end

return chupacabra