// Имя {"(" Выраж | Тип ")"} | Число | "(" Выраж ")" static tType Factor() { Obj X; tType T = tType.None; if (Scan.Lex == tLex.lexName) { if ((X = Table.Find(Scan.Name)).Cat == tCat.Var) { Gen.Addr(X); //Адрес переменной Gen.Cmd(OVM.cmLoad); Scan.NextLex(); return(X.Type); } else if (X.Cat == tCat.Const) { Gen.Const(X.Val); Scan.NextLex(); return(X.Type); } else if (X.Cat == tCat.StProc && X.Type != tType.None) { Scan.NextLex(); Check(tLex.lexLPar, "\"(\""); T = StFunc(X.Val); Check(tLex.lexRPar, "\")\""); } else { Error.Expected( "переменная, константа или процедура-функции" ); } } else if (Scan.Lex == tLex.lexNum) { Gen.Const(Scan.Num); Scan.NextLex(); return(tType.Int); } else if (Scan.Lex == tLex.lexLPar) { Scan.NextLex(); T = Expression(); Check(tLex.lexRPar, "\")\""); } else { Error.Expected("имя, число или \"(\""); } return(T); }
static void StProc(int P) { switch (P) { case spDEC: Variable(); Gen.Cmd(OVM.cmDup); Gen.Cmd(OVM.cmLoad); if (Scan.Lex == tLex.lexComma) { Scan.NextLex(); IntExpression(); } else { Gen.Cmd(1); } Gen.Cmd(OVM.cmSub); Gen.Cmd(OVM.cmSave); return; case spINC: Variable(); Gen.Cmd(OVM.cmDup); Gen.Cmd(OVM.cmLoad); if (Scan.Lex == tLex.lexComma) { Scan.NextLex(); IntExpression(); } else { Gen.Cmd(1); } Gen.Cmd(OVM.cmAdd); Gen.Cmd(OVM.cmSave); return; case spInOpen: // Пусто ; return; case spInInt: Variable(); Gen.Cmd(OVM.cmIn); Gen.Cmd(OVM.cmSave); return; case spOutInt: IntExpression(); Check(tLex.lexComma, "\",\""); IntExpression(); Gen.Cmd(OVM.cmOut); return; case spOutLn: Gen.Cmd(OVM.cmOutLn); return; case spHALT: Gen.Const(ConstExpr()); Gen.Cmd(OVM.cmStop); return; } }