Re: RPN example? SOLVED

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
FredBeck
Posts: 77
Joined: Fri Nov 01, 2013 3:07 pm
Location: Paris
Contact:

Re: RPN example? SOLVED

Post by FredBeck » Sun Nov 03, 2013 11:20 am

HI!
I'm new to the forum, and I'd like to thank the team first for bringing Hypercard back to life! I used to make adventure games when I was a teenager back in the 90s.
I wonder if someone could share a RPN expression example.
I've been through the RPN calculator sample stack but it's a big mess, sorry to say! Can't help to mention there is a function called Double(x) that returns x*2 :)
I tried to make my own stuff but I'm a little confused on how to pop and push from a "stack" (how should I call it btw??) and the use of passing parameters by reference in this scope.
Cheers,
Fred
Last edited by FredBeck on Sat Nov 09, 2013 7:29 pm, edited 1 time in total.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9648
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: RPN example?

Post by dunbarx » Sun Nov 03, 2013 8:42 pm

Hi.

Ah, so you conversant with HC? You will be right at home here.

This is straightforward. I would make a literal "stack" of four fields, and start with five buttons, just like the old HP-35 introduced (my first calculator): "Enter", "Plus", "Minus","Multiply" and "Divide". Simple handlers in each object script will manage the whole thing. I bet you can do this with a total of 50 lines of code.

Am I assuming too much? Write back if you need help.

Craig Newman

FredBeck
Posts: 77
Joined: Fri Nov 01, 2013 3:07 pm
Location: Paris
Contact:

Re: RPN example?

Post by FredBeck » Mon Nov 04, 2013 10:24 am

Hi Craig,
Thanks for your reply.
Yes I feel at home already =)
I should have said that I do not want to make a calculator, but I want to translate from human notation to polish notation and then compute the result. The reason I'm doing this is because I use custom operators, nothing to do with "Plus", "Minus","Multiply" and "Divide"... Also I don't know the length of my "values stack".
I think it's exactly what's in the RPN sample stack - I can see a pop and a push function and a lots of @ in the code - but it is absolutely unreadable, there is is not a single line of comment and the handler's names are all acronyms so... It doesn't really qualify as an example, does it?
Anyway I made my workaround already, I just have something like 5 consecutive parsing loops and a hack* in the end to perform the computation... I should be able to do better with the proper mechanisms.
That's why I was asking about passing parameters by reference.


* Is there a better way to evaluate a string like "2+3"to get 5 ? Is there something that could say "read this text as a script"? (I imagine could be a security issue!) Here's how I did it :

Code: Select all

put "2+3" into tExpression
set the script of button "Interface" to "on ComputeMyString" & cr & "put " & tExpression & " into field "Result"" & cr & "end ComputeMyString"
send ComputeMyString to  button "Interface"

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9648
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: RPN example?

Post by dunbarx » Mon Nov 04, 2013 8:24 pm

Hi.

So are you loading computational expressions somewhere and executing them? Do you have to create a script on the fly, and then run it? This seems clunky to me. I would try to make a gadget that you access with parameters

Is this simpler:

Code: Select all

on mouseUp
   put "2+3" into tEval
    compute tEval
end mouseUp

on compute var
   answer the value of var
end compute
You can do something similar with a "do" construction, where the expression would not have to be explicitly written in the calling handler, but could be passed as a parameter. You could then have a single working gadget, to which you send your expression. You have worked with these, I assume?

Craig

FredBeck
Posts: 77
Joined: Fri Nov 01, 2013 3:07 pm
Location: Paris
Contact:

Re: RPN example?

Post by FredBeck » Mon Nov 04, 2013 9:43 pm

Oh yes! That's what I wanted to do! Indeed it was clunky :)
I missed "the value of" and "Do" Thanks!
Coming from other languages, I was thinking "(PHP) Livecode has an eval function like perl", and "Do" was associated with "Loop while" in my mind!
Again thanks for your kind help.
F.

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9648
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: RPN example?

Post by dunbarx » Tue Nov 05, 2013 12:22 am

Good to hear.

I noticed that you were glad that HC had been resurrected, and the fact that you composed that on-the-fly handler made me think you were well experienced in it. So I meant do you remember how to use the "do" construction ala HC. The syntax and utilization are the same in LC. This would give you a much more portable tool:

Code: Select all

on mouseUp
   put "2+3" into tEval
    compute tEval
end mouseUp

on compute var
   do "answer" && var
   answer the value of var
end compute
Craig

FredBeck
Posts: 77
Joined: Fri Nov 01, 2013 3:07 pm
Location: Paris
Contact:

Re: RPN example?

Post by FredBeck » Tue Nov 05, 2013 11:05 am

You must be thinking "Who is this guy who wants to implement custom operators and doesn't even know about Do ?!?"
Back then I was 15 and I didn't really script anything. HC had a button wizard with destination an visual effect menus (I kind of miss it...). The most complex thing I did was have the Millennium Falcon hover above the desert while playing harpsichord c d e f g Soooo much fun when I think of it!
I'm a boat designer by trade, not a developer. I sometimes forget obvious stuff or mix up with other languages I've been using in Grasshopper 3D ( see my page -> ) like C# and VB .N E T and a little bit of python, + my casio college (I think the Do...LoopWhile in my head came from there!)

Thanks for the precision on the Do structure. It'll do until I sort out this stack structure issue. For the time being I'm replacing operators in my string with the actual functions they perform and then get the value of the whole. It'll allow me to go on testing the rest of my app.

Eventually I should be able to iterate through the rpn expression and do stuff like :

if tWord is "FISH" then
Push( someTernaryOperator(Pop(), Pop(), Pop()) )

else if tWord is "COOK" then
Push( someUnaryOperator(Pop()) )

etc..

FredBeck
Posts: 77
Joined: Fri Nov 01, 2013 3:07 pm
Location: Paris
Contact:

Re: RPN example? SOLVED

Post by FredBeck » Sat Nov 09, 2013 2:47 pm

Actually it was very easy! I'm not sure I did everything right but I finally got it working.
Now I just have to change my parser from PN to RPN and write my custom operators.
Thanks for the support.

Image

Code: Select all

global RPNstack

  -- Pop and Push "methods"
function stackPush @pStack pValue
   put pValue & space after pStack
   return pStack   
end stackPush

function stackPop @pStack
   local tValue
   set the itemDelimiter to space
   put word -1 of pStack into tValue
   delete item -1 of pStack
   return tValue 
end stackPop


-- Basic binary operators

function myMultiplier pArg1 pArg2
   return pArg1 * pArg2
end myMultiplier

function myAdder pArg1 pArg2
   return pArg1 + pArg2
end myAdder

#  MAIN
on computeRPN
   local tRPNexpression
   
   -- the expression to compute
   put the text of field "RPN" into tRPNexpression
   --  test :
   --  put "2 2 + 3 * 5 +" into tRPNexpression
   
   -- initialize the "stack"
   put empty into RPNstack
   
   repeat for each word tWord in tRPNexpression
      --  iterate over the RPN expression
      
      if tWord is a number then
         -- just push any numerical value
         get stackPush(RPNstack, tWord) 
         
         #  get numerical value from the key name 
         #  see that later
         --         if tWord is in th keys of gDatabase["InputVars"] then
         --            get stackPush(RPNstack, gDatabase["InputVars"][tWord])
         --         else
         --            answer "Input var not found"
         --            exit computeRPN
         
      else
         --  operator found,  pop the arguments out of the stack and push the result
         switch tWord
            case "*"
               get stackPush(RPNstack, myMultiplier( stackPop(RPNstack) , stackPop(RPNstack))) 
               break
            case "+"
               get stackPush(RPNstack, myAdder( stackPop(RPNstack) , stackPop(RPNstack)))
               break
         end switch
         
      end if
      
      --  Debug : display stack (breakpoint)
      put it & cr after field "the Stack"
      
   end repeat
   -- show the result
   
   put RPNstack into field "Result"
   
end computeRPN

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”