diff options
author | elioat <elioat@tilde.institute> | 2024-06-09 11:10:57 -0400 |
---|---|---|
committer | elioat <elioat@tilde.institute> | 2024-06-09 11:10:57 -0400 |
commit | b72b5e6ab57173afd5daa555396f8d0c7aa9c1f6 (patch) | |
tree | 6722e5f6d97a7c54d707ce0f5ff77226bef6a108 | |
parent | 0d5a8c704d517e7f880c5b704867e3d491e9ec8f (diff) | |
download | tour-b72b5e6ab57173afd5daa555396f8d0c7aa9c1f6.tar.gz |
*
-rw-r--r-- | lua/chupacabra/chupacabra.lua | 79 | ||||
-rw-r--r-- | lua/chupacabra/scratch.lua | 1 | ||||
-rw-r--r-- | lua/chupacabra/test_chupacabra.lua | 22 |
3 files changed, 102 insertions, 0 deletions
diff --git a/lua/chupacabra/chupacabra.lua b/lua/chupacabra/chupacabra.lua new file mode 100644 index 0000000..645d327 --- /dev/null +++ b/lua/chupacabra/chupacabra.lua @@ -0,0 +1,79 @@ +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 \ No newline at end of file diff --git a/lua/chupacabra/scratch.lua b/lua/chupacabra/scratch.lua new file mode 100644 index 0000000..e0bab8c --- /dev/null +++ b/lua/chupacabra/scratch.lua @@ -0,0 +1 @@ +local chupacabra = require("chupacabra") \ No newline at end of file diff --git a/lua/chupacabra/test_chupacabra.lua b/lua/chupacabra/test_chupacabra.lua new file mode 100644 index 0000000..4d75f70 --- /dev/null +++ b/lua/chupacabra/test_chupacabra.lua @@ -0,0 +1,22 @@ +local chupacabra = require("chupacabra") + +-- Define a function to run a test case +local function test_case(input, expected_output) + local output = chupacabra.run(input, {}) + assert(output == expected_output, "Test failed: " .. input .. " => " .. output .. ", expected: " .. expected_output) + print("Test passed: " .. input .. " => " .. output) +end + + +-- Run some test cases +test_case("1", 1) -- 1 +test_case("2 1 pop", 2) -- 2 +test_case("3 4 +", 7) -- 3 + 4 = 7 +test_case("5 2 -", 3) -- 5 - 2 = 3 +test_case("2 3 *", 6) -- 2 * 3 = 6 +test_case("8 2 /", 4) -- 8 / 2 = 4 +test_case("2 3 4 + *", 14) -- 2 * (3 + 4) = 14 +test_case("5 2 3 + 4 + +", 14) -- 5 + 2 + 3 + 4 = 14 +test_case("7 2 + 3 4 + +", 16) -- 7 + 2 + 3 + 4 = 16 +test_case("5 2 - 3 4 * +", 15) -- (5 - 2) + (3 * 4) = 15 +test_case("8 2 / 3 4 * +", 16) -- (8 / 2) + (3 * 4) = 16 \ No newline at end of file |