ooc-compiler Mailing List for Optimizing Oberon-2 Compiler (Page 3)
Brought to you by:
mva
You can subscribe to this list here.
| 2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(34) |
Aug
(19) |
Sep
(33) |
Oct
(14) |
Nov
(4) |
Dec
(4) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2001 |
Jan
(6) |
Feb
(11) |
Mar
(8) |
Apr
(1) |
May
(24) |
Jun
(12) |
Jul
(13) |
Aug
(16) |
Sep
(8) |
Oct
(6) |
Nov
|
Dec
(5) |
| 2002 |
Jan
|
Feb
(14) |
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
(3) |
Aug
(8) |
Sep
|
Oct
(3) |
Nov
|
Dec
(6) |
| 2003 |
Jan
(6) |
Feb
(4) |
Mar
(1) |
Apr
(1) |
May
(11) |
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(12) |
Nov
(22) |
Dec
(3) |
| 2004 |
Jan
(11) |
Feb
(16) |
Mar
(8) |
Apr
|
May
(35) |
Jun
(3) |
Jul
(14) |
Aug
(3) |
Sep
(7) |
Oct
(4) |
Nov
(30) |
Dec
(3) |
| 2005 |
Jan
(7) |
Feb
(16) |
Mar
(2) |
Apr
|
May
(10) |
Jun
(2) |
Jul
(4) |
Aug
(5) |
Sep
(4) |
Oct
(11) |
Nov
(1) |
Dec
(14) |
| 2006 |
Jan
(15) |
Feb
(6) |
Mar
(3) |
Apr
|
May
(1) |
Jun
(7) |
Jul
(11) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2007 |
Jan
|
Feb
(5) |
Mar
(6) |
Apr
|
May
|
Jun
(11) |
Jul
(2) |
Aug
|
Sep
(9) |
Oct
(4) |
Nov
(2) |
Dec
|
| 2008 |
Jan
(5) |
Feb
(4) |
Mar
(5) |
Apr
|
May
(11) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(4) |
Dec
(7) |
| 2009 |
Jan
(8) |
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(3) |
Sep
(6) |
Oct
(6) |
Nov
|
Dec
|
| 2010 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
(2) |
Jul
(28) |
Aug
(18) |
Sep
|
Oct
(9) |
Nov
|
Dec
|
| 2011 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
(2) |
Jul
(16) |
Aug
(18) |
Sep
(1) |
Oct
|
Nov
(1) |
Dec
(1) |
| 2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(2) |
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
| 2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(4) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(2) |
| 2016 |
Jan
(4) |
Feb
(1) |
Mar
(3) |
Apr
(1) |
May
(1) |
Jun
|
Jul
(2) |
Aug
(4) |
Sep
|
Oct
|
Nov
|
Dec
|
|
From: August K. <fus...@gm...> - 2011-06-12 12:25:01
|
After using GetEnv in ProcessParameters I would like to convert the Object.String to a character array. Does anyone know how to do that? Regards, August |
|
From: s d. <syl...@ya...> - 2011-02-14 20:53:14
|
Norayr, Thanks for the link. I hear for some time that it was possible to go native on android (the salt and pepper thing). But never found the actual 'Hollo world!' showing how its done. Very intersting! Sylvain. ----- Original Message ---- > From: Norayr Chilingarian <no...@ar...> > To: ooc...@li... > Sent: Sun, February 13, 2011 2:08:20 PM > Subject: [ooc-compiler] android native development > > > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Since version 2.3 it is possible to write purely native application > without a line of java code. > This is an example: > http://developer.android.com/reference/android/app/NativeActivity.html > This means it's possible to to the same in Oberon/oo2c > > Sincerely, > Norayr > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v2.0.16 (GNU/Linux) > Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ > > iQEcBAEBAgAGBQJNWCwkAAoJEDbv/aplkZ1FrZYH/0v5tWSJRVJftStbsj+uq/19 > TZNvlUDZkLQgSxkHRvQqkXDpjVuFrzAf3oef7Nxfboh6vQ7qInyhXIADPoHNrLss > ti1WMMDizhdcC49blNRa79gQIv8q6ypVmVY1YIkOEGIjqBmugc/QqUIzC32Ez/jg > TNEmvQEkljWZryLizFqezYlL1fVd4yDlsdjgqiR19OOLZoa7umpBYPEqyBaoVaxM > EN+lhGUGSgVNUJjCF/OWxL5rCK0HGrpsvDSx1uOnw0QDDVXdQdQ+1zsBMtwsWa82 > dZU/cSwe/BGgI1+YkNrByvycFeRZqfNr/kmEKk820oK3uKS53LMjadHYYfK0w+A= > =UsYr > -----END PGP SIGNATURE----- > > > ------------------------------------------------------------------------------ > The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE: > Pinpoint memory and threading errors before they happen. > Find and fix more than 250 security defects in the development cycle. > Locate bottlenecks in serial and parallel code that limit performance. > http://p.sf.net/sfu/intel-dev2devfeb > _______________________________________________ > ooc-compiler mailing list > ooc...@li... > https://lists.sourceforge.net/lists/listinfo/ooc-compiler > |
|
From: Norayr C. <no...@ar...> - 2011-02-13 19:34:22
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Since version 2.3 it is possible to write purely native application without a line of java code. This is an example: http://developer.android.com/reference/android/app/NativeActivity.html This means it's possible to to the same in Oberon/oo2c Sincerely, Norayr -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.16 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJNWCwkAAoJEDbv/aplkZ1FrZYH/0v5tWSJRVJftStbsj+uq/19 TZNvlUDZkLQgSxkHRvQqkXDpjVuFrzAf3oef7Nxfboh6vQ7qInyhXIADPoHNrLss ti1WMMDizhdcC49blNRa79gQIv8q6ypVmVY1YIkOEGIjqBmugc/QqUIzC32Ez/jg TNEmvQEkljWZryLizFqezYlL1fVd4yDlsdjgqiR19OOLZoa7umpBYPEqyBaoVaxM EN+lhGUGSgVNUJjCF/OWxL5rCK0HGrpsvDSx1uOnw0QDDVXdQdQ+1zsBMtwsWa82 dZU/cSwe/BGgI1+YkNrByvycFeRZqfNr/kmEKk820oK3uKS53LMjadHYYfK0w+A= =UsYr -----END PGP SIGNATURE----- |
|
From: Stewart G. <sgr...@us...> - 2010-10-12 05:08:12
|
Hi Norayr, Sorry for the delay. I see the problem, but I'm not sure what you're trying to achieve. Within Resources, Discipline is an extension of Discipline.Discipline and it looks like most of the procedures in this module require the extended type. These will break if you change the signature of GetDisc. Why do you want to change the signature of GetDisc? Cheers, Stewart On 7/10/10 5:46 AM, Norayr Chilingaryan wrote: > Hey, > thank you for reply. > ok, I see, indeed. > > So, here we have Resources.Mod from Ulm's Oberon LIbrary which contains: > > TYPE > List = POINTER TO ListRec; > ListRec = > RECORD > resource: Resource; > next: List; > END; > Discipline = POINTER TO DisciplineRec; > DisciplineRec = > RECORD > (Disciplines.DisciplineRec) > state: State; (* alive, unreferenced, or terminated *) > stopped: BOOLEAN; (* may be TRUE, if alive or unreferenced *) > refcnt: LONGINT; (* # of Attach - # of Detach *) > eventType: Events.EventType; (* may be NIL *) > dependants: List; (* list of resources which depends on us *) > dependsOn: Resource; (* we depend on this resource *) > key: Key; (* attach key for dependsOn *) > END; > > ... > > PROCEDURE GetDisc(resource: Resource; VAR disc: Discipline); > BEGIN > IF ~Disciplines.Seek(resource, discID, disc) THEN > NEW(disc); disc.id <http://disc.id> := discID; > disc.state := alive; disc.refcnt := 0; > disc.eventType := NIL; > disc.dependants := NIL; disc.dependsOn := NIL; > Disciplines.Add(resource, disc); > END; > END GetDisc; > > Procedure GetDisc is called a lot of times: > hacktar ulmoberonlib # grep GetDisc * > Resources.Mod: PROCEDURE GetDisc(resource: Resource; VAR disc: > Discipline); > Resources.Mod: END GetDisc; > Resources.Mod: GetDisc(resource, disc); > Resources.Mod: GetDisc(resource, resourceDisc); > Resources.Mod: GetDisc(dependant, dependantDisc); > Resources.Mod: GetDisc(resource, disc); > Resources.Mod: GetDisc(resource, disc); > Resources.Mod: GetDisc(resource, disc); > Resources.Mod: GetDisc(resource, disc); > Resources.Mod: GetDisc(resource, disc); > Resources.Mod: GetDisc(resource, resourceDisc); > Resources.Mod: GetDisc(dependant, dependantDisc); > Resources.Mod: GetDisc(resource, disc); > Resources.Mod: GetDisc(resource, disc); > Resources.Mod: GetDisc(resource, disc); > hacktar ulmoberonlib # > > like this: > > PROCEDURE GenEvent(resource: Resource; change: StateChange); > VAR > disc: Discipline; > event: Event; > BEGIN > GetDisc(resource, disc); > IF disc.eventType # NIL THEN > NEW(event); > event.type := disc.eventType; > event.message := "Resources: state change notification"; > event.change := change; > event.resource := resource; > Events.Raise(event); > END; > END GenEvent; > > PROCEDURE ^ Detach(resource: Resource; key: Key); > PROCEDURE Unlink(dependant, resource: Resource); > (* undo DependsOn operation *) > VAR > dependantDisc, resourceDisc: Discipline; > prev, member: List; > BEGIN > GetDisc(resource, resourceDisc); > IF resourceDisc.state = terminated THEN > (* no necessity for clean up *) > RETURN > END; > GetDisc(dependant, dependantDisc); > > prev := NIL; member := resourceDisc.dependants; > WHILE member.resource # dependant DO > prev := member; member := member.next; > END; > IF prev = NIL THEN > resourceDisc.dependants := member.next; > ELSE > prev.next := member.next; > END; > > (* Detach reference from dependant to resource *) > Detach(dependantDisc.dependsOn, dependantDisc.key); > dependantDisc.dependsOn := NIL; dependantDisc.key := NIL; > END Unlink; > > > PROCEDURE InternalNotify(resource: Resource; change: StateChange); > VAR > disc: Discipline; > event: Event; > dependant: List; > BEGIN > GetDisc(resource, disc); > CASE change OF > | communicationResumed: disc.stopped := FALSE; > | communicationStopped: disc.stopped := TRUE; > | terminated: disc.stopped := FALSE; disc.state := > terminated; > END; > GenEvent(resource, change); > > (* notify all dependants *) > dependant := disc.dependants; > WHILE dependant # NIL DO > InternalNotify(dependant.resource, change); > dependant := dependant.next; > END; > > (* remove dependency relation in case of termination, if present *) > IF (change = terminated) & (disc.dependsOn # NIL) THEN > Unlink(resource, disc.dependsOn); > END; > END InternalNotify; > > (* === exported procedures > =========================================== *) > > PROCEDURE TakeInterest*(resource: Resource; VAR eventType: > Events.EventType); > (* return resource specific event type for state notifications; > eventType is guaranteed to be # NIL even if > the given resource is already terminated > *) > VAR > disc: Discipline; > BEGIN > GetDisc(resource, disc); > IF disc.eventType = NIL THEN > Events.Define(disc.eventType); > Events.Ignore(disc.eventType); > END; > eventType := disc.eventType; > END TakeInterest; > > PROCEDURE Attach*(resource: Resource; VAR key: Key); > (* mark the resource as being used until Detach gets called *) > VAR > disc: Discipline; > BEGIN > GetDisc(resource, disc); > IF disc.state IN {terminated, unreferenced} THEN > key := NIL; > ELSE > INC(disc.refcnt); NEW(key); key.valid := TRUE; > key.resource := resource; > END; > END Attach; > > PROCEDURE Detach*(resource: Resource; key: Key); > (* mark the resource as unused; the returned key of Attach must > be given -- this allows to check for proper balances > of Attach/Detach calls; > the last Detach operation causes a state change to unreferenced > *) > VAR > disc: Discipline; > BEGIN > IF (key # NIL) & key.valid & (key.resource = resource) THEN > GetDisc(resource, disc); > IF disc.state # terminated THEN > key.valid := FALSE; DEC(disc.refcnt); > IF disc.refcnt = 0 THEN > GenEvent(resource, unreferenced); > disc.state := unreferenced; > IF disc.dependsOn # NIL THEN > Unlink(resource, disc.dependsOn); > END; > END; > END; > END; > END Detach; > > PROCEDURE Notify*(resource: Resource; change: StateChange); > (* notify all interested parties about the new state; > only valid state changes are accepted: > - Notify doesn't accept any changes after termination > - unreferenced is generated conditionally by Detach only > - communicationResumed is valid after communicationStopped only > valid notifications are propagated to all dependants (see below); > *) > VAR > disc: Discipline; > event: Event; > dependant: List; > BEGIN > IF change # unreferenced THEN > GetDisc(resource, disc); > IF (disc.state # terminated) & (disc.state # change) & > ((change # communicationResumed) OR disc.stopped) THEN > InternalNotify(resource, change); > END; > END; > END Notify; > > PROCEDURE DependsOn*(dependant, resource: Resource); > (* states that `dependant' depends entirely on `resource' -- > this is usually the case if operations on `dependant' > are delegated to `resource'; > only one call of DependsOn may be given per `dependant' while > several DependsOn for one resource are valid; > DependsOn calls implicitly Attach for resource and > detaches if the dependant becomes unreferenced; > all other state changes propagate from `resource' to > `dependant' > *) > VAR > dependantDisc, resourceDisc: Discipline; > member: List; > BEGIN > GetDisc(resource, resourceDisc); > IF resourceDisc.state <= unreferenced THEN > (* do not create a relationship to dead or unreferenced objects > but propagate a termination immediately to dependant > *) > IF resourceDisc.state = terminated THEN > Notify(dependant, resourceDisc.state); > END; > RETURN > END; > > GetDisc(dependant, dependantDisc); > IF dependantDisc.dependsOn # NIL THEN > (* don't accept changes *) > RETURN > END; > dependantDisc.dependsOn := resource; > > NEW(member); member.resource := dependant; > member.next := resourceDisc.dependants; > resourceDisc.dependants := member; > Attach(resource, dependantDisc.key); > END DependsOn; > > PROCEDURE Alive*(resource: Resource) : BOOLEAN; > (* returns TRUE if the resource is not yet terminated > and ready for communication (i.e. not communicationStopped) > *) > VAR > disc: Discipline; > BEGIN > GetDisc(resource, disc); > RETURN ~disc.stopped & (disc.state IN {alive, unreferenced}) > END Alive; > > PROCEDURE Stopped*(resource: Resource) : BOOLEAN; > (* returns TRUE if the object is currently not responsive > and not yet terminated > *) > VAR > disc: Discipline; > BEGIN > GetDisc(resource, disc); > RETURN disc.stopped > END Stopped; > > PROCEDURE Terminated*(resource: Resource) : BOOLEAN; > (* returns TRUE if the resource is terminated *) > VAR > disc: Discipline; > BEGIN > GetDisc(resource, disc); > RETURN disc.state = terminated > END Terminated; > > BEGIN > discID := Disciplines.Unique(); > END Resources. > > > > And we have module Disciplines: > > > MODULE Disciplines; > > (* Disciplines allows to attach additional data structures to > abstract datatypes like Streams; > these added data structures permit to parametrize operations > which are provided by other modules (e.g. Read or Write for Streams) > *) > > IMPORT Objects; > > TYPE > Identifier* = LONGINT; > > Discipline* = POINTER TO DisciplineRec; > DisciplineRec* = > RECORD > (Objects.ObjectRec) > id*: Identifier; (* should be unique for all types of > disciplines *) > END; > > DisciplineList = POINTER TO DisciplineListRec; > DisciplineListRec = > RECORD > discipline: Discipline; > id: Identifier; (* copied from discipline.id > <http://discipline.id> *) > next: DisciplineList; > END; > > Object* = POINTER TO ObjectRec; > ObjectRec* = > RECORD > (Objects.ObjectRec) > (* private part *) > list: DisciplineList; (* set of disciplines *) > END; > > ... > > PROCEDURE Seek*(object: Object; id: Identifier; > VAR discipline: Discipline) : BOOLEAN; > (* returns TRUE if a discipline with the given id is found *) > VAR > dl: DisciplineList; > BEGIN > dl := object.list; > WHILE (dl # NIL) & (dl.id <http://dl.id> # id) DO > dl := dl.next; > END; > IF dl # NIL THEN > discipline := dl.discipline; > ELSE > discipline := NIL; > END; > RETURN discipline # NIL > END Seek; > > If I change PROCEDURE GetDisc(resource: Resource; VAR disc: Discipline); > to > PROCEDURE GetDisc(resource: Resource; VAR disc: Disciplines.Discipline); > Then this code: > IF ~Disciplines.Seek(resource, discID, (*disctmp*)disc) THEN > NEW(disc); disc.id <http://disc.id> := discID; > disc.state := alive; disc.refcnt := 0; > disc.eventType := NIL; > disc.dependants := NIL; disc.dependsOn := NIL; > Disciplines.Add(resource, disc); > END; > will not work. > > If I use local tmpdisc, assign tmpdisc.id <http://tmpdisc.id> := disc.id > <http://disc.id> and pass it instead, > I anyway have to assign back pointer disc := tmpdisc which is not > allowed, and this is not an optimal solution as well. > > Any idea? > Thank you. > > On Wed, Oct 6, 2010 at 7:24 AM, Stewart Greenhill > <sgr...@ii... <mailto:sgr...@ii...>> wrote: > > Hi Norayr, > > I think the restriction is correct. > > This can be confusing, but think of it like this: if your parameter > is declared "aaa(VAR p : T1)" then it means the procedure can write > ANY value of type T1 to p. Sure, T2 is a subtype of T1 but there are > other subtypes of T1 which are not also T2. It would be an error for > the compiler to allow aaa(p2) because you could then assign > something to p2 which is not a subtype of T2. For example: > > > PROCEDURE aaa (VAR p : T1); > BEGIN > NEW(p); (* assign new instance of T1 to p *) > END aaa; > > Now, allowing aaa(p2) would break the type system. > > Its hard to say how to best handle this without knowing some more > details of what you're trying to do. This sort of pattern could work: > > VAR > p1 : T1; > ... > p1 := NEW(T2); > aaa(p1); > > Cheers, > Stewart > > > On 6/10/10 1:18 AM, Norayr Chilingaryan wrote: > > Hello, yet another question which came out during library porting > work. > > MODULE test2; > > > > TYPE T1 = POINTER TO TRec; > > TRec = RECORD > > a : INTEGER > > END; > > > > TYPE T2 = POINTER TO T2Rec; > > T2Rec = RECORD (TRec) > > b : REAL > > END; > > VAR p1 : T1; > > p2 : T2; > > > > PROCEDURE aaa (VAR p : T1); > > BEGIN > > > > END aaa; > > > > BEGIN > > p2 := NEW(T2); > > p1 := NEW(T1); > > aaa(p2); > > > > END test2. > > > > So, this won't compile unless: > > we change procedure to PROCEDURE aaa (p : T1); i. e. without VAR > > or > > pointer passed to the procedure is not a pointer to the extended > type, > > so aaa(p1) will work. > > > > Are that restrictions intentional? > > What would be an optimal (or nicer) workaround to solve this if I > need > > to compile library which have been written like this. > > > > Thank you > > Norayr > [...] > > > > > ------------------------------------------------------------------------------ > Beautiful is writing same markup. Internet Explorer 9 supports > standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2& L3. > Spend less time writing and rewriting code and more time creating great > experiences on the web. Be a part of the beta today. > http://p.sf.net/sfu/beautyoftheweb > > > > _______________________________________________ > ooc-compiler mailing list > ooc...@li... > https://lists.sourceforge.net/lists/listinfo/ooc-compiler |
|
From: Norayr C. <ch...@gm...> - 2010-10-06 21:46:54
|
Hey,
thank you for reply.
ok, I see, indeed.
So, here we have Resources.Mod from Ulm's Oberon LIbrary which contains:
TYPE
List = POINTER TO ListRec;
ListRec =
RECORD
resource: Resource;
next: List;
END;
Discipline = POINTER TO DisciplineRec;
DisciplineRec =
RECORD
(Disciplines.DisciplineRec)
state: State; (* alive, unreferenced, or terminated *)
stopped: BOOLEAN; (* may be TRUE, if alive or unreferenced *)
refcnt: LONGINT; (* # of Attach - # of Detach *)
eventType: Events.EventType; (* may be NIL *)
dependants: List; (* list of resources which depends on us *)
dependsOn: Resource; (* we depend on this resource *)
key: Key; (* attach key for dependsOn *)
END;
...
PROCEDURE GetDisc(resource: Resource; VAR disc: Discipline);
BEGIN
IF ~Disciplines.Seek(resource, discID, disc) THEN
NEW(disc); disc.id := discID;
disc.state := alive; disc.refcnt := 0;
disc.eventType := NIL;
disc.dependants := NIL; disc.dependsOn := NIL;
Disciplines.Add(resource, disc);
END;
END GetDisc;
Procedure GetDisc is called a lot of times:
hacktar ulmoberonlib # grep GetDisc *
Resources.Mod: PROCEDURE GetDisc(resource: Resource; VAR disc:
Discipline);
Resources.Mod: END GetDisc;
Resources.Mod: GetDisc(resource, disc);
Resources.Mod: GetDisc(resource, resourceDisc);
Resources.Mod: GetDisc(dependant, dependantDisc);
Resources.Mod: GetDisc(resource, disc);
Resources.Mod: GetDisc(resource, disc);
Resources.Mod: GetDisc(resource, disc);
Resources.Mod: GetDisc(resource, disc);
Resources.Mod: GetDisc(resource, disc);
Resources.Mod: GetDisc(resource, resourceDisc);
Resources.Mod: GetDisc(dependant, dependantDisc);
Resources.Mod: GetDisc(resource, disc);
Resources.Mod: GetDisc(resource, disc);
Resources.Mod: GetDisc(resource, disc);
hacktar ulmoberonlib #
like this:
PROCEDURE GenEvent(resource: Resource; change: StateChange);
VAR
disc: Discipline;
event: Event;
BEGIN
GetDisc(resource, disc);
IF disc.eventType # NIL THEN
NEW(event);
event.type := disc.eventType;
event.message := "Resources: state change notification";
event.change := change;
event.resource := resource;
Events.Raise(event);
END;
END GenEvent;
PROCEDURE ^ Detach(resource: Resource; key: Key);
PROCEDURE Unlink(dependant, resource: Resource);
(* undo DependsOn operation *)
VAR
dependantDisc, resourceDisc: Discipline;
prev, member: List;
BEGIN
GetDisc(resource, resourceDisc);
IF resourceDisc.state = terminated THEN
(* no necessity for clean up *)
RETURN
END;
GetDisc(dependant, dependantDisc);
prev := NIL; member := resourceDisc.dependants;
WHILE member.resource # dependant DO
prev := member; member := member.next;
END;
IF prev = NIL THEN
resourceDisc.dependants := member.next;
ELSE
prev.next := member.next;
END;
(* Detach reference from dependant to resource *)
Detach(dependantDisc.dependsOn, dependantDisc.key);
dependantDisc.dependsOn := NIL; dependantDisc.key := NIL;
END Unlink;
PROCEDURE InternalNotify(resource: Resource; change: StateChange);
VAR
disc: Discipline;
event: Event;
dependant: List;
BEGIN
GetDisc(resource, disc);
CASE change OF
| communicationResumed: disc.stopped := FALSE;
| communicationStopped: disc.stopped := TRUE;
| terminated: disc.stopped := FALSE; disc.state :=
terminated;
END;
GenEvent(resource, change);
(* notify all dependants *)
dependant := disc.dependants;
WHILE dependant # NIL DO
InternalNotify(dependant.resource, change);
dependant := dependant.next;
END;
(* remove dependency relation in case of termination, if present *)
IF (change = terminated) & (disc.dependsOn # NIL) THEN
Unlink(resource, disc.dependsOn);
END;
END InternalNotify;
(* === exported procedures =========================================== *)
PROCEDURE TakeInterest*(resource: Resource; VAR eventType:
Events.EventType);
(* return resource specific event type for state notifications;
eventType is guaranteed to be # NIL even if
the given resource is already terminated
*)
VAR
disc: Discipline;
BEGIN
GetDisc(resource, disc);
IF disc.eventType = NIL THEN
Events.Define(disc.eventType);
Events.Ignore(disc.eventType);
END;
eventType := disc.eventType;
END TakeInterest;
PROCEDURE Attach*(resource: Resource; VAR key: Key);
(* mark the resource as being used until Detach gets called *)
VAR
disc: Discipline;
BEGIN
GetDisc(resource, disc);
IF disc.state IN {terminated, unreferenced} THEN
key := NIL;
ELSE
INC(disc.refcnt); NEW(key); key.valid := TRUE;
key.resource := resource;
END;
END Attach;
PROCEDURE Detach*(resource: Resource; key: Key);
(* mark the resource as unused; the returned key of Attach must
be given -- this allows to check for proper balances
of Attach/Detach calls;
the last Detach operation causes a state change to unreferenced
*)
VAR
disc: Discipline;
BEGIN
IF (key # NIL) & key.valid & (key.resource = resource) THEN
GetDisc(resource, disc);
IF disc.state # terminated THEN
key.valid := FALSE; DEC(disc.refcnt);
IF disc.refcnt = 0 THEN
GenEvent(resource, unreferenced);
disc.state := unreferenced;
IF disc.dependsOn # NIL THEN
Unlink(resource, disc.dependsOn);
END;
END;
END;
END;
END Detach;
PROCEDURE Notify*(resource: Resource; change: StateChange);
(* notify all interested parties about the new state;
only valid state changes are accepted:
- Notify doesn't accept any changes after termination
- unreferenced is generated conditionally by Detach only
- communicationResumed is valid after communicationStopped only
valid notifications are propagated to all dependants (see below);
*)
VAR
disc: Discipline;
event: Event;
dependant: List;
BEGIN
IF change # unreferenced THEN
GetDisc(resource, disc);
IF (disc.state # terminated) & (disc.state # change) &
((change # communicationResumed) OR disc.stopped) THEN
InternalNotify(resource, change);
END;
END;
END Notify;
PROCEDURE DependsOn*(dependant, resource: Resource);
(* states that `dependant' depends entirely on `resource' --
this is usually the case if operations on `dependant'
are delegated to `resource';
only one call of DependsOn may be given per `dependant' while
several DependsOn for one resource are valid;
DependsOn calls implicitly Attach for resource and
detaches if the dependant becomes unreferenced;
all other state changes propagate from `resource' to
`dependant'
*)
VAR
dependantDisc, resourceDisc: Discipline;
member: List;
BEGIN
GetDisc(resource, resourceDisc);
IF resourceDisc.state <= unreferenced THEN
(* do not create a relationship to dead or unreferenced objects
but propagate a termination immediately to dependant
*)
IF resourceDisc.state = terminated THEN
Notify(dependant, resourceDisc.state);
END;
RETURN
END;
GetDisc(dependant, dependantDisc);
IF dependantDisc.dependsOn # NIL THEN
(* don't accept changes *)
RETURN
END;
dependantDisc.dependsOn := resource;
NEW(member); member.resource := dependant;
member.next := resourceDisc.dependants;
resourceDisc.dependants := member;
Attach(resource, dependantDisc.key);
END DependsOn;
PROCEDURE Alive*(resource: Resource) : BOOLEAN;
(* returns TRUE if the resource is not yet terminated
and ready for communication (i.e. not communicationStopped)
*)
VAR
disc: Discipline;
BEGIN
GetDisc(resource, disc);
RETURN ~disc.stopped & (disc.state IN {alive, unreferenced})
END Alive;
PROCEDURE Stopped*(resource: Resource) : BOOLEAN;
(* returns TRUE if the object is currently not responsive
and not yet terminated
*)
VAR
disc: Discipline;
BEGIN
GetDisc(resource, disc);
RETURN disc.stopped
END Stopped;
PROCEDURE Terminated*(resource: Resource) : BOOLEAN;
(* returns TRUE if the resource is terminated *)
VAR
disc: Discipline;
BEGIN
GetDisc(resource, disc);
RETURN disc.state = terminated
END Terminated;
BEGIN
discID := Disciplines.Unique();
END Resources.
And we have module Disciplines:
MODULE Disciplines;
(* Disciplines allows to attach additional data structures to
abstract datatypes like Streams;
these added data structures permit to parametrize operations
which are provided by other modules (e.g. Read or Write for Streams)
*)
IMPORT Objects;
TYPE
Identifier* = LONGINT;
Discipline* = POINTER TO DisciplineRec;
DisciplineRec* =
RECORD
(Objects.ObjectRec)
id*: Identifier; (* should be unique for all types of disciplines *)
END;
DisciplineList = POINTER TO DisciplineListRec;
DisciplineListRec =
RECORD
discipline: Discipline;
id: Identifier; (* copied from discipline.id *)
next: DisciplineList;
END;
Object* = POINTER TO ObjectRec;
ObjectRec* =
RECORD
(Objects.ObjectRec)
(* private part *)
list: DisciplineList; (* set of disciplines *)
END;
...
PROCEDURE Seek*(object: Object; id: Identifier;
VAR discipline: Discipline) : BOOLEAN;
(* returns TRUE if a discipline with the given id is found *)
VAR
dl: DisciplineList;
BEGIN
dl := object.list;
WHILE (dl # NIL) & (dl.id # id) DO
dl := dl.next;
END;
IF dl # NIL THEN
discipline := dl.discipline;
ELSE
discipline := NIL;
END;
RETURN discipline # NIL
END Seek;
If I change PROCEDURE GetDisc(resource: Resource; VAR disc: Discipline);
to
PROCEDURE GetDisc(resource: Resource; VAR disc: Disciplines.Discipline);
Then this code:
IF ~Disciplines.Seek(resource, discID, (*disctmp*)disc) THEN
NEW(disc); disc.id := discID;
disc.state := alive; disc.refcnt := 0;
disc.eventType := NIL;
disc.dependants := NIL; disc.dependsOn := NIL;
Disciplines.Add(resource, disc);
END;
will not work.
If I use local tmpdisc, assign tmpdisc.id := disc.id and pass it instead,
I anyway have to assign back pointer disc := tmpdisc which is not allowed,
and this is not an optimal solution as well.
Any idea?
Thank you.
On Wed, Oct 6, 2010 at 7:24 AM, Stewart Greenhill
<sgr...@ii...>wrote:
> Hi Norayr,
>
> I think the restriction is correct.
>
> This can be confusing, but think of it like this: if your parameter is
> declared "aaa(VAR p : T1)" then it means the procedure can write ANY value
> of type T1 to p. Sure, T2 is a subtype of T1 but there are other subtypes of
> T1 which are not also T2. It would be an error for the compiler to allow
> aaa(p2) because you could then assign something to p2 which is not a subtype
> of T2. For example:
>
>
> PROCEDURE aaa (VAR p : T1);
> BEGIN
> NEW(p); (* assign new instance of T1 to p *)
> END aaa;
>
> Now, allowing aaa(p2) would break the type system.
>
> Its hard to say how to best handle this without knowing some more details
> of what you're trying to do. This sort of pattern could work:
>
> VAR
> p1 : T1;
> ...
> p1 := NEW(T2);
> aaa(p1);
>
> Cheers,
> Stewart
>
>
> On 6/10/10 1:18 AM, Norayr Chilingaryan wrote:
> > Hello, yet another question which came out during library porting work.
> > MODULE test2;
> >
> > TYPE T1 = POINTER TO TRec;
> > TRec = RECORD
> > a : INTEGER
> > END;
> >
> > TYPE T2 = POINTER TO T2Rec;
> > T2Rec = RECORD (TRec)
> > b : REAL
> > END;
> > VAR p1 : T1;
> > p2 : T2;
> >
> > PROCEDURE aaa (VAR p : T1);
> > BEGIN
> >
> > END aaa;
> >
> > BEGIN
> > p2 := NEW(T2);
> > p1 := NEW(T1);
> > aaa(p2);
> >
> > END test2.
> >
> > So, this won't compile unless:
> > we change procedure to PROCEDURE aaa (p : T1); i. e. without VAR
> > or
> > pointer passed to the procedure is not a pointer to the extended type,
> > so aaa(p1) will work.
> >
> > Are that restrictions intentional?
> > What would be an optimal (or nicer) workaround to solve this if I need
> > to compile library which have been written like this.
> >
> > Thank you
> > Norayr
> [...]
>
>
|
|
From: Stewart G. <sgr...@ii...> - 2010-10-06 02:24:15
|
Hi Norayr, I think the restriction is correct. This can be confusing, but think of it like this: if your parameter is declared "aaa(VAR p : T1)" then it means the procedure can write ANY value of type T1 to p. Sure, T2 is a subtype of T1 but there are other subtypes of T1 which are not also T2. It would be an error for the compiler to allow aaa(p2) because you could then assign something to p2 which is not a subtype of T2. For example: PROCEDURE aaa (VAR p : T1); BEGIN NEW(p); (* assign new instance of T1 to p *) END aaa; Now, allowing aaa(p2) would break the type system. Its hard to say how to best handle this without knowing some more details of what you're trying to do. This sort of pattern could work: VAR p1 : T1; ... p1 := NEW(T2); aaa(p1); Cheers, Stewart On 6/10/10 1:18 AM, Norayr Chilingaryan wrote: > Hello, yet another question which came out during library porting work. > MODULE test2; > > TYPE T1 = POINTER TO TRec; > TRec = RECORD > a : INTEGER > END; > > TYPE T2 = POINTER TO T2Rec; > T2Rec = RECORD (TRec) > b : REAL > END; > VAR p1 : T1; > p2 : T2; > > PROCEDURE aaa (VAR p : T1); > BEGIN > > END aaa; > > BEGIN > p2 := NEW(T2); > p1 := NEW(T1); > aaa(p2); > > END test2. > > So, this won't compile unless: > we change procedure to PROCEDURE aaa (p : T1); i. e. without VAR > or > pointer passed to the procedure is not a pointer to the extended type, > so aaa(p1) will work. > > Are that restrictions intentional? > What would be an optimal (or nicer) workaround to solve this if I need > to compile library which have been written like this. > > Thank you > Norayr [...] |
|
From: Norayr C. <ch...@gm...> - 2010-10-05 17:18:45
|
Hello, yet another question which came out during library porting work.
MODULE test2;
TYPE T1 = POINTER TO TRec;
TRec = RECORD
a : INTEGER
END;
TYPE T2 = POINTER TO T2Rec;
T2Rec = RECORD (TRec)
b : REAL
END;
VAR p1 : T1;
p2 : T2;
PROCEDURE aaa (VAR p : T1);
BEGIN
END aaa;
BEGIN
p2 := NEW(T2);
p1 := NEW(T1);
aaa(p2);
END test2.
So, this won't compile unless:
we change procedure to PROCEDURE aaa (p : T1); i. e. without VAR
or
pointer passed to the procedure is not a pointer to the extended type, so
aaa(p1) will work.
Are that restrictions intentional?
What would be an optimal (or nicer) workaround to solve this if I need to
compile library which have been written like this.
Thank you
Norayr
On Tue, Oct 5, 2010 at 6:54 AM, Stewart Greenhill
<sgr...@us...>wrote:
> Hi Norayr,
>
> Normally, you would to a LONGINT->INTEGER conversion like this:
> RETURN SHORT(int);
>
> Personally I'm not a fan of SHORT. It requires you to know the size of the
> original types in order to figure out how many SHORTs are required to do the
> conversion. So a LONGINT -> SHORTINT conversion goes:
> RETURN SHORT(SHORT(int));
> ...but you can't for example convert an arbitrary integer type to a
> SHORTINT.
>
> It looks like OOC's interpretation of SYSTEM.VAL requires it to be a pure
> type-cast. Normally you would use it like this for casting pointer types.
> You would need to explicitly SHORTen the argument if casting to a smaller
> size. Since conversion between numeric types is supported in the language
> anyway its probably not a big problem.
>
> Cheers,
> Stewart
>
>
> On 5/10/10 3:19 AM, Norayr Chilingaryan wrote:
>
>> MODULE test;
>> IMPORT SYSTEM;
>> PROCEDURE ToInt16*(int: LONGINT) : INTEGER;
>> BEGIN
>> RETURN SYSTEM.VAL(INTEGER, int)
>> END ToInt16;
>>
>>
>> END test.
>>
>> test.Mod:5:32: Size mismatch between type and expression
>>
>> Is it normal behavour to not permit LONGINT->INTEGER cast?
>> I am still translating Types.Mod from Ulm library.
>> Types.Mod contains type conversions. It is supposed that people will use
>> Types exported functions like ToInt16, ToInt32 instead of importing
>> SYSTEM and use VAL in their higher level modules.
>>
>> This is why I have this question.
>> In Ulm's compiler, according to the docs:
>> *VAL* allows a large number of system-dependent type conversions. It
>> permits any numerical type to be converted to any other numerical type.
>> Other type conversions are supported only if both, type and the type of
>> value, occupy the same number of bytes.
>> However, Wirth report states:
>>
>> Name |Argument types |Result type|Function
>>
>> _________|________________________|_____________|____________________________
>>
>> VAL(T,x)|T,x: any type |T |x interpreted as of typeT
>>
>> ooc's reference manual for SYSTEM module is incomplete.
>>
>> Sincerely,
>> Norayr
>>
>> On Mon, Oct 4, 2010 at 6:53 AM, Stewart Greenhill
>> <sgr...@us... <mailto:sgr...@us...>> wrote:
>>
>> Hi Norayr,
>>
>> On 2/10/10 5:42 AM, Norayr Chilingaryan wrote:
>> [...]
>>
>> So, is it possible in principle to create a VAL wrapper, by
>> taking in
>> consideration that it is implemented on the compiler level
>> actually.
>> Usually, modules in Ulm's library import SYSTEM by using SYS
>> alias, like
>> this:
>> IMPORT SYS:=SYSTEM
>> which I replace by SYS := ULMSYSTEM
>> It is of course possible to change every occurence of SYS.VAL by
>> the
>> SYSTEM.VAL, but I consider it as a dirty option.
>> It is also possible to wrap VAL by using C implementation, what
>> I also
>> would like to avoid for now.
>>
>>
>> You can't wrap the SYSTEM.VAL function because it is implemented in
>> the compiler. There's no way to pass type parameters to Oberon-2
>> procedures; although OOC supports generics, this only works for
>> Object types. I think the solution you suggested is probably the
>> best option, though as you say it is not ideal.
>>
>> Cheers,
>> Stewart
>>
>>
>>
>>
>>
>> ------------------------------------------------------------------------------
>> Virtualization is moving to the mainstream and overtaking non-virtualized
>> environment for deploying applications. Does it make network security
>> easier or more difficult to achieve? Read this whitepaper to separate the
>> two and get a better understanding.
>> http://p.sf.net/sfu/hp-phase2-d2d
>>
>>
>>
>> _______________________________________________
>> ooc-compiler mailing list
>> ooc...@li...
>> https://lists.sourceforge.net/lists/listinfo/ooc-compiler
>>
>
>
|
|
From: Stewart G. <sgr...@us...> - 2010-10-05 01:55:12
|
Hi Norayr, Normally, you would to a LONGINT->INTEGER conversion like this: RETURN SHORT(int); Personally I'm not a fan of SHORT. It requires you to know the size of the original types in order to figure out how many SHORTs are required to do the conversion. So a LONGINT -> SHORTINT conversion goes: RETURN SHORT(SHORT(int)); ...but you can't for example convert an arbitrary integer type to a SHORTINT. It looks like OOC's interpretation of SYSTEM.VAL requires it to be a pure type-cast. Normally you would use it like this for casting pointer types. You would need to explicitly SHORTen the argument if casting to a smaller size. Since conversion between numeric types is supported in the language anyway its probably not a big problem. Cheers, Stewart On 5/10/10 3:19 AM, Norayr Chilingaryan wrote: > MODULE test; > IMPORT SYSTEM; > PROCEDURE ToInt16*(int: LONGINT) : INTEGER; > BEGIN > RETURN SYSTEM.VAL(INTEGER, int) > END ToInt16; > > > END test. > > test.Mod:5:32: Size mismatch between type and expression > > Is it normal behavour to not permit LONGINT->INTEGER cast? > I am still translating Types.Mod from Ulm library. > Types.Mod contains type conversions. It is supposed that people will use > Types exported functions like ToInt16, ToInt32 instead of importing > SYSTEM and use VAL in their higher level modules. > > This is why I have this question. > In Ulm's compiler, according to the docs: > *VAL* allows a large number of system-dependent type conversions. It > permits any numerical type to be converted to any other numerical type. > Other type conversions are supported only if both, type and the type of > value, occupy the same number of bytes. > However, Wirth report states: > > Name |Argument types |Result type|Function > _________|________________________|_____________|____________________________ > > VAL(T,x)|T,x: any type |T |x interpreted as of typeT > > ooc's reference manual for SYSTEM module is incomplete. > > Sincerely, > Norayr > > On Mon, Oct 4, 2010 at 6:53 AM, Stewart Greenhill > <sgr...@us... <mailto:sgr...@us...>> wrote: > > Hi Norayr, > > On 2/10/10 5:42 AM, Norayr Chilingaryan wrote: > [...] > > So, is it possible in principle to create a VAL wrapper, by > taking in > consideration that it is implemented on the compiler level actually. > Usually, modules in Ulm's library import SYSTEM by using SYS > alias, like > this: > IMPORT SYS:=SYSTEM > which I replace by SYS := ULMSYSTEM > It is of course possible to change every occurence of SYS.VAL by the > SYSTEM.VAL, but I consider it as a dirty option. > It is also possible to wrap VAL by using C implementation, what > I also > would like to avoid for now. > > > You can't wrap the SYSTEM.VAL function because it is implemented in > the compiler. There's no way to pass type parameters to Oberon-2 > procedures; although OOC supports generics, this only works for > Object types. I think the solution you suggested is probably the > best option, though as you say it is not ideal. > > Cheers, > Stewart > > > > > ------------------------------------------------------------------------------ > Virtualization is moving to the mainstream and overtaking non-virtualized > environment for deploying applications. Does it make network security > easier or more difficult to achieve? Read this whitepaper to separate the > two and get a better understanding. > http://p.sf.net/sfu/hp-phase2-d2d > > > > _______________________________________________ > ooc-compiler mailing list > ooc...@li... > https://lists.sourceforge.net/lists/listinfo/ooc-compiler |
|
From: Norayr C. <ch...@gm...> - 2010-10-04 19:20:00
|
MODULE test;
IMPORT SYSTEM;
PROCEDURE ToInt16*(int: LONGINT) : INTEGER;
BEGIN
RETURN SYSTEM.VAL(INTEGER, int)
END ToInt16;
END test.
test.Mod:5:32: Size mismatch between type and expression
Is it normal behavour to not permit LONGINT->INTEGER cast?
I am still translating Types.Mod from Ulm library.
Types.Mod contains type conversions. It is supposed that people will use
Types exported functions like ToInt16, ToInt32 instead of importing SYSTEM
and use VAL in their higher level modules.
This is why I have this question.
In Ulm's compiler, according to the docs:
*VAL* allows a large number of system-dependent type conversions. It permits
any numerical type to be converted to any other numerical type. Other type
conversions are supported only if both, type and the type of value, occupy
the same number of bytes.
However, Wirth report states:
Name | Argument types | Result type| Function
_________|________________________|_____________|____________________________
VAL(T, x)| T, x: any type | T | x interpreted as of type T
ooc's reference manual for SYSTEM module is incomplete.
Sincerely,
Norayr
On Mon, Oct 4, 2010 at 6:53 AM, Stewart Greenhill
<sgr...@us...>wrote:
> Hi Norayr,
>
> On 2/10/10 5:42 AM, Norayr Chilingaryan wrote:
> [...]
>
> So, is it possible in principle to create a VAL wrapper, by taking in
>> consideration that it is implemented on the compiler level actually.
>> Usually, modules in Ulm's library import SYSTEM by using SYS alias, like
>> this:
>> IMPORT SYS:=SYSTEM
>> which I replace by SYS := ULMSYSTEM
>> It is of course possible to change every occurence of SYS.VAL by the
>> SYSTEM.VAL, but I consider it as a dirty option.
>> It is also possible to wrap VAL by using C implementation, what I also
>> would like to avoid for now.
>>
>
> You can't wrap the SYSTEM.VAL function because it is implemented in the
> compiler. There's no way to pass type parameters to Oberon-2 procedures;
> although OOC supports generics, this only works for Object types. I think
> the solution you suggested is probably the best option, though as you say it
> is not ideal.
>
> Cheers,
> Stewart
>
|
|
From: Stewart G. <sgr...@us...> - 2010-10-04 02:23:05
|
Hi Norayr, On 2/10/10 5:42 AM, Norayr Chilingaryan wrote: [...] > So, is it possible in principle to create a VAL wrapper, by taking in > consideration that it is implemented on the compiler level actually. > Usually, modules in Ulm's library import SYSTEM by using SYS alias, like > this: > IMPORT SYS:=SYSTEM > which I replace by SYS := ULMSYSTEM > It is of course possible to change every occurence of SYS.VAL by the > SYSTEM.VAL, but I consider it as a dirty option. > It is also possible to wrap VAL by using C implementation, what I also > would like to avoid for now. You can't wrap the SYSTEM.VAL function because it is implemented in the compiler. There's no way to pass type parameters to Oberon-2 procedures; although OOC supports generics, this only works for Object types. I think the solution you suggested is probably the best option, though as you say it is not ideal. Cheers, Stewart |
|
From: Duke N. <duk...@ml...> - 2010-10-01 23:00:49
|
On Sat, 2 Oct 2010, Norayr Chilingaryan wrote: Hello Norayr [snip] > Any ideas, Stewart? (or anybody besides you still read this mail list?) No ideas! I'm an Oberon noob. However I'll be listening in with much interest. Also now we know that there's at least 2 of us reading this list :) L8r... -- Duke |
|
From: Norayr C. <ch...@gm...> - 2010-10-01 21:42:18
|
Hey, I am porting Ulm's Oberon Library to use with ooc. All separate definition/implementation modules are already merged, and I have managed to compile some set of modules. Every occurence of INTEGER also must be changed to the LONGINT. I don't deal with it now, because LONGINT in Ulm's system also may be used as an ADDRESS, so, I would like to review every occurence and change it according to the context later. So, most important parts of the library use the SYSTEM module described here: http://www.mathematik.uni-ulm.de/oberon/current/lib/man/SYSTEM.html and SYSTEM.UNIXCALL calls. I have created a wrapper module ULMSYSTEM.Mod, which currently has the following state: MODULE ULMSYSTEM; (* Norayr Chilingaryan, 2010 This module is a wrapper which emulates SYSTEM module of Ulm's Oberon Library *) IMPORT SYSTEM; TYPE INT16* = INTEGER (*oo2c's INTEGER is 2 bytes long, norayr*) (* 2-byte integer type *); TYPE ADDRESS* = SYSTEM.ADDRESS (*in oo2c SYSTEM.ADDRESS is 4 bytes long on 32bit systems and 8 bytes long on 64bit systems, norayr *) (* LONGINT-compatible & traced by the GC *); TYPE UNTRACEDADDRESS* = SYSTEM.ADDRESS (* see above line, norayr *)(* LONGINT-compatible & ignored by the GC *); TYPE BYTE* = SYSTEM.BYTE; (* added by me because of existence of BYTE in ULMs library. For instance, needed by Types.Mod, norayr *) PROCEDURE TAS*(VAR flag : BOOLEAN): BOOLEAN; VAR tmpfl: BOOLEAN; BEGIN tmpfl := flag; flag := TRUE; RETURN tmpfl END TAS; PROCEDURE VAL*(type: AnyTypeName; value: AnyType) : type; BEGIN RETURN SYSTEM.VAL(type, value); END VAL; END ULMSYSTEM. So, is it possible in principle to create a VAL wrapper, by taking in consideration that it is implemented on the compiler level actually. Usually, modules in Ulm's library import SYSTEM by using SYS alias, like this: IMPORT SYS:=SYSTEM which I replace by SYS := ULMSYSTEM It is of course possible to change every occurence of SYS.VAL by the SYSTEM.VAL, but I consider it as a dirty option. It is also possible to wrap VAL by using C implementation, what I also would like to avoid for now. Any ideas, Stewart? (or anybody besides you still read this mail list?) Sincerely, Norayr |
|
From: Duke N. <duk...@ml...> - 2010-08-05 01:24:02
|
Just a quick note of thanks to all the oo2c gurus on this for their advise and recommendations and suggestions concerning the building of oo2c on my Xubuntu box. I am now the proud owner of a clean oo2c build and install! Much appreciated... -- Duke |
|
From: Frank H. <hr...@te...> - 2010-08-04 12:18:28
|
On 08/03/2010 04:38 AM, Riza Dindir wrote: > What I suspect is that the initialization/copying done by the > OOC_INITIALIZE_VPAR, OOC_ALLOCATE_VPAR pair is not correct. > If the above code works, then the problem would be in those > OOC_* calls (they might be macros). > > If you would not mind, could you please do this change and > test? Hi Riza, I seems Stewart has solved the puzzle. Thanks for your help, -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil |
|
From: Frank H. <hr...@te...> - 2010-08-04 12:15:45
|
On 08/03/2010 10:29 PM, Stewart Greenhill wrote: > I'm not sure what to recommend here. Obviously care should be taken with > this version of GCC. The fact that OOC builds itself fine indicates that > the problem is probably fairly rare. For efficiency, you would normally > pass records by reference anyway. I think gcc has decided to eliminate > the call to memcpy because it thinks the result is unused. When I added > a printf statement (list[0].first) after the OOC_INITIALIZE_VPAR the > problem went away. I expect that for non-trivial code its much less > likely to occur. If you want to be perfectly safe you could run oo2c > without optimization, or see if the problem is resolved in later > versions of gcc. Wow, I didn't expect you to dive downto assembler level. My personal choice is to leave the code as it is (a little bit less efficient but clearer) and switch off optimization. The last step in program development (completion, a state which my toy programs hardly ever reach) could then be optimization. Does it make sense to inform the gcc developers about the case? (I don't care about the actual restriction, just for the sake of free software code quality). Thank you a lot for your help. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil |
|
From: Duke N. <duk...@ml...> - 2010-08-04 04:21:52
|
On Wed, 4 Aug 2010, Stewart Greenhill wrote: > Duke Normandin wrote: > > On Wed, 4 Aug 2010, Alexander Elkhovskiy wrote: > > > > > Duke, > > > > > > try to use an older version of gc, 6.8 for example. > > > > Do I have to un-install the version of `gc' that I just installed? Or > > will installing the older version simply "overwrite" the newer one? > > Hi Duke, > > It will probably work to just overwrite the old one. I removed the files > created in the include directory: "gc", "gc_*.h" and "leak_detector.h" before > installing the new version, but the same files were recreated anyway. > Hey Stewart.... Thanks for the tip. It looks like its a "6 of one - half a dozen of the other" type of thing. I'll leave it alone, and let it get overwritten, and see what happens. Thanks for your guidance! BTW, would you mind if I contacted you off-lists to ask your opinion on an Oberon-related (but OT to this list) question? -- Duke |
|
From: Stewart G. <sgr...@ii...> - 2010-08-04 03:39:41
|
Duke Normandin wrote: > On Wed, 4 Aug 2010, Alexander Elkhovskiy wrote: > >> Duke, >> >> try to use an older version of gc, 6.8 for example. > > Do I have to un-install the version of `gc' that I just installed? Or > will installing the older version simply "overwrite" the newer one? Hi Duke, It will probably work to just overwrite the old one. I removed the files created in the include directory: "gc", "gc_*.h" and "leak_detector.h" before installing the new version, but the same files were recreated anyway. Cheers, Stewart |
|
From: Stewart G. <sgr...@ii...> - 2010-08-04 03:30:25
|
> On Wed, Jul 28, 2010 at 10:58 PM, Stewart Greenhill > <sgr...@ii...> wrote: >> It looks like there is quite a trend these days towards interpreted, >> dynamically typed code especially for things like web frameworks, which >> is where my interest in Python comes from. It looks like there is a >> great community and lots of libraries available. For some applications >> this can dramatically reduce development time which is a big point in >> its favour. However, I'm not a great fan of dynamic typing. It means >> that many bugs are not detected until run-time, and therefore requires a >> lot more testing to verify code. Also, the lack of defined return types >> makes APIs very hard to navigate. > > You may want to take a look at Google's Go language at golang.org > because it has some of the niceties of Python and friends combined > with solid Oberon (and even Lagoona :-D) roots, albeit hidden behind a > C-like syntax of dubious attractiveness. I've played with it a bit > last year and had a lot of fun. Still intend to do more with it later > this year. And oh, it's statically typed and compiled, they even > target embedded development to some extent. Hi Peter, "Go" looks nice. Like Oberon it gives you type safety without the baggage of a huge VM. It looks like they are using gcc as a back end. Interesting that they have implemented interfaces not subclassing. Providing you can easily use aggregation that's probably a good idea - solves the "fragile base class" problem. Interfaces are a cleaner way to get run-time polymorphism. I notice you're directing a gaming lab. What software tools do you use for game development? Cheers, Stewart |
|
From: Duke N. <duk...@ml...> - 2010-08-04 03:28:35
|
On Wed, 4 Aug 2010, Stewart Greenhill wrote: > Hi Duke, > > I checked this out, and it looks like the problem is related to the GC > version. The API seems to have changed slightly in the 7.X series and some of > the functions OOC expects have been removed or renamed. > > If you use GC 6.8 it should work fine. BTW, this is also the "default" version > you get if you download gc.tar.gz. OK! I'll get busy tomorrow and report back one way or another! Thanks... -- Duke |
|
From: Duke N. <duk...@ml...> - 2010-08-04 03:25:49
|
On Wed, 4 Aug 2010, Alexander Elkhovskiy wrote: > Duke, > > try to use an older version of gc, 6.8 for example. Do I have to un-install the version of `gc' that I just installed? Or will installing the older version simply "overwrite" the newer one? -- Duke |
|
From: Stewart G. <sgr...@ii...> - 2010-08-04 02:27:01
|
Michael van Acken wrote: [...] > regarding the Python documentation: it took me years to get to a > decent hit rate when looking things up. For some reason or other, > I was always looking at the wrong places first for a particular piece of > information. The docs and my brain seem to be structured along > different lines ;-) > > Just yesterday I read a nice article "Strong Typing vs. Strong > Testing" http://docs.google.com/View?id=dcsvntt2_25wpjvbbhk > With Python and Clojure I do not miss static type checks at all. > Both have their ways to make up for it. Hi Michael, Interesting article, but I'm not sure I agree with the conclusion: "what we need is strong testing, not strong typing." Its true that testing pick up some errors that static typing would otherwise have picked up. But what we actually need is strong testing AND strong typing. Static typing allows us to define a "contract" which the compiler can help enforce. As well as ensuring correctness, it also helps to document code. Without some static guarantees, APIs are really hard to navigate. >> What sort of things are you doing with Clojure? > > I've done a lot of web application stuff, both at work and in private. > Libraries like compojure and hiccup make server side request parsing > and HTML generation trivial. Also a big boon: for development one > can set up things so that functions can be replaced in the running > server, from within the editor. With this, the turnaround time from > changing a function to running it for new HTML takes a fraction of a > second. Btw, the package management done by leiningen or cljr is > great: a trivial interface towards the user but able to resolve all package > dependencies in the background. With this I really appreciate the > wealth of Java libraries available. For example, it took me three > minutes to get an OpenGL demo up and running on a laptop where > no Clojure was installed beforehand. > > The other stuff I've done is database access (Oracle and CouchDB), > 3D graphics (just a few days ago I implemented shadow mapping > for OpenGL using penumbra, something I wanted to do since I toyed > with OpenGL under Python), data analysis (unsurprisingly, Clojure > shines at list processing), and by now even general scripting > (although the JVM has a rather long startup time). Sounds neat. The JVM is a good platform with so many implementations and libraries around. For some things it can be quite inefficient as its not possible to allocate objects on the stack or in arrays. I used to do some Lisp programming myself, and learned a bit about implementing interpreters from studying different LISP implementations (eg. xlisp). Cheers, Stewart |
|
From: Stewart G. <sgr...@ii...> - 2010-08-04 01:27:36
|
Hi Frank,
I checked this out and it seems to be a bug in gcc's optimizer.
The Oberon-2 source code is this:
PROCEDURE IsEmpty* (list:Header): BOOLEAN;
BEGIN RETURN list.first=NIL
END IsEmpty;
OOC generates this object code:
OOC_CHAR8 L__IsEmpty(const struct L__Header *list__ref) {
register OOC_INT32 i0;
OOC_ALLOCATE_VPAR(list,L__Header ,1)
OOC_INITIALIZE_VPAR(list__ref,list,L__Header ,8)
i0 = (OOC_INT32)*(OOC_INT32*)(OOC_INT32)list;
return (i0==0);
;
}
It allocates a local copy of the Header record (OOC_ALLOCATE_VPAR).
It copies "list" since the record is passed by value
(OOC_INITIALIZE_VPAR just calls memcpy).
It then tests the "first" field, which just happens to be the first
element in the structure.
With the normal optimization level (-O2), gcc generates this:
.globl L__IsEmpty
.type L__IsEmpty, @function
L__IsEmpty:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl -8(%ebp), %eax
leave
testl %eax, %eax
sete %al
ret
This is just plain wrong. for some reason it has eliminated the call to
memcpy, so its testing the value of an uninitialised local record.
Compiling the same C code without optimisation gives this:
globl L__IsEmpty
.type L__IsEmpty, @function
L__IsEmpty:
pushl %ebp
movl %esp, %ebp
pushl %ebx
subl $36, %esp
movl $8, 8(%esp)
movl 8(%ebp), %eax
movl %eax, 4(%esp)
leal -16(%ebp), %eax
movl %eax, (%esp)
call memcpy
leal -16(%ebp), %eax
movl (%eax), %ebx
testl %ebx, %ebx
sete %al
addl $36, %esp
popl %ebx
popl %ebp
ret
.size L__IsEmpty, .-L__IsEmpty
This code actually works fine and gives the right output.
I'm not sure what to recommend here. Obviously care should be taken with
this version of GCC. The fact that OOC builds itself fine indicates that
the problem is probably fairly rare. For efficiency, you would normally
pass records by reference anyway. I think gcc has decided to eliminate
the call to memcpy because it thinks the result is unused. When I added
a printf statement (list[0].first) after the OOC_INITIALIZE_VPAR the
problem went away. I expect that for non-trivial code its much less
likely to occur. If you want to be perfectly safe you could run oo2c
without optimization, or see if the problem is resolved in later
versions of gcc.
Cheers,
Stewart
Frank Hrebabetzky wrote:
> On 07/30/2010 01:30 AM, Stewart Greenhill wrote:
>
>>> oo2c --version
>>> oo2c/gcc 2.1.11
>>> gcc --version
>>> gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
>
> This remembers me that the MinGW folks recently had considerable
> difficulties with the update to a newer gcc version. I followed the
> discussion without understanding anything. Don't know whether this is
> relevant here.
|
|
From: Stewart G. <sgr...@ii...> - 2010-08-04 01:06:55
|
Hi Duke, I checked this out, and it looks like the problem is related to the GC version. The API seems to have changed slightly in the 7.X series and some of the functions OOC expects have been removed or renamed. If you use GC 6.8 it should work fine. BTW, this is also the "default" version you get if you download gc.tar.gz. Cheers, Stewart Duke Normandin wrote: > Hi.... > > I've been booted off my wife's OSX machine ;D and am now in the > process of getting comfortable on my Xubuntu installation. > > I'm trying to install oo2c_32-2.1.11. I got `gc' installed with no > (apparent) problems. oo2c `configure' did not choke on anything! > However, when I ran `make', a hairball got in the way: > > gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/obj/Object.c -o ./lib/obj/Object.o > gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/obj/Object/BigInt.c -o ./lib/obj/Object/BigInt.o > gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/obj/Object/Boxed.c -o ./lib/obj/Object/Boxed.o > gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/obj/Out.c -o ./lib/obj/Out.o > gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/src/PosixFileDescr.c -o ./lib/obj/PosixFileDescr.o > gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/obj/ProgramArgs.c -o ./lib/obj/ProgramArgs.o > gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/src/RT0.c -o ./lib/obj/RT0.o > ./lib/src/RT0.c:86: error: expected ')' before 'ptr' > ./lib/src/RT0.c: In function 'RT0__NewObject': > ./lib/src/RT0.c:130: error: 'HandleFinalize' undeclared (first use in this function) > ./lib/src/RT0.c:130: error: (Each undeclared identifier is reported only once > ./lib/src/RT0.c:130: error: for each function it appears in.) > ./lib/src/RT0.c:130: error: 'GC_PTR' undeclared (first use in this function) > ./lib/src/RT0.c:130: error: expected expression before ')' token > make[1]: *** [lib/obj/RT0.o] Error 1 > make[1]: Leaving directory `/home/dnormandin/Programming/Oberon/oo2c_32-2.1.11/stage0' > make: *** [stage0/oo2c] Error 2 > dnormandin@select-man:~/Programming/Oberon/oo2c_32-2.1.11$ > > Would one of you bright C programmers lurking this list be able to > suggest a solution? Is this a `libtool' issue? TIA! |
|
From: Duke N. <duk...@ml...> - 2010-08-03 18:09:49
|
Hi.... I've been booted off my wife's OSX machine ;D and am now in the process of getting comfortable on my Xubuntu installation. I'm trying to install oo2c_32-2.1.11. I got `gc' installed with no (apparent) problems. oo2c `configure' did not choke on anything! However, when I ran `make', a hairball got in the way: gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/obj/Object.c -o ./lib/obj/Object.o gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/obj/Object/BigInt.c -o ./lib/obj/Object/BigInt.o gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/obj/Object/Boxed.c -o ./lib/obj/Object/Boxed.o gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/obj/Out.c -o ./lib/obj/Out.o gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/src/PosixFileDescr.c -o ./lib/obj/PosixFileDescr.o gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/obj/ProgramArgs.c -o ./lib/obj/ProgramArgs.o gcc -g -O2 -Ilib/src -I./obj -I./lib/obj -c ./lib/src/RT0.c -o ./lib/obj/RT0.o ./lib/src/RT0.c:86: error: expected ')' before 'ptr' ./lib/src/RT0.c: In function 'RT0__NewObject': ./lib/src/RT0.c:130: error: 'HandleFinalize' undeclared (first use in this function) ./lib/src/RT0.c:130: error: (Each undeclared identifier is reported only once ./lib/src/RT0.c:130: error: for each function it appears in.) ./lib/src/RT0.c:130: error: 'GC_PTR' undeclared (first use in this function) ./lib/src/RT0.c:130: error: expected expression before ')' token make[1]: *** [lib/obj/RT0.o] Error 1 make[1]: Leaving directory `/home/dnormandin/Programming/Oberon/oo2c_32-2.1.11/stage0' make: *** [stage0/oo2c] Error 2 dnormandin@select-man:~/Programming/Oberon/oo2c_32-2.1.11$ Would one of you bright C programmers lurking this list be able to suggest a solution? Is this a `libtool' issue? TIA! -- Duke |
|
From: Frank H. <hr...@te...> - 2010-08-03 11:42:33
|
On 08/02/2010 10:10 PM, Stewart Greenhill wrote: > Hi Frank, > > Try: > r := sc.real; (* REAL value scanned from input *) > instead of > r := TextRider.real; (* constant for REAL token type *) A stupid error and a polite response. Thanks, Stewart! -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil |