compiler/src/test/vt100/vt100.Mod
2014-04-14 01:22:03 +04:00

342 lines
8.6 KiB
Modula-2

MODULE vt100;
IMPORT Console, Strings;
(* reference http://en.wikipedia.org/wiki/ANSI_escape_code
& http://misc.flogisoft.com/bash/tip_colors_and_formatting
*)
CONST
Escape* = 1BX;
SynchronousIdle* = 16X;
LeftCrotchet* = '[';
(* formatting *)
Bold* = "1m";
Dim* = "2m";
Underlined* = "4m";
Blink* = "5m"; (* does not work with most emulators, works in tty and xterm *)
Reverse* = "7m"; (* invert the foreground and background colors *)
Hidden* = "8m"; (* useful for passwords *)
(* reset *)
ResetAll* = "0m";
ResetBold* = "21m";
ResetDim* = "22m";
ResetUnderlined* = "24m";
ResetBlink* = "25m";
ResetReverse* = "27m";
ResetHidden* = "28m";
(* foreground colors *)
Black* = "30m";
Red* = "31m";
Green* = "32m";
Yellow* = "33m";
Blue* = "34m";
Magenta* = "35m";
Cyan* = "36m";
LightGray* = "37m";
Default* = "39m";
DarkGray* = "90m";
LightRed* = "91m";
LightGreen* = "92m";
LightYellow* = "93m";
LightBlue* = "94m";
LightMagenta* = "95m";
LightCyan* = "96m";
White* = "97m";
(* background colors *)
BBlack* = "40m";
BRed* = "41m";
BGreen* = "42m";
BYellow* = "43m";
BBlue* = "44m";
BMagenta* = "45m";
BCyan* = "46m";
BLightGray* = "47m";
BDefault* = "49m";
BDarkGray* = "100m";
BLightRed* = "101m";
BLightGreen* = "102m";
BLightYellow* = "103m";
BLightBlue* = "104m";
BLightMagenta*= "105m";
BLightCyan* = "106m";
BWhite* = "107m";
VAR
CSI* : ARRAY 5 OF CHAR;
tmpstr : ARRAY 32 OF CHAR;
(* IntToStr routine taken from
https://github.com/romiras/Oberon-F-components/blob/master/Ott/Mod/IntStr.cp
and modified to work on 64bit system,
in order to avoid using oocIntStr, which has many dependencies *)
PROCEDURE Reverse0 (VAR str : ARRAY OF CHAR; start, end : INTEGER);
(* Reverses order of characters in the interval [start..end]. *)
VAR
h : CHAR;
BEGIN
WHILE start < end DO
h := str[start]; str[start] := str[end]; str[end] := h;
INC(start); DEC(end)
END
END Reverse0;
PROCEDURE IntToStr*(int: LONGINT; VAR str: ARRAY OF CHAR);
(* Converts the value of `int' to string form and copies the possibly truncated
result to `str'. *)
VAR
b : ARRAY 21 OF CHAR;
s, e: INTEGER;
maxLength : SHORTINT; (* maximum number of digits representing a LONGINT value *)
BEGIN
IF SIZE(LONGINT) = 4 THEN maxLength := 11 END;
IF SIZE(LONGINT) = 8 THEN maxLength := 20 END;
(* build representation in string 'b' *)
IF int = MIN(LONGINT) THEN (* smallest LONGINT, -int is an overflow *)
IF SIZE(LONGINT) = 4 THEN
b := "-2147483648";
e := 11
ELSE (* SIZE(LONGINT) = 8 *)
b := "-9223372036854775808";
e := 20
END
ELSE
IF int < 0 THEN (* negative sign *)
b[0] := "-"; int := -int; s := 1
ELSE (* no sign *)
s := 0
END;
e := s; (* 's' holds starting position of string *)
REPEAT
b[e] := CHR(int MOD 10+ORD("0"));
int := int DIV 10;
INC(e)
UNTIL int = 0;
b[e] := 0X;
Reverse0(b, s, e-1);
END;
COPY(b, str) (* truncate output if necessary *)
END IntToStr;
PROCEDURE EscSeq0 (letter : ARRAY OF CHAR);
VAR
cmd : ARRAY 9 OF CHAR;
BEGIN
COPY(CSI, cmd);
Strings.Append (letter, cmd);
Console.String (cmd);
END EscSeq0;
PROCEDURE EscSeq (n : INTEGER; letter : ARRAY OF CHAR);
VAR nstr : ARRAY 2 OF CHAR;
cmd : ARRAY 7 OF CHAR;
BEGIN
IntToStr (n, nstr);
COPY(CSI, cmd);
Strings.Append (nstr, cmd);
Strings.Append (letter, cmd);
Console.String (cmd);
END EscSeq;
PROCEDURE EscSeqSwapped (n : INTEGER; letter : ARRAY OF CHAR);
VAR nstr : ARRAY 2 OF CHAR;
cmd : ARRAY 7 OF CHAR;
BEGIN
IntToStr (n, nstr);
COPY(CSI, cmd);
Strings.Append (letter, cmd);
Strings.Append (nstr, cmd);
Console.String (cmd);
END EscSeqSwapped;
PROCEDURE EscSeq2(n, m : INTEGER; letter : ARRAY OF CHAR);
VAR nstr, mstr : ARRAY 5 OF CHAR;
cmd : ARRAY 12 OF CHAR;
BEGIN
IntToStr(n, nstr);
IntToStr(m, mstr);
COPY (CSI, cmd);
Strings.Append (nstr, cmd);
Strings.Append (';', cmd);
Strings.Append (mstr, cmd);
Strings.Append (letter, cmd);
Console.String (cmd);
END EscSeq2;
(* Cursor up
moves cursor n cells in the given direction. if the cursor is already at the edge of the screen, this has no effect *)
PROCEDURE CUU*(n : INTEGER);
BEGIN
EscSeq (n, 'A');
END CUU;
(* Cursor down
moves cursor n cells in the given direction. if the cursor is already at the edge of the screen, this has no effect *)
PROCEDURE CUD*(n : INTEGER);
BEGIN
EscSeq (n, 'B');
END CUD;
(* Cursor forward
moves cursor n cells in the given direction. if the cursor is already at the edge of the screen, this has no effect *)
PROCEDURE CUF*(n : INTEGER);
BEGIN
EscSeq (n, 'C');
END CUF;
(* Cursor back
moves cursor n cells in the given direction. if the cursor is already at the edge of the screen, this has no effect *)
PROCEDURE CUB*(n : INTEGER);
BEGIN
EscSeq (n, 'D');
END CUB;
(* Curnser Next Line
moves cursor to beginning of the line n lines down *)
PROCEDURE CNL*( n: INTEGER);
BEGIN
EscSeq (n, 'E');
END CNL;
(* Cursor Previous Line
Moves cursor to beginning of the line n lines down *)
PROCEDURE CPL*( n : INTEGER);
BEGIN
EscSeq (n, 'F');
END CPL;
(* Cursor Horizontal Absolute
Moves the cursor to column n *)
PROCEDURE CHA*( n : INTEGER);
BEGIN
EscSeq (n, 'G');
END CHA;
(* Cursor position, moves cursor to row n, column m *)
PROCEDURE CUP*(n, m : INTEGER);
BEGIN
EscSeq2 (n, m, 'H');
END CUP;
(* Erase Display
if n = 0 then clears from cursor to end of the screen
if n = 1 then clears from cursor to beginning of the screen
if n = 2 then clears entire screen *)
PROCEDURE ED* (n : INTEGER);
BEGIN
EscSeq(n, 'J');
END ED;
(* Erase in Line
Erases part of the line. If n is zero, clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change *)
PROCEDURE EL*( n : INTEGER);
BEGIN
EscSeq(n, 'K');
END EL;
(* Scroll Up
Scroll whole page up by n lines. New lines are added at the bottom *)
PROCEDURE SU*( n : INTEGER);
BEGIN
EscSeq(n, 'S')
END SU;
(* Scroll Down
Scroll whole page down by n (default 1) lines. New lines are added at the top *)
PROCEDURE SD*( n : INTEGER);
BEGIN
EscSeq(n, 'T');
END SD;
(* Horizontal and Vertical Position,
Moves the cursor to row n, column m. Both default to 1 if omitted. Same as CUP *)
PROCEDURE HVP*(n, m : INTEGER);
BEGIN
EscSeq2 (n, m, 'f');
END HVP;
(* Select Graphic Rendition
Sets SGR parameters, including text color. After CSI can be zero or more parameters separated with ;. With no parameters, CSI m is treated as CSI 0 m (reset / normal), which is typical of most of the ANSI escape sequences *)
PROCEDURE SGR*( n : INTEGER);
BEGIN
EscSeq(n, 'm');
END SGR;
PROCEDURE SGR2*( n, m : INTEGER);
BEGIN
EscSeq2(n, m, 'm');
END SGR2;
(* Device Status Report
Reports the cursor position (CPR) to the application as (as though typed at the keyboard) ESC[n;mR, where n is the row and m is the column.) *)
PROCEDURE DSR*(n : INTEGER);
BEGIN
EscSeq(6, 'n');
END DSR;
(* Save Cursor Position *)
PROCEDURE SCP*;
BEGIN
EscSeq0('s');
END SCP;
(* Restore Cursor Position *)
PROCEDURE RCP*;
BEGIN
EscSeq0('u');
END RCP;
(* Hide the cursor *)
PROCEDURE DECTCEMl*;
BEGIN
EscSeq0("?25l")
END DECTCEMl;
(* shows the cursor *)
PROCEDURE DECTCEMh*;
BEGIN
EscSeq0("?25h")
END DECTCEMh;
PROCEDURE SetAttr*(attr : ARRAY OF CHAR);
VAR tmpstr : ARRAY 16 OF CHAR;
BEGIN
COPY(CSI, tmpstr);
Strings.Append(attr, tmpstr);
Console.String(tmpstr);
END SetAttr;
BEGIN
(* init CSI sequence *)
COPY(Escape, CSI);
Strings.Append(LeftCrotchet, CSI);
(*
EraseDisplay;
GotoXY (0, 0);
COPY(CSI, tmpstr);
Strings.Append(Green, tmpstr);
Strings.Append("hello", tmpstr);
Console.String(tmpstr); Console.Ln;
*)
END vt100.