Discussion:
Pointer in Record not Being Assigned NIL
(too old to reply)
Michael Daniluk
2009-05-07 19:09:32 UTC
Permalink
Hello All,

I am waiting for the Wirth book to come in the mail but in the meantime
I encountered a bug for which I can find no references. Here are some
type declarations that I made all in the same file:

TYPE LexAnalyzer = POINTER TO TokenList;

TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : TypeOfTerminal;
value : String;
next : TokenNodePointer;
END;

TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;

The key here is the TokenList record. I want to initialize it so
the three pointers it contains are all initialzed to the value NIL. Here
is the code I am using to do this.

PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);

VAR tl : TokenList;

BEGIN
ALLOCATE(la, SIZE(TokenList));
tl := la^;
tl.headToken := NIL;
tl.tailToken := NIL;
tl.currentToken := NIL;

END InitializeTokenList;

My program compiles but I ran into some erroneous behaviour at runtime.
I tracked down the bug to the function above. It turns out that though
tl.headToken and tl.tailToken are both successfully initialized,
tl.currentToken is not successfully initialized to NIL. I confirmed this
with several runs and Print statements. I have not encountered behaviour
like this in any other programming language and I am very troubled by
it. The only compiler warning (I am using StonyBrook and building for
Windows) I get is about the TokenNode record:

"Record field not naturally aligned"

Does anyone have any ideas about this?

truly,
Michael
Manuel Collado
2009-05-07 20:47:56 UTC
Permalink
Post by Michael Daniluk
Hello All,
I am waiting for the Wirth book to come in the mail but in the
meantime I encountered a bug for which I can find no references. Here
TYPE LexAnalyzer = POINTER TO TokenList;
TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : TypeOfTerminal;
value : String;
next : TokenNodePointer;
END;
TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;
The key here is the TokenList record. I want to initialize it so the
three pointers it contains are all initialzed to the value NIL. Here is
the code I am using to do this.
PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
VAR tl : TokenList;
BEGIN
ALLOCATE(la, SIZE(TokenList));
tl := la^;
tl.headToken := NIL;
tl.tailToken := NIL;
tl.currentToken := NIL;
END InitializeTokenList;
My program compiles but I ran into some erroneous behaviour at
runtime. I tracked down the bug to the function above. It turns out that
though tl.headToken and tl.tailToken are both successfully initialized,
tl.currentToken is not successfully initialized to NIL. I confirmed this
with several runs and Print statements. I have not encountered behaviour
like this in any other programming language and I am very troubled by
it. The only compiler warning (I am using StonyBrook and building for
"Record field not naturally aligned"
Does anyone have any ideas about this?
You are initializing a *copy* (tl) of the allocated record, and not the
record pointed to by "la".
--
Manuel Collado - http://lml.ls.fi.upm.es/~mcollado
Michael Daniluk
2009-05-08 19:44:01 UTC
Permalink
Post by Manuel Collado
Post by Michael Daniluk
Hello All,
I am waiting for the Wirth book to come in the mail but in the
meantime I encountered a bug for which I can find no references. Here
TYPE LexAnalyzer = POINTER TO TokenList;
TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : TypeOfTerminal;
value : String;
next : TokenNodePointer;
END;
TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;
The key here is the TokenList record. I want to initialize it so
the three pointers it contains are all initialzed to the value NIL.
Here is the code I am using to do this.
PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
VAR tl : TokenList;
BEGIN
ALLOCATE(la, SIZE(TokenList));
tl := la^;
tl.headToken := NIL;
tl.tailToken := NIL;
tl.currentToken := NIL;
END InitializeTokenList;
My program compiles but I ran into some erroneous behaviour at
runtime. I tracked down the bug to the function above. It turns out
that though tl.headToken and tl.tailToken are both successfully
initialized, tl.currentToken is not successfully initialized to NIL. I
confirmed this with several runs and Print statements. I have not
encountered behaviour like this in any other programming language and
I am very troubled by it. The only compiler warning (I am using
"Record field not naturally aligned"
Does anyone have any ideas about this?
You are initializing a *copy* (tl) of the allocated record, and not the
record pointed to by "la".
Your point is welling taken and that was a programming mistake on my
part for sure. I chaged the code to:

ALLOCATE(la, SIZE(TokenList));
la^.headToken := NIL;
la^.tailToken := NIL;
la^.currentToken := NIL;

However I am still getting the dumbfounding behaviour of not seeing
la^.currentToken having the value of NIL after explicitly assigning it
that value.
Michael Daniluk
2009-05-08 19:49:47 UTC
Permalink
Post by Manuel Collado
Post by Michael Daniluk
Hello All,
I am waiting for the Wirth book to come in the mail but in the
meantime I encountered a bug for which I can find no references. Here
TYPE LexAnalyzer = POINTER TO TokenList;
TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : TypeOfTerminal;
value : String;
next : TokenNodePointer;
END;
TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;
The key here is the TokenList record. I want to initialize it so
the three pointers it contains are all initialzed to the value NIL.
Here is the code I am using to do this.
PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
VAR tl : TokenList;
BEGIN
ALLOCATE(la, SIZE(TokenList));
tl := la^;
tl.headToken := NIL;
tl.tailToken := NIL;
tl.currentToken := NIL;
END InitializeTokenList;
My program compiles but I ran into some erroneous behaviour at
runtime. I tracked down the bug to the function above. It turns out
that though tl.headToken and tl.tailToken are both successfully
initialized, tl.currentToken is not successfully initialized to NIL. I
confirmed this with several runs and Print statements. I have not
encountered behaviour like this in any other programming language and
I am very troubled by it. The only compiler warning (I am using
"Record field not naturally aligned"
Does anyone have any ideas about this?
You are initializing a *copy* (tl) of the allocated record, and not the
record pointed to by "la".
Your point is welling taken and that was a programming mistake on my
part for sure. I chaged the code to:

ALLOCATE(la, SIZE(TokenList));
la^.headToken := NIL;
la^.tailToken := NIL;
la^.currentToken := NIL;

However I am still getting the dumbfounding behaviour of not seeing
la^.currentToken having the value of NIL after explicitly assigning it
that value.
Rainard Buchmann
2009-05-09 13:16:53 UTC
Permalink
...
Sorry - your example was incomplete -
I have compiled and run with StonyBrook for Windows
the following modified example
and all was correct (without any warning) :


MODULE test2;

FROM Storage IMPORT
ALLOCATE ;


TYPE LexAnalyzer = POINTER TO TokenList;
String = ARRAY [0..127] OF CHAR ;

TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : CARDINAL;
value : String;
next : TokenNodePointer;
END;

TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;

VAR vla : LexAnalyzer;

PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
BEGIN
ALLOCATE(la, SIZE(TokenList));
la ^ .headToken := NIL;
la ^ .tailToken := NIL;
la ^ .currentToken := NIL;
END InitializeTokenList;

BEGIN
InitializeTokenList (vla);
END test2.


If with your compiler something goes wrong, please mark in

Options
Compiler Options
Misc
Machine Code Listing
Yes

and let us see the resulting file <modulname>.lst


Rainard
Michael Daniluk
2009-05-11 14:53:14 UTC
Permalink
Thank you Rainard for your help. I was also able to compile your code
without any warnings. However, I am still getting the same erroneous
behavior. Look at the print statements I inserted below. On my machine,
the first one is printed. The second one is not, indicating that current
token is not being set successfully to NIL. Can you see if you get the
same behaviour? That would confirm it is not something odd on my end.

MODULE test;

FROM Storage IMPORT
ALLOCATE ;

FROM STextIO IMPORT WriteString, WriteLn;

TYPE LexAnalyzer = POINTER TO TokenList;
String = ARRAY [0..127] OF CHAR ;

TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : CARDINAL;
value : String;
next : TokenNodePointer;
END;

TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;

VAR vla : LexAnalyzer;

PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
BEGIN
ALLOCATE(la, SIZE(TokenList));
la ^ .headToken := NIL;
la ^ .tailToken := NIL;
la ^ .currentToken := NIL;

IF (NIL = la^.headToken) AND (NIL = la^.tailToken) THEN
WriteString("Head and Tail Tokens are NIL"); WriteLn();
END;
IF (NIL = la^.currentToken) THEN WriteString("Current Token is
NIL"); WriteLn();
END;

END InitializeTokenList;

BEGIN
InitializeTokenList (vla);
END test.

Thanks!

truly,
Michael
Post by Rainard Buchmann
...
Sorry - your example was incomplete -
I have compiled and run with StonyBrook for Windows
MODULE test2;
FROM Storage IMPORT
ALLOCATE ;
TYPE LexAnalyzer = POINTER TO TokenList;
String = ARRAY [0..127] OF CHAR ;
TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : CARDINAL;
value : String;
next : TokenNodePointer;
END;
TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;
VAR vla : LexAnalyzer;
PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
BEGIN
ALLOCATE(la, SIZE(TokenList));
la ^ .headToken := NIL;
la ^ .tailToken := NIL;
la ^ .currentToken := NIL;
END InitializeTokenList;
BEGIN
InitializeTokenList (vla);
END test2.
If with your compiler something goes wrong, please mark in
Options
Compiler Options
Misc
Machine Code Listing
Yes
and let us see the resulting file <modulname>.lst
Rainard
Michael Daniluk
2009-05-11 15:20:20 UTC
Permalink
Thanks for the assistance Rainard. I compiled your code without error or
warning. However, the erroneous behaviour I am experiencing still
occurs. Check out the two print statements I inserted into your code. On
my machine, the first one is printing and the second one is not. This
indicates that current token is not being set to NIL. Can you verify
this on your box? That would help me a lot. Thank you.

MODULE test;

FROM Storage IMPORT
ALLOCATE ;

FROM STextIO IMPORT WriteString, WriteLn;

TYPE LexAnalyzer = POINTER TO TokenList;
String = ARRAY [0..127] OF CHAR ;

TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : CARDINAL;
value : String;
next : TokenNodePointer;
END;

TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;

VAR vla : LexAnalyzer;

PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
BEGIN
ALLOCATE(la, SIZE(TokenList));
la ^ .headToken := NIL;
la ^ .tailToken := NIL;
la ^ .currentToken := NIL;

IF (NIL = la^.headToken) AND (NIL = la^.tailToken) THEN
WriteString("Head and Tail Tokens are NIL"); WriteLn();
END;
IF (NIL = la^.currentToken) THEN WriteString("Current Token is
NIL"); WriteLn();
END;

END InitializeTokenList;

BEGIN
InitializeTokenList (vla);
END test.

truly,
Michael
Post by Rainard Buchmann
...
Sorry - your example was incomplete -
I have compiled and run with StonyBrook for Windows
MODULE test2;
FROM Storage IMPORT
ALLOCATE ;
TYPE LexAnalyzer = POINTER TO TokenList;
String = ARRAY [0..127] OF CHAR ;
TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : CARDINAL;
value : String;
next : TokenNodePointer;
END;
TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;
VAR vla : LexAnalyzer;
PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
BEGIN
ALLOCATE(la, SIZE(TokenList));
la ^ .headToken := NIL;
la ^ .tailToken := NIL;
la ^ .currentToken := NIL;
END InitializeTokenList;
BEGIN
InitializeTokenList (vla);
END test2.
If with your compiler something goes wrong, please mark in
Options
Compiler Options
Misc
Machine Code Listing
Yes
and let us see the resulting file <modulname>.lst
Rainard
Rainard Buchmann
2009-05-12 17:40:18 UTC
Permalink
This seems to be a failure in the codegenerator of Stonybrook-compiler

The NIL-value is assigned correctly, but the IF-statement is compiled
not correctly.

The problem can be eliminated if you write

IF (la^.currentToken = NIL) THEN ...

instead of

IF (NIL = la^.currentToken) THEN ...


Then the compiler generates the correct code.

with friendly regards

Rainard
Post by Michael Daniluk
Thanks for the assistance Rainard. I compiled your code without error or
warning. However, the erroneous behaviour I am experiencing still
occurs. Check out the two print statements I inserted into your code. On
my machine, the first one is printing and the second one is not. This
indicates that current token is not being set to NIL. Can you verify
this on your box? That would help me a lot. Thank you.
MODULE test;
FROM Storage IMPORT
ALLOCATE ;
FROM STextIO IMPORT WriteString, WriteLn;
TYPE LexAnalyzer = POINTER TO TokenList;
String = ARRAY [0..127] OF CHAR ;
TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : CARDINAL;
value : String;
next : TokenNodePointer;
END;
TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;
VAR vla : LexAnalyzer;
PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
BEGIN
ALLOCATE(la, SIZE(TokenList));
la ^ .headToken := NIL;
la ^ .tailToken := NIL;
la ^ .currentToken := NIL;
IF (NIL = la^.headToken) AND (NIL = la^.tailToken) THEN
WriteString("Head and Tail Tokens are NIL"); WriteLn();
END;
IF (NIL = la^.currentToken) THEN WriteString("Current Token is
NIL"); WriteLn();
END;
END InitializeTokenList;
BEGIN
InitializeTokenList (vla);
END test.
truly,
Michael
Michael Daniluk
2009-05-12 18:33:44 UTC
Permalink
Thank You Rainard. That is also the case on my machine, and it seems
like a fairly significant bug on the part of the SB Compiler.

truly,
Michael Daniluk
Post by Rainard Buchmann
This seems to be a failure in the codegenerator of Stonybrook-compiler
The NIL-value is assigned correctly, but the IF-statement is compiled
not correctly.
The problem can be eliminated if you write
IF (la^.currentToken = NIL) THEN ...
instead of
IF (NIL = la^.currentToken) THEN ...
Then the compiler generates the correct code.
with friendly regards
Rainard
Post by Michael Daniluk
Thanks for the assistance Rainard. I compiled your code without error
or warning. However, the erroneous behaviour I am experiencing still
occurs. Check out the two print statements I inserted into your code.
On my machine, the first one is printing and the second one is not.
This indicates that current token is not being set to NIL. Can you
verify this on your box? That would help me a lot. Thank you.
MODULE test;
FROM Storage IMPORT
ALLOCATE ;
FROM STextIO IMPORT WriteString, WriteLn;
TYPE LexAnalyzer = POINTER TO TokenList;
String = ARRAY [0..127] OF CHAR ;
TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : CARDINAL;
value : String;
next : TokenNodePointer;
END;
TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;
VAR vla : LexAnalyzer;
PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
BEGIN
ALLOCATE(la, SIZE(TokenList));
la ^ .headToken := NIL;
la ^ .tailToken := NIL;
la ^ .currentToken := NIL;
IF (NIL = la^.headToken) AND (NIL = la^.tailToken) THEN
WriteString("Head and Tail Tokens are NIL"); WriteLn();
END;
IF (NIL = la^.currentToken) THEN WriteString("Current Token is
NIL"); WriteLn();
END;
END InitializeTokenList;
BEGIN
InitializeTokenList (vla);
END test.
truly,
Michael
Fruttenboel
2009-07-03 20:00:56 UTC
Permalink
Post by Michael Daniluk
Thank You Rainard. That is also the case on my machine, and it seems
like a fairly significant bug on the part of the SB Compiler.
truly,
Michael Daniluk
Post by Rainard Buchmann
This seems to be a failure in the codegenerator of Stonybrook-compiler
The NIL-value is assigned correctly, but the IF-statement is compiled
not correctly.
The problem can be eliminated if you write
IF (la^.currentToken = NIL) THEN ...
instead of
IF (NIL = la^.currentToken) THEN ...
Then the compiler generates the correct code.
with friendly regards
Rainard
Post by Michael Daniluk
Thanks for the assistance Rainard. I compiled your code without error
or warning. However, the erroneous behaviour I am experiencing still
occurs. Check out the two print statements I inserted into your code.
On my machine, the first one is printing and the second one is not.
This indicates that current token is not being set to NIL. Can you
verify this on your box? That would help me a lot. Thank you.
MODULE test;
FROM Storage IMPORT
ALLOCATE ;
FROM STextIO IMPORT WriteString, WriteLn;
TYPE LexAnalyzer = POINTER TO TokenList;
String = ARRAY [0..127] OF CHAR ;
TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : CARDINAL;
value : String;
next : TokenNodePointer;
END;
TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;
VAR vla : LexAnalyzer;
PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
BEGIN
ALLOCATE(la, SIZE(TokenList));
la ^ .headToken := NIL;
la ^ .tailToken := NIL;
la ^ .currentToken := NIL;
IF (NIL = la^.headToken) AND (NIL = la^.tailToken) THEN
WriteString("Head and Tail Tokens are NIL"); WriteLn();
END;
IF (NIL = la^.currentToken) THEN WriteString("Current Token is
NIL"); WriteLn();
END;
END InitializeTokenList;
BEGIN
InitializeTokenList (vla);
END test.
truly,
Michael
I don't see this as a bug in the compiler.

It's VERY uncommon to have the constant upfront in a conditional
statement.

I wrote my PLOV compiler and know from experience that conditionals
are parsed from left to right. Most probably, SB parses left to right
as well. The parser first finds a CONST and gets confused. So the type
of the second operand must be a CONST as well, but it isn't. It's a
VAR. It looks like the compiler ignores this at compiletime but gets
stuck in runtime.

In a C-ish language, chaos proggramming like 'IF 2 = value THEN ...'
may be allowed but I think this is not the thing a true Modula-2
programmer should ever even consider using. And, sorry, it looks
stupid too.
Chris Burrows
2009-07-04 01:29:44 UTC
Permalink
Post by Fruttenboel
I don't see this as a bug in the compiler.
I see it as a bug in the compiler. It is a valid Modula-2 expression.
Post by Fruttenboel
It's VERY uncommon to have the constant upfront in a conditional
statement.
Uncommon perhaps but not invalid.
Post by Fruttenboel
In a C-ish language, chaos proggramming like 'IF 2 = value THEN ...'
may be allowed but I think this is not the thing a true Modula-2
programmer should ever even consider using. And, sorry, it looks
stupid too.
My initial reaction was the same as yours but I changed my mind when I
thought about it a little more. I would agree that that the original example
looks VERY unfamiliar - I certainly wouldn't use it myself. However, there
are other examples which are more appropriate where the constant can come
first. For example:

IF ("a" <= ch) & (ch <= "z") THEN ...

is quite a natural representation of

"a" <= ch <= "z"

Again, I don't usually write it this way myself but I have seen it often in
programs written by "true Modula-2 programmers" ;-)

--
Chris Burrows
CFB Software
http://www.cfbsoftware.com/modula2
Fruttenboel
2009-07-05 16:25:31 UTC
Permalink
Post by Chris Burrows
My initial reaction was the same as yours but I changed my mind when I
thought about it a little more. I would agree that that the original example
looks VERY unfamiliar - I certainly wouldn't use it myself. However, there
are other examples which are more appropriate where the constant can come
IF ("a" <= ch) & (ch <= "z") THEN ...
is quite a natural representation of
"a" <= ch <= "z"
Again, I don't usually write it this way myself but I have seen it often in
programs written by "true Modula-2 programmers" ;-)
Ah, you got a code snippet from the Grand Master himself (Professor
Wirth), He is very fond of this kind of constructions indeed.
Especially in his PL/0 compiler.

Still, the compiler may get confused by the reversed condition. As was
the case with the (oldfashioned) Stony Brook compiler.

Another thing, Wirth is 'famous' for is:

BEGIN test;
react;
act;
END proc;

The first line is rather confusing for a newbie (or a person that
likes to code very clearly). It may be a trick of the Grans Master to
keep the linecount of his sources low, since he claims that a source
longer than 5000 lines indicates that the programmer did not
understand the algoriithm he tries to implement... :o)

g***@netscape.net
2009-05-15 19:23:35 UTC
Permalink
Hi,
Post by Rainard Buchmann
This seems to be a failure in the codegenerator of Stonybrook-compiler
The NIL-value is assigned correctly, but the IF-statement is compiled
not correctly.
The problem can be eliminated if you write
IF (la^.currentToken = NIL) THEN ...
instead of
IF (NIL = la^.currentToken) THEN ...
Then the compiler generates the correct code.
Interesting, first time I have seen "NIL = ptr" in Modula-2 and that
may
be the reason why the compiler missed it. In C, however, it is very
common
to do it to catch the common mistake of writing "if (ptr = NULL)"
instead of
"if (ptr == NULL)", wwhere writing "if (NULL = ptr)" by mistake will
be caught
by the compiler since NULL can't be assigned to. This type of error is
not
possible in Modula-2 so the more natural "ptr = NIL" is used.
Martin Brown
2009-05-15 21:11:20 UTC
Permalink
Post by Rainard Buchmann
This seems to be a failure in the codegenerator of Stonybrook-compiler
The NIL-value is assigned correctly, but the IF-statement is compiled
not correctly.
The problem can be eliminated if you write
IF (la^.currentToken = NIL) THEN ...
instead of
IF (NIL = la^.currentToken) THEN ...
Then the compiler generates the correct code.
You might like to try it on the (now free) XDS M2 compiler. I have been
very favourably impressed with its deep static analysis of code and so
far all the apparent compiler bugs have been in the source code being
compiled rather than in the compiler. That is it is finding bugs in code
that other compilers would happily compile without errors or warnings.

Regards,
Martin Brown
Fruttenboel
2009-07-03 20:03:17 UTC
Permalink
Post by Martin Brown
You might like to try it on the (now free) XDS M2 compiler.
I see XDS more as a front end for a nice C compiler.
Fruttenboel
2009-07-03 20:08:52 UTC
Permalink
Post by Michael Daniluk
Thanks for the assistance Rainard. I compiled your code without error or
warning. However, the erroneous behaviour I am experiencing still
occurs. Check out the two print statements I inserted into your code. On
my machine, the first one is printing and the second one is not. This
indicates that current token is not being set to NIL. Can you verify
this on your box? That would help me a lot. Thank you.
MODULE test;
FROM Storage IMPORT
ALLOCATE ;
FROM STextIO IMPORT WriteString, WriteLn;
TYPE LexAnalyzer = POINTER TO TokenList;
String = ARRAY [0..127] OF CHAR ;
TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : CARDINAL;
value : String;
next : TokenNodePointer;
END;
TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;
VAR vla : LexAnalyzer;
PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
BEGIN
ALLOCATE(la, SIZE(TokenList));
la ^ .headToken := NIL;
la ^ .tailToken := NIL;
la ^ .currentToken := NIL;
IF (NIL = la^.headToken) AND (NIL = la^.tailToken) THEN
WriteString("Head and Tail Tokens are NIL"); WriteLn();
END;
IF (NIL = la^.currentToken) THEN WriteString("Current Token is
NIL"); WriteLn();
END;
END InitializeTokenList;
BEGIN
InitializeTokenList (vla);
END test.
truly,
Michael
Post by Rainard Buchmann
...
Sorry - your example was incomplete -
I have compiled and run with StonyBrook for Windows
MODULE test2;
FROM Storage IMPORT
ALLOCATE ;
TYPE LexAnalyzer = POINTER TO TokenList;
String = ARRAY [0..127] OF CHAR ;
TYPE TokenNodePointer = POINTER TO TokenNode;
TYPE TokenNode = RECORD
type : CARDINAL;
value : String;
next : TokenNodePointer;
END;
TYPE TokenList = RECORD
headToken : TokenNodePointer;
tailToken : TokenNodePointer;
currentToken : TokenNodePointer;
END;
VAR vla : LexAnalyzer;
PROCEDURE InitializeTokenList(VAR la : LexAnalyzer);
BEGIN
ALLOCATE(la, SIZE(TokenList));
la ^ .headToken := NIL;
la ^ .tailToken := NIL;
la ^ .currentToken := NIL;
END InitializeTokenList;
BEGIN
InitializeTokenList (vla);
END test2.
If with your compiler something goes wrong, please mark in
Options
Compiler Options
Misc
Machine Code Listing
Yes
and let us see the resulting file <modulname>.lst
Rainard
Compiled it with Mocka (the vey best Modula-2 compiler for Linux,
gravely underestimated):

***@Beryllium:~$ mocka
Mocka 0608m
Post by Michael Daniluk
Post by Rainard Buchmann
i ttt
p ttt
.. Compiling Program Module ttt I/0002
.. Compiling Program Module ttt I/0002 II/0002
.. Linking ttt
Post by Michael Daniluk
Post by Rainard Buchmann
./ttt
Head and Tail Tokens are NIL
Current Token is NIL
I rest my case.
Loading...