# Infix expression parser

(This is an attempt at making CC expression parsing simpler and easier to grok.
I do so with a complete reboot that is not C-specific. This isn't integrated to
CC yet.)

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. 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 can be used with "infix[ ... ]infix ( -- n )". Calling
these boundary words consumes the input stream between them. Example:

  infix[ 2 + 3 ]infix . \ Prints "5"

Tokens are parsed through the general tokenizer [doc/comp/tok].

Infix operations always know when they're finished parsing, but because they
need to peek into the input stream, they will generally end in a "nexttok" set
in the tokenizer, which will not be automatically sent back to NEXTWORD, which
means that the word directly following the expression will be missed.

If you want to parse an infix expression within the context of another process
using the tokenizer, then you can use "infix<< ( -- n )" which has the same
effect as the boundary words.

Operands are resolved through the "nextoperand ( -- n )" word which is designed
to be realiased if needed. By default, it's the equivalent of the regular
interpreter loop ("word" then "runword").

Operators are expected to be part of the "active" operator dictionary where the
"infixops" value points. By default, it points to "mathops", a dictionary with
the "boring" math operators: + - * /.

## API

### InfixOp struct

This structure represents an infix operator. The "infixops" is a dictionary of
those structures. It's designed to be extended.

:exec ( n1 n2 op -- n )
  Executes the operator on "n1" and "n2", yielding "n".

priority ( field )
  Operator's priority

### Words

infixops ( value )
  Points to the active operator dictionary. Each entry is an InfixOp struct.

nextoperand ( -- n )
  Parse an operand from the input stream and yield it. This is designed to be
  realiased by fancier expression resolvers.

infix<< ( -- n )
  Parse an infix expression from the input stream using the general tokenizer.
  Might over-consume one token which will end up in "nexttok".

infix[ ... ]infix ( -- n )
  Same as infix<< except that it won't over-consume the input stream.
