<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">The code segment</div><div class=""><br class=""></div><div class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>List = POINTER TO RECORD</div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>item: T;</div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>next: List</div><div class=""><span class="Apple-tab-span" style="white-space: pre;"> </span>END</div></div><div class=""><br class=""></div><div class="">(1) does <b class="">NOT</b> compile under the Original Oberon compiler for RISC (as currently published on the web)</div><div class="">(2) <b class="">does</b> compile under my original suggestion (which creates a type descriptor for the anonymous record type)</div><div class="">(3) does <b class="">NOT</b> compile under the alternative suggestion (which simply disallows pointers to anonymous records)</div><div class=""><br class=""></div><div class="">In my version of the Oberon compiler I have (2) implemented. I was just wondering whether one should in fact restrict the language further to obtain (3).</div><div class=""><br class=""></div><div class="">PS: I don’t think “declaration bloat” is a big issue. After all the *entire* Oberon system is written with pointers to *named* record types, and it really is not all that more verbose, while increasing readability. But it can be debated. Personally I’d be fine with leaving (2), so that your code actually compiles.</div><div class=""><br class=""></div><div class=""><b class="">$ grep POINTER Oberon/Sources/*.Mod</b><br class="">Oberon/Sources/Checkers.Mod: TYPE Frame = POINTER TO FrameDesc;<br class="">Oberon/Sources/Curves.Mod: Curve* = POINTER TO CurveDesc;<br class="">Oberon/Sources/EBNF.Mod: Item = POINTER TO ItemDesc;<br class="">Oberon/Sources/EBNF.Mod: Symbol = POINTER TO SymbolDesc;<br class="">Oberon/Sources/FileDir.Mod: FileHd* = POINTER TO FileHeader;<br class="">Oberon/Sources/Files.Mod: File* = POINTER TO FileDesc;<br class="">Oberon/Sources/Files.Mod: Buffer = POINTER TO BufferRecord;<br class="">Oberon/Sources/Files.Mod: Index = POINTER TO IndexRecord;<br class="">Oberon/Sources/Fonts.Mod: TYPE Font* = POINTER TO FontDesc;<br class="">Oberon/Sources/Fonts.Mod: LargeFont = POINTER TO LargeFontDesc;<br class="">Oberon/Sources/GraphicFrames.Mod: Frame* = POINTER TO FrameDesc;<br class="">Oberon/Sources/GraphicFrames.Mod: Location* = POINTER TO LocDesc;<br class="">Oberon/Sources/Graphics.Mod: Graph* = POINTER TO GraphDesc;<br class="">Oberon/Sources/Graphics.Mod: Object* = POINTER TO ObjectDesc;<br class="">Oberon/Sources/Graphics.Mod: Method* = POINTER TO MethodDesc;<br class="">Oberon/Sources/Graphics.Mod: Line* = POINTER TO LineDesc;<br class="">Oberon/Sources/Graphics.Mod: Caption* = POINTER TO CaptionDesc;<br class="">Oberon/Sources/Graphics.Mod: Macro* = POINTER TO MacroDesc;<br class="">Oberon/Sources/Graphics.Mod: MacHead* = POINTER TO MacHeadDesc;<br class="">Oberon/Sources/Graphics.Mod: MacExt* = POINTER TO MacExtDesc;<br class="">Oberon/Sources/Graphics.Mod: Library* = POINTER TO LibraryDesc;<br class="">Oberon/Sources/MenuViewers.Mod: TYPE Viewer* = POINTER TO ViewerDesc;<br class="">Oberon/Sources/Modules.Mod: TYPE Module* = POINTER TO ModDesc;<br class="">Oberon/Sources/ORB.Mod: TYPE Object* = POINTER TO ObjDesc;<br class="">Oberon/Sources/ORB.Mod: Module* = POINTER TO ModDesc;<br class="">Oberon/Sources/ORB.Mod: Type* = POINTER TO TypeDesc;<br class="">Oberon/Sources/ORP.Mod: TYPE PtrBase = POINTER TO PtrBaseDesc;<br class="">Oberon/Sources/ORS.Mod: EnterKW(pointer, "POINTER");<br class="">Oberon/Sources/Oberon.Mod: Task* = POINTER TO TaskDesc;<br class="">Oberon/Sources/Rectangles.Mod: Rectangle* = POINTER TO RectDesc;<br class="">Oberon/Sources/Stars.Mod: TYPE Frame = POINTER TO FrameDesc;<br class="">Oberon/Sources/TextFrames.Mod: TYPE Line = POINTER TO LineDesc;<br class="">Oberon/Sources/TextFrames.Mod: Frame* = POINTER TO FrameDesc;<br class="">Oberon/Sources/Texts.Mod: TYPE Piece = POINTER TO PieceDesc;<br class="">Oberon/Sources/Texts.Mod: Text* = POINTER TO TextDesc;<br class="">Oberon/Sources/Texts.Mod: Buffer* = POINTER TO BufDesc;<br class="">Oberon/Sources/Viewers.Mod: Viewer* = POINTER TO ViewerDesc;<br class="">Oberon/Sources/Viewers.Mod: Track = POINTER TO TrackDesc;<br class=""></div><div class=""><br class=""></div><div class="">Andreas</div><div class=""><br class=""></div>---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<div class="">August Karlstrom fusionfile at <a href="http://gmail.com" class="">gmail.com</a> Sat Sep 23 13:22:41 CEST 2017<br class=""><br class="Apple-interchange-newline"><div class="">In most cases we don't need a name for the record type, for instance in</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>List = POINTER TO RECORD</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>item: T;</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>next: List</div><div class=""><span class="Apple-tab-span" style="white-space:pre"> </span>END</div><div class=""><br class=""></div><div class="">Forcing the above to be split into two declarations only leads to declaration bloat.</div><div class=""><br class=""></div><div class="">-- August</div><br class=""></div>---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 23 Sep 2017, at 10:01, Andreas Pirklbauer <<a href="mailto:andreas_pirklbauer@yahoo.com" class="">andreas_pirklbauer@yahoo.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">No, they don’t need to be exported. Here is an even more minimal program showing the effect:</div><div class=""><br class=""></div><div class=""><div class="" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;"> MODULE M;</div><div class="" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;"> VAR x: POINTER TO RECORD i: INTEGER END;</div><div class="" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;"><br class=""></div><div class="" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;"> PROCEDURE P*;</div><div class="" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;"> BEGIN NEW(x); x.i := 0</div><div class="" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;"> END P;</div><div class="" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;"><br class=""></div><div class="" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;"> END M.</div></div><div class=""><br class=""></div><div class="">The compiler compiles this program with no error message. But at runtime, multiple executions of the command M.P will lead to a trap.</div><div class=""><br class=""></div><div class="">I just noticed that nowhere in the Original Oberon system are pointer variables declared as shown above. They all point to *named* record types.</div><div class=""><br class=""></div><div class="">This makes me inclined to actually disallow the above program to be compiled. To achieve that, one would only have to change the language rule from “Pointers must point to records” to “Pointers must point to named records” in the language definition (see the last sentence in <a href="https://www.inf.ethz.ch/personal/wirth/Oberon/Oberon07.pdf" class="">https://www.inf.ethz.ch/personal/wirth/Oberon/Oberon07.pdf</a> ) and adjust the proposed change to procedure ORP.Type0 accordingly:</div><div class=""><br class=""></div><div class=""> IF (type.base.form # ORB.Record) OR (type.base.typobj = NIL) THEN ORS.Mark("must point to named record”) END ;</div><div class=""><br class=""></div><div class="">Andreas</div><div class=""><br class="">------------------------------------------------------------------------------------------------------------</div><div class=""><br class="">Chris Burrows chris at <a href="http://cfbsoftware.com/" class="">cfbsoftware.com</a> Sat Sep 23 06:24:28 CEST 2017<br class=""><div class=""><br class=""></div><div class="">I’m having difficulty understanding the possible intended use of your example. Did you really mean for x and y to be marked for export? If so, can you provide an example client module which would demonstrate how they could be usefully referenced?</div><div class=""><br class=""></div><div class=""> </div><div class="">Regards,</div><div class=""><br class=""></div><div class="">Chris Burrows</div><div class="">CFB Software</div><div class=""><br class=""></div><a href="http://www.astrobe.com/" class="">http://www.astrobe.com</a><div class=""><br class=""></div><div class=""><br class=""></div><div class="">------------------------------------------------------------------------------------------------------------</div></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 22 Sep 2017, at 16:47, Andreas Pirklbauer <<a href="mailto:andreas_pirklbauer@yahoo.com" class="">andreas_pirklbauer@yahoo.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class="">It seems that the Oberon 2013 compiler on RISC creates type descriptors only for *named* record types, but not for *anonymous* record types. This creates a problem if a dynamic variable pointing to an anonymous record type is allocated in the heap via the predefined procedure NEW.</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""><br class=""></div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class="">For example, in the following test program:</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""><br class=""></div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""><div class=""> MODULE M;</div><div class=""> TYPE R* = RECORD i: INTEGER END;</div><div class=""><br class=""></div><div class=""> VAR x*: POINTER TO R;</div><div class=""> y*: POINTER TO RECORD x, y, z: INTEGER END;</div><div class=""><br class=""></div><div class=""> PROCEDURE P*;</div><div class=""> BEGIN NEW(x)</div><div class=""> END P;</div><div class=""><br class=""></div><div class=""> PROCEDURE Q*;</div><div class=""> BEGIN NEW(y)</div><div class=""> END Q;</div><div class=""><br class=""></div><div class=""> END M.</div><div class=""><br class=""></div><div class="">the pointer variable 'x' points to a dynamic record of *named* record type 'R' for which a type descriptor is created by the compiler when the declaration for 'R' is processed. However, the pointer variable 'y' points to an *anonymous* record type for which *no* type descriptor is created by the compiler. So the command M.Q will crash the system as soon as the garbage collector uses the type tag of ‘y' to access the (non existing) type descriptor of the anonymous record pointed to by ‘y’.</div><div class=""><br class=""></div><div class="">The proposed solution is to also creates a type descriptor for a variable declaration of a pointer variable pointing to an *anonymous* record type. This is achieved by adding a single line to procedure ORP.Type0:</div></div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""><br class=""></div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> PROCEDURE Type0(Var type: ORB.Type);</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> ...</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> BEGIN</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> ...</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> IF sym = ORS.ident THEN ...</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> ELSIF sym = ORS.array THEN .....</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> ELSIF sym = ORS.record THEN ...</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> ELSIF sym = ORS.pointer THEN .....</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> ...</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> IF sym = ORS.ident THEN ...</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> ELSE Type(type.base);</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> IF type.base.form # ORB.Record THEN ORS.Mark("must point to record”)</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class="">--> ELSIF (type.base.typobj = NIL) & (level = 0) THEN ORG.BuildTD(type.base, dc) (*type descriptor; len used as its address*)</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""><div class=""> END ;</div><div class=""> CheckRecLevel(level)</div></div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> END</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> ELSIF sym = ORS.procedure THEN ...</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> ELSE ...</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> END</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""> END Type0;</div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""><br class=""></div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""><div class="">I’d be interested if anyone else has bumped into this issue before and whether there are any comments on the proposed solution. In particular, are there any other cases that should be considered and that people have reported before? Also, I have not tested the proposed solution with record extensions.</div><div class=""><br class=""></div></div><div style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 13px;" class=""><div class=""><div class="">Best regards,</div><div class="">AP</div><div class=""><br class=""></div><div class=""><br class=""></div></div></div></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></body></html>