[Oberon] FPGA - Simple OOP example
Tomas Kral
thomas.kral at email.cz
Thu Aug 16 16:26:37 CEST 2018
On Thu, 16 Aug 2018 14:11:27 +0200
Tomas Kral <thomas.kral at email.cz> wrote:
> 1) Space: m^ = methods^
> vs
> 2) Consistency m = methods
Hi, after much advice from Joerg, I wish to post a revised OOP
example, so you can have a go, too. I managed to hide `VAR W:
Texts.Writer' in the base Term type (class). Example hopefully
demonstrates calling `base' vs `overriden' methods. The fact Oberon-07
exports read only VARs leaves some room for tinkering, simplifying the
code further.
MODULE Term; (* TK 16.8.2018 revised OOP example *)
IMPORT Texts, Oberon;
TYPE
Term* = POINTER TO TDesc;
Methods* = POINTER TO MDesc;
(* Base method suite *)
MDesc* = RECORD
Write*: PROCEDURE(t: Term; ch: CHAR);
Refresh*: PROCEDURE(t: Term);
Ln*: PROCEDURE(t: Term)
(* other methods come here *)
END ;
(* Base data suite *)
TDesc* = RECORD
do*: Methods;
(* generic terminal data comes here *)
END ;
VAR W: Texts.Writer; methods: Methods;
(* ------ Initialisation for clients ------ *)
PROCEDURE Init*(t: Term);
BEGIN t.do := methods
END Init;
PROCEDURE Clone*(VAR m: Methods);
BEGIN m^ := methods^
END Clone;
PROCEDURE Get*(VAR m: Methods);
BEGIN m := methods
END Get;
(* ------ Term base methods ----- *)
PROCEDURE Write(t: Term; ch: CHAR);
BEGIN Texts.Write(W, ch)
END Write;
PROCEDURE Refresh(t: Term);
BEGIN Texts.Append(Oberon.Log, W.buf)
END Refresh;
PROCEDURE Ln(t: Term);
BEGIN Texts.WriteLn(W)
END Ln;
BEGIN Texts.OpenWriter(W); NEW(methods); methods.Write := Write;
methods.Refresh := Refresh; methods.Ln := Ln END Term.
MODULE CapTerm;
IMPORT Term;
TYPE
CapTerm* = POINTER TO CTDesc;
CTDesc* = RECORD (Term.TDesc)
(* specific cap terminal data comes here *)
col: INTEGER
END ;
VAR self, super: Term.Methods;
PROCEDURE Init*(t: CapTerm; color: INTEGER (* other data for the
CapTerm if any *) ); BEGIN t.do := self; t.col := color
END Init;
PROCEDURE CAP(ch: CHAR): CHAR;
VAR up: CHAR;
BEGIN
IF (ch >= "a") OR (ch <= "z") THEN
up := CHR(ORD(ch) + ORD("A") - ORD("a"))
ELSE up := ch END
RETURN up END CAP;
(* --------- Methods to override from Term base ------- *)
PROCEDURE Write(t: Term.Term; ch: CHAR);
(* Write method specific for CapTerm *)
BEGIN
ch := CAP(ch); super.Write(t, ch) (* upcalls base Term.Write() *)
END Write;
(* Refresh() method not to be overriden *)
(* Ln() method not to be overriden *)
BEGIN NEW(self); Term.Clone(self); Term.Get(super); self.Write := Write
END CapTerm.
MODULE TestTerm;
IMPORT Texts, Term, CapTerm, Oberon;
VAR t: Term.Term; c: CapTerm.CapTerm;
PROCEDURE Run*;
VAR S: Texts.Scanner;
BEGIN
Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos);
Texts.Scan(S); WHILE S.class = Texts.Name DO
t.do.Write(t, S.s[0]); t.do.Refresh(t);
c.do.Write(c, S.s[0]); c.do.Refresh(c); (* calls Term.Refresh() *)
Texts.Scan(S)
END ;
c.do.Ln(t); t.do.Ln(t); c.do.Refresh(c) (* calls Term.Ln() twice *)
END Run;
BEGIN NEW(t); Term.Init(t); NEW(c); CapTerm.Init(c, 20)
END TestTerm.
TestTerm.Run a b c ~
--
Tomas Kral <thomas.kral at email.cz>
More information about the Oberon
mailing list