Building a CLI App

We will utilize the basic calculator app logic from the parsing guide to produce a linked calculator agent %rpn supporting the following operators by the appropriate parsers:

  • numbers (as @rs without . dot prefix) (royl-rs:so)

  • + lus, addition (lus)

  • - hep, subtraction (hep)

  • * tar, multiplication (tar)

  • / fas, division (fas)

  • . dot, display top of stack (dot)

We will leave all regular Gall arms as their defaults, but of course poking, subscribing, and peeking should be supported in a full application.

Agent Logic

/sur/rpn.hoon

We just need to define the expected operators that will show up in the stack. These are @t text constants.

|%
+$  op  $?  [%op %add]
            [%op %sub]
            [%op %mul]
            [%op %div]
            [%op %sho]
        ==
+$  num  @rs
+$  command  ?(@rs op)
--

($command doesn't really feel like the right name here, but we're pattern-matching with the demo /app/shoe.hoon.)

/lib/rpn.hoon

These are the parsing rules that the CLI agent will use. We could include these directly in the agent file but we'll post them to a library file.

/app/rpn.hoon

+command-parser

We want this arm to wait until RETURN is pressed so we +stag the value with | FALSE/%.n.

+on-command

This arm pushes values onto the stack, displays the stack, then checks to parse for the result of an operation.

For this we add a helper arm to /lib/rpn.hoon which takes each entry, makes sure it is a @rs atom, and carries out the operation. (This could probably be made more efficient.)

/lib/rpn.hoon

Linking

After a %sole agent has been |installed, it should be registered for Dojo to cycle input to it using |dojo/link.

Now Ctrl+X allows you to switch to that app and evaluate expressions using it.

Exercises

  • Extend the calculator app to support modulus as % cen.

  • Extend the calculator app so it instead operates on @rd values. Either use +cook to automatically convert the input values from a 1.23-style input to the .~1.23 @rd style or build a different input parser from the entries in +royl:so.

  • Extend the calculator app so that it can support named variables (using @tas) with = tis. What new data structure do you need? For convenience, expose the result of the last operation as ans (a feature of TI graphing calculators and MATLAB, among other programs).

  • The calculator app stack isn't really a proper CS stack with push and pop operations. Refactor it to use such a type.

Last updated