Page 2 of 3

Re: Further revision of Oberon-07

Posted: Sat Sep 17, 2011 3:21 pm
by augustk
That is a pity - I would have found it useful.
As far as I understand it's the assignment compatibility between strings and character arrays that allows a string to be passed to a procedure expecting a character array (even though no copying of characters take place). So if character variables were to be compatible with character array parameters I reason that they would also have to be assignment compatible with character arrays. Implementation-wise the parameter passing part would probably be a bit difficult though, as a character variable cannot be simply converted to a character array.

Re: Further revision of Oberon-07

Posted: Thu Sep 22, 2011 1:34 pm
by cfbsoftware
It is also worth noting that the string 0X needs special interpretation.
Our interpretation of the 2011 report led to the following test program which demonstrates various ways of creating a null string:

Code: Select all

MODULE NullStr1;

IMPORT 
  Main, Out, Strings;
  
VAR
  ch: CHAR;
  s: ARRAY 1 OF CHAR;

PROCEDURE Length(s: ARRAY OF CHAR);
BEGIN
  Out.Int(Strings.Length(s), 0); Out.Ln
END Length;

PROCEDURE Run();  
BEGIN
  s := "";      ASSERT(s = "", 100); Length(s);
  s := 0X;      ASSERT(s = "", 101); Length(s);
  s[0] := 0X;   ASSERT(s = "", 102); Length(s); 
  ch := 0X;    
  s[0] := ch;   ASSERT(s = "", 103); Length(s);
END Run;

BEGIN
  Run();
  Out.String("NullStr1 Finished OK"); Out.Ln
END NullStr1.
When compiled with the Oberon 2011 compiler it produces the following (expected) output when run:

0
0
0
0
NullStr1 Finished OK

Re: Further revision of Oberon-07

Posted: Thu Sep 22, 2011 3:38 pm
by augustk
Does the compiler reject the statement

Code: Select all

ch := ""
If it does I guess the scanner uses a distinct token type for string ordinals. Otherwise the parser would not be able to tell the empty string from the null string (0X) as both compare equal and are of length zero.

Re: Further revision of Oberon-07

Posted: Fri Sep 23, 2011 8:19 am
by cfbsoftware
Correct. "" is not a single-character string so it cannot be assigned to a CHAR variable. Single-character strings are interpreted in either of two ways in the Astrobe Oberon 2011 compiler depending on whether the context is a CHAR or an ARRAY OF CHAR. The following example illustrates the two different uses:

Code: Select all

MODULE CharString7;

IMPORT Strings;

TYPE
  String = ARRAY 32 OF CHAR;

VAR
  ch: CHAR;
  i: INTEGER;
  s: String;

PROCEDURE CharProc(ch: CHAR);
BEGIN
END CharProc;
  
PROCEDURE StringProc(s: String);
BEGIN
END StringProc;
  
BEGIN
  (* Single-character strings used as CHARs *)
  ch := 0X;
  ch := 22X;
  ch := "x";
  ch := "'"; (* Single-quote enclosed in double-quotes *)
  i := ORD(0X);
  i := ORD(22X);
  i := ORD("x");
  i := ORD("'"); 
  IF (ch = 0X) OR (ch = 22X) OR (ch = "x") OR (ch = "'") THEN (* Do something *) END; 
  CharProc(0X);
  CharProc(22X);
  CharProc("x");
  CharProc("'"); 
  CASE ch OF
    0X, 22X, "x", "'": (* Do something *)
  END;
 
  (* Single-character strings used as ARRAY OF CHARs *)
  s := 0X;
  s := 22X;
  s := "x";
  s := "'";
  Strings.Append(s, 0X);
  IF (s = 0X) OR (s = 22X) OR (s = "x") OR (s = "'") THEN (* Do something *) END; 
  StringProc(0X);
  StringProc(22X);
  StringProc("x");
  StringProc("'")
END CharString7.

Re: Further revision of Oberon-07

Posted: Fri Sep 23, 2011 8:25 pm
by augustk
OK, but the scanner does not know about these contexts (CHAR or ARRAY OF CHAR). Although the language was simplified to use only strings, as far as I can tell the scanner still needs two token types (like charString and ordString) so that the parser can tell the empty string ("") from the null string (0X).

Re: Further revision of Oberon-07

Posted: Fri Sep 23, 2011 10:39 pm
by augustk
Never mind, I found a rather simple solution: In the case of the empty string ("") the scanner can store it as s[0] := 0X; s[1] := 1X to differentiate it from the null string (0X) which is typically stored as s[0] := 0X; s[1] := 0X.

Re: Further revision of Oberon-07

Posted: Fri Sep 30, 2011 12:54 pm
by kevinhely
Hi,

I was away and missed this conversation.
Thankfully not! That 'solution' creates more problems than it solves.
What problems? (I ask because I implemented it on my Oberon compiler without difficulty.)

Kevin.

Re: Further revision of Oberon-07

Posted: Fri Sep 30, 2011 11:30 pm
by cfbsoftware
If you nominate a character as an escape character e.g. "\" then you also have to specify how to represent that escape character in the situations where you want to use it as literal character, not an escape. Typically this is done by doubling the character e.g. "\\". Unfortunately in computing contexts the "\" character is quite common (e.g. in pathnames).

e.g. If you used "\" to escape a " character, as proposed, then to output the text:

"C:\temp"

I assume you would would need to write:

Code: Select all

Out.String("\"C:\\temp\\\"");   (* ??? *)
Personally, although it is more 'wordy', I prefer to be able to write:

Code: Select all

CONST
  quotes = 22X;

Out.Char(quotes); Out.String("C:\temp\"); Out.Char(quotes);
and find this easier to comprehend at a glance.

Re: Further revision of Oberon-07

Posted: Sat Oct 01, 2011 10:54 am
by augustk
If the path in your example is to be exported as a constant, say, it gets a bit more involved if we decide to add quotes. A module like

Code: Select all

MODULE M;

	CONST path* = "C:\temp\";

END M.
will turn into something like this:

Code: Select all

MODULE M;

	CONST quotes = 22X;

	VAR path: ARRAY 10 OF CHAR;

	PROCEDURE GetPath*(VAR out: ARRAY OF CHAR);
	BEGIN
		COPY(path, out)
	END GetPath;

BEGIN
	path := " C:\temp\ ";
	path[0] := quotes;
	foo[9] := quotes
END M.
It is unfortunate that character array variables cannot be exported.

Re: Further revision of Oberon-07

Posted: Sat Oct 01, 2011 8:25 pm
by kevinhely
Well, I'm afraid I'm not convinced that the example you gave justifies the assertion that
That 'solution' creates more problems than it solves.
The "escaping" use of the backslash character is well-established and has certainly never caused me any difficulties in path name processing in C or Java (e.g. in the compilers I've written). I understood the string you'd written in your example straight away (as I'm sure any competent C/Java programmer would). However, with the single-quote string delimiters, the code of your example would have been simpler and clearer.

I applaud the simplification achieved by the elimination of "character constants" but eliminating single-quote delimiters was unnecessarily parsimonious. (Perhaps they'll return in a later revision ;) )

Regards,
K.