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

📄 tc.mod

📁 一个Modula-2语言分析器
💻 MOD
字号:
IMPLEMENTATION MODULE TC;

IMPORT STextIO, SWholeIO, TasteP;

CONST
  MemSize = 15000;

VAR
  code: ARRAY [0 .. MemSize] OF CHAR;
  GeneratingCode : BOOLEAN;

PROCEDURE Emit (op: INTEGER);
  BEGIN
    IF GeneratingCode THEN
      IF pc >= MemSize - 4
        THEN TasteP.SemError(125); GeneratingCode := FALSE
        ELSE code[pc] := CHR(op); INC(pc)
      END
    END
  END Emit;

PROCEDURE Emit2 (op, val: INTEGER);
  BEGIN
    IF GeneratingCode THEN
      Emit(op);
      code[pc] := CHR(val DIV 256); code[pc+1] := CHR(val MOD 256);
      INC(pc, 2)
    END
  END Emit2;

PROCEDURE Emit3 (op, level, val: INTEGER);
  BEGIN
    IF GeneratingCode THEN
      Emit(op); code[pc] := CHR(level);
      code[pc+1] := CHR(val DIV 256); code[pc+2] := CHR(val MOD 256);
      INC(pc, 3)
    END
  END Emit3;

PROCEDURE Fixup (adr: INTEGER);
  BEGIN
    IF GeneratingCode THEN
      code[adr] := CHR(pc DIV 256); code[adr+1] := CHR(pc MOD 256)
    END
  END Fixup;

PROCEDURE Interpret;
  VAR
    stack:     ARRAY [0 .. 1000] OF INTEGER;
    top:       INTEGER;
    base:      INTEGER;
    val,a,lev: INTEGER;

  PROCEDURE Next(): INTEGER;
    BEGIN
      INC(pc); RETURN ORD(code[pc-1])
    END Next;

  PROCEDURE Next2(): INTEGER;
    VAR
      x, y: CARDINAL;
    BEGIN
      x := ORD(code[pc]); y := ORD(code[pc+1]); INC(pc, 2); RETURN x*256 + y
    END Next2;

  PROCEDURE Push(val:INTEGER);
    BEGIN
      stack[top] := val; INC(top)
    END Push;

  PROCEDURE Pop(): INTEGER;
    BEGIN
      DEC(top); RETURN stack[top]
    END Pop;

  PROCEDURE Up (level: INTEGER): INTEGER;
    VAR
      b: INTEGER;
    BEGIN
      b := base; WHILE level > 0 DO b := stack[b]; DEC(level) END;
      RETURN b
    END Up;

  BEGIN
    STextIO.WriteString("Interpreting");
    STextIO.WriteLn;
    pc := progStart; base := 0; top := 3;
    LOOP
      CASE ORD(Next()) OF
        LOAD:  lev := Next(); a := Next2(); Push(stack[Up(lev) + a])
      | LIT:   Push(Next2())
      | STO:   lev := Next(); a := Next2(); stack[Up(lev) + a] := Pop()
      | ADD:   val := Pop(); Push(Pop() + val)
      | SUB:   val := Pop(); Push(Pop() - val)
      | DIVI:  val := Pop(); Push(Pop() DIV val)
      | MUL:   val := Pop(); Push(Pop() * val)
      | EQU:   val := Pop(); Push(ORD(Pop() = val))
      | LSS:   val := Pop(); Push(ORD(Pop() < val))
      | GTR:   val := Pop(); Push(ORD(Pop() > val))
      | CALL:  Push(Up(Next())); Push(base); Push(pc+2);
               pc := Next2(); base := top - 3
      | RET:   top := base; base := stack[top+1]; pc := stack[top+2]
      | RES:   INC(top, Next2())
      | JMP:   pc := Next2()
      | FJMP:  a := Next2(); IF Pop() = 0 THEN pc := a END
      | HALTc: EXIT
      | NEG:   Push(-Pop())
      | READ:  lev := Next(); a := Next2();
               STextIO.WriteString("? ");
               SWholeIO.ReadInt(val); STextIO.SkipLine;
               stack[Up(lev) + a] := val
      | WRITE: SWholeIO.WriteInt(Pop(), 6);
               STextIO.WriteLn
      ELSE HALT
      END
    END
  END Interpret;

BEGIN
  pc := 1; GeneratingCode := TRUE
END TC.

⌨️ 快捷键说明

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