This file contains a line-by-line explanation of the contents of Define.uc.
It may help to browse through BASIC.Txt first.

As mentioned elsewhere, uCalc Language Builder has no built-in keywords.  It has
no syntax, functions, operators, or special symbols that it recognizes.  It has
no constructs for defining such things either.  What it does have is a small
bootstrapping language, with which you can build a language with all of the
functions, operators, and constructs you need.  There is a separation between
the bootstrapping language, and your language, so that the keywords used in
the bootstrapping language will not interfere with your language (on the other
hand, you can add things that will be recognized by the bootstrapping language).

Define.uc contains early-stage bootstrapping constructs for defining primitive
functions, operators, and variables, with which other files such as Library.uc
can define such items, on top of which you can later define more sophisticated
constructs.

Each line explanation is separated from the next with a ========= . . .

==============================================================================

uCalc Prefix "uCalc Define Pattern: "

The uCalc Interpreter has one hard-coded keyword, which is the word "uCalc"
(not case sensitive).  And it is a keyword only if it appears as the left-most
word on a new line followed by a space.  Regardless of the language you have
constructed, there is a list of interpreter commands always at your disposal,
which you can invoke by preceding the command with "uCalc ".

Prefix is a useful command that you'll find many times elsewhere.  It simply
adds the text that you specify, at the beginning of every subsequent line, so
that you don't have to type it each time expecitely.  So for instance, the
lines that say:

   :::        ~~ Properties: ucStatementSep
   ~t         ~~ Properties: ucCurrentThread
   ~Eval      ~~ Properties: ucEvalInsert

are equivalent to:

uCalc Define Pattern: :::        ~~ Properties: ucStatementSep
uCalc Define Pattern: ~t         ~~ Properties: ucCurrentThread
uCalc Define Pattern: ~Eval      ~~ Properties: ucEvalInsert

In this group of lines, we use the Define command to define a series of
patterns.  A pattern item consists first of a regular expression (RegEx),
which describes units of text that the parser can recognize.  In addition
to the regular expression, you generally (but not necessarily) will want to
associate one or more properties with a given pattern.  So, depending on how
you've defined the patterns for your language, when the parser sees
"1234.456", it might recognize that as a number, whereas, "Abc_xyz" might be
recognized as alphanumeric (which can be used in naming items, such as
variables).

The parser takes the correct action for each unit of text based on the
properties you associate with a pattern.  The regular expressions below are
separated from the properties with the "~~" definition separator.  A
different string can be set as the separator if necessary.

Although the Language Builder itself has no pre-defined patterns, the
interpreter does define a few essential ones at start-up, such as numeric
alphanumeric, quotes, parenthesis, etc..., to spare you from an even lower,
messier level of bootstrapping.  

All of the pre-defined patterns can later be re-defined differently as
necessary (as is done in Basic.uc).  Although it is possible to delete a
pattern (if you know its handle), the best way to go about is to simply define
new patterns, which will hide older ones.

Anyway, in this block of code, we define a few patterns that should be useful
in many settings.  Property names such as ucStatementSep are simply constants
that represent certain numeric values, as defined in ucalcpb.bas.


==============================================================================

   :::        ~~ Properties: ucStatementSep

This abitrarily sets three consecutive colons as a statement separator.  Once
preliminary definitions are resolved, you will almost certainly want to choose
something else as statement separator.


==============================================================================

   ~t         ~~ Properties: ucCurrentThread

This sets ~t as a placeholder that represents the handle of the current thread.


==============================================================================

   ~Eval      ~~ Properties: ucEvalInsert

~Eval can be used for immediately evaluating a piece of code during the parsing
stage, and inserting the result in its place in the expression.  There are 3
ways to invoke it.  If ~Eval is followed by parenthesis or other pattern
defined as a code block, then the code within the parenthesis will be
evaluated.  If it's followed by a quote pattern, then the item within quotes
will be evaluated.  If followed by a space, then all the rest of the line will
be evaluated.


==============================================================================

   ~Expand    ~~ Properties: ucExpandInsert

This works similarly to ~Eval, except instead of evaluating an expression and
inserting the result, it expands the expression, and inserts the expansion.
Expansion involves changing syntax constructs to their replacements.  For
instance, if you define a syntax where "A" is transformed to "B", then
"~Expand(A)" will return "B".  The expression is transformed until no
applicable syntax rules are left to transform it.

In cases where no applicable syntax transformations are applicable to begin
with, or if there is a syntax error, then the same original expression is
returned.

==============================================================================

   \\q ~~ \\q ~~ Properties: ucQuotedText + ucLiteral ~~ DataType: String

So far, we have dealt with patterns consisting only of one part, and which
have only one property.  Patterns such as quoted text, and code blocks are
typically defined in pairs.  Here, we define  \q  as starting and ending text
quote delimiters, as an alternative to the pre-defined double and single
quotes.  The first of the two consecutive \ characters is a RegEx escape that
says that we want the literal \.  Otherwise "\q" would itself be interpreted
as an escape.  Multiple properties (of the general kind; the group of constants
defined in ucalcpb.bas) are combined by adding them together.  So here we have
a pattern that represents a literal quoted string.  It is then associated with
the String data type (so that the parser knows how to allocate memory for a
quoted string literal).


==============================================================================

   ~mStart    ~~ Properties: ucPartialBlockStart
   ~mEnd      ~~ Properties: ucPartialBlockEnd

~mStart sets a flag that causes all subsequent lines to be interpreted as part
of the same code block.  If you are using the interpreter interactively, it
will display a different prompt, and will not return any result, until you
conclude with ~mEnd (or an equivalent construct that reduces to ~mEnd), at
which point the code block (if not nested within another code block), will
then proceed to execute.


==============================================================================

   \{ ~~ \}   ~~ Properties: ucCodeBlock ~~ DataType: Stack _
      ~~ Address: ucAddr(uc_Func_Populate_Stack) ~~ Rank: 10

This defines curly brace characters { and } as code block delimiters, similar
to parenthesis.  Unlike ordinary code block delimiters, this pattern is given
a data type (Stack), and the address of a function returned from
ucAddr(uc_Func_Populate_Stack).  In this situation, where applicable, the curly
braces will work as though it were a function, but one without a name.  Where
it's not applicable it will continue to operate as a simple code block
delimiter as before.

What this function does is that if you have an expression such as:

MyStack = {"Hello", 1, MyVariable, 5*2}

It will push each of these four items: "Hello", 1, MyVariable, and the result
of 5*2, (using whatever data types are associated with each), onto a stack
variable named MyStack (assuming this variable was defined).  You can also
perform operations directly on them at the command line, as in:

{1, 2, 3} + {4, 5, 6}

The rank of 10 is not so important.  However, it ranks this new definition
higher than the curly braces previously defined at startup, but lower than
other patterns.  Ideally, patterns should be ranked according to the
likelihood of occurrence in an expression.  Things work a bit more efficiently
when the most frequently encountered patterns have a higher rank.  (Patterns,
which each have a unique rank, are ranked differently from symbols, which
compete in ranking only with other symbols that share the same name).


==============================================================================

uCalc Prefix ""

This simply resets the prefix back to nothing.


==============================================================================

// All of the following syntax defs use a default precedence level of 1
// +++ VarName extensions [@#!%&$]? are for BASIC. May remove for other langs.

This is just a comment that will be ignored by the parser.  // as with other
symbols is defined in another file.  As noted, the following syntax definitions
will use the default precedence level.  For the syntax definitions in this
file, precedence levels are largely irrelevant, so they are not explicitly
set, the way the are in BASIC.uc or elsewhere.


==============================================================================

uCalc Prefix "uCalc Syntax "

This sets the prefix so that the following lines will us the Syntax command.
More details of what syntax is all about can be found in the help file.  You
will also find other Syntax examples explained in BASIC.uc.


==============================================================================

   Name_: ::= Name:

This syntax is simply a place holder.  If you only load the interpreter with the
default ucalc.uc file, and not BASIC.uc, then occurrences of "Name_:" will
simply be replaced with the "Name:" property.  In BASIC.uc, "Name_:" is put to
use as part of a special construct.


==============================================================================

   Var: {VarName:"[ ]*[a-z_][0-9a-z_]*[@#!%&$]?"} [As {Type}] _
      [{ = {Value} | At {Addr:" .+"} }] ::=          _
      variable ~~ Name_: {VarName}                   _
      {Type: ~~ DataType: {Type}}                    _
      {Value: ~~ Value: {Value}}                     _
      {Addr: ~~ Address: {Addr}}

This line (the " _" character at the end of each line turns this block of code
into a single line before it is parsed), uses uCalc Bootstrap code to create a
construct for defining variables.  With bootstrapping, you start with ungainly,
and unfamiliar code, which is uCalc-specific, and gradually build on top of it
until you get constructs that resemble the language you are trying to build.

At this stage, this does not yet represent the construct we want for defining
variables.  Instead it is the basis for defining other constructs that can be
used for defining variables, constants, function parameters, operator operands,
and the like.  For now we are adding constructs for further use in the
Bootstrapping language itself, prior to being ready for another language.

It may help to start browsing through BASIC.uc which uses bootstrapping at a
higher level, to get a hang of how Syntax definitions work, and then work your
way backwards until you reach this file.  This file might not go into detail
for certain concepts that are explained elsewhere.

Here, we define "Var:" in a style somewhat like that of a Bootstrap property.
This "property" will accept a variable name, followed optionally by the name
of a data type preceded by the word "AS" (which is decidedly BASIC-like, but
can be changed if you like).  The RegEx for the variable name is alphanumeric,
plus one optional character at the end that BASIC-like languages accept as
type identifiers.

After the optional type, you have an optional clause consisting of either the
"=" sign followed by a default value, or the word "AT", followed by an address.
If an address is supplied, no memory will be allocated.  The supplied memory
address will be associated with the variable.  And it will not free that memory
address if the variable is deleted.

Alternative sections are denoted by curly braces { and }, with each optional
part separated by the | character.  Optional sections are enclosed in square
brackets [ and ].

     variable 

On the right hand side of the "::=" symbol, you have the "variable" property.
It takes no parameters, and indicates that the item is variable-like.  A
variable-like item can be anything from a variable, array, constant, function
parameter, or other similar entity.

      ~~ Name_: {VarName}                   _

"Name_:" is reduced to the "Name:" property, which is appropriate for a
variable to have.  As described earlier this can be put to good use by being
redefined as a different construct, as it is done in BASIC.uc.

The three following lines consist of a curly brace "{",
immediately followed by a syntax argument name (Type, Value, and Addr in this
case), a colon, some code, and a closing curly brace "}".  This indicates that
if the optional syntax argument is used, then instead of substituting the
argument itself, it will substitute the text that comes between the colon and
the closing curly brace.  So "As Integer" for instance would be transformed
into "~~ DataType: Integer".

      {Type: ~~ DataType: {Type}}                    _

The DataType property is self-descriptive.  It takes either a numerical value,
representing the handle of a data type, or the name of a data type.  If no
data type is set, than the default data type is what's used.  (The
interpreter starts with Extended precision as the default type).

      {Value: ~~ Value: {Value}}                     _

If an expression is supplied here, then that is evaluated, and the result is
stored in the memory address allocated for the variable.  A different construct,
which is described further down, is used if you are dealing with a default value
for a function parameter.

      {Addr: ~~ Address: {Addr}}

If this property is used, then the supplied address is used for the variable,
instead of allocating a new address.  Since the variable did not allocate the
address, when the variable is destroyed, it will not free that address either.


==============================================================================

   Var: {VarName:"[ ]*[a-z_][0-9a-z_]*"} As AnyType ::= AnyType~~Var: {VarName}

The previous section described only one out of 5 different constructs for
"Var:".  This is the second.  Here we use the AnyType property (on the left of
"::=", AnyType represents a syntax word as it will appear in code, and to the
right it represents a property; different words could have been chosen for
each).  This construct is intended for function parameters rather than for
variables.  This causes the parameter to accept an argument of any type.  Type
checking will be suppressed.  And it will be up to your function to handle
type compatibility.  When specific types are used, uCalc returns an error if
the wrong type is used, and the argument cannot be converted to the proper
type.

Notice that all of the Var: constructs, except for the first one, are
constructed using Var: again as part of their definition.  This is typical of
uCalc's bootstrapping method of building on itself.


==============================================================================

   Var: {PassBy:"( +ByRef)|( +ByVal)|( +ByHandle)|( +ByExpr)"}::={PassBy}~~Var:

This one is also intended for function parameters.  ByRef, ByVal, ByHandle, and
ByExpr, are all properties.  If one of these is in the code the expression is
rewritten with that property, as organized on the right hand side of "::=".

ByRef (By Reference), and ByVal (By Value) should already be familiar.  The two
others are specific to uCalc.  Every item defined with uCalc, wither it's a
data type, thread, function, pattern, syntax, or other, has a handle.  Even an
expression, if it constitutes more than a item unit, temporarily has a handle.
This handle is passed to your function as a 32-bit value (such as Dword).
Given an item's handle, you can access all applicable properties, such as name,
data type, address, precedence level, etc...

A ByExpr expression is not evaluated before being passed to a function.  Instead
the expression's handle, as a 32-bit pointer value, is what's passed.  Using
this pointer, the function can choose to evaluate an argument 0, 1, or many
times.  Looping and conditional routines found in Library.uc for instance use
this.

[+++ For now, these are implemented for StdCall and NativeCall functions only]

==============================================================================

   Var: {Def} ... ::= Var: {Def} ~~ VariableArgList

This too, is for function parameters.  It sets the VariableArgList property if
you define a function argument consisting of a name followed by three
consecutive dots "...".  Subsequent optional parameters will inherit the
properties of the last parameter.


==============================================================================

   Var: ... ::= Var: _ ~~ VariableArgList

This is similar to the previous construct.  However, this is for when the 3
dots do not immediately follow a parameter clause, but the 3 dots are used as
the clause itself.  For instance (Param1 As String, Param2 As Long ...) would
match the previous definition, whereas (Param1 As String, Param2 As Long, ...)
with a comma separating "..." from the previous parameter would match this
definition.  The difference in behavior is that in the previous definition,
the optional parameters would have the same properties as Param2, but in this
one, the optional parameters would have properties associated with the default
data type (Extended precision).


==============================================================================

   Var: {"[ ]*"}{ArrayName:"[a-z_][0-9a-z_]*[@#!%&$]?"} ({MaxIndex}) [{etc}] _
      ::= SetInput(\quCalc Syntax {ArrayName} ({Index})                      _
          ::= ValueAtAddr(~Eval(DataType("{ArrayName}")),                    _
                          ~Eval(Address("{ArrayName}")), {Index})\q)         _
      Count: {MaxIndex} ~~ Var: {ArrayName} {etc}


This construct is for defining arrays.  For now it handles only single
dimension arrays.  You can extend it to more dimensions, once you've decided
on such things as whether you want multi-dimensions to be organized in row-
major or column major form, etc...

This takes an array name, followed by a the element size enclosed in
parenthesis, optionally followed by type name etc...  It then creates a new
syntax based on the array name, which it sends back to the interpreter for
further processing via SetInput (see Basic.uc for more details).  The new
syntax definition consists of changing the array to a call to the special
ValueAtAddr function, which unlike ordinary routines, takes a data type handle,
a memory, and optionally an index (though not optional in this particular
context), giving you direct access to the memory location via the interface of
the given data type.  ~Eval is used in the first argument because a numeric
literal is required there, and the data type must be resolved prior to parsing.
And for the second arg it is used mainly for efficiency, as the address will
typically be known once and for all, making it unnecessary to call a function
to determine the address each time the array is accessed, except for the index.
(In the case of resizing dynamic arrays, which would produce a new base address,
you can easily add a construct that simply redefines this syntax whenever the
array is resized).

The Count parameter in the context of a variable determines the number of
multiple units of memory of a given type to allocate for a variable.


==============================================================================

   Params: ([{SingleParam}])::=IsParam ~~ { {SingleParam: Var: {SingleParam}} }

This, along with the next few definitions, resolves parameters for routines,
such as functions or operators.  This one in particular is for resolving a
function with 0 or 1 parameters, or for resolving one particular parameter
out of several.  It sets the IsParam property, and then defines the parameter
(if it exists) as a local variable, indicated by the outer curly braces on
the right hand side of ::=.


==============================================================================

   Params: ({Variable:"[^=]+"} = {Default}) _
           ::= Params: ({Variable} ~~ TextData: {Default})

This one resolves optional parameters that have a default value.  The default
value is stored in the TextData property.


==============================================================================

   Params: ({Param1}, {OtherParams}) ::= Params: ({Param1}) _
           ~~ Params: ({OtherParams})

This takes a list of parameters, and separates them into two parts.  The first
part consists of the first parameter, which will be processed individually, and
the second part consists of the rest of the arguments, which will later go
through the same separation process until each individual parameter gets its
turn to be processed.


==============================================================================

   Param:  {ParamDef} ~~ ::= IsParam ~~ { Var: {ParamDef} } ~~

This is similar to the first Params: construct, but is specifically tailored
towards operator parameters, as each operator operands come already separated
into units.


==============================================================================

   Func: {FuncName} ([{ParamList}])                                           _
      [As {type:" +[a-z]+[a-z0-9]*"}] [{ At {addr:".+"} | = {Def:".+"} }] ::= _
      Properties: ucFunction + ucPrefix ~~                                    _
      Params: ({ParamList}) ~~ DataType: {type} ~~ Name_: {FuncName}          _
      {addr: ~~ Address: {addr} ~~ StdCall} ~~ FuncBody: {Def}

This construct is for single-line function definitions.  It works very much
like the first Var: construct described earlier on.  The differences worth
noting is that the properties for this one is ucFunction + ucPrefix (indicates
that operands are prefixed by a function name).  The Params: construct defined
in previous sections is used.  If an address is supplied, the StdCall property
is set.  But StdCall is superceded by NativeCall if that it used.  And the
parameter supplied to FuncBody represents the code (if present) for the
function.

See Library.uc for a list of function defined with this construct.  (Functions
there that use the next construct below, also rely indirectly on this one).

==============================================================================

   Func:: {Def:".+"} ::= NativeCall ~~ Func: {Def}

If two colons are used instead of one, then the NativeCall property is set.
uCalc can call conventional StdCall functions, such as Windows API routines,
or DLL routines that you might create using StdCall, as well as end-user type
functions such as those defined at the end of BASIC.uc.  However uCalc uses
the least amount of overhead for functions defined using NativeCall.  The
following example is the PowerBASIC source code for the IIF function defined
in Library.uc, which uses NativeCall.

Sub Func_IIF(Expr As ExpressionType)
   Local Condition As Long
   Local TruePart, FalsePart As Dword

   Condition = Expr.@ArgList[1].@ValueLng
   TruePart  = Expr.@ArgList[2].ValuePtr
   FalsePart = Expr.@ArgList[3].ValuePtr

   If Condition _
   Then Expr.@ResultExt = ucEvaluateExt(TruePart) _
   Else Expr.@ResultExt = ucEvaluateExt(FalsePart)
End Sub


==============================================================================

   Op: {Name} "{" {Operand} "}" [As {type:" +[a-z]+[a-z0-9]*"}] _
      [{ At {addr} | = {Def:".+"} }] ::= _
      Properties: ucPrefix + ucOperator ~~ Param: {Operand} ~~ Name_: {Name} ~~ _
      DataType: {type} {addr: ~~ Address: {addr} ~~ StdCall} ~~ FuncBody: {Def}

This construct is for Prefix operators, as the ucPrefix + ucOperator property
combination indicates.  Overall, it is similar to the Func: construct.  However,
the syntax consists of an operator name, followed by an operand within curly
braces.  If the definition is supplied a body of code (as opposed to the address
of a routine), then the operand appears on the other side of the = sign, but
without braces.  Here Param: is used instead of Params:.

It might be possible to conceive of a simpler syntax.  But this is what is used
for now.


==============================================================================

   Op: "{" {Operand} "}" {Name} [As {type:" +[a-z]+[a-z0-9]*"}] _
      [{ At {addr} | = {Def:".+"} }]  ::= _
      Properties: ucPostfix+ucOperator ~~ Param: {Operand} ~~ Name_: {Name} ~~ _
      DataType: {type} {addr: ~~ Address: {addr} ~~ StdCall} ~~ FuncBody: {Def}

This construct is for postfix operators as indicated by the ucPostfix+ucOperator
combination.  It is otherwise similar to the previous construct.


==============================================================================

   Op: "{" {LeftOp} "}" {Name} "{" {RightOp} "}" [As {type:" +[a-z]+[a-z0-9]*"}] _
      [{ At {addr} | = {Def:".+"} }] ::= Name_: {Name} ~~                        _
      Properties: ucInfix + ucOperator ~~ Param: {LeftOp} ~~ Param: {RightOp} ~~ _
      DataType: {type} {addr: ~~ Address: {addr} ~~ StdCall} ~~ FuncBody: {Def}

This one is for infix operators.


==============================================================================

   Op: {pValue:' *[0-9]+ '} {Def} ::= Precedence: {pValue} ~~ Op: {Def}

All operators have a precedence level.  If none is supplied, a default level
is used.  This is using the Precedence property.  However, this construct
simplifies things by allowing you to simply precede the operator definition
with a numeric value without the word Precedence.  Browse through Library.uc
to see how much simpler it is this way compared to if each line explicitly
included the word Precedence.


==============================================================================

   Op:: {Def:".+"} ::= NativeCall ~~ Op: {Def}

This does the same thing for Op: as Func:: does for Func:.


==============================================================================

   syntax {Def:" .+"} ::= SetInput("ucalc syntax {Def}")
   func   {Def:" .+"} ::= SetInput("ucalc define func: {Def}")
   var    {Def:" .+"} ::= SetInput("ucalc define var: {Def}")
   expand {Def:" .+"} ::= SetInput("ucalc expand {Def}")

These lines are shortcuts for similarly named constructs defined earlier in
this file.  They remove the requirement of using the uCalc keyword along with
a command.  For instance, at the command line, instead of:

uCalc Define Func: f(x) = x ^ 2

you can now simply enter:

func f(x) = x ^ 2


==============================================================================

uCalc Define PassOnce ~~ Syntax: Quote({text}) ::= "{text}"

When expanding an expression, each time there is a syntax match, the relevant
section of code is modified.  Each time this happens that part of code is
re-processed.  This continues until the expression can no longer be changed to
a different form.  In some cases, you want your construct to do a modification
only once, and then move on.  This is particular useful in constructs such as
the one above, 

[+++ This particular line turns out to be useless as an example for PassOnce]


