ooc-compiler Mailing List for Optimizing Oberon-2 Compiler (Page 11)
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: Stewart G. <sgr...@ii...> - 2006-01-12 09:10:31
|
Hi Folks,
I'm interested in being able to use existing C++ APIs from Oberon-2.
Currently, oo2c has a limited ability to call methods of C++ objects.
When one declares a record with the VTABLE flag, oo2c builds a C++-style
virtual method table for all instantiated objects, and calls methods of
that object via VTABLE dispatch. This means (for example) that you can
call methods of COM interfaces, and even implement your own COM objects.
This is fine if one follows a design methodology like COM, which ensures
that there is a language-independent binary interface to your API. COM
uses abstract interfaces and VTABLE method dispatch. It also has a
language-independent type mechanism (ie. IUnknown::QueryInterface).
Unfortunately, most C++ coders seem completely uninterested in language
interoperability. The biggest obstacle with existing C++ APIs is the use
of static (ie. non-virtual) methods. Its only really possible to call
these methods from a C++ compiler, since the symbol names are mangled to
include type information.
The approach that I'm proposing is to:
1) Introduce a [STATIC] method flag. This causes calls to methods to be
dispatched statically, rather than using type-descriptor lookup.
2) Write (by hand, or automatically) a FOREIGN implementation that can
be processed by the C++ compiler. This dispatches method calls to the
C++ objects.
I'll try to illustrate this by means of an example. Suppose we have a
simple C++ library:
-- Foreign.h --
class T {
public:
virtual void Virtual(void);
void Static(void);
};
-- end Foreign.h --
-- Foreign.cpp --
#include <stdio.h>
#include "Foreign.h"
void T::Virtual(void) {
printf("T::Virtual\n");
}
void T::Static(void) {
printf("T::Static\n");
}
-- end Foreign.cpp --
Using a VTABLE declaration, I can call method "Virtual", but not method
"Static". Now OOC already has a concept of static methods. A method is
called statically (ie. without using a type-descriptor method lookup) if
it is known not to be overridden, or if it is a special predefined
method like INIT. I'm proposing to add a "STATIC" procedure flag, which
specifies that a method is to be treated as a static method (ie. it has
procClass = staticMethod) rather than a virtual method. The address of
the method is always based on an objects static type.
This allows us to write:
-- ForeignStatic.Mod --
MODULE ForeignStatic [ FOREIGN "C"; LINK FILE "ForeignStatic.cpp"; LIB
"foreign"; LIB "stdc++" END ];
TYPE
TDesc* = RECORD [VTABLE] END;
T* = POINTER TO TDesc;
PROCEDURE (t : T) Virtual*;
PROCEDURE (t : T) [STATIC] Static*;
PROCEDURE NewT* () : T;
END ForeignStatic.
-- end ForeignStatic.Mod --
Now to make things work, we need the FOREIGN implementation. For the
above library, it looks like this:
-- ForeignStatic.cpp --
#include "Foreign.h"
extern "C" {
#include <ForeignStatic.d>
#include <__oo2c.h>
#include <setjmp.h>
void ForeignStatic__TDesc_Virtual(ForeignStatic__T t) {
((T*) t)->Virtual();
}
void ForeignStatic__TDesc_Static(ForeignStatic__T t) {
((T*) t)->Static();
}
void OOC_ForeignStatic_init(void) {
return;
;
}
void OOC_ForeignStatic_destroy(void) {
}
ForeignStatic__TDesc* ForeignStatic__NewT(void) { return
(ForeignStatic__TDesc *) new T(); }
}
/* --- */
-- end ForeignStatic.cpp --
To generate this, I compiled a "stub" module using oo2c, and manually
inserted a few things.
- Included the header for the C++ library.
- The "extern C" is necessary so that the C++ compiler does not mangle
the symbol names.
- Inserted dispatch statements in any methods that are to be called
statically. Actually, "Virtual" is alreadly dispatched by OOC through
the VTABLE, but I could have allowed C++ to do the virtual dispatch here
by declaring it STATIC.
- Inserted a constructor.
This allows one to do this sort of thing:
-- TestForeignStatic.Mod --
MODULE TestForeignStatic;
IMPORT ForeignStatic;
PROCEDURE TestForeignStatic1;
VAR t : ForeignStatic.T;
BEGIN
t := ForeignStatic.NewT();
t.Virtual;
t.Static;
END TestForeignStatic1;
BEGIN
TestForeignStatic1;
END TestForeignStatic.
-- end TestForeignStatic.Mod --
That is, I can call virtual or static methods of objects as if they are
native objects. Note that I don't need to change the calling conventions
used within OOC. It already handles virtual and static dispatch. The
wrapper functions simply redirect the method dispatch using the host
compiler.
Anyway, with a bit of fiddling I managed to get it to work. The STATIC
flag was easy to implement, but it would be nice if this process could
be streamlined somehow. Ideally, the FOREIGN wrapper implementation
should be generated automatically by OO2C. This should not be hard to do
- If we can get some consensus regarding how it should work I'm willing
to have a go at it. Since the wrapper requires the use of
implementation-specific symbol names and structures it would make sense
for the compiler to provide this feature, rather than an external tool.
1) There would need to be a declaration that this is a special type of
FOREIGN module (eg. "WRAPPER", or "PROXY"?). Records declared within are
assumed to have no type descriptors. Stub procedures are generated that
dispatch methods in the host ("C++") language.
2) There should be a list of headers to include at the top of the object
file.
3) For each record type, we need an optional "link name" saying what the
proxy C++ type is called. This would be used to generate the type casts
in the wrapper methods.
4) For each method, we need an optional "link name" saying what the
method of the proxy C++ type is called. In the case of an overloaded
method, there will be multiple Oberon-2 names that map to the same C++ name.
5) There would need to be a way of declaring constructors which would be
dispatched via new().
What do people think about these issues? Any suggestions, or violent
objections? ;-)
Cheers,
Stewart
|
|
From: Michael v. A. <mic...@gm...> - 2006-01-09 07:58:28
|
On 09/01/06, August Karlstrom <fus...@co...> wrote: > > Great! > > Compiled almost cleanly with gcc 4.0 on Ubuntu. See warnings below. I can live with these warnings. If anyone wants to provide a patch to get rid of them as well... -- mva ... > In file included from ./lib/obj/LRealConv.d:2, > from ./lib/obj/LRealConv.c:1: > ./lib/obj/libc.oh:13: warning: conflicting types for built-in function > 'sprintf' > ... > In file included from ./lib/obj/LRealStr.d:2, > from ./lib/obj/LRealStr.c:1: > ./lib/obj/libc.oh:13: warning: conflicting types for built-in function > 'sprintf' > ... > In file included from ./lib/obj/RealConv.d:2, > from ./lib/obj/RealConv.c:1: > ./lib/obj/libc.oh:13: warning: conflicting types for built-in function > 'sprintf' > ... > In file included from ./lib/obj/RealStr.d:2, > from ./lib/obj/RealStr.c:1: > ./lib/obj/libc.oh:13: warning: conflicting types for built-in function > 'sprintf' > ... > lib/src/XML/UnicodeCodec/ImportAll.Mod:4:20: Warning: Unused object > lib/src/XML/UnicodeCodec/ImportAll.Mod:4:44: Warning: Unused object > lib/src/XML/UnicodeCodec/ImportAll.Mod:5:20: Warning: Unused object > lib/src/XML/UnicodeCodec/ImportAll.Mod:5:44: Warning: Unused object > ... > In file included from lib/obj/LRealConv.d:2, > from lib/obj/LRealConv.c:1: > lib/obj/libc.oh:13: warning: conflicting types for built-in function > 'sprintf' > ... > In file included from lib/obj/LRealStr.d:2, > from lib/obj/LRealStr.c:1: > lib/obj/libc.oh:13: warning: conflicting types for built-in function > 'sprintf' > ... > In file included from lib/obj/RealConv.d:2, > from lib/obj/RealConv.c:1: > lib/obj/libc.oh:13: warning: conflicting types for built-in function > 'sprintf' > ... > In file included from lib/obj/RealStr.d:2, > from lib/obj/RealStr.c:1: > lib/obj/libc.oh:13: warning: conflicting types for built-in function > 'sprintf' > ... > /home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c: In function > 'IO_Socket__SocketDesc_FinishConnect': > /home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c:99: warning: pointer > targets in passing argument 5 of 'getsockopt' differ in signedness > /home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c: In function > 'IO_Socket__SocketDesc_RemoteAddress': > /home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c:121: warning: > pointer targets in passing argument 3 of 'getpeername' differ in > signedness > /home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c: In function > 'IO_Socket__ServerDesc_Accept': > /home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c:186: warning: > pointer targets in passing argument 3 of 'accept' differ in signedness > ... > In file included from lib/obj/liboo2c.d:58, > from lib/obj/liboo2c.c:1: > lib/obj/libc.oh:13: warning: conflicting types for built-in function > 'sprintf' > ... > src/oob.Mod:520:10: Warning: Exception `IO.Error' not caught > src/oob.Mod:535:15: Warning: Exception `IO.Error' not caught > src/oob.Mod:537:19: Warning: Exception `IO.Error' not caught > src/oob.Mod:539:23: Warning: Exception `IO.Error' not caught > ... > src/ooef.Mod:578:10: Warning: Exception `IO.Error' not caught > ... > src/oowhereis.Mod:140:10: Warning: Exception `IO.Error' not caught > ... > |
|
From: August K. <fus...@co...> - 2006-01-09 01:44:46
|
Michael van Acken wrote:
> This is purely a bugfix release.
>=20
> (oo2c) Fix type guards involving type variables.
>=20
> (oo2c) Fix LSH and ROT to the right for types smaller than 32 bit.
>=20
> (oo2c) Fix exported but unnamed record pointers.
>=20
> (oo2c) Some error recovery fixes.
>=20
> (PROBLEMS) Add hint about static linking with libtool.
Great!
Compiled almost cleanly with gcc 4.0 on Ubuntu. See warnings below.
Regards,
August
...
In file included from ./lib/obj/LRealConv.d:2,
from ./lib/obj/LRealConv.c:1:
./lib/obj/libc.oh:13: warning: conflicting types for built-in function=20
=91sprintf=92
...
In file included from ./lib/obj/LRealStr.d:2,
from ./lib/obj/LRealStr.c:1:
./lib/obj/libc.oh:13: warning: conflicting types for built-in function=20
=91sprintf=92
...
In file included from ./lib/obj/RealConv.d:2,
from ./lib/obj/RealConv.c:1:
./lib/obj/libc.oh:13: warning: conflicting types for built-in function=20
=91sprintf=92
...
In file included from ./lib/obj/RealStr.d:2,
from ./lib/obj/RealStr.c:1:
./lib/obj/libc.oh:13: warning: conflicting types for built-in function=20
=91sprintf=92
...
lib/src/XML/UnicodeCodec/ImportAll.Mod:4:20: Warning: Unused object
lib/src/XML/UnicodeCodec/ImportAll.Mod:4:44: Warning: Unused object
lib/src/XML/UnicodeCodec/ImportAll.Mod:5:20: Warning: Unused object
lib/src/XML/UnicodeCodec/ImportAll.Mod:5:44: Warning: Unused object
...
In file included from lib/obj/LRealConv.d:2,
from lib/obj/LRealConv.c:1:
lib/obj/libc.oh:13: warning: conflicting types for built-in function=20
'sprintf'
...
In file included from lib/obj/LRealStr.d:2,
from lib/obj/LRealStr.c:1:
lib/obj/libc.oh:13: warning: conflicting types for built-in function=20
'sprintf'
...
In file included from lib/obj/RealConv.d:2,
from lib/obj/RealConv.c:1:
lib/obj/libc.oh:13: warning: conflicting types for built-in function=20
'sprintf'
...
In file included from lib/obj/RealStr.d:2,
from lib/obj/RealStr.c:1:
lib/obj/libc.oh:13: warning: conflicting types for built-in function=20
'sprintf'
...
/home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c: In function=20
'IO_Socket__SocketDesc_FinishConnect':
/home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c:99: warning: pointer=20
targets in passing argument 5 of 'getsockopt' differ in signedness
/home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c: In function=20
'IO_Socket__SocketDesc_RemoteAddress':
/home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c:121: warning:=20
pointer targets in passing argument 3 of 'getpeername' differ in signedne=
ss
/home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c: In function=20
'IO_Socket__ServerDesc_Accept':
/home/august/src/oo2c_32-2.1.10/lib/src/IO/Socket.c:186: warning:=20
pointer targets in passing argument 3 of 'accept' differ in signedness
...
In file included from lib/obj/liboo2c.d:58,
from lib/obj/liboo2c.c:1:
lib/obj/libc.oh:13: warning: conflicting types for built-in function=20
'sprintf'
...
src/oob.Mod:520:10: Warning: Exception `IO.Error' not caught
src/oob.Mod:535:15: Warning: Exception `IO.Error' not caught
src/oob.Mod:537:19: Warning: Exception `IO.Error' not caught
src/oob.Mod:539:23: Warning: Exception `IO.Error' not caught
...
src/ooef.Mod:578:10: Warning: Exception `IO.Error' not caught
...
src/oowhereis.Mod:140:10: Warning: Exception `IO.Error' not caught
...
|
|
From: Michael v. A. <mic...@gm...> - 2006-01-08 13:49:52
|
This is purely a bugfix release. (oo2c) Fix type guards involving type variables. (oo2c) Fix LSH and ROT to the right for types smaller than 32 bit. (oo2c) Fix exported but unnamed record pointers. (oo2c) Some error recovery fixes. (PROBLEMS) Add hint about static linking with libtool. A happy new year to all of you! -- mva |
|
From: Isaac G. <ig...@ya...> - 2005-12-14 20:06:33
|
iirc XDS Oberon-2 uses .ob2 but also allows the extension to be redefined. --- August Karlstrom <fus...@co...> wrote: > Stewart Greenhill wrote: > > Section 15 of Wirth's Modula-2 definition (1980) describes the > > implementation of the Modula compiler for the PDP-11 computer. It > > recommends that ".MOD" be used for "program modules", ".DEF" for > > "definition modules", and ".SYM" for symbol files. All of the > > descendants of Modula seem to have adopted these same conventions. > > Well, for MODula (implementation) files ".MOD" is of course the > natural > choice. It was probably kept for Oberon files as they too contain > MODules. > > By the way, I tried to use oo2c with the ".obn" extension and... it > works. When I first tried that I forgot to recompile all imported > modules, so I falsely concluded that it wasn't possible. Sorry. On > the > other hand, in oowhereis I noticed the the constant declaration > > moduleExtension = ".Mod"; > > > Its true that there are other uses for the ".MOD" extension, but I > think > > you'll find that Wirth's use (>25 years) probably pre-dates most of > the > > alternatives. > > Sure, but why not avoid potential problems and use ".obn" instead? > However, since (at least) oo2c seems to support arbitrary file > extensions, everyone is free to choose their own preferred extension. > > > August > > > ------------------------------------------------------- > This SF.net email is sponsored by: Splunk Inc. Do you grep through > log files > for problems? Stop! Download the new AJAX search engine that makes > searching your log files as easy as surfing the web. DOWNLOAD > SPLUNK! > http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click > _______________________________________________ > ooc-compiler mailing list > ooc...@li... > https://lists.sourceforge.net/lists/listinfo/ooc-compiler > __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com |
|
From: August K. <fus...@co...> - 2005-12-14 19:22:40
|
Stewart Greenhill wrote:
> Section 15 of Wirth's Modula-2 definition (1980) describes the
> implementation of the Modula compiler for the PDP-11 computer. It
> recommends that ".MOD" be used for "program modules", ".DEF" for
> "definition modules", and ".SYM" for symbol files. All of the
> descendants of Modula seem to have adopted these same conventions.
Well, for MODula (implementation) files ".MOD" is of course the natural
choice. It was probably kept for Oberon files as they too contain MODules.
By the way, I tried to use oo2c with the ".obn" extension and... it
works. When I first tried that I forgot to recompile all imported
modules, so I falsely concluded that it wasn't possible. Sorry. On the
other hand, in oowhereis I noticed the the constant declaration
moduleExtension = ".Mod";
> Its true that there are other uses for the ".MOD" extension, but I think
> you'll find that Wirth's use (>25 years) probably pre-dates most of the
> alternatives.
Sure, but why not avoid potential problems and use ".obn" instead?
However, since (at least) oo2c seems to support arbitrary file
extensions, everyone is free to choose their own preferred extension.
August
|
|
From: Stewart G. <sgr...@ii...> - 2005-12-14 04:32:10
|
Hi August, > Is it possible to use a filename extension other than ".Mod" for Oberon > source texts? The extension clashes with files of a number of different > file formats, see > > http://www.wotsit.org/search.asp?page=26&s=ALLFILES > > Moreover, I don't think the ".Mod" extension makes much sense outside of > the Oberon operating system. The natural extension ".obn" would be a > much better choice, I think, and it's not used by any known file format > as far as I know. Section 15 of Wirth's Modula-2 definition (1980) describes the implementation of the Modula compiler for the PDP-11 computer. It recommends that ".MOD" be used for "program modules", ".DEF" for "definition modules", and ".SYM" for symbol files. All of the descendants of Modula seem to have adopted these same conventions. Its true that there are other uses for the ".MOD" extension, but I think you'll find that Wirth's use (>25 years) probably pre-dates most of the alternatives. Cheers, Stewart |
|
From: August K. <fus...@co...> - 2005-12-13 16:06:58
|
Hi,
Is it possible to use a filename extension other than ".Mod" for Oberon
source texts? The extension clashes with files of a number of different
file formats, see
http://www.wotsit.org/search.asp?page=26&s=ALLFILES
Moreover, I don't think the ".Mod" extension makes much sense outside of
the Oberon operating system. The natural extension ".obn" would be a
much better choice, I think, and it's not used by any known file format
as far as I know.
Regards,
August
|
|
From: Stewart G. <sgr...@ii...> - 2005-12-07 02:20:42
|
August Karlstrom wrote: > Michael van Acken wrote: >> Beforehand, you can't. What you can do is check if the result >> maxes out the array, and call again with a larger array if this >> is the case. Repeat until not maxed out. Not very elegant, I >> know :-) > > > OK, I see. This is (of course) a general problem in Oberon. In C we can > just return a pointer to a constant string so there is no need to either > allocate a buffer or know the size of it. In defense of Oberon, a C > program may crash if we inadvertently try to write to a constant string. > Still a bit annoying though. The method returns a string which is constructed from a template and a set of attributes. In this sense its a little more complicated than something like strerror(), which could indeed return a pointer to a constant string. In Oberon-2, string constants are treated as ARRAY OF CHAR, so the convention is to represent strings in this way. Its true that the API could have returned a POINTER TO ARRAY OF CHAR, which would get around the size limitation. I guess it is for simplicity that people usually use the same type (ARRAY OF CHAR) for inputs and outputs to functions that deal with strings. OOC also has its own STRING type (Object.String) which has a concatenation operator and many other utility methods. It abstracts over the different underlying characters sets (allowing 8-, 16- or 32-bit characters). Most of the newer APIs use this type of string, and it is possible to convert between the different representations. Cheers, Stewart |
|
From: August K. <fus...@co...> - 2005-12-06 18:23:47
|
Stewart Greenhill wrote: -snip- > Normal Oberon-2 style is to declare names for most > types, which is possibly why this problem has not been noticed. > For example: > MODULE M; > TYPE T = POINTER TO RECORD y-: LONGINT END; > VAR x-: T; > END M. > In this case you already have a declaration for the type, which is used > for both variable declarations in the C code. Especially for records, > you need a name for the type in order to pass the record type by > reference (eg. as a VAR parameter), or to extend the record type. I agree that this is the recommended approach. Still the compiler probably needs to be complete. Even though Oberon-2 is a rather simple language it's obviously quite a complex task for a compiler developer to get everything right. August |
|
From: August K. <fus...@co...> - 2005-12-06 18:13:14
|
Michael van Acken wrote: > On 29/11/05, *August Karlstrom* <fus...@co... > <mailto:fus...@co...>> wrote: > > Hi, > > The procedure GetText in Msg has the signature > > PROCEDURE (msg: Msg) GetText(VAR text: ARRAY OF CHAR) > > How do I make sure the message fits in `text'? > > > > Beforehand, you can't. What you can do is check if the result > maxes out the array, and call again with a larger array if this > is the case. Repeat until not maxed out. Not very elegant, I > know :-) OK, I see. This is (of course) a general problem in Oberon. In C we can just return a pointer to a constant string so there is no need to either allocate a buffer or know the size of it. In defense of Oberon, a C program may crash if we inadvertently try to write to a constant string. Still a bit annoying though. August |
|
From: Michael v. A. <mic...@gm...> - 2005-12-06 07:33:14
|
On 29/11/05, August Karlstrom <fus...@co...> wrote: > > Hi, > > The procedure GetText in Msg has the signature > > PROCEDURE (msg: Msg) GetText(VAR text: ARRAY OF CHAR) > > How do I make sure the message fits in `text'? Beforehand, you can't. What you can do is check if the result maxes out the array, and call again with a larger array if this is the case. Repeat until not maxed out. Not very elegant, I know :-) -- mva |
|
From: Stewart G. <sgr...@ii...> - 2005-12-06 02:53:13
|
Hi August,
Looks like you found a bug.
For me, the compiler accepts that module. The error is from the C
compiler during code generation.
obj/M.d:4: error: conflicting types for 'M__x'
obj/M.oh:11: error: previous declaration of 'M__x' was here
obj/M.d:4: error: conflicting types for 'M__x'
obj/M.oh:11: error: previous declaration of 'M__x' was here
I think there is a slight problem with the output of type declarations.
In this case, "x" is exported, so oo2c needs to generate an "extern"
declaration for "x" in M.oh (public headers for module M). Although it
is the same declaration, this conflicts with the local declaration of
"x" in M.d (private headers for module M). This is because C uses name
equivalence, not structural equivalence for records. Its probably not a
problem for other type constructors (eg. pointers, arrays) because they
use structural equivalence in C.
What oo2c needs to do is to output a separate declaration for the type
of "x" in M.oh. Normal Oberon-2 style is to declare names for most
types, which is possibly why this problem has not been noticed.
For example:
MODULE M;
TYPE T = POINTER TO RECORD y-: LONGINT END;
VAR x-: T;
END M.
In this case you already have a declaration for the type, which is used
for both variable declarations in the C code. Especially for records,
you need a name for the type in order to pass the record type by
reference (eg. as a VAR parameter), or to extend the record type.
Cheers,
Stewart
August Karlstrom wrote:
> Hi,
>
> Is the following module is invalid?
>
> MODULE M;
> VAR x-: POINTER TO RECORD y-: LONGINT END;
> END M.
>
> OOC 2.1.9 thinks it is. Why?
>
>
> Regards,
>
> August
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc. Do you grep through log
> files
> for problems? Stop! Download the new AJAX search engine that makes
> searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
> http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
> _______________________________________________
> ooc-compiler mailing list
> ooc...@li...
> https://lists.sourceforge.net/lists/listinfo/ooc-compiler
>
|
|
From: August K. <fus...@co...> - 2005-12-05 23:43:31
|
Hi,
Is the following module is invalid?
MODULE M;
VAR x-: POINTER TO RECORD y-: LONGINT END;
END M.
OOC 2.1.9 thinks it is. Why?
Regards,
August
|
|
From: August K. <fus...@co...> - 2005-12-05 14:40:33
|
Stewart Greenhill wrote: -snip- > Ideally, what we need is something like this: > > /* ASH(x,n) */ > #define _ashl(_x,_n) (ST(_x) << _n) > #define _ashr(_x,_n) (ST(_x) >> _n) > #define _ash(_x,_n) (_n >= 0) ? _ashl(_x,_n) : _ashr(_x,- _n) > > /* SYSTEM.LSH(x,n) */ > #define _lshl(_x,_n,_type) ((_type)(UT(_x) << _n)) > #define _lshr(_x,_n,_type) ((_type)(UT(_x) >> _n)) > #define _lsh(_type,_x,_n) ((_n >= 0) ? _lshl(_x,_n,_type) : _lshr(_x,- > _n,_type)) > > Where ST(_x) and UT(_x) cast _x to the signed and unsigned > (respectively) types of the same size. Unfortunately, "C" doesn't > provide such an operator, so to make this work OOC would have to pass > this type as an argument to the ASH/LSH function. -snip- Thanks for the detailed explanation. Why not define one function for each type: _ash_OOC_INT8, _ash_OOC_INT16, _ash_OOC_INT32 and so on. As far as I understand the compiler will know which version to choose depending on the type of the first argument. Regards, August |
|
From: Stewart G. <sgr...@ii...> - 2005-12-05 04:13:06
|
Hi August, The oo2c ASH/LSH implementation (in __oo2c.h) looks like this: /* ASH(x,n) */ #define _ashl(_x,_n) (_x << _n) #define _ashr(_x,_n) (_x >> _n) | ((_x >= 0) ? 0 : ~(~(OOC_INT32)0 >> _n)) #define _ash(_x,_n) (_n >= 0) ? _ashl(_x,_n) : _ashr(_x,- _n) /* SYSTEM.LSH(x,n) */ #define _lshl(_x,_n,_type) ((_type)(_x << _n)) #define _lshr(_x,_n,_type) ((_type)(_x >> _n)) #define _lsh(_type,_x,_n) ((_n >= 0) ? _lshl(_x,_n,_type) : _lshr(_x,- _n,_type)) For LSH, it just uses the shift operator. For ASH, it explicitly adds the sign extension bits. According to my "C" definition (Harbison & Steele, 1984) the C shift operator does an arithmetic shift for signed integer types, and a logical shift (ie. fill with zero) for unsigned integer types. So there are a few problems with the above implementation. 1) _ashr will work for signed integers, but for these integers the sign test is redundant (>> already does the right thing). For unsigned integers, the sign test always fails (ie. they are all positive) so the sign extension is not done. I suspect that it also fails for negative 64-bit integers since the sign extension bits will be in the wrong place. 2) _lshr will only work correctly for unsigned types. For signed types, it does an arithmetic shift. Ideally, what we need is something like this: /* ASH(x,n) */ #define _ashl(_x,_n) (ST(_x) << _n) #define _ashr(_x,_n) (ST(_x) >> _n) #define _ash(_x,_n) (_n >= 0) ? _ashl(_x,_n) : _ashr(_x,- _n) /* SYSTEM.LSH(x,n) */ #define _lshl(_x,_n,_type) ((_type)(UT(_x) << _n)) #define _lshr(_x,_n,_type) ((_type)(UT(_x) >> _n)) #define _lsh(_type,_x,_n) ((_n >= 0) ? _lshl(_x,_n,_type) : _lshr(_x,- _n,_type)) Where ST(_x) and UT(_x) cast _x to the signed and unsigned (respectively) types of the same size. Unfortunately, "C" doesn't provide such an operator, so to make this work OOC would have to pass this type as an argument to the ASH/LSH function. One option (ie. hack) would be to do: #define ST(_x) ((signed) _x) #define UT(_x) ((unsigned) _x) but that would only work properly for arguments up to the size of the host "int" type (probably 32 bits). Another option is to cast integers to the corresponding CHAR type before doing LSH. This also limits you to 32 bits, since there is no 64-bit CHAR in OOC. Cheers, Stewart August Karlstrom wrote: > Hi, > > For integers, SYSTEM.LSH seems to be implemented as ASH, e.g. the result > of LSH(-1, -1) is -1 rather than MAX(SHORTINT). Why? > > Here is what I expect: > > LSH(-1, -1): 1111 1111 -> 0111 1111 > ASH(-1, -1): 1111 1111 -> 1111 1111 > > > Regards, > > August > > > > ------------------------------------------------------- > This SF.net email is sponsored by: Splunk Inc. Do you grep through log > files > for problems? Stop! Download the new AJAX search engine that makes > searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! > http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click > _______________________________________________ > ooc-compiler mailing list > ooc...@li... > https://lists.sourceforge.net/lists/listinfo/ooc-compiler > |
|
From: August K. <fus...@co...> - 2005-12-04 18:42:13
|
Hi,
For integers, SYSTEM.LSH seems to be implemented as ASH, e.g. the result
of LSH(-1, -1) is -1 rather than MAX(SHORTINT). Why?
Here is what I expect:
LSH(-1, -1): 1111 1111 -> 0111 1111
ASH(-1, -1): 1111 1111 -> 1111 1111
Regards,
August
|
|
From: August K. <fus...@co...> - 2005-11-28 23:38:11
|
Hi,
The procedure GetText in Msg has the signature
PROCEDURE (msg: Msg) GetText(VAR text: ARRAY OF CHAR)
How do I make sure the message fits in `text'?
Regards,
August
|
|
From: Michael v. A. <mic...@gm...> - 2005-10-18 06:24:13
|
On 17/10/05, August Karlstrom <fus...@co...> wrote: > [...] > OK, thanks. Maybe your detailed explanations above should be added to > the module documentation. I also think the values need to be mentioned > in the documentation of New, Old and Tmp. The type SET alone gives no clu= e. Feel free to send me a patch. -- mva |
|
From: August K. <fus...@co...> - 2005-10-17 12:21:35
|
Michael van Acken wrote: > On 17/10/05, August Karlstrom <fus...@co...> wrote: >>In the module Files, what values does the parameter `flags' in the >>procedures New, Old and Tmp accept? > > > read* = 0; > (* If the file cannot be opened for reading access, then it isn't opened > at all. In this case the error code is set to `noReadAccess'. *) > write* = 1; > (* If the file cannot be opened for writing access, then it isn't opened > at all. In this case the error code is set to `noWriteAccess'. *) > tryRead* = 2; > (* Try to open this file for reading access. If the file permissions > don't permit reading the file is opened nevertheless, but the file > descriptor's attribute `File.readable' is set to `FALSE'. *) > tryWrite* = 3; > (* Try to open this file for writing access. If the file permissions > don't permit writing the file is opened nevertheless, but the file > descriptor's attribute `File.writable' is set to `FALSE'. *) OK, thanks. Maybe your detailed explanations above should be added to the module documentation. I also think the values need to be mentioned in the documentation of New, Old and Tmp. The type SET alone gives no clue. Regards, August |
|
From: Michael v. A. <mic...@gm...> - 2005-10-17 05:51:42
|
On 17/10/05, August Karlstrom <fus...@co...> wrote:
> Hi,
>
> In the module Files, what values does the parameter `flags' in the
> procedures New, Old and Tmp accept?
read* =3D 0;
(* If the file cannot be opened for reading access, then it isn't opened
at all. In this case the error code is set to `noReadAccess'. *)
write* =3D 1;
(* If the file cannot be opened for writing access, then it isn't opened
at all. In this case the error code is set to `noWriteAccess'. *)
tryRead* =3D 2;
(* Try to open this file for reading access. If the file permissions
don't permit reading the file is opened nevertheless, but the file
descriptor's attribute `File.readable' is set to `FALSE'. *)
tryWrite* =3D 3;
(* Try to open this file for writing access. If the file permissions
don't permit writing the file is opened nevertheless, but the file
descriptor's attribute `File.writable' is set to `FALSE'. *)
-- mva
|
|
From: August K. <fus...@co...> - 2005-10-16 23:55:23
|
Hi, In the module Files, what values does the parameter `flags' in the procedures New, Old and Tmp accept? August |
|
From: Michael v. A. <mic...@gm...> - 2005-10-11 06:03:09
|
> Comments like (*in*) and (*out*) seems to be common practice in ETH > Oberon as a part of the module interface documentation, see e.g. > > http://www.oberon.ethz.ch/ethoberon/defs/Strings.Def.html > > Just by looking at the procedure signature you know the purpose of VAR. They must have introduced this after my acquaintance with ETH Oberon. I have never seen this, nor used it. -- mva |
|
From: August K. <fus...@co...> - 2005-10-11 03:02:17
|
Michael van Acken wrote:
> On 10/10/05, August Karlstrom <fus...@co...> wrote:
>>When generating documentation with oo2c, parameter comments like in e.g.
>>
>> PROCEDURE P(VAR (*in*) a: ARRAY OF LONGINT);
>>
>>are removed. Why?
>
> Mh, I do not understand the question. Documentation, like the output of oob, is
> generated from the symbol file. The compiler discards comments at a very early
> stage, way before the symbol file is generated.
Comments like (*in*) and (*out*) seems to be common practice in ETH
Oberon as a part of the module interface documentation, see e.g.
http://www.oberon.ethz.ch/ethoberon/defs/Strings.Def.html
Just by looking at the procedure signature you know the purpose of VAR.
August
|
|
From: Michael v. A. <mic...@gm...> - 2005-10-10 18:39:32
|
On 10/10/05, August Karlstrom <fus...@co...> wrote: > Hello all, > > When generating documentation with oo2c, parameter comments like in e.g. > > PROCEDURE P(VAR (*in*) a: ARRAY OF LONGINT); > > are removed. Why? Mh, I do not understand the question. Documentation, like the output of oo= b, is generated from the symbol file. The compiler discards comments at a very e= arly stage, way before the symbol file is generated. -- mva |