📄 chapter 6 assignment and expressions.htm
字号:
* | - - MULB MULW MULD MULQ MULB MULW MULD MULQ FMULS FMULD
/ | - - - - - - - - - - FDIVS FDIVD
div | - - DIVB DIVW DIVD DIVQ DIVB DIVW DIVD DIVQ - -
mod | - - MODB MODW MODD MODQ MODB MODW MODD MODQ - -
</PRE>
<P>
<H3>6.2.9 Rule UnaryExpression</TT> </H3><!----------------------------------------------------------------------------->
<MENU><IMG src="Chapter 6 Assignment and Expressions.files/RULE26.gif">
<P><FONT face=arial size=-1><B>Figure {RULE26}.</B></FONT> </P></MENU>This rule
is basically simple. The operator is saved, and <TT>RuleFactor()</TT> is called.
Once <TT>RuleFactor()</TT> returns, code is emmitted to change the sign of the
operand that will be on the EES. This is demonstrated by figure {UOPRCOD}
<P>
<MENU><IMG src="Chapter 6 Assignment and Expressions.files/UOPRCOD.gif">
<P><FONT face=arial size=-1><B>Figure {UOPRCOD}.</B></FONT> </P></MENU>Remember
that certain types of operands can be negated and others can not. <PRE> Type Legal Unary
Operator(s)
======================
bool not
char <I>none</I>
int -, +
card +
real -, +
OP | bool char int8 int16 int32 int64 card8 card16 card32 card64 real32 real64
============================================================================================
- | - - NEGB NEGW NEGD NEGQ - - - - FNEGS FNEGD
~ | - - NOTB NOTW NOTD NOTQ NOTB NOTW NOTD NOTQ - -
not | LIB 01 - - - - - - - - - - -
| XORB
</PRE>Notice that you can not take the negative of a cardinal, since cardinals
by definition are positive.
<P>Notice also that there is not one single instruction that will negate a
boolean value. The way to "not" a boolean expression is to load an immediate
byte containing the value 01h, and then do an <TT>XORB</TT>.
<P>
<H3>6.2.10 Rule ExpExpression</TT> </H3><!----------------------------------------------------------------------------->
<MENU><IMG src="Chapter 6 Assignment and Expressions.files/RULE25.gif">
<P><FONT face=arial size=-1><B>Figure {RULE25}.</B></FONT> </P></MENU><I>As of
the time of this writing, there is no facility within the SAL VM for doing
exponentiation This feature will be added at a later date. Do not worry about
the implementation of this rule. However, do make sure that proper semantic
checking is performed.</I>
<P><!----------------------------------------------------------------------------->
<H2>6.3 Rule Factor</H2><!----------------------------------------------------------------------------->A
factor is the tiniest element of an expression. It is a single discrete item
without operators (excluding those of a contained expression) that still yields
a result. For the most part, <TT>RuleFactor()</TT>'s prototype looks like that
of <TT>RuleIdentExpression()</TT>. <PRE> void Factor ( Set Follow, Type &RType )
</PRE>The <TT>RType</TT> parameter is used to resolve constants, and is set to
the return type of the factor. If <TT>RType</TT>'s value is not set by
<TT>RuleFactor()</TT> then it is set in <TT>RuleIdentExpr()</TT>. Looking at the
grammar rule for Factor, we see that it calls two rules, either Expression or
IdentExpr.
<MENU><IMG src="Chapter 6 Assignment and Expressions.files/RULE24.gif">
<P></P></MENU>In addition, Factor also accepts a character, a string, an integer
or a real. All four of these are <I>literal</I> constants. This rule has to face
the same issues of resolving a constant't type as rule IdentExpr. The difference
is that rule IdentExpr works with symbolic constants, and rule Factor works with
literal ones. In all other respects however, the job of dealing with constants
is identical between both rules.
<P>
<H3>6.3.1 Emitting code for a literal constants</H3><!----------------------------------------------------------------------------->The
techniques used for loading a literal constant onto the EES in rule Factor are
the same ones used for loading a symbolic constant onto the EES in rule
IdentExpr. When we come to working with symbolic constants in rule IdentExpr, we
will refer back this section.
<P>When it comes to generating code, a constant is treated as raw binary data.
The only formatting used is the number of bytes used to represent the value. The
only exception to this approach is in the case of strings. For strings we use a
pointer. There four are instructions to load an immediate value onto the EES:
<TT>LIB</TT>, <TT>LIW</TT>, <TT>LID</TT>, and <TT>LIQ</TT>. Each of these
corresponds to one, two, four, and eight bytes. We will use the instruction that
corresponds with the constant's type (See section 6.5.1.1).
<P>
<MENU>
<TABLE cellSpacing=1 cellPadding=3 border=3>
<TBODY>
<TR align=middle>
<TD><B>Type</B></TD>
<TD><B>Size in bytes</B></TD>
<TD><B>Instruction</B></TD>
<TR>
<TR>
<TD><TT> char</TT></TD>
<TD align=middle>1</TD>
<TD><TT> LIB</TT></TD>
<TR>
<TR>
<TD><TT> bool</TT></TD>
<TD align=middle>1</TD>
<TD><TT> LIB</TT></TD>
<TR>
<TR>
<TD><TT> int</TT></TD>
<TD align=middle>4</TD>
<TD><TT> LID</TT></TD>
<TR>
<TR>
<TD><TT> int8</TT></TD>
<TD align=middle>1</TD>
<TD><TT> LIB</TT></TD>
<TR>
<TR>
<TD><TT> int16</TT></TD>
<TD align=middle>2</TD>
<TD><TT> LIW</TT></TD>
<TR>
<TR>
<TD><TT> int32</TT></TD>
<TD align=middle>4</TD>
<TD><TT> LID</TT></TD>
<TR>
<TR>
<TD><TT> int64</TT></TD>
<TD align=middle>8</TD>
<TD><TT> LIQ</TT></TD>
<TR>
<TR>
<TD><TT> card</TT></TD>
<TD align=middle>4</TD>
<TD><TT> LID</TT></TD>
<TR>
<TR>
<TD><TT> card8</TT></TD>
<TD align=middle>1</TD>
<TD><TT> LIB</TT></TD>
<TR>
<TR>
<TD><TT> card16</TT></TD>
<TD align=middle>2</TD>
<TD><TT> LIW</TT></TD>
<TR>
<TR>
<TD><TT> card32</TT></TD>
<TD align=middle>4</TD>
<TD><TT> LID</TT></TD>
<TR>
<TR>
<TD><TT> card64</TT></TD>
<TD align=middle>8</TD>
<TD><TT> LIQ</TT></TD>
<TR>
<TR>
<TD><TT> real</TT></TD>
<TD align=middle>8</TD>
<TD><TT> LIQ</TT></TD>
<TR>
<TR>
<TD><TT> real32</TT></TD>
<TD align=middle>4</TD>
<TD><TT> LID</TT></TD>
<TR>
<TR>
<TD><TT> real64</TT></TD>
<TD align=middle>8</TD>
<TD><TT> LIQ</TT></TD>
<TR></TR></TBODY></TABLE></MENU>Notice that both <TT>bool</TT>s and
<TT>char</TT>s are a single byte. Again, <TT>true</TT> is one, and
<TT>false</TT> is zero. Immediate characters are loaded by ASCII value, 0
through 255. Signed integers are in two's compliment binary form, and unsigned
integers are in their standard binary form.
<P>Some languages actually load real numbers from a constant pool. Since the SAL
VM allows us to load immediate constants up to a qword in size, a constant pool
is unnecessary. Real constants are loaded in their binary form. This has the
disadvantage of being illegible at runtime. Here are some examples of loading
constants onto the EES:
<MENU>
<TABLE cellSpacing=1 cellPadding=3 border=3>
<TBODY>
<TR align=middle>
<TD><B>Constant Value</B></TD>
<TD><B>Final Resolved Type</B></TD>
<TD><B>Instruction</B></TD></TR>
<TR>
<TD> <TT>true</TT></TD>
<TD><TT> bool</TT></TD>
<TD><TT> LIB 01</TT></TD></TR>
<TR>
<TD> <TT>'A'</TT></TD>
<TD><TT> char</TT></TD>
<TD><TT> LIB 41</TT></TD></TR>
<TR>
<TD> <TT>-123</TT></TD>
<TD><TT> int32</TT></TD>
<TD><TT> LID FFFFFF85</TT></TD></TR>
<TR>
<TD> <TT>64000</TT></TD>
<TD><TT> card16</TT></TD>
<TD><TT> LID FA000</TT></TD></TR>
<TR>
<TD> <TT>3.1415926535897932384626433832795</TT></TD>
<TD><TT> real64</TT></TD>
<TD><TT> LIQ 400921FB54442D18</TT></TD></TR></TBODY></TABLE></MENU>
<P>
<H4>6.3.1.1 Emitting a Boolean Constant</H4>Rule Factor will not handle boolean
constants. The reason is that <TT>true</TT> and <TT>false</TT> are considered
identifiers by the scanner. Rule Factor does not handle identifiers; that is
what rule IdentExpr does. However, loading a boolean is always a byte that is
zero (00h) for false and one (01h) for true.
<P><PRE> LIB 00 ; Loading a literal false
LIB 01 ; Loading a literas true
</PRE>Once the constant is emitted, set the RType as follows: <PRE> RType.Init ( booltyp, _u8s, NULL );
</PRE>
<H4>6.3.1.2 Emitting a Character Constant</H4>This will be done if the current
token is a character (<TT>charconsy</TT>). The value will be in
<TT>Token.data.ch</TT>. Emitting a character constant is very straightforward.
Characters at the VM level are just unsigned bytes as an ASCII value. Use the
<TT>LIB</TT> instruction for characters, too, just like for booleans. For
instance, the letter 'A' will be loaded onto the EES by the instruction: <PRE> LIB 41 ; The letter A
</PRE>Once the character has been emitted, set RType as follows: <PRE> RType.Init ( chartyp, _u8s, NULL );
</PRE>
<H4>6.3.1.3 Emitting an Integer or Cardinal (semi-optional) Constant</H4><B>You
only have to worry about emitting 32-bit integers. All other sizes and types
(cardinals) are optional.</B> This is a tricky operation, esecially considering
that the integer and cardinal domains overlap. Consider the following example. <PRE> program IntCardConst;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -