This text file offers a line-by-line explanation of the code found in BASIC.uc,
which defines a BASIC language that can be used interactively (or as a script)
with the uCalc interpreter (uCalc.exe).  It will generally help if you start
browsing this text file from the beginning, as concepts that repeat themselves
throughout the code will not necessarily be explained in each re-occurrence.
You may also want to browse through uCalc.Txt and other Txt files, where you
will find other constructs that this file relies on.

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

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

uCalc Load "ucalc.uc"

uCalc Language Builder has no hard-coded keywords.  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 at your disposal, which you can invoke by
preceding the command with "uCalc".  In the above line, the interpreter loads
the "ucalc.uc" file.  The loaded file is plain text.  When the interpreter
loads a file, it simply runs through the code found in that file.  The
"ucalc.uc" file in particular contains some general code that can work as the
starting point for building various kinds of languages.  It also has enough
start-up code to let you run an interpreter session where you can evaluate
expressions, and define things interactively, even without creating a langauge.


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

' +++ Perhaps have a tutorial with line-by-line explanation

If you see lines with +++ throughout, you can ignore those.  These are
comments to myself as I continue to develop.  You will see further down how
the single quote character (') is defined as a comment.


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

uCalc Prefix "uCalc Define Pattern:"

Prefix is a useful command that you'll find many times here.  It simply
adds the text that you specify to every subsequent line, so that you don't
have to type it each time explicitly.  So the line below that says:

Rem .*       ~~ Properties: ucWhiteSpace

is seen by the interpreter as:

uCalc Define Pattern:   Rem .*       ~~ Properties: ucWhiteSpace

The prefix text here is "uCalc Define Pattern:".  The Define command is what
lets you define various aspects of your language, such as data types,
syntaxes, patterns, etc...  Each definition corresponds to a unit of data
called an "Item".  A definition may consist of a combination of properties
to form items that can represent things such as data types, function,
operator, or variable constructs, etc..., which through bootstrapping can
then be used to define actual functions, operators, variables, etc..., which
are also items.  Everything in uCalc is an item.  You start with simple items,
and build more complex items using, or with the help of, a combination of other
items.

The particular items defined in this code block are 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, to allow things to get started.  Those patterns,
however, are generic and might not be suitable for the language you are
creating.  So here, we create a set of patterns more suitable for the BASIC
language.  More recently defined patterns have precedence over previously
defined ones (unless you explicitly set a different ranking).

Not all of the following patterns are strictly BASIC.  Some are helper patterns
for syntax constructs.  They will generally not interfere with your normal BASIC
code.


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

   Rem .*       ~~ Properties: ucWhiteSpace

REM is the familiar BASIC comment indicator.  Because of the ucWhiteSpace
property that is set, When the parser encounters REM, along with the rest of
the line (represented by the ".*" regular expression), it will ignore it just
like any other white space.


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

   '.*          ~~ Properties: ucWhiteSpace

This works the same way as the REM pattern above, but using the single quote
character.


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

   ~FuncEnd     ~~ Properties: ucFuncDefEnd

With the ucFuncDefEnd property set, whenever ~FuncEnd is encountered, this will
signal the end of a multi-line function definition.  (A "function" is any
method or procedure-like code).


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

   :            ~~ Properties: ucStatementSep

This sets the : as a statement separator.

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

   :::          ~~ Properties: ucStatementSep

This is not a BASIC construct, but it is used in the background as a separator
for syntax constructs found in Library.uc, which are in turn used by BASIC.uc.


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

   \.           ~~ Properties: ucMemberAccess

This sets the "." as a member separator.  This would work for instance in user
defined types.


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

   ,            ~~ Properties: ucArgSeparator

This character separates Sub or Function arguments. 


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

   \( ~~ \)     ~~ Properties: ucCodeBlock

Typically a pattern has just one Regular Expression.  However, if the item
represents a code block, then you will typically have two regular expressions.
The first one represents the block beginning, and the second one represents the
block end.


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

   [ ]+         ~~ Properties: ucWhiteSpace

Just like REM, and ' defined further above, the white ucWhiteSpace property
causes the interpreter to ignore this pattern when encountered. Unlike REM,
which ignores up until the end of the line, this regular expression is for
consecutive spaces, after which the parser resumes analysis of further
patterns.

It is important to note that in pattern definitions, spaces are trimmed from
around the pattern Regular Expression.  For this reason the blank space is
enclosed in brackets, to distinguish it from blank space that is not part of
the definition.


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

   [\|+/*^$&#\-=@!`\\<>?;%]+ ~~ Properties: ucReducible

There are two properties for patterns that can be used for naming items.  These
are ucAlphaNumeric, and ucReducible.  ucAlphaNumeric is intended for
irreducible units of text, which is typically for (but is not restricted to)
things like alphanumeric words such as those used in naming functions or
variables.  A reducible pattern on the other hand would typically be used for
naming things like operators.  The difference is that if you have an item named
"+", but do not also have one named "++".  Then "++" will be interpreted as
two consecutive "+" items.  Whereas if you have an alpha numeric item named
"B", but the parser encounters "BB", it will not be reduced to "B", even if
there is no match for "BB".

Spacing is required between two consecutive alphanumeric items, whereas no
spacing is necessary between consecutive reducibles.


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

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

This pattern looks like the following one (and might get you confused), but it
is different.  It is the literal backslash character, followed by the literal
letter "q".  It is used as in:    \q My quoted text \q

This is not a BASIC construct, but just like ":::" described earlier, it is used
in the background for syntax constructs found in Library.uc, which are in turn
used by BASIC.uc.  In this case we're dealing with a special quote character,
in addition to the normal double quotes used in BASIC.  This allows a quote
within a quote (although BASIC can use two double quotes to signify the same
thing +++ (to be defined later) ).

Previous patterns so far had just one property apiece.  This one has several.
ucQuotedText should be self-explanatory.  ucLiteral causes the parser to
immediately turn the quoted text into an item when encountered.  It is also
given the data type of String.  Literal items should have an associated data
type, so that parser knows how to allocate space for it.


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

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

This pattern looks like the previous one, but should not be confused.  \q is
an escape that represents the double quote  "  character (+++ Hmmm, maybe
simply use ["] for better clarity and convention).

This works similarly to the previously described pattern, but this one is the
conventional BASIC double quote character used in literal strings, as in:
"My String".


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

   ([0-9]+\.)?[0-9]*(e[-+]?[0-9]+)? ~~ Properties: ucLiteral~~DataType: Extended

This pattern represents floating point numbers.  Units of text such as:
123 or 12.5 or 33e26 etc... will be allocated as Extended Precision items when
encountered.  Because this is the only numeric pattern defined, it causes all
numeric literals to default to Extended precision.  But you can similarly
define patterns specifically for integers or other numeric types as well.


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

   [a-z_][0-9a-z_]*[@#!%&$]? ~~ Properties: ucAlphaNumeric

This is an alphanumeric pattern, for naming things like functions and
variables.  Unlike normal alphanumeric patterns, notice the [@#!%&$]? at the
end (no, that's not some kind of swear word) that allows you to optionally use
characters such as #, !, %, etc, which are BASIC data type identifiers.  When
present they are incorporated in a definition to determine its type, as shown
further down.


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

uCalc Prefix ""

The prefix used for defining the above list of properties is no longer needed,
so it is removed by setting it to "" (empty quotes).


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

RenameItem("Print", "_Print")

Any named item can be renamed to something else.  The default PRINT item is a
generic function that can print only one argument, which must be a string
argument.  And unlike BASIC's typical print, this generic print does not append
a carriage return at the end.  In order to construct a more sophisticated PRINT
that is more BASIC-like, we rename the default print to _Print. It's possible
to delete the default print altogether, however, the default simple print is
used as the bases for the more sophisticated PRINT, as defined further down.


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

RenameItem("=", "->") ' Assignment operator (string, numeric, table)
RenameItem("=", "->")
RenameItem("=", "->")

RenameItem("==", "=") ' comparison op (string, numeric)
RenameItem("==", "=")

RenameItem is called three times in a row with the same arguments because in
Library.uc, there are three related but distinct definitions for "=", and we
want to rename all three.  One is for assigning a value to string variable, the
two others are for numeric and table variables.  In that same Library.uc file,
the comparison operator (for which there are two definitions; one for string,
the other for numeric) is "==".  In BASIC, the same "=" operator is used both
for assigning a value to a variable, and for comparing to operands.  In order
to distinguish the two, we play a little bit of musical chairs, and "=" is
renamed to a different symbol ("->" is chosen arbitrarily), and "==" is renamed
to "=".  Further down, you'll see how the construct is set up so that by
default "=" will be recognized as a comparison operator, while in certain
contexts, it is an assignment operator.


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

' The numerical values at the beginning represent precedence levels

That line is just a comment.  The comment pattern was described earlier on.
The actual numerical values chosen for precedence levels are arbitrary, but
chosen in relation to each other.  The smaller the number, the lower the item's
precedence level when compared to other items (unlike for the ranking property,
in which a 1 is the highest rank, and the larger the number the lower the rank).
You will find further details about precedence levels as you browse along.


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

uCalc Prefix "uCalc Syntax "

Previously, we changed the prefix in order to define a group of patterns.  Now
we want to define a group of syntaxes.  See the help file for further details
of how to define a syntax.


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

5    _basic: ::=

The 5 here represents the precedence level.  Each syntax definition has a
precedence level.  A precedence level is necessary especially for an open-ended
syntax; that is a syntax that starts or ends with a non-RegEx (regular
expression) syntax argument and consists of more than just one syntax argument.
If a level is not supplied, a default level (which is configurable), is used.
The above line contains no syntax arguments.  So the value given is irrelevant,
but is included only for uniformity with the rest of the syntax definitions.

This line works in pair with the following line.  It consists of the word
"_basic", followed by a colon.  The ::= after that means that the parser will
replace occurrences of whatever's on the left of ::=, with whatever is on the
right of ::=.  In this particular case, occurrences of "_basic:" are simply
replaced with nothing.  This happens when an occurrence of "_basic:" does not
match the other syntax definition for "_basic:", which is described in the
next line.


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

5    _basic: {variable:"[ ]+[a-z_][0-9a-z_]*[@#!%&$]?[ ]*"}= ::= {variable} ->

This definition works in pair with the definition found in the previous line.
As in that one, the number 5, which represents the precedence level is
irrelevant, but is included for uniformity with the rest of the syntax
definitions.  The purpose of this particular syntax is help determine whether
the occurrence of the "=" sign in a line of code represents a variable
assignment, or a comparison between two arguments.

The way this works is that all statement lines of basic code (as defined in
this file) are preceded with the term "_basic:".  If "_basic:" is followed by
an alphanumeric word, and then the "=" sign, then it is deemed a variable
assignment.  If so, the "=" sign is changed to the "->" assignment operator
that was discussed earlier.  For all other cases, "_basic:" is simply replaced
with nothing, as described in the previous line, and the parser moves on.

"_basic" is the name of the syntax (should you want to check its properties,
delete it, or rename it, etc...).  The first pattern in a syntax serves as its
name (unless it is a regex argument; in which case see the explanation for the
next definition).  Following the alphanumeric word "_basic", you have a colon
pattern.  Next to that you have a syntax argument enclosed in curly braces {}.
Within the curly braces, you have the name of the syntax argument, which is
"variable" in this case.  Notice that the syntax argument found on the left of
::= is also found to the right of it.  Following the argument name is a colon,
and then a quoted item, which represents the RegEx pattern for alpha numeric
words (including optional data type suffixes at the end).

The RegEx pattern can either be a literal value with quotes, as in this case,
or a string variable containing the pattern text as its value.  It is important
to remember that unlike non-RegEx syntax arguments (as you'll find further
down), the argument must exactly match the RegEx pattern, so leading and ending
spaces, where applicable, might be required, as in this particular case.

Following the RegEx syntax argument is the = sign (which is not particular
about surrounding spaces).  Then you have ::= followed by the new code that it
is transformed into.

So the following line:

MyVariable& = "Yes" = "No"

with the implied "_basic:" prefix at the beginning would be transformed into:

MyVariable& -> "Yes" = "No"

where "->" is an assignment operator as discussed previously.  In this case,
the "Yes" string would be compared to the "No" string to see whether they are
equal, and the return value (0 in this case) would be stored in the long
integer variable named MyVariable&.

It is important to note that unlike alphanumeric names, which can be either
case sensitive or not (depending on how you've configured it), the names of
syntax arguments are always case sensitive (so {Variable} is not the same as
{VARIABLE}).


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

5    {":"} {variable:"[ ]+[a-z_][0-9a-z_]*[@#!%&$]?[ ]*"}= ::= :{variable} ->

This syntax has a similar purpose and explanation as the previous one.  So only
the differences here will be discussed.  The previous syntax works for
statements that are at the beginning of the line, as a new line in BASIC
generally represents a new statement.  However, statements can also be
separated by a colon, which this syntax takes care of.

The other syntaxes defined here start with a name (either an alphanumeric or
reducible symbol).  This one is different in that it starts with a RegEx
argument.  Unlike named syntaxes, one that starts with a RegEx is stored as a
pattern, separately from the symbol table.  Whenever there's a choice, it is
generally best to start a syntax with a name, making it more efficient, and
allowing you to later refer to the syntax by name if necessary.  (You can,
however, still refer to a pattern syntax by handle, as you can with all items).
In this particular case, a RegEx pattern is required at the start, because the
colon character as statement separator is also defined as a pattern and not a
symbol.  Named items can be overloaded with each other, and ranked relative to
each other in whatever order desired, whereas, patterns always have priority
over symbols, and are ranked only relative to other patterns.

(A definition rank, which is discussed further down, is different from a
precedence level; both of which can be calibrated independently for a given
definition). 

Syntax argument names are optional.  If a syntax argument will not be used
anywhere else in a syntax definition, it is not necessary to name it.  So the
colon argument at the start of the line is not named.


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

5    _basic: Mid$({Var}, {Start}) = {Replacement} _
     ::= Poke$(StrPtr({Var})+{Start}-1, {Replacement}) : _Void

Using the very same concept as that previous few lines of code, the line above
determines whether a given occurrence of Mid$ should be interpreted as a
statement (one that replaces part of a string), or as a function (which returns
part of a string).  So far, we've only looked at syntax arguments of the RegEx
kind.  This line introduces non-RegEx syntax arguments; in this case {Var},
{Start}, and {Replacement}.  RegEx arguments are parsed based on a strict match
to the given regular expression for that argument.  Non-RegEx arguments on the
other hand are parsed based on the cumulative list of more general rules as
defined up to that point, as well as some internal logic (for instance, an
argument will not overstep code block boundaries, etc...).

This syntax is formed with a combination of words units, which are "_basic",
":", "Mid$", "(", ",", ")", and "=", and the syntax arguments: {Var}, {Start},
and {Replace}.  Once defined, in an expression that uses this syntax, each word
can be separated from other words with spaces (optional if only one of two
consecutive words is alphanumeric, and, though this doesn't apply here,
required when both consecutive words are alphanumeric) in a parsed expression.
So you can have 0 or more spaces between _basic: and Mid$, and around the =
sign etc...  It will even accept spaces between Mid and $ and (.  However, if
you do not desire this, you could insert a RegEx argument there to force it not
to accept any space between Mid and (.

As with all the other syntax definitions, an expression that matches the syntax
to the left of ::= will be transformed to code that's on the right of ::=.
Poke$, which is functionally similar to the one found in PowerBASIC, is defined
in the PBFlavor.uc file, while StrPtr is defined in Library.uc .  This syntax
works by poking a replacement value directly at the specified memory location
for the string.

Although the interpreter can accept lines of any length from a file, for
aesthetic reasons, it was broken in two using " _", which is defined in ucalc.uc
as the line continuation character.

This line ends with _Void, which does nothing if it is in the middle of source
code, or else returns the word "Ok" (or whatever other return word you specified
for the Void type in the types.uc file) at the interpreter command line.


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

20   Print [{Data}]          ::= _Print({Data: Str({Data})+} Chr(13)+Chr(10))
20   Print {Data}  ; [{etc}] ::= _Print(Str({Data})) {etc: : Print {etc}}
20   Print [{Data}]:         ::= (Print {Data}) :

These lines define a Print statement in the style of BASIC (+++ The comma
syntax, and a few other things are not yet implemented).

New to these lines are optional syntax segments, denoted by square brackets.
Missing arguments are transformed to null space on the right side.  So the
line that says:

20   Print [{Data}]:         ::= (Print {Data}) :

is logically equivalent to the following two lines (in that order):

20   Print :         ::= (Print ) :
20   Print {Data}:   ::= (Print {Data}) :

Also new starting with these lines is the option you have of transforming
an argument into something other than itself on the right hand side of the
"::=" symbol.  So in the Print definition with the semicolon, the {etc}
argument is transformed into something else.  It can be anything, but in
this case it is transformed into the same {etc}, but which is preceded by
": Print".  This concept is used in the first line as well.  To do this,
the syntax argument, which is enclosed in curly braces must start with the
argument name, followed by a colon, and then the replacement text.

Notice that the Print definition has a lower (bigger number) precedence level
than syntaxes such as the single-line versions of For/Next and If/Then defined
further down.

A definition can have both a rank and a precedence level.  An item's precedence
level sets its priority relative to any other item that has a precedence level.
An item's rank on the other hand sets the item's priority only relative to items
that share the same name.  In this case the three Print definitions are ranked
implicitly, simply by the order in which they are defined, with the first line
having the lowest priority, and the last line having the highest.  This means
that where Print occurs in a line of code, Print with the colon is considered
first.  If that doesn't match, it tries Print with semicolon, and finally the
first definition otherwise, which contains just one piece of data, which is
optional.

You can rank definitions differently, by explicitly setting the Rank property
for each definition, or by reconfiguring the default ranking behavior to get
the reverse order implicitly.

_Print is the generic PRINT function that was defined in Library.uc, except
it was renamed further above to _Print so that the word Print could be available
for this new BASIC-like definition.  The generic print is in turn defined based
on the WriteConsole routine, which is defined in the WinAPI.uc file.

The generic _Print only takes string arguments.  So the Str function is used
in order to coerce any data type to a string.  This Str is not conventional
BASIC, which would normally only convert numeric types to a string.  However,
should this added flexibility be considered undesirably, you easily re-define
a Str() (and rename it Str$()) to work in a more conventional BASIC way.

  
==============================================================================
10   For {Var} = {Start} To {Stop} [Step {Step=1}] _
     ::= ~mStart uc_For({Var}, {Start}, {Stop}, {Step},
10   Next ::= ) ~mEnd

This represents the multi-line construct for a For/Next loop.  Peculiar to these
lines are the ~mStart and ~mEnd patterns (which are defined in Define.uc).
~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, at which point the code block (if not nested within
another code block), will then proceed to execute.

So the code such as the following:

For x = 1 to 10
   Print x
   Print x^2
Next

Would be logically equivalent to something like this:

uc_For(x, 1, 10, 1, {Print x : Print x^2})

except things are parsed line by line on an ongoing bases, instead of being
jammed all into one long string before parsing it altogether.

The section at the end within square brackets is optional.  The {Step} syntax
argument is given a default value of 1, which is used whenever the Step section
is ommited from the expression.

For now the uc_For is optimized for working with an Extended precision counter
variable.  Although the counter variable can be of any numeric type, it would
run significantly slower.  Creating alternative versions of uc_For() that are
optimized for a given type is very easy [+++ Though not documented yet].


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

15   For {Var} = {Start} To {Stop} [Step {Step=1}] : {Code} : Next _
     ::= uc_For({Var}, {Start}, {Stop}, {Step}, {Code})

This is the syntax for the single-line version of For/Next, as in:

For x = 1 to 10: Print x: Next

This single line definition must come after the multi-line definition, giving
it a higher ranking than the multi-line version.  This is necessary, otherwise,
The first part of the multi-line For/Next definition would match all occurrences
of For ..., in which case the single-line definition would never be invoked.

The single line definition has a higher ranking, but a lower precedence
level than the multi-line definition.  The lower precedence level is irrelevant
in comparison to the multi-line version of the definition, because a multi-line
For statement cannot have other statements on the same line.  But the multi-line
definition must have a level that is lower than all other operators (in case
the start or end parameters of For are expressions containing operators instead
of just numbers).


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

10   Until {x}                   ::= ({x}) = 0
10   Do [[While] {DoCond=1}]     ::= ~mStart uc_Loop({DoCond},
10   Loop [[While] {LoopCond=1}] ::= , {LoopCond}) ~mEnd

This syntax represents the Do/Loop construct.  There are various possible ways
of defining such constructs.  This approach is generally similar to the multi-
line For/Next construct described above.

Special to these lines are nested optional parts, as well as a a default value
for a syntax argument.  In previous definitions, when an expression did not
contain an syntax argument that was optional, the argument was rendered as
null space.  Here, if the optional {DoCond} or {LoopCond} syntax arguments are
not present, instead of nothing, a default value of 1 is substituted in.
[+++ default already introduced earlier]

Until is defined separately, in order to simplify the definitions.  It will work
as a sub-syntax under either Do, or Loop in the multi-line version, or Do or
Loop in the single line version.


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

15   Do [[While] {DoCond=1}] : {Code}  Loop [[While] {LoopCond=1}] _
     ::= uc_Loop({DoCond}, ({Code}), {LoopCond})

This single line syntax version of Do/Loop is to the multi-line version of
Do/Loop what the single line For/Next is to the multi-line counterpart.  See
the single For/Next explanations.


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

10   While {Cond} ::= ~mStart uc_Loop({Cond},
10   Wend         ::= , 1) ~mEnd

15   While {Cond} : {Code} : Wend ::= uc_Loop({Cond}, {Code}, 1)

The concept here is very similar to the explanations given under For/Next and
Do/Loop above.  Both While/Wend and Do/Loop are mapped onto the uc_Loop routine.


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

10   If {cond} Then     ::= ~mStart _If({cond},
10   Else               ::= , 1,
10   ElseIf {cond} Then ::= , {cond},
10   End If             ::= ) ~mEnd

The construct here is similar to For/Next (explained further up), but a little
more involved.  The special thing here is that this construct is mapped out to
the _If() function, which can take an indefinite number of arguments (as
opposed to the IIF() function that takes exactly 3 arguments).  The indefinite
number of arguments accommodate the ElseIf clause, of which there might be, 0,
1, or more within the code block.  The else clause might be present 0 or 1
times.

The arguments of _If work in pairs.  If the first argument is true, then the
second argument is executed, and the rest of arguments (if there are any) are
ignore.  If the first argument is not true, then the third argument is checked.
If that one is true the fourth argument is executed, and so on.

If the code block only has an If and End If, without Else or ElseIf then _If
is implemented with two arguments.  Each ElseIf adds another pair of arguments.
Else by itself is similar to Else, except it passes a 1, making it always true,
so the argument following 1 is always executed if all other conditions fail.

The _If function is different from most typical functions in that arguments are
passed by expression, which means that an expression passed as an argument is
not evaluated.  Instead, the expression handle is passed, and the expression is
executed only if the condition is true.

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

15   If {cond} Then {code} [Else {Other}] _
     ::= _If({cond}, _basic: {code} {Other: , 1, _basic: {Other}})

This is the single-line version of the If/Then statement.  The ideas behind it
are very similar to that of the single-line versions of previously explained
constructs.  There is, however, an important peculiarity.  The second argument,
and the optional fourth argument of _if, which represent statements to be
executed, are preceded by "_basic:", which as explained further up, as a way
to help distinguish the code immediately following that word as a statement;
as in the case of "=" which in BASIC is used both for variable assignments
statements or as a comparison operator.

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

10   Val   ::= ToFloat

This simply maps the Val word onto the name of the ToFloat function that was
defined in Library.uc.  ToFloat() is not the same as the conventional BASIC
Val() function, in that it coerces any argument (not just strings) into a
floating point number (Extended Precision).  ToFloat is based on the
GenericConvert().  Should you wish to have it work only on string based data
types, you can simply replace the GenericConvert definition in Library.uc,
which takes a value of AnyType as the second argument, and define one or more
that takes the String type or other types like LPCSTR or ASCIIZ.


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

10   Timer ::= (GetTickCount/1000)

This simply replaces occurrences of Timer in your code with (GetTickCount/1000),
using the GetTickCount function defined in WinAPI.uc.  This is slightly
different from the tradition BASIC Timer that starts at midnight, whereas this
function starts from the time the system was turned on.


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

10   String * {size:" [0-9]+"} ::= FixedString ~~ Size: {size}

This syntax is for defining fixed strings.  It is designed to work in the
context of a Dim statement, where the word String is changed to FixedString,
and the given size is set using the bootstrap "Size:" property.  The
FixedString type is defined in Types.uc.

Notice that there is a number of different definitions for String.  There is
the dynamic String type, and several String$ functions (define further down or
elsewhere), and now the fixed length string.  Each syntax is recognized
depending on the context.


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

99   &{"b"}{BinaryNumber:"[0-1]+"} ::= BaseConvert("{BinaryNumber}", 2)
99   &{"o"}{OctalNumber:"[0-7]+"}  ::= BaseConvert("{OctalNumber}",  8)
99   &{"h"}{HexNumber:"[0-9A-F]+"} ::= BaseConvert("{HexNumber}",   16)

These define the BASIC syntax for hex, binary, and octal numbers, by mapping
them out to BaseConvert, which is a function that can display numbers of any
type.  The ideas in the above syntax that have not been covered so far include
the fact that syntax name (the first word in the syntax), does not have to be
alphanumeric.  It can be a reducible symbol as well.  And on the other side of
"::=", the argument names are located within quotes.  Syntax arguments on the
right hand side of "::=" are always ...

Unlike the traditional syntax, BaseConvert is capable of working with
fractional numbers.  Should you desire this additional feature, simply
extended the RegExes above to include an optional decimal part.


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

10   UBound({MyArray})::=~Eval(uCalc(uc_GetItemData,"{MyArray}",0,uc_ArgCount))

Several important concepts are introduced in this syntax.  First is a call to
the uCalc Language Builder function.  This is distinct from the uCalc
Interpreter statement discussed earlier on.  The Interpreter statement is the
word uCalc followed by a space, and then a command.  This one here is a
function, with the word uCalc followed by parenthesis and one more arguments.
The uCalc function allows you to do a wide variety of things.  See the help
file for more details.  In this particular case we use uc_GetItemData to
retrieve the number of elements in the given array (indicated by the
uc_ArgCount property).

The second important thing here is the ~Eval pattern (defined in Define.uc).
~Eval allows the parser to evaluate a given expression at the moment it is
parsed, instead of later at the moment where the rest of the code executed.

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

10   Function {FuncName} ([{ParamList}]) [As {Type}] ::=          _
     SetInput(\q{ Var: {FuncName} {Type:~~ DataType: {Type}} }    _
               ~~ { Execute: RenameItem("{FuncName}", "__", ~t) } _
               ~~ { Syntax: Function ::= __ }                     _
               ~~ { Syntax: {FuncName}{NoParenth:"[^\(]"} ::= __{NoParenth} } _
               ~~ Params: ({ParamList})                           _
               ~~ DataType: {Type}                                _
               ~~ name_: {FuncName}                               _
               ~~ Rank: 2                                         _
               ~~ Properties: ucFunction+ucPrefix                 _
               ~~ FuncStart\q)                                    _
     SetInput("uCalc Prefix \quCalc Define _basic: \q")           _
     SetInput("FuncName$ = \q{FuncName}\q")

This syntax is more intricate than all the other ones introduced so far.  There
are quite a few concepts involved here.  Concepts related to the first line are
pretty much covered already in previous explanations.  The second line
introduces SetInput.  SetInput, which is defined in Library.uc, looks like a
function, but is itself a syntax construct.  It immediately pushes a line of
code onto the interpreter's input stack.  In this particular syntax, we are
pushing three lines of code, after which the interpreter will pull them out one
at a time, starting with the last one, and execute them, before waiting for
further input from the user (or from a file).  This set-up is necessary because
we are not merely defining an syntax or other item, but we're defining a
definition so to speak.  We are creating a syntax that will define other
syntaxes when we want to define a function

SetInput works with a string argument.  The alternative "\q" delimiter is used
instead of double quotes in the first occurrence of SetInput, in order to allow
the regular double quote character within the string.

Since the last SetInput line is the one that will be interpreted first, let's
start with that one.  This sets a global variable named FuncName$ to whatever
function name is currently being defined.  (This is different for now from PB's
FuncName$, which is available locally to the function itself).  The main purpose
of this is to allow the interpreter to remember the current function's name up
until the "End Function" line, at which point the function name will be used
to construct another syntax explained in the next session.

The next SetInput line changes the interpreter's prefix to
"uCalc Define _basic: ".  The interpreter's Define command was explained a
little in a previous section where patterns were being defined.  In that
situation a series of unrelated patterns were being defined.  Here, all
subsequent lines of code will be part of the same definition, as indicated in
the final SetInput.

The final SetInput includes a series of properties or instructions, all of which
are part of the same line of definition, even if the definition is broken down
into multiple lines using the " _" line continuation term for clarity.  Each
property or instruction is separated from the next with a "~~".  Let's separate
each one:


{ Var: {FuncName} {Type:~~ DataType: {Type}} } _

This line has curly braces that serve several different purposes.  So far, we
have discussed curly braces surrounding syntax arguments.  If an alphanumeric
word is surrounded by curly braces, and is to the left side of "::=", then it
is a syntax argument.  That same argument may appear on the right side of
"::=" as well, as is the case above for {FuncName} and {Type} (both the
inner {Type}, and the outer {Type:...}).  The other set of curly braces does
not match an argument found on the left of "::=".  Those serve a different
purpose discussed further down.

{FuncName} and {Type} actually straddle two separate definitions.  The first
definition is what is taking place now that we are defining the
Function / End Function construct.  The second definition is one that will
take place at some future point, whenever a function is defined.  That's what
the other curly braces belong to.  What is being defined at present is a
syntax.  The other item that will be defined later includes a combination of
things, not all of which are syntax definitions.

So the line above in particular represents a user defined definition (as
opposed to a syntax definition); in this case "Var:", the definition of which
you will find in the Define.uc file.  It defines a variable.  In this
particular case the outer curly braces makes the definition local to the
function item currently being defined.  If you define a function named
MyFunction$(), then the above line will create a local variable named
MyFunction$.  If a the optional {Type} argument was specified, then the
DataType clause would be appended.  By default if you define a function-like
procedure the first variable to be defined will also represent the function's
return value.


~~ { Execute: RenameItem("{FuncName}", "__", ~t) } _

It might take a bit of conceptual experimentation to better understand this
and subsequent lines.  There are several issues at play.  If you have a
function named MyFunction$, you want MyFunction$ to serve as a kind of return
variable.  You also want the word "Function" itself to alternatively serve as
a synonym for the return variable. Furthermore, if you will be doing recursive
calls, you want to distinguish between the variable named MyFunction$, and
the function named MyFunction$.  Despite all this, the most important reason
why this particular line is required, as opposed to simply naming the local
return variable "Function" to begin with and mapping the name MyFunction$ onto
it as a synonym, is that the actual function name (MyFunction$ in this case) is
required for the local variable definition especially if it has a data type
extention ($ for String in this case) is used instead of an explicit type
declaration, such as "As String".  A separate syntax described further down
handles implicit type declarations using extensions.

Anyway, what this line actually does is to perform the Execute command and
rename the local variable (MyFunction$) to the symbol "__".  The chosen name
"__" is completely arbitrary.  It can be any name that will not likely be used
elsewhere.  (Preferably you might wish to use a non-printable name such as
Chr$(15)).  RenameItem was discussed previously.  However, here we have a 3rd
argument, ~t.  The ~t pattern, which is defined in Define.uc, represents the
current local thread.


~~ { Syntax: Function ::= __ } _

This syntax simply maps out the word "Function" as an alternative name for the
return variable.  The curly braces makes this syntax definition applicable only
locally (it will not be confused with the parent Function construct).


~~ { Syntax: {FuncName}{NoParenth:"[^\(]"} ::= __{NoParenth} } _

This local syntax is what lets the definition distinguish between the function
name, when used as a return variable, and the function name when used in a
recursive call.  Basically if the name is not followed by parenthesis, then it
is renamed to "__".


~~ Params: ({ParamList}) _

Previous lines in this group so far were local to the function, and were each
enclosed in curly braces.  This line, as well as the ones that follow now apply
to the function itself.  Just like "Var:", "Params:" is also a user defined
definition, found in the Define.uc file.  See Define.Txt for more details.


~~ DataType: {Type} _

Unlike "Params:", this one is an item property.  If an explicit type name was
given, this line will set the function to that type.  If no type name is given,
this line will be irrelevant.  It would actually go through and temporary assign
a default type, however, the real type would eventually be settled in the next
line.


~~ name_: {FuncName} _

This line is what assigns the function item its name, based on the value
supplied in the {FuncName} syntax argument.  "Name_:" is defined in Define.uc
simply as a place holder synonym for the "Name:" property.  Further down,
you'll see how "Name_:" is redefined in a way that allows definitions to
determine an item's data type, based on the extension character found at the
end of a name (as in $ for string in MyVariable$).


~~ Rank: 2 _

So far, we've discussed implicit item ranking.  Here, however, we assign an
explicit rank.  Why?  That is because in addition to defining a function as
an alphanumeric name followed by parentheses, and 0 or more arguments, you'll
see in the next section that we are also tacking on a definition that allows
you to invoke the function as a statement.  

In order for the statement syntax to work, it must have a higher rank than the
function of the same name.  If you define a given function just once, then the
default ranking order will work just fine.  However, if you overload a
function -- that is to define a function of the same name, but with an
alternative definition -- as is the case for instance with the Mid$ function of
which there are several versions in this file, without an explicit rank, you
would end up with a ...

Unlike an item's precedence level, which is a fixed value that you assign, and
that can be the same value as that of other items, items that share the same
name each have a unique rank number ranging from 1 to a number that corresponds
to the number of items that share the same name.  Using the default ranking,
each alternative new definition using the same name causes previous
definitions to shift to a lower rank.  (In reality a rank is not a true item
property that is stored somewhere, but a conceptual number that takes effect at
the moment an item is defined, and can be computed if necessary should you
later want to find the rank of a given item).

In any event, since the rank shifts with each alternative definition, by
defining a function twice, you'd end up with [+++ Revisit]


~~ Properties: ucFunction+ucPrefix _

This sets the property as a function (a procedure type item) of the form where
the function name precedes the arguments.


~~ FuncStart\q) _

FuncStart sets a flag that causes all subsequent definitions to be part of the
same procedure definition, until the ~FuncEnd pattern is encountered.  In
between that space represents the body of your function.  The\q represents the
end of the long quoted text string that included all the previous lines in this
group.  It's followed by a parenthesis that closes the SetInput found a few
lines earlier.


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

10   End Function ::= ~FuncEnd                                           _
     SetInput("uCalc Prefix \q_basic: \q")                               _
     SetInput("Syntax: 10 " + FuncName$ + "{\q[ ]+\q}{Params:\q[^~]+\q}" _
              + "::=" + FuncName$ + "({Params})")

This concludes a function definition.  As in the previous section, the second
SetInput line that is pushed last onto the input stack is the first one to be
retrieved by the interpreter.  It creates a syntax with the same name as the
function, allowing you to call the item either as a function or a statement.
So once MsgBox is defined (see further down), you can call it either of the
following ways:

MsgBox "Hello"
Result = MsgBox("Great",,"New Title")


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

10   Sub {Def:" .+"} ::= Function {Def} As Void
10   End Sub         ::= SetInput("End Function") _
                         SetInput("__ -> 0") ' +++ SetInput shouldn't be needed in this line

This maps the Sub / End Sub construct onto the Function / End Function
construct described in the previous section.  A Sub routine is identical to a
Function except that it doesn't use a return value.  The elaborate function
construct does rely on a type, so a Sub here is defined as a function of type
Void.  Void, which is defined in Types.uc is a little different from other
types in that its only use is to print the word "Ok", if a Void item is invoked
at the top level from the interpreter.

"End Sub" is replaced by "End Function".  However, the functions return value
is set to 0 [+++ due to a bug].

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

10   TypeExtention {"[ ]+"}{Extention:"[$#!%&@?]{1,3}"}{"[ ]+"}{TypeName} _
     ::= SetInput(\quCalc Syntax 10 Name_: {ItemName:" *[a-z_][0-9a-z_]*[{Extention}]"} _
        ::= Name: {ItemName} ~~ DataType: {TypeName}\q)

This complicated line looks a little ungainly, but allows you to add support
for implicit type extensions (such as $ for string, or ! for Single precision).
The clearer section associated with this is a few sections down starting with
the line that says: uCalc Prefix "TypeExtention ".

Pretty much all the concepts used in this line are discussed in previous
sections.  What this does is it allows you to associate a type extension with
a type.  This is done by redefining the user defined "Name_:" definition --
which was defined in Define.uc only as a place holder -- so that it appends
a DataType property clause to the Name property clause.  The actual definition
does take place here.  Now we are only definition a definition of how to do
this.  The actual definition takes place a few sections down.  A different
"Name_:" syntax is defined for each extension.


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

15   Line Input [{Prompt:\q[ ]+"[^"]*"\q=""}] [,] {StringVar} _
     ::= {StringVar} -> _LineInput$({Prompt})


This maps out a Line Input statement onto the _LineInput$ function (which is
defined further down).  New here so far, is a default value for the {Prompt}
argument, if no prompt is supplied.  In previous cases, the absence of an
optional syntax argument translated to empty space.  However the _LineInput$
function requires an actual string, even if the string consists of empty
quotes.  _LineInput$("") will work, whereas _LineInput$() with nothing inside
would not.  A default value is supplied ending the syntax arg with an "="
followed by the default value).  The literal characters after the "=" sign are
used ("" in this case).


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

uCalc Prefix ""

Discussed earlier.


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

uCalc Prefix "TypeExtention "
   $    String
   #    Double
   !    Single
   %    Integer
   &    Long
   @    Currency
uCalc Prefix ""

TypeExtention is a syntax defined a few sections earlier that associates an
extension symbol with a data type.


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

Dim FuncName$

This is the first occurrence of the Dim statement in this file.  Dim is defined
in Library.uc, and is generally similar to what you'd expect in BASIC.  An
additional enhancement, which allow you to dim pointer variables is available
if you use the PBFlavor.uc file (it is loaded here by default).  FuncName$ in
particular was described earlier.


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

uCalc Define Func:: Chr$(Code As Long) As String At ucAddr(uc_Func_Chr)

Earlier, we created a more elaborate construct for defining multi-line
functions.  Define.uc includes simpler constructs for single line function
definitions.  There are two editions.  This one -- with two consecutive semi-
colons -- is for callback functions implemented using uCalc's NativeCall, a
number of which -- such as this Chr routine -- are included in the uCalc DLL.


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

uCalc Prefix "uCalc Define Func: "
   CBYT(x) As Byte     = x
   CCUR(x) As Currency = x
   CDBL(x) As Double   = x
   CINT(x) As Integer  = x
   CLNG(x) As Long     = x
   CSNG(x) As Single   = x
uCalc Prefix ""

In the previous section, we had Func followed by two colons.  Here it is
followed by only one colon.  A function defined with one colon can either be
attached to a conventional StdCall function, such as those found in the Windows
API, or for user defined functions, such as the ones above.  This too is a
syntax construct defined in Define.uc

The functions above are conversion routines as found in VB and PB.  A type is
not specified for the "x" argument so it uses the default (which is set at
Extended precision).


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

uCalc Prefix "uCalc Define Op: "
   10 IsTrue  {x} = ((x)<>0)
   10 IsFalse {x} = ((x)=0)
uCalc Prefix ""

In the same way that functions can be defined using the single-line format, so
too can operators be defined, using the "Op:" construct defined in Define.uc.
Unlike function arguments which are enclosed in parentheses, for operators,
parenthesis do not apply.  An operator can be either Prefix, Infix, or Postfix.
And in addition to a alphanumeric names used for functions, an operator name
can either be a reducible symbol, or an alphanumeric word.  To accommodate all
of this, operands to the left of the "=" sign must be enclosed within curly
braces, but no braces to the right of the "=" sign.  Though it has taken some
thought to come up with this arrangement, it is somewhat arbitrary.  If
necessary, you can modify the Op: construct.

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

Function MsgBox(Text$, Style& = 0, Title$ = "uCalc") As Long
   Function = MessageBox(0, Text$, Title$, Style&)
End function

Function String$(Count As Long, Code As Long)
   Dim TotalStr As String
   Dim x As Long

   For x = 1 To Count
      TotalStr = TotalStr + Chr$(Code)
   Next

   String$ = TotalStr
End Function

By this point we have enough syntax to define functions like the ones above,
using BASIC-like syntax.  The keyword "Optional" was not implemented, but a
construct for it can easily be added if needed.  Here a parameter is deemed
optional simply by virtue of having an "=" sign.


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

uCalc Load "PBFlavor.uc"

This loads and runs the code found in the PBFlavor.uc file, which contains
BASIC items that are more specific to PowerBASIC.

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

' Left$, Right$, and Mid$ below include some PB flavoring in that
' they can accept negative value for the second arg.

Function Left$(text$, Count As Long)
   Count = Min(Count, Len(Text$))
   If Count < 0 Then Count = Len(Text$)-Abs(Count)
   Left$ = Peek$(StrPtr(Text$), Count)
End Function

Function Right$(text$, Count As Long)
   Count = Min(Count, Len(Text$))
   If Count < 0 Then Count = Len(Text$)-Abs(Count)
   Right$ = Peek$(StrPtr(Text$)+Len(Text$)-Count, Count)
End Function

Function Mid$(text$, Start&, Length&)
   Length& = Min(Length&, Len(Text$)-Start&+1)
   If Length& < 0 Then Length& = Len(Text$)-Abs(Length&)
   Mid$ = Peek$(StrPtr(Text$)+Start&-1, Length&)
End Function

Function Mid$(Text$, Start&)
   Mid$ = Mid$(Text$, Start&, Len(Text$)-Start&+1)
End Function

Function LTrim$(text$, TrimChars$ = " ")
   Dim Start As Long
   Dim TrimCharLen As Long

   Start = 1
   TrimCharLen = Len(TrimChars$)

   While Mid$(text$, Start, TrimCharLen) = TrimChars$
      Start = Start + TrimCharLen
   Wend

   LTrim$ = Mid$(text$, Start)
End Function

Function _LineInput$(Prompt$)
   Dim LineLength&, Ignore&

   _Print(Prompt$)   
   SetConsoleMode(StdIn, ENABLE_LINE_INPUT+ENABLE_ECHO_INPUT+ENABLE_PROCESSED_INPUT)
   ReadConsole(StdIn, _lpText, 80, LineLength&, Ignore&)
   _LineInput$ -> Left$(_lpText, LineLength&-2)
End Function

These are all functions defined using the BASIC constructs that we have
defined.  They represent a few common functions you might find in a typical
BASIC.  Notice that some functions are overloaded, such as Mid$, which has
two alternative definitions (plus a 3rd one defined earlier on as a statement).
Several functions employ the PB-like Peek$ function, which is defined in
PBFlavor.uc [+++ re-organize]


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

uCalc Prefix "_basic: "

In order for our BASIC to distinguish between the "=" symbol as an assignment
operator, or as a comparison operator, and to distinguish between Mid$ as a
statement and as a function, as described earlier, this prefix, which is
implicitly appended in front of every line is required.


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

ucVersion = ucVersion + "uCalc BASIC. January 2007 (beta)"+\cr

This is a simple string variable, in which it is a good idea to append product
information for whatever special language or library add-ons you create.

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

MainPrompt      = "ucalc:BASIC> "
MultiLinePrompt = "ucalc:BASIC>>"

These two variables are attached to internal variables within the interpreter,
which display a prompt.  When you create a language or environment, you may
want to change the prompt so that the user knows what environment they are
dealing with.  The multi-line prompt is automatically used by the interpreter
when it wants to signal to the end-user that it requires more lines of code to
complete an action.

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

' End of file

This comment at the end of the file is not required, but I use it as a visual
marker.

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

