home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mod201j.zip / modula2.exe / os2doc / faq.txt next >
Text File  |  1996-01-04  |  28KB  |  551 lines

  1. Frequently asked questions May-July 1995
  2. ========================================
  3.  
  4. This document is based upon releases 2.01F-2.01H of the Modula-2 compiler
  5. for OS/2. It contains a summary of frequently asked questions
  6. and the author's replies.
  7.  
  8.  
  9. Complex Numbers
  10. ---------------
  11.  
  12. I am testing your OS/2 compiler with some large Modula-2 process simulation
  13. applications that I have developed. The new version (2.01f) seem quite robust.
  14. I will let you know if I find any new bugs.
  15. The ISO Modula-2 standard includes support for complex numbers.
  16. I would very much like to see you include complex number support in a
  17. future release of your compiler. Except for ISO Modula-2, only Fortran
  18. directly supports complex numbers, but Fortran is far too archaic for any
  19. new software development. Of course, complex number arithmetic can be handled
  20. by function calls, but this is still very awkward.
  21.  
  22.     Adding COMPLEX would of course involve some runtime functions like
  23.     PROCEDURE AddCOMPLEX( VAR lval:COMPLEX; rval1,rval2:COMPLEX );
  24.     that is, not just adding reals. However: COMPLEX arithmetic might become
  25.     more complicated if it also includes mixed mode operations with reals,
  26.     e.g. complex x + real y, or SQRT( x ). Sometimes the resulting type
  27.     cannot be determined during compilation, but only at runtime.
  28.     So the whole thing might end up using OOP classes...
  29.  
  30. Complex numbers are always a superset of real numbers. A simple solution
  31. would be to require explicit type conversion of real numbers to complex,
  32. e.g. x = CMPLX(2.0,0)+y, where x and y are of type COMPLEX, so that the
  33. type of operation could be resolved at compile time. For the square root
  34. function, a separate function such as
  35. PROCEDURE CSQRT( x: COMPLEX) : COMPLEX; could be used.
  36. This would be a simple yet effective approach. Mixed mode arithmetic should
  37. not be any more difficult than mixing REAL and INTEGER variables.
  38.  
  39.    I think the additional complexity with such an approach closely matches
  40.    the problem of returning structures (see my reply on the subject
  41.    "function procedures"). Do you have a COMPLEX Modula-2 source module where
  42.    all the basic COMPLEX operators and functions are implemented?
  43.  
  44. The usefulness of being able to return function values of any type is that
  45. the result can be passed as a value parameter to another function or
  46. procedure (as in the case of complex numbers). Also, if source code reads
  47. x := CSQRT(y), then this is immediately identifiable as an assignment
  48. statement. The alternative would be to use a procedure call such as
  49. CSQRT(x,y) to assign the complex square root of y to x. However, in this
  50. case the code is much less transparent, and you would have to see the
  51. procedure definition to know what is being done. This applies to many
  52. different types of situations, and not just complex numbers. The best
  53. implementation may be to push the address of the return value on the stack
  54. before pushing any of the function parameters. In the case of an assignment
  55. statement, the address of the receiving variable would be pushed. In all
  56. other cases, the value would be returned on the stack by subtracting the
  57. type size from the stack pointer before calling the routine, and then pushing
  58. the address of this stack location.
  59.  
  60.  
  61. With regard to possible complex number support for operators + - / *
  62. in a future compiler release, it seems to be not too difficult to
  63. implement ... so if you ever have time to add it, many people would
  64. find it useful.
  65.  
  66.  
  67. OOP
  68. ---
  69.  
  70. I think that your OOP extensions (based on Oberon) are very elegant.
  71. However, only single inheritance is supported. I have previously used
  72. the 16-bit TopSpeed Modula-2 compiler and found that its multiple inheritance
  73. can sometimes be very useful and elegant for solving certain classes of
  74. problems. Are you considering support for multiple inheritance in the future?
  75.  
  76.     At first glance multiple inheritance seems quite simple and natural.
  77.     On closer inspection, however, it suffers various problems. E.g.,
  78.     if class C inherits from A and B:
  79.     1) If A and B contain fields or methods with identical names,
  80.     a name clash results in C, the names are inherited from both superclasses
  81.     and become ambiguous. Hence some mechanism for resolving such name clashes
  82.     would be needed.
  83.     2) If A and B are extensions of a class D, the repeated inheritance may
  84.     result in a diamond structure:
  85.         D
  86.        / \
  87.        A  B
  88.        \ /
  89.         C
  90.     All methods of D are inherited from both A and B. This does not only lead
  91.     to name clashes, all data fields of D are present in both A and B objects.
  92.     Should they now be present twice or only once in C objects?
  93.     3) Multiple inheritance leads to class libraries that are not trees,
  94.     but directed acyclic graphs, thus resulting in greater overall complexity.
  95.     4) Multiple inheritance also leads to less efficient code. A method
  96.     invocation would cause addtitional runtime costs, even if the program
  97.     uses only single inheritance. Multiple inheritance will violate the
  98.     rule that any method name can keep its associated virtual method table
  99.     offset unchanged.
  100.     Most well known class libraries (e.g. Smalltalk's or SOM/WPS's) do
  101.     without multiple inheritance. Even the new Oberon-2 does not implement
  102.     multiple inheritance.
  103.     HOWEVER: There are work around solutions for implementing multiple
  104.     inheritances using single inheritance mechanisms only:
  105.     1)  In many cases a class hierarchy like
  106.           A         B
  107.           |         |
  108.           B   or    A
  109.           |         |
  110.           C         C
  111.     will do the same.
  112.     2) If above mentioned solution does not work, you can wrap B in C
  113.     and inherit only from A or vice versa.
  114.           A   B
  115.           |
  116.           C
  117.            b:B
  118.     A    = POINTER TO ARec;
  119.     Rec  = RECORD ...END;
  120.     C    = POINTER TO CRec;
  121.     CRec = RECORD( ARec ) b:B; ...END;
  122.     3) Or you can also extend A and B to subclasses CA and CB and link
  123.     these via data fields:
  124.           A      B
  125.           |      |
  126.           CA     CB
  127.            b:CB   a:CA
  128.     CA    = POINTER TO CARec;
  129.     CARec = RECORD( ARec ) b:CB; ...END;
  130.     CB    = POINTER TO CBRec;
  131.     CBRec = RECORD( BRec ) a:CA; ...END;
  132.  
  133. Thank you for explaining the difficulties associated multiple inheritance.
  134. The small benefits of multiple inheritence for certain programming problems
  135. probably do not justify the increase in complexity.
  136.  
  137.  
  138. Oberon-2
  139. --------
  140.  
  141.   I have "Programming in Oberon" by Reiser and Wirth. Is that a good reference
  142. book for your compiler? My old TopSpeed manuals contain too much TS specific
  143. stuff to be much use.
  144.  
  145.   
  146.     It certainly is, because that's where I took my OOP-extensions from.
  147.     There is even a better book called "Object-Oriented Programming in
  148.     Oberon-2" by Hanspeter Moessenboeck, published by Springer-Verlag. In
  149.     my opinion it's the best introduction to OOP-pro
  150.     ramming, especially for those (like me) who do not like the messy 
  151.     C/C++ language. In fact, I might one day also write an Oberon-2
  152.     front-end for my compiler. Apart from language extensions, my compiler
  153.     is based upon N.Wirth's "Programming in Modula-2", 4th
  154.     edition.
  155.  
  156.  
  157.  
  158.  
  159. MathLib0
  160. --------
  161.  
  162. I noticed in your Mathlib0 module that you use the FSINCOS instruction
  163. in both the sin and cos functions. You should be using FSIN and FCOS
  164. instead because unless you need sin and cos simultaneously,
  165. the FSINCOS instruction is a little slower and, according to Intel,
  166. may also be less precise.
  167.  
  168.     The FSIN instruction takes the sine of ST(0). However: Instead of
  169.     simply replacing ST(0) with the answer, the 387 does a curious thing:
  170.     it pushes an extra slot onto the floating point-point stack, then it
  171.     replaces the input operand with two numbers Y = ST(1) and X = ST(0),
  172.     such that Y/X will give the correct answer. Hence, the FSIN would have
  173.     to be followed by a FDIVR ST, ST(1). The total execution time would be
  174.     slightly above the FSINCOS approach.
  175.  
  176.     As regards the math libraries: Porting existing 287-inline code to
  177.     387-inline code shouldn't be too difficult. My compiler always assumes
  178.     the presence of an FPU. The only purpose of compiler switch -F
  179.     ( or directive (*$F+*) ) is to tell the inline assembler that it should
  180.     also accept FPU-instructions.
  181.  
  182. I realize that the FSINCOS instruction appears more convenient than the
  183. FSIN and FCOS instructions, however, I am concerned by the following
  184. comment on page 371 in the book "Programming the 80386" by John H. Crawford
  185. and Patrick P. Gelsinger:
  186.  
  187. "The sine result of FSINCOS may be less precise than the FSIN and FCOS
  188. instructions".
  189.  
  190. I presume that this information originates from Intel. I have not done
  191. any tests myself to observe the difference in accuracy.
  192. With regard to instruction timings, FSIN requires 122 to 771 cycles for
  193. the 80387 or 193 to 279 cycles for the 80486.
  194. The FSINCOS instruction timings are 194 to 809 cycles for the 80387 or
  195. 243 to 392 cycles for the 80486.
  196. Since sine calculation using the FSIN instruction requires an additional
  197. FDIV instruction (88 cycles on 80387 and 73 cycles on 80486), the
  198. FSIN + FDIV timing is roughly equivalent to the timing of the FSINCOS
  199. instruction. Therefore, there is no real penalty for using the FSIN
  200. instruction, but there may be a slight advantage in accuracy.
  201. For the sake of a potential slight increase in accuracy with no execution
  202. speed penalty, I think its best to use the FSIN+FDIV combination.
  203. There is no mention in the same book that the FSINCOS instruction is
  204. less accurate than FCOS+FDIV. However, the FCOS instruction has the same
  205. timing as the FSIN instruction, but it requires only an additional FSTP ST
  206. instruction  (12 cycles on 80387 and 3 cycles on 80486) instead of an FDIV
  207. instruction. Therefore, if you want to calculate a cosine, FCOS is always
  208. faster than using FSINCOS.
  209.  
  210.     You have convinced me. The new MathLib0 now uses FSIN/FDIVP and
  211.     FCOS/FDIVP. I have also inserted some FWAITs into sqrt and exp,
  212.     just to be on the safe side. These are normally produced automatically
  213.     by the code generator after FST or FSTP, if the next instruction is
  214.     not a FPU-instruction, unless writing explicit INLINE instructions.
  215.     The updated Mathlib0 will be uploaded with my next compiler release.
  216.  
  217.  
  218.  
  219. Debugging
  220. ---------
  221.  
  222. Do you have a compiler option to output assembler code? I would be interested
  223. in seeing and commenting on the type of code the compiler generates.
  224.  
  225.       No, I haven't. But the new compiler release supports the SD386 source
  226.       level debugger (source level lines, full symbols and types in a few
  227.       weeks time). Here is a SD386 debug sample (combined assembly and
  228.       source view):
  229.  
  230.           File  Run  Breakpoints  Search  Data  View  Settings  Misc  Help
  231.         PROCEDURE WriteLn();
  232.         CONST
  233.           cr = CHR( 13 );
  234.           lf = CHR( 10 );
  235.         VAR
  236.           buffer       : ARRAY [0..1] OF CHAR;
  237.           rc           : APIRET;
  238.           BytesWritten : LONGCARD;
  239.         BEGIN
  240.         178B01B7  C80C0001        ENTER      000CH,01H
  241.         178B01BB  51              PUSH       ECX
  242.         178B01BC  52              PUSH       EDX
  243.         178B01BD  53              PUSH       EBX
  244.         178B01BE  56              PUSH       ESI
  245.         178B01BF  57              PUSH       EDI
  246.         178B01C0  06              PUSH       ES
  247.           buffer[ 0 ] := cr;
  248.         178B01C1  C645FA0D        MOV        BYTE_[-6H+EBP],0DH
  249.           buffer[ 1 ] := lf;
  250.         178B01C5  C645FB0A        MOV        BYTE_[-5H+EBP],0AH
  251.           rc := DosWrite( ScreenHandle, buffer, 2, BytesWritten );
  252.         178B01C9  8D7DFA          LEA        EDI,[-6H+EBP]
  253.         E:\TERMINAL.DLL <C:\CLIB\MOD32\OS2MOD\TERMINAL.MOD>          Thread 1
  254.         Instruction Step
  255.  
  256.       The debugger works fine for my compiler. I haven't yet tested IPMD.
  257.       As far as I know IPMD uses the same internal debug formats.
  258.       You can also source-debug DLLs with SD386. I'll test SD386 a little bit
  259.       further, just to see, whether it will also handle PM applications and
  260.       SOM/WPS classes.
  261.  
  262.  
  263. Foreign definition modules
  264. --------------------------
  265.  
  266. I notice you have DEF and LIB files in the os2lib and the corresponding 
  267. Modula DEF modules in os2api when you have proc declarations and a 
  268. standalone DEF module (e.g. os2def.def) for types and constants. 
  269. Is this correct?
  270.  
  271.       Yes, it is! The DEF-files in the OS2LIB directory are not needed for
  272.       the compiler. I only used them for creating import library files (*.LIB).
  273.       Any DEF-file in the OS2LIB-directory is basically a linker definition file,
  274.       containing the target DLL-name and its exported names, along with their
  275.       ordinals. Such a linker definition file is read by the IMPLIB utility
  276.       which then creates an import LIB-file for the target DLL. Unfortunately,
  277.       the *.DEF file name extensions are also used by Modula's definition files,
  278.       hence I had to place them into separate directories, e.g. OS2API and
  279.       OS2MOD. It is only for the linker response files where I use *.LDF
  280.       instead of *.DEF for the compiler-generated linker definition files,
  281.       which are referenced in the linker response file *.RSP.
  282.  
  283. Also, I am planning on making heavy use of the MMPM and DIVE API's (and
  284. possibly the OpenGL API's) so if you aren't planning on creating your own
  285. series of Modula DEF modules for them, do you have any suggestions on the
  286. easiest way to create my own?
  287.  
  288.       At the moment I am busy writing IPMD debugger support, so I am afraid
  289.       it will take some time before writing additional API definition modules.
  290.       But you can write your own definition modules for *.LIB and *.DLL files.
  291.       You will always find the corresponding *.H files for the C-language.
  292.       I've manually translated almost all *.H files from the OS/2 Developers
  293.       Toolkit 2.x to the *.DEF files. The name of the definition module must
  294.       match the DLL-name or LIB-name (except for the different file extensions).
  295.       While porting from a *.H file you will find many function prototypes using
  296.       pointer paramaters. These can be expressed either as VAR-parameters
  297.       (passed by reference) or as pointer-parameters (passed by value ) in
  298.       Modula. C-language makes no distinction between a pointer to array
  299.       and pointer to type.
  300.  
  301.       For instance, a C-prototype like
  302.         void <proc-id>( char* s );
  303.       may be expressed as
  304.         PROCEDURE <proc-id>( VAR s : CHAR );
  305.       or (if it is an input/output string)
  306.         PROCEDURE <proc-id>( VAR s : ARRAY OF CHAR );
  307.       or (if it is an input string)
  308.         PROCEDURE <proc-id>( s : ARRAY OF CHAR );
  309.  
  310.       The procedure-headings must be preceded by a (*CDECL+*) comment embedded
  311.       directive because C uses different parameter-passing order and different
  312.       return sequence (callee clears stack). An open array parameter is always
  313.       passed as a pointer. If it is declared to be passed by value (not a
  314.       VAR-param) the procedure makes a local stack copy (unless procedure is
  315.       C-style declared).
  316.  
  317.  
  318.  
  319. Workframe/2 integration
  320. -----------------------
  321.  
  322. Your latest readme says something about a future IDE and Debugger. I'm using
  323. your compiler right now with WF/2 ver 2.1. The automatic dependency checking
  324. of your compiler takes care of 90% of the work ... I have the rest of the
  325. link, rc, etc commands in a CMD file that I edit (I haven't figured out how to
  326. get MakeMake to deal with RSP files yet). I was also pleasantly surprised to
  327. find that I could compile in a WF Monitor window and drag my errors to my
  328. editor and have them highlighted.
  329.  
  330.       Congratulations! You are the first one who has integrated my compiler
  331.       into Workframe/2. How do you do this? I have never used Workframe/2,
  332.       only Multi-Edit from American Cybernetics. There are many users who'd
  333.       like to adopt my M2 into WF/2 but don't know how. Maybe you can E-mail
  334.       me a summary on how to do it, and I'll put it into the *.INF-files.
  335.       As regards the IDE (other than WF/2): Someone has offered me a sample
  336.       IDE. However, it will take some time to port it into Modula-2.
  337.  
  338. My Modula-2 Settings for IBM's WorkFrame/2 ver2.1
  339.  
  340. Composite Project Folder - Cribbage (substitute your own here)
  341.   Notebook Settings - Relevant Pages (set the following items after creating
  342.   the contents)
  343.      Page 1 - Target, Target Project = Cribbage Project
  344.      Page 2 - Sequence, Add Cribbage Project to Project Sequence
  345.   Composite Project Contents
  346.   1) Cribbage Log     - a WF/2 Actions Log
  347.        No settings needed ... just drag the Actions Log Template inside
  348.        the Composite Project and give it a name.
  349.   2) Cribbage Profile - a WF/2 Actions Profile
  350.        Drag the Actions Profile Template inside the Composte Project and
  351.        name it. Settings as follows :
  352.          Page 1
  353.            The only thing different here from the regular settings given
  354.            the tutorial is the compiler. Select Add. Select COMPILE as
  355.            class, give it a name like Modula-2 Compiler and enter
  356.            c:\mod32\os2bin\mod.exe (or whatever the path you actually
  357.            have mod.exe) in the "Command" field. The path is not necessary
  358.            but I like to know where all my tools are coming from.
  359.            Select the "Monitor", "Regular Popup" and "Files" buttons. You
  360.            may want to mess with the latter 2 to suit your organizational
  361.            needs but the first needs to be selected if you want your
  362.            compiler output to go to a WF/2 monitored session. (i.e., you
  363.            want to be able to go directly to source errors in your WF/2
  364.            enabled editor).
  365.          Page 2
  366.            In the "Source masks/types" field, enter *.def and *.mod, each
  367.            on its own line. In the "target masks.types", enter *.obj and
  368.            *.rsp
  369.            each on its own line. If you've added all of this stuff in your
  370.            Default Actions Profile, then these masks will appear in the
  371.            "Available Types" window and you can simply select them from
  372.            there.
  373.          Page 3
  374.            Press Reset. This will enter DDE3DEF2 in the Options DLL name
  375.            field and DEFAULT in the Entrypoint Class. Scroll down and select
  376.            COMPILE as the entrypoint.
  377.          Page 4
  378.            In the "Command" field, enter view c:\mod32\os2doc\mod-us.inf (or
  379.            whatever your path and preferred help file).
  380.          Now click on Add and the COMPILE class should be added to your
  381.          Actions Profile.
  382.   3) Cribbage Project - a WF/2 Project
  383.        Open the Settings notebook
  384.          Page 1 - Source
  385.            Enter all directory paths that contain your source code in the
  386.            "Source directories" window. Enter *.* in the "File Masks".
  387.          Page 2 subpage 1 - Target
  388.            Make the Working Directory the same as the main source directory.
  389.            Ignore the Make File entry unless you have figured out how to
  390.            write Make files ... I haven't and IBM's MakeMake doesn't
  391.            understand RSP files. (Or I haven't figured out how to do it).
  392.          Page 2 subpage 2 - Target
  393.            If your main module is called Main.mod then enter Main.exe in the
  394.            "Target program file name" field and select the Monitored button
  395.            so
  396.            that errors get directed to the WF/2 monitor. If your program
  397.            requires
  398.            command line parameters, put them in the "Parameters" field.
  399.          Page 3 - Profile
  400.            Drag and drop your Actions Profile object into the "Actions
  401.            Profile"
  402.            field. It will then fill in the Title automatically.
  403.          Page 4 - Actions subpage 1
  404.            Select the Modula compiler and click on Options. The Compile
  405.            Options
  406.            page will come up. Click on default and then add after the %f, any
  407.            compiler switches exactly as you would on the command line. Leave
  408.            the Error Template in its default state. Click Ok. Repeat this
  409.            with
  410.            your WF/2 enabled editor and insure that Send Errors to Editor is
  411.            clicked on. For me, I just Clicked Default and it worked fine. I'm
  412.            using EPM 6.0C Beta as my editor but Preditor and Rimstar both
  413.            work.
  414.          Page 4 - Actions subpages 2 and 3
  415.            I ignored these since the RSP files tell the linker what files to
  416.            get
  417.            and what to do with them and also contain the switches passed from
  418.            the
  419.            compiler settings (e.g. stacksize, VIO or PM, etc)
  420.          Page 5 - Monitor
  421.            Try Multiple concurrent monitors on or off and see what you like
  422.            the
  423.            best. I like a single monitor to avoid screen clutter.
  424.          Page 6 - Access
  425.            Click Default.
  426.        The rest of the pages are just standard folder stuff.
  427.  
  428. Now when I open the Composite Project folder I see the above 3 objects. If I
  429. open the Project Folder, I see all of the files in my source directory(s).
  430. If I right click on a file with a MOD or DEF extension, COMPILE should be
  431. one of the menu options. If I set rc.exe up also in my actions profile,
  432. then I will see a COMPILE on all *.rc files as well. Since you specified the
  433. source masks for each compiler, WF/2 knows what to invoke.
  434. The modula compiler then handles the compilation of all dependent modules
  435. so a DEP file is not needed. You can see how powerful this can be especially
  436. if you are compiling some DLL's as well. You can group them in another Project
  437. Folder within the Composite folder and specify different compiler switches
  438. for them. Then a COMPILE on one of the objects in the DLL folder will behave
  439. differently than the COMPILE in the "EXE" folder. The ability to group files
  440. based on their actions or output is a nice WF/2 ver2 feature
  441.  
  442. I use the "right click" method to compile my modula source, resource files,
  443. help files etc. Then I have an OS/2 cmd file that contains the rest.
  444. See the Hello.Mod instructions for what to put in it. In that case I
  445. selected COMPILE from hello.mod's and hello.rc's menus, and placed the
  446. LINK386 @HELLO.RSP and RC HELLO.RC HELLO.EXE commands in the cmd
  447. file and selected Run/Monitored from its menu. The cmd file solution is a
  448. little messy because you have to manually add in all RSP, RC, etc files to
  449. insure a good link. If you compile a new source module but forget to add its
  450. RSP to your cmd file then the link will fail. If I can figure out how to
  451. create a proper Make file or get MakeMake to create a valid one then I can
  452. eliminate this manual step. In any event, having the ability to
  453. direct the editor to my compile errors is a big plus.
  454.  
  455. If your editor is WF enabled, compile errors that show up in a monitored
  456. session can be either double clicked on to bring up the editor with those
  457. line numbers highlighted or you can drag them to your editor and get the same
  458. result. You can then step through the errors getting a description of each one.
  459.  
  460. Hope this helps others get their modula going with WF/2. It's working nicely
  461. for me. If anyone out there gets MakeMake working here then I'd like to hear
  462. about it.
  463.  
  464.  
  465.  
  466. FCOS/FSIN mysteries
  467. -------------------
  468.  
  469. The sin(x) and cos(x) functions in MathLib0 do not work. Corrected versions
  470. are given below. ...
  471.  
  472.     Why not? The book "The 80386/387 Architecture" by Stephen P.Morse says
  473.     that FSIN causes an extra slot to be pushed onto the floating-point stack
  474.     and that it then replaces the input operand with 2 numbers y=ST(1) and
  475.     x=ST(0), such that y/x will give the correct answer. That's why I put
  476.     an FDIVP ST(1),ST after FSIN. I'll test it again with the SD386 tomorrow
  477.     and let you know what I get.
  478.  
  479. I too was surprised that your original coding using FSIN did not work.
  480. According to the book "Programming the 80386" by J.H. Crawford and
  481. P.P. Gelsinger, the effect of the FSIN instruction is to set the registers
  482. ST=1.0 and ST(1)=sin(x), where x was the original value in ST. However,
  483. I also have "Microsoft's 80386/80486 Programming Guide", 2nd edition
  484. by R.P. Nelson, which says that FSIN simply replaces ST with sin(ST).
  485. (The FCOS instruction has the same discrepancy.) To answer the question,
  486. I ran some tests on my Pentium 90 MHz machine. I used Borland C++ for OS/2
  487. version 1.5, which has an integrated debugger that allows one to track the
  488. numeric coprocessor contents step-by-step. I found that the FSIN and FCOS
  489. instructions DO NOT push 1.0 into ST. They return the result directly in ST.
  490. Any attempt to carry out FSTP ST(1),ST resulted in an error, since ST(1) was
  491. empty. So I conclude that the earlier 80386 information is incorrect and may
  492. be based on early design information, but not production releases of the math
  493. coprocessors. I corrected the sin() and cos() functions in MathLib0 and they
  494. now work correctly (except for the bug in FCOS instruction coding).
  495. If you get different results, then there may be a difference between different
  496. math coprocessord (80387 vs. Pentium), but I will be further surprised to see
  497. this.
  498.  
  499.     I've just done some testing on my 486DX-2 66 machine, with the same
  500.     results than yours. It seems Intel has changed the 80x87 architecture,
  501.     at least for 487 and 587. Maybe someone else will read this forum message
  502.     and let us know how the 387 processes the FSIN and FCOS instructions.
  503.     For the time being I've changed the MathLib0 as you have suggested.
  504.     As far as I remember Intel has its own CompuServe forum, hope to get
  505.     some official information from there.
  506.  
  507.  
  508. Typed constants
  509. ---------------
  510.  
  511. I can not get the following structured "CONST" to compile in definition module. 
  512. It compiles fine in implementation module.
  513. CONST CoreXlate : ARRAY OF INTEGER = [1,2,3,4,5];
  514.  
  515.     Currently typed constants are only supported for implementation modules, 
  516.     not for definition modules. The reason is, that definition modules only 
  517.     describe the externals of variables or procedures, not their 
  518.     implementational details. You can get around this problem when you declare 
  519.     a pointer to the array and set that pointer to the initialized array 
  520.     variable in the implementation module.
  521.  
  522.  
  523. REXX support
  524. ------------
  525.  
  526. Are you aware of GPF'S 3GL GUI designer ? We are considering it  
  527. as a front end to develope user interface and make calls to process 
  528. control software developed with your compiler. It generates "C" code  or
  529. "REXX" for user interface but has support for hooking to DLL'S and 
  530. static library's  from other languages.  Any comments you have in 
  531. requards to this would be appreciated.
  532.  
  533.  
  534.     You can develop REXX DLLs using this Modula-2 compiler. Tony Busigin
  535.     has done some pioneering work on this. Any DLL called from REXX
  536.     requires a certain API suitable for REXX. My latest upload will 
  537.     include a code sample illustrating how to develop DLLs for REXX.
  538.  
  539.     REXX has by default a very small stack only, hence it is often useful
  540.     to switch to another bigger stack within the DLL by using
  541.     SYSTEM.NEWPROCESS and SYSTEM.TRANSFER.
  542.  
  543.     I do not not recommend static libraries, because every programming
  544.     language has its own runtime library. Mixing 2 different runtime
  545.     libraries might cause more work than necessary. Use dynamic linking
  546.     instead with DLLs developed in Modula-2. This compiler
  547.     supports DLL interfaces for Pascal-style, C-style, and REXX-style
  548.     APIs, all of which is simply a matter of writing corresponding
  549.     definition modules.
  550.  
  551.