Allow for multiple indent levels

The old code only allowed terms that were indented one level (4
spaces).  The new code behaves the same way but it includes a parameter
indicating the expected indent level.
Factor out list_dict/3

Relates a list to a dict with integer keys.  This uses a dict to
represent an array in the same way that Lua uses its tables to represent
an array.
Teach list_dict/3 about keys

When a list of words contains a key ("foo:") that provides the key for
the next value.
Move atom_codes/2 inside word//1

Converting to an atom inside word//1 makes other code simpler.  In this
case, it eliminates a call to maplist.
Add a more complicated parsing test

This test is taken from the first predicate in an CSV munging sample
app.
Simplify list_dict/3 with DCG implementation

This feels like a more natural description of the list_dict/3
predicate.  Although the line count is identical, each line of the new
code is smaller.
Change parsing of double-quoted strings

Amalog doesn't have native strings.  It has terms and it has byte
sequences.  Based on those two fundamental pieces, libraries will
implement string handling.
Split term//2 into separate parts

Amalog has two ways of representing a term.  One flavor occupies only a
single line.  Another flavor occupies multiple lines.  Distinguish
between them because certain types of terms are only allowed in certain
locations.
More accurate clause//1

A clause head must be a uniline term.  The old description allowed for
multiline terms in the clause head, which was not intended.
Reduce arity of separator predicates

The goal's final argument was not used anywhere.  There's no need to
have it cluttering the code.
More precise uniline_term//2

This DCG matches the same things as before but the predicate's structure
is closer to what it should be eventually.  Namely, the first part of a
uniline term should be a word.  After that comes the list of arguments.