课程主页:

https://www.edx.org/course/compilers

课程视频:

https://www.bilibili.com/video/BV1NE411376V?p=20&t=6

这次回顾编译原理作业一,这次的作业使用cool语言编写一个stack machine。

作业一不是很难,主要时间是cool的语言特性学习上,注意cool本身不包含数组,需要参考list的写法实现类似数组的功能,完整代码如下:

(*
 *  CS164 Fall 94
 *
 *  Programming Assignment 1
 *    Implementation of a simple stack machine.
 *
 *  Skeleton file
 *)

class Main inherits IO {
   -- 对象需要初始化
   stack : Stack <- (new Stack);
   char : String;
   flag : Bool <- true;
   basicCommand : StackCommand <- (new StackCommand);
   dCommand : DCommand <- (new DCommand);
   plusCommand : PlusCommand <- (new PlusCommand);
   eCommand : ECommand <- (new ECommand);

   main() : Object {
      {
         while flag loop
            {
               out_string(">");
               char <- in_string();

               if char = "d" then
                  dCommand.operate(stack, char)
               else if char = "x" then
                  {
                     flag <- false;
                  }
               else if char = "e" then
                  {
                     stack <- eCommand.operate(stack, char);
                  }
               else
                  {
                     stack <- basicCommand.operate(stack, char);
                  }
               fi
               fi
               fi;
            }
         pool;
      }
   };
};

-- Stack

-- Empty Stack
class Stack {

   isEmpty() : Bool { true };

   top()  : String { { abort(); ""; } };

   tail()  : Stack { { abort(); self; } };

   push(s : String) : Stack {
      (new Cons).init(s, self)
   };
};

class Cons inherits Stack {

   car : String;	-- The element on the top of the stack

   cdr : Stack;	-- The rest of the stack

   isEmpty() : Bool { false };

   top()  : String { car };

   tail() : Stack { cdr };

   init(s : String, stack : Stack) : Stack {
      {
         car <- s;
         cdr <- stack;
         self;
      }
   };

};

-- StackCommand
class StackCommand {
   operate(stack : Stack, char : String) : Stack {
      stack.push(char)
   };
};

class ECommand inherits StackCommand {
   char : String;
   
   operate(stack : Stack, char : String) : Stack {
      {
         if stack.isEmpty() then
            {
               stack;
            }
         else if stack.top() = "+" then
            {
               stack <- stack.tail();
               (new PlusCommand).operate(stack, char);
            }
         else if stack.top() = "s" then
            {
               stack <- stack.tail();
               (new SCommand).operate(stack, char);
            }
         else
            {
               stack;
            }
         fi
         fi 
         fi;
      }
   };
};

class SCommand inherits StackCommand {
   d1 : String;
   d2 : String;

   operate(stack : Stack, char : String) : Stack {
      {
         d1 <- stack.top();
         stack <- stack.tail();
         d2 <- stack.top();
         stack <- stack.tail();
         -- swap
         stack <- stack.push(d1);
         stack <- stack.push(d2);
         stack;
      }
   };
};

class PlusCommand inherits StackCommand {
   d1 : Int;
   d2 : Int;
   d3 : Int;
   num : String;
   op : A2I <- new A2I;

   operate(stack : Stack, char : String) : Stack {
      {
         d1 <- op.a2i(stack.top());
         stack <- stack.tail();
         d2 <- op.a2i(stack.top());
         stack <- stack.tail();
         d3 <- d1 + d2;
         stack <- stack.push(op.i2a(d3));
         stack;
      }
   };
};

class DCommand {
   io : IO <- new IO;
   operate(stack : Stack, char : String) : Object {
      {
         if stack.isEmpty() 
            then io.out_string("")
            else
               {
                  io.out_string(stack.top());
                  io.out_string("\n");
                  operate(stack.tail(), char);
               }
         fi;
      }
   };
};

make测试:

make test

实验结果:

备注:注意当从文件输入时,>符号不会换行。

命令行测试:

spim stack.s

实验结果: