# Infix expression parser

The unit at /comp/infix.fs parses infix expressions using regular mathematical
rules:

1. Operators are binary, with the first operand coming before the operator and
   the second operand coming after it. Ex: 1 + 2.
2. Operators can be chained. Ex: 1 + 2 - 3.
3. Operators have "priority" score. A lower score trumps a higher score. For
   example, if "+" has a score of 1 and "*" a score of 0, in "1 + 2 * 3", "2 *
   3" is applied first with its result feeding "1 +".
4. Operators can share the same priority. In those cases, operators are applied
   from left to right. In "1 + 2 - 3", "1 + 2" is applied, then the result of
   this is fed to "- 3".
5. An operator can have its "rwins" flag set, in which case, the right part
   "wins" in case of a priority tie.
6. Parentheses can be used to override operator priorities. Expressions inside
   parentheses are always applied first. For example, in "(1 + 2) * 3", "1 + 2"
   is applied first.

## Usage

The expression parser, "infix< ( 'term< ops -- )" feeds itself from a
"term< ( -- term )" word, with "term" being expected to follow [doc/comp/tok]
rules with regards to lifetime. It also needs to be specified a dictionary of
operators, which follow this structure:

4b priority
4b rwins?
4b pointer to :assemble ( left right optok -- sexpr )

When called, it repeatedly feeds itself from "term<" as long as an indix
expression can be validly constructed. It then yields the string "sexpr", which
means "sequenced expression".

A sequenced expression is a string where terms have been re-ordered so that it
makes sense to just "execute" them in Forth. For example, "math< ( -- sexpr )"
would yield the following results:

  math< a + b stype       --> prints "a b +"
  math< a + b * c stype   --> prints "a b c * +"
  math< (a + b) * c stype --> prints "a b + c *"

"ops" is a dictionary where entries' payload are the struct previously
mentioned. For example, math ops are defined thus:

  dictlink mathops
  : binaryop ( rwin? pri "opname" -- ) mathops word entry , , ['] tricat , ;
  0 1 binaryop +
  0 1 binaryop -
  0 0 binaryop *
  0 0 binaryop /

The ":assemble ( left right optok -- sexpr )" pointer is called whenever we
assemble a left operand with a right operand and an operator. All arguments are
strings.

"tricat ( s1 s2 s3 -- )" is a simple word that concatenates 3 strings with a
space in between, which is what we generally want when assembling binary ops.

Sometimes, you need something fancier than "tricat", which is why the
":assemble" pointer exists. For example, the shorcut operators && and || in
the C compiler need to insert themselves in between the operand and add a "then"
at the end, so that "a && b" becomes "a && b then".

And that's pretty much all there is to this unit!
