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

📄 pll2.pas

📁 一个嵌入式系统的C代码
💻 PAS
📖 第 1 页 / 共 4 页
字号:
              DispError(BAD_IDENT);
            GetNextToken(Tok1);
            EvalExpr;
          END;
        SEM_CLOSE, SEM_OPEN, SEM_WAIT,
        SEM_SIGNAL,SHR_CLOSE, SHR_OPEN, SHR_SIZE:
          BEGIN
          END
      ELSE
          DispError(BAD_IDENT)
      END
    END;
    Assm(CSP, LitFlag, INTEGER(arg1));
    IF Tok1.ID <> RC_RRB THEN
      DispError(NO_RRB);
    GetNextToken(Tok1)
  END
END;

{-----------
{ Process STATEMENT
}
PROCEDURE EvalStmt;
BEGIN
  CASE Tok1.ID OF
    RC_IDENT:   ProcAssmnt;
    RC_IF:      StmtIf;
    RC_FOR:     StmtFor;
    RC_WHILE:   StmtWhile;
    RC_CASE:    StmtCase;
    RC_REPEAT:  StmtRepeat;
    RC_BEGIN:   StmtCompound;
    RC_READ:    StmtRead;
    RC_WRITE:   StmtWrite(Tok1.ID);
    RC_WRITELN: StmtWrite(Tok1.ID);
  ELSE
    BEGIN
      DispError(BAD_SYM);
      GetNextToken(Tok1)
    END
  END
END;

{-----------
{ Process a Function/procedure block (main, even)..
{ Statement before END may (but should not) have a semi-colon.
}
PROCEDURE Statements (nRT : INTEGER);
BEGIN
  Assm(INT, 0, nRT);
  REPEAT
    GetNextToken(Tok1);
    IF Tok1.ID <> RC_END THEN
      EvalStmt;
  UNTIL Tok1.ID <> RC_SEMI;
  IF Tok1.ID <> RC_END THEN
    DispError(NO_END);
  GetNextToken(Tok1);
  Assm(OPR, 0, INTEGER(_RET))
END;

{-----------------
{ Process parameters for procedure or function..
}
PROCEDURE ProcParam (VAR k : INTEGER; STref : INTEGER);
VAR
  dummy : INTEGER;
BEGIN
  ProcVarDecl(Tok1, 0);
  k := k + 1;
  IF (Tok1.ID <> RC_COLON) AND (Tok1.ID <> RC_SEP) THEN
    DispError(NO_COLON)
  ELSE
    IF Tok1.ID = RC_COLON THEN BEGIN
      ProcVarType(STref, dummy);
      STref := symTop;
      GetNextToken(Tok1);
      IF (Tok1.ID <> RC_SEMI) AND (Tok1.ID <> RC_RRB) THEN
        DispError(NO_RRB);
    END;
  GetNextToken(Tok1)
END;

{-----------
{ Create preamble for a procedure..
{ Proc name is entered in symbol table, followed by any parameters, constants
{ and variables (at one level higher).  The offset of the parameters (if any)
{ are then adjusted to be relative to the run-time Stack Pointer, since they
{ will be passed on the stack.  Recursive calls allow imbedded procedures.
{ Finally, the procedure body statements are processed and the symbol table
{ top reset so that we "forget" everything except the procedure's name.
}
PROCEDURE ProcBlock;
VAR
  idx, params : INTEGER;
  nRT, ref1, ref2 : INTEGER;
BEGIN
  GetNextToken(Tok1);
  IF Tok1.ID <> RC_IDENT THEN
    DispError(NO_IDENT)
  ELSE BEGIN
    CreateSymbol(Tok1.sTokLit, TP_PROCEDURE, 0);
    nRT := 3;
    params := 0;
    Assm(JMP, 0, 0);
    LiFoPush(PcdPtr);
    BlkLev := BlkLev + 1;
    ref1 := symTop;
    GetNextToken(Tok1);
    IF Tok1.ID = RC_LRB THEN BEGIN
      GetNextToken(Tok1);
      ref2 := symTop;
      WHILE Tok1.ID = RC_IDENT DO
        ProcParam(params, ref2);
    END;
    IF Tok1.ID <> RC_SEMI THEN
      DispError(NO_SEMI);
    FOR idx := 1 TO params+1 DO BEGIN
      IF idx >= params THEN
        symTable[symTop-idx+1].Aux := params;
      IF idx <= params THEN
        symTable[symTop-idx+1].Ofs := -idx
    END;
    GetNextToken(Tok1);
    WHILE Tok1.ID <> RC_BEGIN DO
      CodeBlock(nRT);
    FixFwdRef(LiFoPop);
    symTable[ref1].Ofs := PcdPtr;
    Statements(nRT);
    BlkLev := BlkLev - 1;
    symTop := ref1;
    IF Tok1.ID <> RC_SEMI THEN
      DispError(NO_SEMI);
    GetNextToken(Tok1)
  END
END;

{-----------
{ Create preamble for a function..
{ Processing is very similar to a procedure (they could be merged at the
{ expense of some readabiliy) except that a function always has at least
{ one "parameter" which is the return value.  This is created as a symbol
{ table entry with the same name as the function, but a type of TP_RETURN.
{ Like the procedure, all symbols except the function's name are disgarded
{ on exit.
{
{ NOTE: At this release, function type can only be an INTEGER.
}
PROCEDURE FuncBlock;
VAR
  idx, params : INTEGER;
  ref1, ref2, nRT : INTEGER;
BEGIN
  GetNextToken(Tok1);
  IF Tok1.ID <> RC_IDENT THEN
    DispError(NO_IDENT)
  ELSE BEGIN
    CreateSymbol(Tok1.sTokLit, TP_FUNCTION, 0);
    nRT := 3;
    params := 1;
    Assm(JMP, 0, 0);
    LiFoPush(PcdPtr);
    BlkLev := BlkLev + 1;
    ref1 := symTop;
    CreateSymbol(Tok1.sTokLit, TP_RETURN, 0);
    GetNextToken(Tok1);
    IF Tok1.ID = RC_LRB THEN BEGIN
      GetNextToken(Tok1);
      ref2 := symTop;
      WHILE Tok1.ID = RC_IDENT DO
        ProcParam(params, ref2);
    END;
    IF Tok1.ID <> RC_COLON THEN
      DispError(NO_COLON);
    CkNextToken(RC_INTEGER, BAD_TYPE);
    CkNextToken(RC_SEMI, NO_SEMI);
    FOR idx := 1 TO params+1 DO BEGIN
      IF idx >= params THEN
        symTable[symTop-idx+1].Aux := params - 1;
      IF idx <= params THEN
        symTable[symTop-idx+1].Ofs := -idx
    END;
    GetNextToken(Tok1);
    WHILE Tok1.ID <> RC_BEGIN DO
      CodeBlock(nRT);
    FixFwdRef(LiFoPop);
    symTable[ref1].Ofs := PcdPtr;
    Statements(nRT);
    BlkLev := BlkLev - 1;
    symTop := ref1;
    IF Tok1.ID <> RC_SEMI THEN
      DispError(NO_SEMI);
    GetNextToken(Tok1)
  END
END;

{---------------
{ Scan source, extracting CONST definitions..
}
PROCEDURE ConstBlock;
BEGIN
  GetNextToken(Tok1);
  WHILE Tok1.ID = RC_IDENT DO BEGIN
    CreateConstant(Tok1);
    CkNextToken(RC_SEMI, NO_SEMI);
    GetNextToken(Tok1)
  END
END;

{---------------
{ Scan source vor fairables..
}
Procedure VarBlock (VAR nx : INTEGER);
VAR
  STref : INTEGER;
BEGIN
  STref := symTop;
  GetNextToken(Tok1);
  WHILE Tok1.ID = RC_IDENT DO BEGIN
    ProcVarDecl(Tok1, nx);
    IF NOT (Tok1.ID IN [RC_COLON, RC_SEP]) THEN
      DispError(NO_COLON)
    ELSE
      IF Tok1.ID = RC_COLON THEN BEGIN
        ProcVarType(STref, nx);
        CkNextToken(RC_SEMI, NO_SEMI);
        STref := symTop;
      END;
    GetNextToken(Tok1)
  END
END;

{---------------
{ Process a program block (except main)..
}
PROCEDURE CodeBlock (VAR nRT : INTEGER);
BEGIN
  CASE Tok1.ID OF
    RC_CONST: ConstBlock;
    RC_VAR:   VarBlock(nRT);
    RC_PROC:  ProcBlock;
    RC_FUNC:  FuncBlock;
  ELSE
    DispError(NO_BEGIN)
  END
END;

{------------
{ Process an entry from the Program File list..
}
PROCEDURE ProcFileVar;
BEGIN
  CreateSymbol(Tok1.sTokLit, TP_FILE, 0);
  IF (Tok1.sTokLit = 'INPUT') OR (Tok1.sTokLit = 'OUTPUT') THEN
    symTable[symTop].Aux := 0;
  GetNextToken(Tok1)
END;

{------------------------
{ Process PASCAL program block - Each Block (procedures, functions and main)
{ must "remember" their own runtime variable requirements.  This is done by
{ recursive calls to the procedures that process the Function and Program
{ blocks and by this procedure for "main".  Now read on..
}
PROCEDURE ProgBlock;
VAR
  bLoop : BOOLEAN;
  nrtx  : INTEGER;  {Run-time variable dynamic storage required for main }
BEGIN
  CkNextToken(RC_IDENT, NO_IDENT);
  stProgName := Tok1.sTokLit;
  GetNextToken(Tok1);
  IF Tok1.ID = RC_LRB THEN BEGIN
    GetNextToken(Tok1);
    WHILE Tok1.ID = RC_IDENT DO BEGIN
      ProcFileVar;
      IF Tok1.ID = RC_SEP THEN
        GetNextToken(Tok1)
    END;
    IF Tok1.ID <> RC_RRB THEN
      DispError(NO_RRB);
    GetNextToken(Tok1);
  END;
  IF Tok1.ID <> RC_SEMI THEN
    DispError(NO_SEMI);
  GetNExtToken(Tok1);
  Assm(JMP, 0, 0);
  nrtx := 3;
  bLoop := TRUE;
  WHILE bLoop DO BEGIN
    CASE Tok1.ID OF
      RC_BEGIN:
        BEGIN
          bLoop := FALSE;
          FixFwdRef(1);
          Statements(nrtx);
          IF Tok1.ID <> RC_STOP THEN
            DispError(NO_STOP)
        END;
      RC_CONST, RC_VAR, RC_FUNC, RC_PROC:
        BEGIN
          CodeBlock(nrtx);
        END
      ELSE
        BEGIN
          bLoop := FALSE;
          DispError(NO_BEGIN)
        END
    END;
    IF ErrCnt > MAXERRORS THEN BEGIN
      bLoop := FALSE;
      WriteLn('Too many errors')
    END
  END
END;

{--------------
{ Giant Initialize for compile (with apologies to Di Page-Jones)..
}
PROCEDURE GreatBigInit;
BEGIN
  idxBuf := 0;          { source line index     }
  PcdPtr := 0;          { Pcode address index   }
  symTop := 0;          { Symbol Table index    }
  BlkLev := 0;          { Level Counter         }
  idxStk := 0;          { Internal Stack index  }
  LnNo   := 0;          { current source line   }
  ErrCnt := 0;          { cumulative errors     }
  Lastch := ' ';        { last char read von IP }
  SrcLnLen := -1;       { source line length    }
END;

{-------------------
{ Form input and output file names from the passed string.
{ Assumes that input filename has extension ".PAS" (not verified)..
}
PROCEDURE SetNames (st : STRING);
VAR
  i : INTEGER;
BEGIN
  stIn := st;
  stOut := '';
  i := 1;
  WHILE (i <= Length(st)) AND (st[i] <> '.') DO BEGIN
    stOut := stOut + st[i];
    i := i + 1;
  END;
  stOut := stOut + '.PCD';
END;

{------------------------
{ Try to open a source file of the passed name.
{ Note: NO extension is assumed! It must be correctly supplied.
{ RETURNS: TRUE  .. open ok
{          FALSE .. failed for some reason
}
FUNCTION OpenTarget (Name : STRING; Mode : INTEGER) : BOOLEAN;
BEGIN
  {$I-}
    IF (Mode = READ_FILE) THEN BEGIN
      ASSIGN(Ipf, Name);
      RESET(Ipf)
    END ELSE BEGIN
      ASSIGN(Opf, Name);
      REWRITE(Opf)
    END;
  {$I+}
  OpenTarget := (IOresult = 0)
END;

{----------
{ Good run - write pcode file
}
PROCEDURE WritePcode;
VAR
  i : INTEGER;
BEGIN
  IF NOT OpenTarget(stOut, WRITE_FILE) THEN
    DispError(NO_TARGET)
  ELSE BEGIN
    FOR i := 1 TO PcdPtr DO
      WRITE(Opf, PcdBuff[i]);
    CLOSE(Opf)
  END
END;



{************************************
{
{ Main entry (naturally..)
{
{************************************
}
BEGIN
  WriteLn;
  WriteLn('------------------------------------');
  WriteLn('P-Code PASCAL Compiler  Version ', VERS:2:2);
  WriteLn('for OS Simulator.  Ron Chernich 1992');
  WriteLn('------------------------------------');
  WriteLn;
  IF (ParamCount > 0) THEN BEGIN
    SetNames(ParamStr(1));
    IF NOT OpenTarget(stIn, READ_FILE) THEN
      DispError(NO_SOURCE)
    ELSE BEGIN
      GreatBigInit;
      GetNextToken(Tok1);
      IF Tok1.ID <> RC_PROG THEN
        DispError(NO_PROG)
      ELSE
        ProgBlock;
      IF ErrCnt > 0 THEN
        WriteLn('** ', ErrCnt:2, ' Error(s) encountered **')
      ELSE BEGIN
        WRITE(stIn, ' - ');
        DispError(CLEAN_COMPILE);
        WritePcode
      END;
      Close(Ipf)
    END
  END
END.


{----------------------------------- EOF ----------------------------------}

⌨️ 快捷键说明

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