This repository has been archived on 2024-09-22. You can view files and clone it, but cannot push or open issues or pull requests.
pbi-ide/help/BasicStampHelp/Content/LanguageTopics/Reference/Variables.htm

386 lines
24 KiB
HTML
Raw Normal View History

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" MadCap:lastBlockDepth="6" MadCap:lastHeight="94" MadCap:lastWidth="853" MadCap:disableMasterStylesheet="true" MadCap:tocPath="PBASIC Language Reference" MadCap:InPreviewMode="false" MadCap:PreloadImages="false" MadCap:RuntimeFileType="Topic" MadCap:TargetType="WebHelp" lang="en-us" xml:lang="en-us" MadCap:PathToHelpSystem="../../../" MadCap:HelpSystemFileName="Default.xml" MadCap:SearchType="Stem">
<head><title>Variables</title>
<link href="../../SkinSupport/MadCap.css" rel="stylesheet" />
<link href="../../Resources/Stylesheets/BSE_Help.css" rel="stylesheet" />
<script src="../../SkinSupport/MadCapAll.js" type="text/javascript">
</script>
</head>
<body>
<div class="MCBreadcrumbsBox_0"><span class="MCBreadcrumbsPrefix">You are here: </span><a class="MCBreadcrumbsLink" href="AlphaRef.htm">PBASIC Language Reference</a><span class="MCBreadcrumbsDivider"> &gt; </span><span class="MCBreadcrumbs">Variables</span>
</div>
<h1>Variables</h1>
<div class="ImagePlusCaption">
<div class="Col2">
<p>
<img src="../../graphics/pgm_icon1.gif" border="0" alt="BS1 icon" title="BS1 icon" />
<img src="../../graphics/pgm_icon2.gif" border="0" alt="BS2 icon" title="BS2 icon" />
<img src="../../graphics/pgm_icon2e.gif" border="0" alt="BS2e icon" title="BS2e icon" />
<img src="../../graphics/pgm_icon2sx.gif" border="0" alt="BS2sx icon" title="BS2sx icon" />
<img src="../../graphics/pgm_icon2p.gif" border="0" alt="BS2p icon" title="BS2p icon" />
<img src="../../graphics/pgm_icon2pe.gif" border="0" alt="BS2pe icon" title="BS2pe icon" />
<img src="../../graphics/pgm_icon2px.gif" border="0" alt="BS2px icon" title="BS2px icon" />
</p>
</div>
<p style="text-align: right;">&#160;</p>
<p>&#160;</p>
</div>
<p class="clear">&#160;</p>
<p>&#160;</p>
<p>(See also: <a href="MemoryOrg.htm" target="" title="" alt="" class="MCXref_0">Memory Organization </a>)</p>
<h2>Defining and Using Variables</h2>
<p class="PlainText">Before you can use a variable in a PBASIC program you must declare it.
"Declare" means letting the BASIC Stamp know that you plan to use a variable,
what you want to call it, and how big it is. Although PBASIC does have predefined
variables that you can use without declaring them first (see <a href="MemoryOrg.htm" target="" title="" alt="" class="MCXref_0">Memory Organization </a>),
the preferred way to set up variables is to use the directive <span class="keyword_in_text">SYMBOL</span> (for the BS1)
or <span class="keyword_in_text">VAR</span> (for all other BASIC Stamp models). Here is the syntax for a variable declaration:</p>
<p>
<img align="absmiddle" src="../../graphics/bs1_inline.gif" border="0" />
</p><pre xml:space="preserve">
SYMBOL name = RegisterName
</pre>
<p>
<img align="absmiddle" src="../../graphics/bs2all_inline.gif" border="0" />
</p><pre xml:space="preserve">
name VAR VarType
</pre>
<p class="PlainText">...where <i>name</i> is the name by which you will refer to the variable,
<i>RegisterName</i> is the "fixed" name for the register and <i>VarType</i> indicates
the type (Bit, Nib, Byte, or Word) of storage for the variable. NOTE: The top
example is for the BS1 and the bottom example is for all BASIC Stamp 2 models.</p>
<h2>The Rules of Symbol Names</h2>
<p class="PlainText">There are certain rules regarding symbol names. Symbols must start with a
letter, can contain a mixture of letters, numbers, and underscore (_) characters,
and must not be the same as PBASIC keywords or labels used in your program.
Additionally, symbols can be up to 32 characters long. See the <a href="AlphaRef.htm" target="" title="" alt="" class="MCXref_0">PBASIC Command Reference</a> for a list of PBASIC keywords. PBASIC
does not distinguish between upper and lower case, so the names MYVARIABLE,
myVariable, and MyVaRiAbLe are all equivalent.</p>
<p class="PlainText">Refer to the <a href="ElementsStyle.htm" target="" title="" alt="" class="MCXref_0">Elements of PBASIC Style</a> for
suggested guidelines on naming variables.</p>
<p>
<img align="absmiddle" src="../../graphics/bs1_inline.gif" border="0" />
</p>
<p class="PlainText">For the BS1, the <i>RegisterName</i> is one of the predefined "fixed" variable
names, such as W0, W1, B0, B1, etc. Here are a few examples of variable
declarations on the BS1:</p><pre class="BScode" xml:space="preserve">
SYMBOL temp = W0 ' value can be 0 to 65535
SYMBOL cntr = B1 ' value can be 0 to 255
SYMBOL result = B2 ' value can be 0 to 255
</pre>
<p class="PlainText">The above example will create a variable called <i>temp</i> whose contents
will be stored in the RAM location called W0. Also, the variable <i>cntr</i>will be located at RAM location B1 and <i>result</i> at location B2. Note that
<i>temp</i> is a word-sized variable (because that's what size W0 is) while the
other two are both byte-sized variables. Throughout the rest of the program, we
can use the names <i>temp</i>, <i>cntr</i>, and <i>result</i> instead of W0, B1
and B2, respectively. This makes the code much more readable; it's easier to
determine what <i>cntr</i> is used for than it would be to figure out what the
name B1 means. Please note, that <i>cntr</i> resides at location B1, and B1
happens to be the high byte of W0. This means than changing <i>cntr</i> will also
change <i>temp</i> since they overlap. A situation like this usually is a mistake
and results in strange behavior, but is also a powerful feature if used carefully.</p>
<p>
<img align="absmiddle" src="../../graphics/bs2all_inline.gif" border="0" />
</p>
<p class="PlainText">For the BS2-family, the Size argument has four choices: 1) Bit (1 bit),
2) Nib (nibble; 4 bits), 3) Byte (8 bits), and 4) Word (16 bits). Here are some
examples of variable declarations on the BS2-family:</p><pre class="BScode" xml:space="preserve">
mouse VAR Bit ' Value can be 0 or 1
cat VAR Nib ' Value can be 0 to 15
dog VAR Byte ' Value can be 0 to 255
rhino VAR Word ' Value can be 0 to 65535
</pre>
<p class="PlainText">The example above will create a bit-sized variable called <i>mouse</i>, and
nibble-sized variable called <i>cat</i>, a byte-size variable called <i>dog</i>
and a word-sized variable called <i>rhino</i>. Unlike in the BS1, these variable
declarations don't point to a specific location in RAM. Instead, we only specified
the desired size for each variable; the BASIC Stamp will arrange them in RAM as
it sees fit. Throughout the rest of the program, we can use the names <i>mouse, cat,
dog</i> and <i>rhino</i> to set or retrieve the contents of these variables.</p>
<p>
<img src="../../graphics/bs1_inline.gif" />
<img align="absmiddle" src="../../graphics/bs2all_inline.gif" border="0" />
</p>
<p class="PlainText">A variable should be given the smallest size that will hold the largest value
that will ever be stored in it. If you need a variable to hold the on/off status
(1 or 0) of switch, use a bit. If you need a counter for a <span class="keyword_in_text">FOR...NEXT</span> loop
that will count from 1 to 100, use a byte. And so on.</p>
<p class="PlainText">If you assign a value to a variable that exceeds its size, the excess bits will
be lost. For example, suppose you use the nibble variable <i>cat</i>, from the
example above, and write cat = 260 (%100000100 binary). What will <i>cat</i>contain? It will hold only the lowest 4 bits of 260: %0100 (4 decimal).</p>
<p>
<img align="absmiddle" src="../../graphics/bs2all_inline.gif" border="0" />
</p>
<p class="PlainText">On the BS2-family, you can also define multi-part variables called arrays. An
array is a group of variables of the same size, and sharing a single name, but
broken up into numbered cells, called elements. You can define an array using the
following syntax:</p><pre xml:space="preserve">
name VAR Size(n)
</pre>
<p class="PlainText">where <i>name</i> and Size are the same as described earlier. The new argument,
(n), tells PBASIC how many elements you want the array to have. For example:</p><pre class="BScode" xml:space="preserve">
myList VAR Byte(10) ' Create a 10-byte array
</pre>
<p class="PlainText">Once an array is defined, you can access its elements by number. Numbering
starts at 0 and ends at n1. For example:</p><pre class="BScode" xml:space="preserve">
myList(3) = 57
DEBUG ? myList(3)
</pre>
<p class="PlainText">This code will display "myList(3) = 57" on the PC screen. The real power
of arrays is that the index value can be a variable itself. For example:</p><pre class="BScode" xml:space="preserve">
myBytes VAR Byte(10) ' Define 10-byte array
idx VAR Nib ' Define nibble variable
Main:
FOR idx = 0 TO 9 ' Repeat with idx= 0, 1...9
myBytes(idx) = idx * 13 ' Write idx*13 to array
NEXT
FOR idx = 0 TO 9 ' Repeat with idx= 0, 1...9
DEBUG "myBytes(", DEC idx, ")= ", DEC myBytes(idx), CR ' Show contents of each cell
NEXT
STOP
</pre>
<p class="PlainText">If you run this program, <span class="keyword_in_text">DEBUG</span> will display each of the 10 values stored
in the elements of the array: myBytes(0) = 0 * 13 = 0, myBytes(1) = 1 * 13 = 13,
myBytes(2) = 2 * 13 = 26 ... myBytes(9) = 9 * 13 = 117.</p>
<p class="PlainText">A word of caution about arrays: If you're familiar with other BASICs and have
used their arrays, you have probably run into the "subscript out of range" error.
Subscript is another term for the index value. It is out-of-range when it exceeds
the maximum value for the size of the array. For instance, in the example above,
<i>myBytes</i> is a 10-cell array. Allowable index numbers are 0 through 9. If
your program exceeds this range, PBASIC will not respond with an error message.
Instead, it will access the next RAM location past the end of the array. If you
are not careful about this, it can cause all sorts of bugs.</p>
<p class="PlainText">If accessing an out-of-range location is bad, why does PBASIC allow it? Unlike
a desktop computer, the BASIC Stamp doesn't always have a display device connected
to it for displaying error messages. So it just continues the best way it knows
how. It's up to the programmer (you!) to prevent bugs.</p>
<p class="PlainText">Another unique property of PBASIC arrays is this: You can refer to the 0th
(first) cell of the array by using just the array's name without an index value.
For example:</p>
<p>
<img align="absmiddle" src="../../graphics/bs2all_inline.gif" border="0" />
</p><pre class="BScode" xml:space="preserve">
myBytes VAR Byte(10) ' Define 10-byte array
Main:
myBytes(0) = 17 ' Store 17 to 0th (first) cell
DEBUG ? myBytes(0) ' Display contents of 0th cell
DEBUG ? myBytes ' Also displays contents of 0th cell
</pre>
<p class="PlainText">This feature is how the "string" capabilities of the <span class="keyword_in_text">DEBUG</span> and <span class="keyword_in_text">SEROUT</span> command expect to work, that is, referencing the variable name only and not a specific
element. A string is simply a byte array used to store text. See the "<a href="../Commands/DEBUG.htm#Displayi">Displaying
Strings (Byte Arrays)</a>" section in the <a href="../Commands/DEBUG.htm" target="" title="" alt="" class="MCXref_0">DEBUG</a> command
description for more information.</p>
<p class="PlainText">An <i><b>alias</b></i> is an alternative name for an existing variable. For
example:</p>
<p>
<img align="absmiddle" src="../../graphics/bs1_inline.gif" border="0" />
</p><pre class="BScode" xml:space="preserve">
SYMBOL cat = B0 ' Create a byte-sized variable
SYMBOL tabby = cat ' Create alias for cat
</pre>
<p>
<img align="absmiddle" src="../../graphics/bs2all_inline.gif" border="0" />
</p><pre class="BScode" xml:space="preserve">
cat VAR Byte ' Create a byte-sized variable
tabby VAR cat ' Create alias for cat
</pre>
<p class="PlainText">In this example, <i>tabby</i> is an alias to the variable <i>cat</i>. Anything
stored in <i>cat</i> shows up in <i>tabby</i> and vice versa. Both names refer to
the same physical piece of RAM. This kind of alias can be useful when you want to
reuse a temporary variable in different places in your program, but also want the
variable's name to reflect its function in each place. Use caution, because it is
easy to forget about the aliases; during debugging, you might end up asking 'How
did that value get here?!' The answer is that it was stored in the variable's
alias.</p>
<p>
<img align="absmiddle" src="../../graphics/bs2all_inline.gif" border="0" />
</p>
<p class="PlainText">On the BS2-family an alias can also serve as a window into a portion of another
variable. This is done using "modifiers." Here the alias is assigned with a
modifier that specifies what part:</p><pre class="BScode" xml:space="preserve">
rhino VAR Word ' A 16-bit variable
head VAR rhino.HIGHBYTE ' Highest 8 bits of rhino
tail VAR rhino.LOWBYTE ' Lowest 8 bits of rhino
</pre>
<p class="PlainText">Given that example, if you write the value %1011000011111101 to <i>rhino</i>,
then <i>head</i> would contain %10110000 and <i>tail</i> would contain %11111101.</p>
<p class="PlainText">The table below lists all the variable modifiers. PBASIC2 lets you apply these
modifiers to any variable name and to combine them in any fashion that makes sense.
For example, it will allow:</p><pre class="BScode" xml:space="preserve">
rhino VAR Word ' A 16-bit variable
eye VAR rhino.HIGHBYTE.LOWNIB.BIT1 ' A bit
</pre>
<p>
<center>
<table cellpadding="4" cellspacing="0" border="1">
<tr bgcolor="#CFCFCF" align="center" valign="top">
<td width="80">Symbol</td>
<td width="260">Definitions</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">LOWBYTE</td>
<td>&#160;Low byte of a word</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">HIGHBYTE</td>
<td>&#160;High byte of a word</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">BYTE0</td>
<td>&#160;Low byte of a word</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">BYTE1</td>
<td>&#160;High byte of a word</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">LOWNIB</td>
<td>&#160;Low nibble of a word or byte</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">HIGHNIB</td>
<td>&#160;High nibble of a word or byte</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">NIB0</td>
<td>&#160;Nibble 0 of a word or byte</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">NIB1</td>
<td>&#160;Nibble 1 of a word or byte</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">NIB2</td>
<td>&#160;Nibble 2 of a word</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">NIB3</td>
<td>&#160;Nibble 3 of a word</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">LOWBIT</td>
<td>&#160;Low bit (LSB) of a word, byte, or nibble</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">HIGHBIT</td>
<td>&#160;High bit (MSB) of a word, byte, or nibble</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">BIT0</td>
<td>&#160;Bit 0 (LSB) of a word, byte, or nibble</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">BIT1</td>
<td>&#160;Bit 1 of a word, byte, or nibble</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">BIT2</td>
<td>&#160;Bit 2 of a word, byte, or nibble</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">BIT3</td>
<td>&#160;Bit 3 of a word, byte, or nibble</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">BIT4 ... BIT7</td>
<td>&#160;Bits 4 through 7 of a word or byte</td>
</tr>
<tr valign="MIDDLE">
<td align="CENTER">BIT8 ... BIT15</td>
<td>&#160;Bits 8 through 15 of a word</td>
</tr>
</table>
</center>
</p>
<p>&#160;</p>
<p class="PlainText">The commonsense rule for combining modifiers is that they must get progressively
smaller from left to right. It would make no sense to specify, for instance, the
low byte of a nibble, because a nibble is smaller than a byte! And just because
you can stack up modifiers doesn't mean that you should unless it is the clearest
way to express the location of the part you want get at. The example above might
be improved:</p><pre class="BScode" xml:space="preserve">
rhino VAR Word ' A 16-bit variable
eye VAR rhino.BIT9 ' A bit
</pre>
<p class="PlainText">Although we've only discussed variable modifiers in terms of creating alias
variables, you can also use them within program instructions:</p><pre class="BScode" xml:space="preserve">
rhino VAR Word ' A 16-bit variable
head VAR rhino.HIGHBYTE ' Highest 8 bits of rhino
Main:
rhino = 13567
DEBUG ? head ' Show the value of alias variable head
DEBUG ? rhino.HIGHBYTE ' rhino.HIGHBYTE works too
STOP
</pre>
<p class="PlainText">Modifiers also work with arrays. For example:</p><pre class="BScode" xml:space="preserve">
myBytes VAR Byte(10) ' Define 10-byte array
Main:
myBytes(0) = $AB ' Hex $AB into 0th byte
DEBUG HEX ? myBytes.LOWNIB(0) ' Show low nib ($B)
DEBUG HEX ? myBytes.LOWNIB(1) ' Show high nib ($A)
</pre>
<p class="PlainText">If you looked closely at that example, you probably thought it was a misprint.
Shouldn't myBytes.LowNib(1) give you the low nibble of byte 1 of the array rather
than the high nibble of byte 0? Well, it doesn't. The modifier changes the meaning
of the index value to match its own size. In the example above, when myBytes() is
addressed as a byte array, it has 10 byte-sized cells numbered 0 through 9. When
it is addressed as a nibble array, using myBytes.LowNib(), it has 20 nibble-sized
cells numbered 0 through 19. You could also address it as individual bits using
myBytes.LowBit(), in which case it would have 80 bit-sized cells numbered 0
through 79.</p>
<p class="PlainText">What if you use something other than a “low” modifier, say myBytes.HighNib()?
That will work, but its effect will be to start the nibble array with the high
nibble of myBytes(0). The nibbles you address with this nib array will all be
contiguous, one right after the other, as in the previous example.</p><pre class="BScode" xml:space="preserve">
myBytes VAR Byte(10) ' Define 10-byte array
Main:
myBytes(0) = $AB ' Hex $AB into 0th byte
myBytes(1) = $CD ' Hex $CD into next byte
DEBUG HEX ? myBytes.HIGHNIB(0) ' Show high nib of cell 0 ($A)
DEBUG HEX ? myBytes.HIGHNIB(1) ' Show next nib ($D)
</pre>
<p class="PlainText">This property of modified arrays makes the names a little confusing. If you
prefer, you can use the less-descriptive versions of the modifier names; Bit0
instead of LowBit, Nib0 instead of LowNib, and Byte0 instead of LowByte. These
have exactly the same effect, but may be less likely to be misconstrued.</p>
<p class="PlainText">You may also use modifiers with the 0th cell of an array by referring to just
the array name without the index value in parentheses. It's fair game for aliases
and modifiers, both in <span class="keyword_in_text">VAR </span>directives and in instructions.</p>
<div class="Col2">
<div class="MasterFoot">
<p MadCap:conditions="BSEconditions.BSEWebHelp (Primary)-INCLUDE"><a href="../../HomeTopics/HomePage.htm">Go to Welcome page</a>
</p>
</div>
</div>
<div class="Col2">
<div class="MasterFoot">
<p style="text-align: right;"><span class="ContactInfoProjectName">BASIC Stamp Help</span> <![CDATA[ ]]><span class="ContactInfoVersion#">Version 2.5.4</span> <![CDATA[ ]]></p>
<p style="text-align: right;">Copyright ©&#160;<span class="ContactInfoCompanyName">Parallax Inc.</span></p>
<p style="text-align: right;"><span class="SystemShortDate">8/8/2012</span>
</p>
</div>
</div>
<script type="text/javascript">/* <![CDATA[ */
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-285614-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
/* ]]> */</script>
<script type="text/javascript" src="../../SkinSupport/MadCapBodyEnd.js">
</script>
</body>
</html>