Before I set out on a long journey of code, I wanted to know if Pico-8 had the ability to do something like this:
a=sum("(3+4)*2") print(a) |
Where the answer would come back 12. And yes, the statement needs to be in a string and be able to handle one or more parentheses math.
The TRS-80 could do this:
INPUT A$ PRINT A$ |
And B4GL could as well.
INPUT A$ CODE("PRINT "+A$) |
Not really, but you could easily build your own function using the Shunting-Yard algorithm and Reverse Polish notation.
The Shunting-Yard algorithm is an algorithm that takes a table like this:
{ "(", 3, "+", 4, ")", "*", "2" }
and spits out another table like this:
{ 3, 4, "+", 2, "*" }
...which you can then easily calculate using Reverse Polish notation. The following is a representation of the stack doing a calculation. If it's a number, it gets added to the stack, if it's an operator, it takes however many things it needs off the stack, and adds the result back onto the stack.
3 3 4 3 4 + ** 3 + 4 = 7, so add 7 to the stack ** 7 7 2 7 2 * ** 7 * 2 = 14, so add 14 to the stack ** 14 ** Result = 14 ** |
Both of these concepts have fancy names, but they're much more simple than you think.
I know you just stated "the statement needs to be in a string" but it's trivial to convert that string into the table I supplied. Maybe some algorithm that does this? (quotes on left is input, table on right is output)
"(3.5+4)*2" {} "3.5+4)*2" { "(" } "+4)*2" { "(", 3.5 } "4)*2" { "(", 3.5, "+" } ")*2" { "(", 3.5, "+", 4 } "*2" { "(", 3.5, "+", 4, ")" } "2" { "(", 3.5, "+", 4, ")", "*" } "" { "(", 3.5, "+", 4, ")", "*", 2 } |
The hardest part is probably knowing where a number starts and ends. (You can probably treat numbers like "5e2" as
{ 5, "e", 2 }
without any problems, just remember to support the "e" token in your RPN function)
Edit: formatting error, oof
You hear that ? That's the sound of my head exploding. :)
O K A Y ... so I might do easier by the way I had planned earlier.
- Find deepest parentheses nest (if any).
- Work with just that for the moment.
- Calculate stuff inside there, SQRT ^ / * - + in that order.
- replace that area with new sub-calculated sum.
- repeat until only digits and optional decimal point remain.
- Done.
Thanks for that answer TheV360 but WOW whatta way to go !
Actually, with a bit of Googling, I found a more coherent explanation:
Stack Machines - Fundamentals
Stack Machines - RPN
Stack Machines - Shunting-yard
This series of blog posts seems like a good resource, but I'm only recommending the first 3 because if you keep reading the posts, they just straight up go and make a computer in the second half. (hate it when that happens, just trying to make a thing and suddenly it's turing complete)
Also, with your algorithm -- there's a few gotchas hidden in there, and they're addressed in the Shunting Yard Algorithm.
But the worst part about this is... even though I've been recommending you the Shunting-yard Algorithm, I... haven't actually ever implemented it. I'll try to, and hopefully I'll reply with an example cart in either an hour or a week.
Edit: whoops, here we go again.
[Please log in to post a comment]