Log In  


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$)


1

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.

  1. Find deepest parentheses nest (if any).
  2. Work with just that for the moment.
  3. Calculate stuff inside there, SQRT ^ / * - + in that order.
  4. replace that area with new sub-calculated sum.
  5. repeat until only digits and optional decimal point remain.
  6. 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]