Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error in WITH statement with pointers to related type extended records #98

Open
tkurtbond opened this issue Jul 9, 2022 · 7 comments
Open

Comments

@tkurtbond
Copy link

tkurtbond commented Jul 9, 2022

When I compile the following program with Vishap Oberon:

MODULE example;

  IMPORT Out;

  TYPE
    (** A rope. *)
    T* = POINTER TO TDesc;
    TDesc = RECORD
    END;

    (** Alias for type Rope.T. *)
    Rope* = T;

    PAoC = POINTER TO ARRAY OF CHAR;

    SubNode = POINTER TO SubDesc;
    SubDesc = RECORD (TDesc)
      s: PAoC;
      start: LONGINT;
      length: LONGINT;
    END;

    CatNode = POINTER TO CatDesc;
    CatDesc = RECORD (TDesc)
      height: LONGINT;
      length: LONGINT;
      left: T;
      leftLength: LONGINT;
      right: T;
    END;      

    PROCEDURE print (r: T);
    BEGIN
      Out.Char ('(');
      WITH r: SubNode DO
        Out.String ('SubNode: start: '); Out.Int (r.start, 0);
        Out.String (' length: '); Out.Int  (r.length, 0);
      | r: CatNode DO
        Out.String ('CatNode: height: '); Out.Int (r.height, 0);
        Out.String (' length: '); Out.Int (r.length, 0);
        Out.String (' leftLength: '); Out.Int (r.leftLength, 0);
        Out.String (' left: ');
        print (r.left);
        Out.String (' right: ');
        print (r.right);
      ELSE
        Out.String ('Length: impossible error: r is not SubNode or CatNode'); Out.Ln;
      END;
      Out.Char (')');
    END print;

END example.

I get this error:

voc -f example.Mod -m
example.Mod  Compiling example.

  43:         print (r.left);
                          ^
    pos   985  err 113  incompatible assignment

  45:         print (r.right);
                           ^
    pos  1043  err 113  incompatible assignment

Module compilation failed.

Both of the other Oberon-2 compilers I tried with (oo2c and obc) compiled this without error, but I can't use either of them for the project from which this example is extracted (oo2c has a bug that makes the project fail, for instance).

@norayr
Copy link
Member

norayr commented Jul 9, 2022

Thank you for raising this issue.

I am thinking about this. Most probably we have a bug which needs to be fixed, but hang on, I am investigating this.

It's interesting, I tried your source in OLR, and it's version of OP2 parser was not able to compile it because of different issue - the parser didn't agree with the usage of the pipe (|) symbol, though it seems to be correct Oberon-2 syntax. It said - END expected.

Anyway that didn't directly relate to the actual question of using print (r.left) so I changed the source a little bit, and it was able to compile it.

However voc is inherited from the different line - Linz's version of parser, it would be interesting to see how that compiler would behave. But I cannot, because Oberon V4 for Linux was linked to the old version of glibc (OLR doesn't use libc at all) and is not usable nowadays. Though I have a friend who revived it, extended it, and has a running copy on FreeBSD.

@tkurtbond
Copy link
Author

tkurtbond commented Jul 9, 2022

Is your friend’s revived version of Oberon V4 something that is publicly available? I’d be interested…

@MarkowEduard
Copy link

MarkowEduard commented Jul 10, 2022

This problem is well known and dates back to the early releases of OP2 by Crelier Regis from the ETH.
The reason for the problem is that the WITH statement changes the type of the variable which is in this case a parameter and therefore the type of the procedure is changed.

A simple workaround is to deliberately adjust the type of the supplied parameter:

	print (r.left(CatNode));
	...
	print (r.right(CatNode));

@norayr
Copy link
Member

norayr commented Jul 10, 2022

@MarkowEduard thank you so much!

@tkurtbond will that work for you till i'll fix the parser? because with my current load it'll take time.

@tkurtbond
Copy link
Author

@MarkowEduard thank you so much!

@tkurtbond will that work for you till i'll fix the parser? because with my current load it'll take time.

That will work fine! Thank you, and @MarkowEduard!

@tkurtbond
Copy link
Author

@tkurtbond will that work for you till i'll fix the parser? because with my current load it'll take time.

That will work fine! Thank you, and @MarkowEduard!

I spoke too soon: that let the example I'd extracted from the real module compile fine, and the real module compiled fine, but it died with a HALT(-5) type guard failed. However, the phrase "and therefore the type of the procedure is changed" did lead to a workaround that does work: I introduced a variable t: T and set t to r, and used t in the WITH instead of r. That way the type of the procedure doesn't get changed, if I understand correctly.

Again, thanks @MarkowEduard and @norayr!

@MarkowEduard
Copy link

Can you provide an example?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants