ð#Syntax10.Scn.Fnt” ” MODULE Calendar; IMPORT In, Out; TYPE Month = RECORD days: ARRAY 6, 7 OF INTEGER; (* two dimensional representation of month *) END; VAR dayName: ARRAY 12, 3 OF CHAR; monthName: ARRAY 12, 4 OF CHAR; monthLen: ARRAY 12 OF INTEGER; buffer: ARRAY 4 OF Month; PROCEDURE FirstJanuary (year: INTEGER) : INTEGER; (* calculate weekday of 1. Jan. of a given year *) VAR weekday: INTEGER; BEGIN year := year - 1995; weekday := 6; INC (weekday, year); INC (weekday, (year + 2) DIV 4); (* consider leap years *) RETURN weekday MOD 7 END FirstJanuary; PROCEDURE CalcMonthLength (year: INTEGER); (* calculate length of months of a given year *) BEGIN IF (year MOD 400 = 0) OR ((year MOD 4 = 0) & (year MOD 100 # 0)) THEN monthLen[1] := 29 ELSE monthLen[1] := 28 END END CalcMonthLength; PROCEDURE FillBuffer (startMonth: INTEGER; VAR startday: INTEGER); VAR x, y, i, j: INTEGER; BEGIN FOR i := startMonth TO startMonth + 3 DO (* four months across *) FOR x := 0 TO 5 DO (* init buffer *) FOR y := 0 TO 6 DO buffer[i - startMonth].days[x, y] := 0 END END; FOR j := 0 TO monthLen[i] - 1 DO x := (startday + j) DIV 7; y := (startday + j) MOD 7; (* calc (x, y) position of day in buffer *) buffer[i - startMonth].days[x, y] := j + 1 END; startday := (startday + monthLen[i]) MOD 7 (* weekday of 1. of next month *) END END FillBuffer; PROCEDURE ShowDay (val: INTEGER); BEGIN IF val = 0 THEN Out.String (" ") ELSIF val < 10 THEN Out.F (" #", val) (* align one digit numbers *) ELSE Out.F (" #", val) END END ShowDay; PROCEDURE WriteBuffer (startMonth: INTEGER); VAR i, j: INTEGER; BEGIN FOR i := 0 TO 3 DO Out.String (" "); Out.String (monthName[startMonth + i]) END; Out.Ln; FOR i:=0 TO 6 DO (* write buffer by lines *) Out.String (dayName[i]); Out.String (" "); FOR j := 0 TO 23 DO ShowDay (buffer[j DIV 6].days[j MOD 6, i]) END; Out.Ln END END WriteBuffer; PROCEDURE Show*; VAR year, weekday, i: INTEGER; BEGIN In.Open; In.Int (year); weekday := FirstJanuary (year); CalcMonthLength (year); Out.F (" #$$", year); FOR i := 0 TO 2 DO FillBuffer (4 * i, weekday); WriteBuffer (4 * i); Out.Ln END END Show; BEGIN Out.Open; monthName[0] := "Jan"; monthName[1] := "Feb"; monthName[2] := "Mar"; monthName[3] := "Apr"; monthName[4] := "May"; monthName[5] := "Jun"; monthName[6] := "Jul"; monthName[7] := "Aug"; monthName[8] := "Sep"; monthName[9] := "Okt"; monthName[10] := "Nov"; monthName[11] := "Dec"; monthLen[0] := 31; monthLen[2] := 31; monthLen[3] := 30; monthLen[4] := 31; monthLen[5] := 30; monthLen[6] := 31; monthLen[7] := 31; monthLen[8] := 30; monthLen[9] := 31; monthLen[10] := 30; monthLen[11] := 31; dayName[0] := "Mo"; dayName[1] := "Tu"; dayName[2] := "We"; dayName[3] := "Th"; dayName[4] := "Fr"; dayName[5] := "Sa"; dayName[6] := "So" END Calendar.Show 1995