⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter 7 code generation for control statements.htm

📁 英文版编译器设计:里面详细介绍啦C编译器的设计
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<P>
<MENU><B>Service 00: Console Output</B><BR>This set of services deals with 
  some very basic output to the stream, <I>stdout</I>.
  <P>
  <MENU><B>Function 00: Write String</B><BR>
    <MENU>This function writes a null-terminated string to the console. The 
      address to the string is a 32-bit pointer that is taken from the EES.
      <P><PRE>          EES
       --------
      | char*  |  &lt;-- 32-bit pointer to a string
      |--------|
      |  . .   |
</PRE></MENU><B>Function 01: Write Character</B><BR>
    <MENU>This function writes a single character to the console. The 
      character (8-bit) is taken from the EES.
      <P><PRE>          EES
       --------
      |  char  |  &lt;-- A byte
      |--------|
      |  . .   |
</PRE></MENU><B>Function 02: Write Integer</B><BR>
    <MENU>This function writes integers of various sizes to the console, and 
      formats them, as well. The first byte taken from the EES is one of the VM 
      type specifiers (i.e., _u8, _u16, ..., _f32, _f64). The next four bytes is 
      a pointer to a string that contains formatting data. This pointer may be 
      null. The final data to be taken from the EES is the integer, itself. It 
      may be either signed or unsigned, and can be any size from 8, 16, 32, to 
      64 bits.
      <P><PRE>          EES
       --------
      |   int  |  &lt;-- 1, 2, 4, or 8 bytes
      |--------|
      | Format |  &lt;-- 4 bytes
      |--------|
      |  Type  |  &lt;-- A byte
      |--------|
      |  . .   |
</PRE></MENU><B>Function 03: Write Real</B><BR>
    <MENU>This function writes floating point numbers of various types to the 
      console. The number is taken from the EES.
      <P><PRE>          EES
       --------
      |  real  |  &lt;-- 4 or 8 bytes
      |--------|
      |  . .   |
</PRE></MENU><B>Function 04: Write Boolean</B><BR>
    <MENU>This function writes a character representing a bool to the console. 
      The bool (8-bit) is taken from the EES. If it is a 1, a 'T' is written, if 
      it is 0 then a 'F' is written. Otherwise a '?' is written.
      <P><PRE>          EES
       --------
      |  bool  |  &lt;-- A byte
      |--------|
      |  . .   |
</PRE></MENU></MENU><B>Service 01: Keyboard Input</B><BR>This set of services 
  deals with some very basic input from the stream, <I>stdin</I>.
  <P>
  <MENU><B>Function 00: Read String</B><BR>
    <MENU>This function reads characters from the keyboard. It takes two 
      parameters from the EES. The first one is a word containing the maximum 
      number of characters in the buffer. The second parameter is an address to 
      the buffer. The function will read up to the maximum number minus one, or 
      until the user hits the enter key. The string will be null-terminated.
      <P><PRE>          EES
       --------
      |  char* |  &lt;-- 4 bytes
      |--------|
      | buffsz |  &lt;-- 2 bytes
      |--------|
      |  . .   |
</PRE></MENU><B>Function 01: Read Character</B><BR>
    <MENU>This function reads a single character from the keyboard and leaves 
      it on the EES.
      <P><PRE>          EES
         After
       --------
      |  char  |  &lt;-- 1 byte
      |--------|
      |  . .   |
</PRE></MENU><B>Function 02: Read Integer</B><BR>
    <MENU>This function reads text from the keyboard, interpretes it as an 
      integer, and stores the result (based on a specified size) onto the EES. 
      It takes a single-byte parameter, which is a type specifier--either a _sX 
      or a _uX. It outputs an integer of the sign and size specified onto the 
      EES after the user has hit return.
      <P><PRE>          EES                          EES                  
        Before                        After                 
       --------                     --------                
      |  Type  |  &lt;-- 1 byte       |  int   |  &lt;-- 1, 2, 4, or 8 bytes
      |--------|                   |--------|               
      |  . .   |                   |  . .   |               
</PRE></MENU><B>Function 03: Read Real</B><BR>
    <MENU>This function reads text from the keyboard, interpretes it as a real 
      number, and stores the result (based on a specified size) onto the EES. It 
      takes a single-byte parameter, which is a type specifier--an _f32 or an 
      _f64. It outputs a real number of the size specified onto the EES after 
      the user has hit return.
      <P><PRE>          EES                          EES                  
        Before                        After                 
       --------                     --------                
      |  Type  |  &lt;-- 1 byte       |  real  |  &lt;-- 4 or 8 bytes
      |--------|                   |--------|               
      |  . .   |                   |  . .   |               
</PRE></MENU></MENU><B>Service 04: Memory and String Manipulation</B><BR>This 
  set of services mirrors several of the functions in <TT>string.h</TT> and 
  <TT>memory.h</TT>. The only two real functions that are necessary for our 
  compiler are functions 00 and 80, string and memory copy, respectively.
  <P>
  <MENU><B>Function 00: memcpy()</B><BR>
    <MENU>This function does a <TT>memcpy()</TT>. parameter read from the EES 
      is a word containing the count of bytes to move. The second parameter read 
      is a 32-bit pointer to the destination. The last parameter is another 
      32-bit pointer to the source. This function is used for doing array/record 
      copys.
      <P><PRE>          EES                   
       --------                 
      | dest * |  &lt;-- 4 bytes
      |--------|                
      | src *  |  &lt;-- 4 bytes
      |--------|                
      |  size  |  &lt;-- 2 bytes
      |--------|                
      |  . .   |                
</PRE></MENU></MENU>
  <MENU><B>Function 80: strncpy()</B><BR>
    <MENU>The following is a quote from MSDN: 
      <BLOCKQUOTE><TT>char *strncpy( char *strDest, const char *strSource, 
        size_t count );</TT>
        <P>The strncpy function copies the initial count characters of strSource 
        to strDest and returns strDest. If count is less than or equal to the 
        length of strSource, a null character is not appended automatically to 
        the copied string. If count is greater than the length of strSource, the 
        destination string is padded with null characters up to length count. 
        The behavior of strncpy is undefined if the source and destination 
        strings overlap. </P></BLOCKQUOTE>This function calls <TT>strncpy()</TT>. 
      It is a lot safer than calling <TT>strcpy()</TT>, since <TT>strncpy()</TT> 
      is bounded, whereas <TT>strcpy()</TT> is not. This function is useful for 
      copying a string constant in SAL into an array, If the constant is longer 
      than the buffer, only the count of characters up to the length of the 
      buffer will be copied, protecting memory from corruption. <PRE>          EES                   
       --------                 
      | dest * |  &lt;-- 4 bytes
      |--------|                
      | src *  |  &lt;-- 4 bytes
      |--------|                
      |  size  |  &lt;-- 2 bytes
      |--------|                
      |  . .   |                
</PRE></MENU></MENU><B>Service 70: Network Input/Output</B><BR>This set of 
  services deals with network communication. It is basically a mirror of the 
  Berkley socket stream library. It will not be documented here since it is 
  beyond the scope of this chapter.
  <P>
  <H3>7.5.1 Implementing <TT>read</TT> and <TT>write</TT></H3>The read and write 
  statements are a way of making the language do a series of outputs and inputs 
  on different data types without having to put each item that is read/written 
  on a separate line. The code to generate a series of items to be written or 
  read is taken one item at a time. Each of these rules loop continuously until 
  they encounter a semicolon, and each item is processed separately.
  <P>
  <MENU><IMG 
    src="Chapter 7 Code Generation for Control Statements.files/RULE47.gif">
    <P><FONT face=arial size=-1><B>Figure {RULE47}.</B> Code generation for rule 
    ReadStatement.</FONT> &nbsp;
    <P>&nbsp;
    <P><IMG 
    src="Chapter 7 Code Generation for Control Statements.files/REAMEM.gif">
    <P>&nbsp;
    <P>&nbsp;
    <P></P></MENU>The code to emit the proper sys calls for each item to be read 
  is thus: <PRE>      if VType.type &gt;= chartyp &amp;&amp; VType.type &lt;= realtyp then
        select VType.type from
          case chartyp:           // chars
            Emit (SYS, 01, 01);
          case inttyp, cardtyp:   // ints
            Emit (LIB, vtype.subtype);
            Emit (SYS, 01, 02);
          case realtyp:           // reals
            Emit (LIB, vtype.subtype);
            Emit (SYS, 01, 03);
        end select;

        select VType.subtype from // Store the results
          case _s8, _u8:
            Emit (SSB, 0);
          case _s16, _u16:
            Emit (SSW, 0);
          case _s32, _u32, _f32:
            Emit (SSD, 0);
          case _s64s, _u64s, _f64s:
            Emit (xSSQ, 0);
        end select;
      elseif VType.type=arraytyp and VType.block-&gt;ToAtab()-&gt;eltyp()=chartyp then
        with VType.block-&gt;ToAtab()^ do
          Emit1 (LIW);            // Emit count of chars
          Emit2 (hi().i - lo().i + 1);
          Emit (SYS, 01, 00);   
        end with;
      else
        Error ("Can not read this type");
      end if;
</PRE>There is no way to directly read a boolean, since it makes more sense to 
  have the programmer tell the user to do something like "Do you wish to 
  continue [Y/n]?". Users hate having to type something esoteric like 'T'.
  <P>Character arrays are used in SAL to store strings. If we are going to store 
  the value of some text typed at the keyboard, then we have to be prepared for 
  the user to type literally anything. That is why the system call to read a 
  string takes an upper limit of characters.
  <P>
  <MENU><IMG 
    src="Chapter 7 Code Generation for Control Statements.files/RULE48.gif">
    <P><FONT face=arial size=-1><B>Figure {RULE48}.</B> Code generation for rule 
    WriteStatement.</FONT> &nbsp;
    <P>&nbsp;
    <P><IMG 
    src="Chapter 7 Code Generation for Control Statements.files/WRIMEM.gif">
    <P></P></MENU>The code to emit the proper sys calls for each item to be 
  written is thus: <PRE>      if RType.IsSimpleType()then
        select RType.type from
          case booltyp:                   // bool
            Emit (JPZ, 7);
            Emit (LIB, 'T');
            Emit (JMP, 2);
            Emit (LIB, 'F');
            Emit (SYS, 00, 01);
          case chartyp:                   // char
            Emit (SYS, 00, 01);
          case inttyp, cardtyp:           // int/card
            Emit (LID, 0);
            Emit (LIB, rtype.subtype);
            Emit (SYS, 00, 02);
          case realtyp:                   // real
            Emit (LIB, rtype.subtype);
            Emit (SYS, 00, 03);
        end select;
      else if RType.type = arraytyp then  s// String or array of char 
        if RType.block = null or RType.block-&gt;ToAtab()-&gt;eltyp() = chartyp then
          Emit (SYS, 00, 00);
        else
          Error (ER_INCOMPAT);
        end if;
      end if;
</PRE>Here is a simple program that does some reads and writes: <PRE>      program RWSample;

        var
          i: int;

      begin
        write "Enter a number: ";
        read i;
        write "\nThe number you entered was ", i, nl;
      end program.


      *** DISASSEMBLY *************************************

        ENTR  00000000
        LGA   00000004
        TS
        SJPZ  begin
        RTN

      begin:
        LSTA  00000000            <B>write "Enter a number: ";</B>
        SYS   00 00

        LGA   00000009            <B>read i;</B>
        LIB   _s32
        SYS   01 02
        SSD   00000000

                                  <B>write</B>
        LSTA  00000011              <B>"\nThe number you entered was ",</B>
        SYS   00 00 

        LGD   00000009              <B>i,</B>
        LID   00000000
        LIB   14
        SYS   00 02

        LIB   0A                    <B>nl</B>
        SYS   00 01

        RTN
</PRE></MENU></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -