vishapoberon / compiler

vishap oberon compiler
http://oberon.vishap.am
GNU General Public License v3.0
186 stars 25 forks source link

two questions about constant arrays. #59

Closed norayr closed 7 years ago

norayr commented 7 years ago

0. OP2 has an error 'err 131 LEN not applied to array' when applying it to a string constant.

  1. CONST s0 = "aaa";
    VAR s1 : ARRAY 5 OF CHAR;
    BEGIN
    s1 := s0; (* this cannot be compiled *)
    COPY (s0, s1); (this can be compiled *)

    what do you think about it?

dcwbrown commented 7 years ago

I'm trying to reproduce this. I just tried compiling:

MODULE m1; CONST s0 = "aaa"; VAR s1 : ARRAY 5 OF CHAR; BEGIN s1 := s0; ( this cannot be compiled ) COPY (s0, s1); ( this can be compiled ) END m1.

I don't get a compile error. And adding Out.String calls shows it is working correctly.

Further, looking at the compiler source, error 131 is only raised from the implementation of LEN, and your code does not use LEN, so that's odd.

Can you look into it a bit further?

On 2017-05-22 12:15, Norayr Chilingarian wrote:

  • OP2 has an error 'err 131 LEN not applied to array' when applying it to a string constant.

CONST s0 = "aaa"; VAR s1 : ARRAY 5 OF CHAR; BEGIN s1 := s0; ( this cannot be compiled ) COPY (s0, s1); (this can be compiled *)

is that okay?

-- You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub [1], or mute the thread [2].

Links:

[1] https://github.com/vishaps/voc/issues/59 [2] https://github.com/notifications/unsubscribe-auth/ADChoFtBJTKW4ikVLRJjb7vZu_eTqd9xks5r8W5ngaJpZM4NiNzC

norayr commented 7 years ago

thank you for response, i wanted to discuss this. those are two unrelated questions.

firstly, try this:

MODULE m1;

CONST s0 = "aaa";
VAR s1 : POINTER TO ARRAY OF CHAR;
i : LONGINT;
BEGIN
  i := LEN(s0);
  NEW(s1, 1);
  s1^ := s0; (* this cannot be compiled *)
  COPY (s0, s1); (* this can be compiled *)
END m1.

i := LEN(s0) won't be compiled.

   7:   i := LEN(s0);
                  ^
    pos    88  err 131  LEN not applied to array

secondly, apparently what i've written was misleading. i have actually tried it with POINTER TO ARRAY OF CHAR, and got the error: (line 7 is commented out)

m1.Mod  Compiling m1.

   9:   s1^ := s0; (* this cannot be compiled *) 
                ^
    pos   129  err 113  incompatible assignment
norayr commented 7 years ago

However, Strings.Length(s0) will work, but what if we don't want to use that module?

I don't know, I wanted to discuss this, as well as if assignment to the dereferenced string pointer should work?

dcwbrown commented 7 years ago

Re LEN - I looked at 3 specs: Oberon2, Component Pascal and Oberon07, and they all specify that the parameter must be an array. That fits with the error message 131, as "xxx" is a string, not an array.

So, what if we want it to work on a string? There's an ambiguity - should LEN("abc") return 3 or 4? i.e. should it include the trailing zero terminator. I expect many people would immediately say 3, but I believe it should include the zero terminator (i.e. return 4 in this case). It's not safe to pretend tha the zero terminator is not there, and indeed if you pass a string to a dynamic array param and call LEN on the param, the length will include the zero terminator. Example:

MODULE m5; IMPORT Out;

PROCEDURE p(s: ARRAY OF CHAR);
BEGIN
  Out.Int(LEN(s),1); Out.Ln;
END p;

BEGIN
  p("abc");
END m5.

Displays 4.

So my hunch is: don't support LEN(string), because as many people will be expecting LEN("abc") to return 3 as expect it to return 4. Adding support will increase confusion.


Re assigning a string parameter to an allocated array:

Array assignment is a binary copy, and is allowed only when the target array is at least as big as the source array. In this case the target array size is not known at compile time, so the compiler cannot safely compile the program. Indeed in your example if it had compiled it, there would have been a memory overwrite as it copied a length 4 string to a length 1 array.

So supporting the existing (Oberon-07) semantics would mean deferring the size test until runtime, generating an error in this case at runtime.

Or you could make a special case and define that when an array assignment is applied specifically to arrays of CHAR, it will be treated as a COPY rather than a simple copy of source to target. COPY has the extra semantics of truncating the string if necessary, and of guaranteeing a zero terminator in the target string.

So again I think things are best as they are. I don't recommend detecting oversize at run time because errors are better detected at co,pile time, and I don't recommend have special-case behaviour for arrays of CHAR as opposed to all other arrays.


Just my thoughts -- Dave.

diegosardina commented 7 years ago

Constant strings in Oberon are NOT arrays, however there is an assignment compatibility between them. This is why LEN() doesn't work on constant strings.

Some Oberon compilers relax this rule but it is not a good idea.

norayr commented 7 years ago

thank you so much! indeed that will promote a confusion.

norayr commented 7 years ago

ah and what about an assignment?

dcwbrown commented 7 years ago

That was the second half of my reply? Repeating here:

Re assigning a string parameter to an allocated array:

Array assignment is a binary copy, and is allowed only when the target array is at least as big as the source array. In this case the target array size is not known at compile time, so the compiler cannot safely compile the program. Indeed in your example if it had compiled it, there would have been a memory overwrite as it copied a length 4 string to a length 1 array.

So supporting the existing (Oberon-07) semantics would mean deferring the size test until runtime, generating an error in this case at runtime.

Or you could make a special case and define that when an array assignment is applied specifically to arrays of CHAR, it will be treated as a COPY rather than a simple copy of source to target. COPY has the extra semantics of truncating the string if necessary, and of guaranteeing a zero terminator in the target string.

So again I think things are best as they are. I don't recommend detecting oversize at run time because errors are better detected at co,pile time, and I don't recommend have special-case behaviour for arrays of CHAR as opposed to all other arrays.

norayr commented 7 years ago

sorry, i am over loaded right now at work, and did not follow exactly. thank you.