[Oberon] FPGA - Simple OOP example

Jörg joerg.straube at iaeth.ch
Thu Aug 16 06:17:06 CEST 2018


Tomas

In your code you had the following question:
   PROCEDURE Write(t: Term.Term; ch: CHAR);
    BEGIN
      ch := CAP(ch); Texts.Write(W, ch); Texts.Append(Oberon.Log, W.buf)
      (* could we call base Write instead of Texts.Write/Append ? *)
    END Write;

Yes, you can. You could e.g. modify three lines of your CapTerm as follows:

Instead of 
(*1*)   VAR W: Texts.Writer; m: Term.Methods;
(*2*)   PROCEDURE Init*(t: CapTerm; color: INTEGER (* other data for the
 CapTerm if any *) ); BEGIN t.do := m; t.col := color END Init;
(*3*) BEGIN Texts.OpenWriter(W); NEW(m); Term.InitMethods(m); m.Write := Write

You write
(*1*)   VAR W: Texts.Writer; self, super: Term.Methods;
(*2*)   PROCEDURE Init*(t: CapTerm; color: INTEGER (* other data for the
 CapTerm if any *) ); BEGIN t.do := self; t.col := color END Init;
(*3*) BEGIN Texts.OpenWriter(W); NEW(super); Term.InitMethods(super); NEW(self); self^:= super^; self.Write := Write


After these three modifications your CapTerm.Write could look like this:
   PROCEDURE Write(t: Term.Term; ch: CHAR);
    BEGIN
      ch := CAP(ch); super.Write(t, ch)
    END Write;


br
Jörg
> Am 15.08.2018 um 14:34 schrieb Tomas Kral <thomas.kral at email.cz>:
> 
> Hi,
> 
> I have recoded the example as advised.
> 
>> 1) Space.
> 
> Every Term based type (class) carries its own copy of methods, some may
> be [overriden] overwritten, e.g. Write.
> 
> NEW(m); m^ = methods^; m.Write := Write
> 
>> 2) Consistency.
> 
> To keep the same methods for all Term based types, we can leave out
> NEW(m), and just assign a pointer.
> 
> (*NEW(m)*); m = methods;
> 
> QUESTION, can we somehow call base method from the overwritten one?
> 
> (* ------- OOP EXAMPLE -------- *)
> 
> MODULE Term; (* TK 15.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)
>      (* 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 InitMethods*(VAR m: Methods);
>  BEGIN m^ := methods^
>  END InitMethods;
> 
>  (* ------ 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;
> 
> BEGIN Texts.OpenWriter(W); NEW(methods); methods.Write := Write;
>  methods.Refresh := Refresh END Term.
> 
> 
> MODULE CapTerm;
>  IMPORT Texts, Oberon, Term;
> 
>  TYPE
>    CapTerm* = POINTER TO CTDesc;
>    CTDesc* = RECORD (Term.TDesc)
>      (* specific cap terminal data comes here *)
>      col: INTEGER 
>    END ;
> 
>  VAR W: Texts.Writer; m: Term.Methods;
> 
>  PROCEDURE Init*(t: CapTerm; color: INTEGER (* other data for the
>  CapTerm if any *) ); BEGIN t.do := m; 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); Texts.Write(W, ch); Texts.Append(Oberon.Log, W.buf)
>    (* could we call base Write instead of Texts.Write/Append ? *)
>  END Write;
> 
>  (* Refresh() method not to be overriden *)
> 
> BEGIN Texts.OpenWriter(W); NEW(m); Term.InitMethods(m); m.Write := Write
> END CapTerm.
> 
> 
> MODULE TestTerm;
>  IMPORT Texts, Oberon, Term, CapTerm;
> 
>  VAR
>    W: Texts.Writer; 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 ;
>    Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
>  END Run;
> 
> BEGIN Texts.OpenWriter(W);
>  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>
> --
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
> https://lists.inf.ethz.ch/mailman/listinfo/oberon

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.inf.ethz.ch/pipermail/oberon/attachments/20180816/a069137f/attachment.html>


More information about the Oberon mailing list