History variables: Difference between revisions

no edit summary
m (final touch)
No edit summary
Line 463:
 
Note that only nouns are supported here: If you want to store verbs using this mechanism you will need to use their gerunds.
 
=={{header|Oberon-2}}==
<lang oberon2>
MODULE HVar;
IMPORT Out, Conv;
TYPE
(* Generic Object *)
Object* = POINTER TO ObjectDesc;
ObjectDesc = RECORD
Show: PROCEDURE(o:Object);
AsString: PROCEDURE(o: Object; VAR str: ARRAY OF CHAR);
END;
(* Integers *)
Integer = POINTER TO IntegerDesc;
IntegerDesc = RECORD (ObjectDesc)
val: INTEGER;
END;
(* Chars *)
Char = POINTER TO CharDesc;
CharDesc = RECORD (ObjectDesc)
val: CHAR;
END;
Node = POINTER TO NodeDesc;
NodeDesc = RECORD
val: Object;
next: Node;
END;
(* History Variable *)
HVar* = POINTER TO HVarDesc;
HVarDesc = RECORD
first, last: Node;
size-: INTEGER;
END;
PROCEDURE CharAsString(o:Object; VAR dst: ARRAY OF CHAR);
BEGIN
IF LEN(dst) >= 2 THEN
dst[1] := 0X;
END;
dst[0] := o(Char)^.val
END CharAsString;
PROCEDURE IntAsString(o:Object; VAR dst: ARRAY OF CHAR);
BEGIN
Conv.ConvInt(o(Integer)^.val,dst);
END IntAsString;
PROCEDURE ShowInt(o:Object);
BEGIN
Out.Int(o(Integer)^.val,10);
END ShowInt;
PROCEDURE ShowChar(o:Object);
BEGIN
Out.Char(o(Char)^.val);
END ShowChar;
PROCEDURE BoxChar(val: CHAR): Char;
VAR
c: Char;
BEGIN
NEW(c);
c^.val := val;
c^.Show := ShowChar;
c^.AsString := CharAsString;
RETURN c;
END BoxChar;
PROCEDURE BoxInt(val:INTEGER): Integer;
VAR
i: Integer;
BEGIN
NEW(i);
i^.val := val;
i^.Show := ShowInt;
i^.AsString := IntAsString;
RETURN i;
END BoxInt;
PROCEDURE InitNode(): Node;
VAR
l: Node;
BEGIN
NEW(l);
l.val := NIL;
l.next := NIL;
RETURN l;
END InitNode;
PROCEDURE InitHVar(): HVar;
VAR
hv: HVar;
BEGIN
NEW(hv);
hv.first := NIL;
hv.last := NIL;
hv.size := 0;
RETURN hv;
END InitHVar;
PROCEDURE (v: HVar) Value(): Object;
BEGIN
RETURN v^.first^.val;
END Value;
PROCEDURE (v: HVar) Set(o: Object);
VAR
l: Node;
BEGIN
l := InitNode();
l^.val := o;
IF (v^.first = v^.last) & (v^.first = NIL) THEN
v^.first := l;
v^.last := l;
INC(v^.size);
ELSIF (v^.first = v^.last) & (v^.first # NIL) THEN
v^.first^.next := l;
v^.last := v^.first.next;
INC(v^.size);
ELSIF (v^.first # v^.last) THEN
v^.last^.next := l;
v^.last := l;
INC(v^.size);
END
END Set;
PROCEDURE (v: HVar) Undo(): Object;
VAR
o: Object;
BEGIN
IF (v^.first = v^.last) & (v^.first = NIL) THEN
o := NIL;
ELSIF (v^.first = v^.last) & (v^.first # NIL) THEN
o := v^.first^.val;
v^.first := NIL;
v^.last := NIL;
DEC(v^.size);
ELSE
o := v^.first^.val;
v^.first := v^.first^.next;
DEC(v^.size);
END;
RETURN o;
END Undo;
PROCEDURE (v: HVar) Print();
VAR
iter : Node;
BEGIN
iter := v.first;
WHILE(iter # NIL) DO
iter^.val^.Show(iter^.val);
iter := iter^.next;
END;
Out.Ln;
END Print;
PROCEDURE ShowVal(val: Object);
VAR
s: ARRAY 128 OF CHAR;
BEGIN
val^.AsString(val,s);
Out.String("> ");Out.String(s);Out.Ln;
END ShowVal;
VAR
history: HVar;
BEGIN
history := InitHVar();
history.Set(BoxChar(64X));
history.Set(BoxInt(10));
history.Set(BoxInt(15));
history.Set(BoxInt(20));
history.Print();
ShowVal(history.Undo());
ShowVal(history.Undo());
ShowVal(history.Undo());
END HVar.
</lang>
 
=={{header|OxygenBasic}}==
Anonymous user