calc.atg 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. COMPILER Calc
  2. (* Incomplete four function calculator - CalcManager is "left as an exercise" *)
  3. FROM CalcManager IMPORT NewVar, GetVar, SetVar, ReadVal, WriteVal;
  4. TYPE
  5. String = ARRAY [0 .. 100] OF CHAR;
  6. PROCEDURE GetNumber (VAR Int : INTEGER);
  7. (* Convert latest token to integer value Int *)
  8. VAR
  9. I : CARDINAL;
  10. String : ARRAY [0 .. 20] OF CHAR;
  11. BEGIN
  12. CalcS.GetString(CalcS.pos, CalcS.len, String);
  13. I := 0; Int := 0;
  14. WHILE String[I] # 0C DO
  15. Int := 10 * Int + VAL(INTEGER, ORD(String[I]) - ORD('0')); INC(I)
  16. END;
  17. END GetNumber;
  18. PROCEDURE GetSpix (VAR spix : INTEGER);
  19. (* Compute hash total for latest spelling *)
  20. VAR
  21. IdentName : ARRAY [0 .. 20] OF CHAR;
  22. BEGIN
  23. CalcS.GetName(CalcS.pos, CalcS.len, IdentName);
  24. spix := 17 * ORD(IdentName[0]) + ORD(IdentName[1])
  25. END GetSpix;
  26. IGNORE CASE
  27. CHARACTERS
  28. letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
  29. digit = "0123456789".
  30. eol = CHR(13) .
  31. COMMENTS
  32. FROM '--' TO eol
  33. TOKENS
  34. ident = letter {letter | digit} .
  35. number = digit {digit} .
  36. PRODUCTIONS
  37. Calc =
  38. [Declarations] StatSeq .
  39. Declarations (. VAR spix: INTEGER; .)
  40. = "VAR"
  41. Ident <spix> (. NewVar(spix) .)
  42. { ',' Ident <spix> (. NewVar(spix) .)
  43. } ';'.
  44. StatSeq =
  45. Stat {';' Stat}.
  46. Stat (. VAR spix, val: INTEGER; .)
  47. = "READ" Ident <spix> (. ReadVal(spix) .)
  48. | "WRITE" Expr <val> (. WriteVal(val) .)
  49. | Ident <spix> ":=" Expr <val> (. SetVar(spix, val) .) .
  50. Expr <VAR exprVal: INTEGER> (. VAR termVal: INTEGER; .)
  51. = Term <exprVal>
  52. { '+' Term <termVal> (. exprVal := exprVal + termVal .)
  53. | '-' Term <termVal> (. exprVal := exprVal - termVal .)
  54. } .
  55. Term <VAR termVal: INTEGER> (. VAR factVal: INTEGER; .)
  56. = Fact <termVal>
  57. { '*' Fact <factVal> (. termVal := termVal * factVal .)
  58. | '/' Fact <factVal> (. termVal := termVal DIV factVal .)
  59. } .
  60. Fact <VAR factVal: INTEGER> (. VAR spix: INTEGER; .)
  61. = Ident <spix> (. factVal := GetVar(spix) .)
  62. | number (. GetNumber(factVal) .)
  63. | '(' Expr <factVal> ')' .
  64. Ident <VAR spix : INTEGER>
  65. = ident (. GetSpix(spix) .) .
  66. END Calc.