Discussion:
Conversion style for OS X include files...
(too old to reply)
Charles Turner
2006-07-15 02:01:08 UTC
Permalink
Greetings-

I sat down this evening with some idea of converting the entire
Components.h include file to MacForth structures, etc., etc.

Aside from the large amount of typing, it occurred to me that this
isn't a great idea, since all the unused structs, etc. would end up
being compiled into the dictionary and merely take up space if I didn't
have a vital need for them in my program.

Has/is anyone thinking about how to organize this information? Anyone
got a method they like or works well?

Best and thanks, Charles Turner
ward mcfarland
2006-07-15 10:39:07 UTC
Permalink
Post by Charles Turner
I sat down this evening with some idea of converting the entire
Components.h include file to MacForth structures, etc., etc.
Aside from the large amount of typing, it occurred to me that this
isn't a great idea, since all the unused structs, etc. would end up
being compiled into the dictionary and merely take up space if I didn't
have a vital need for them in my program.
Has/is anyone thinking about how to organize this information? Anyone
got a method they like or works well?
Funny you should ask...

"C" header files from Apple are usually full of stuff I am not
interested in. At the least, they have #if's #ifdef's #include's
galore. So I typically, I copy the contents of the file I am interested
in, like 'gl.h' with its 500+ #define into a 4th source file, naming it
something like 'GL Defines.4th'


I then add a little stuff at the top (and this is copied from such a
Post by Charles Turner
\ Example of bulk including a bunch of #DEFINES from a C header file
\ These will be kept in a special vocabulary that will not increase
\ the code size of turnkey
\ In 3 places, I had to add a space after /* so that it would load
\ from Apple's gl.h
\ found in /Developer/SDKs/MacOSX10.4u.sdk/usr/X11R6/include/GL/gl.h
lacking #define include" :EXTRAS:Mac Enums"
anew --gldefines--
The comments remind me how I did it, in case I have to do it again when
Apple updates its headers.

The conditional include adds the source file for handling the C #defines

The ANEW makes the defined words easier to use LOCATE with, and handles
auto forgetting the contents if I need to recompile the file.


The actual contents of the rest of the file are from the .h file, and
look like...

/*
* Constants
*/

/* Boolean values */
#define GL_FALSE 0x0
#define GL_TRUE 0x1

/* Data types */
#define GL_BYTE 0x1400
#define GL_UNSIGNED_BYTE 0x1401
#define GL_SHORT 0x1402
#define GL_UNSIGNED_SHORT 0x1403
#define GL_INT 0x1404
#define GL_UNSIGNED_INT 0x1405
#define GL_FLOAT 0x1406
#define GL_DOUBLE 0x140A
#define GL_2_BYTES 0x1407
#define GL_3_BYTES 0x1408
#define GL_4_BYTES 0x1409

etc etc etc


The first couple of times I included the file, I found the lazy author
of 'gl.h' didn't put spaces after a couple of /*'s. I fixed those, and
it compiled nicely.


The #defines are all put into a special wordlist/vocabulary called
TMACENUMS. o use these constants after they have been added, you just
add an

ALSO MACENUMS
before using GL_UNSIGNED_BYTE etc.


The trick is that a MacForth vocabulary is really an 'Actel', an
object-like construct. Each vocab lives in its own chunk of memory (not
in Code or Data area) and has its own dispatch table for all functions
done with a vocab, like adding/removing an entry, searching, looking up
a token, etc, and the action that INTERPRET should take when it finds a
token in that vocab.

So, MACENUMS behaves as a normal vocabulary, EXCEPT it saves the
constant value of each #define as its TOKEN, and has a special INTERPRET
action that executes/compiles (depending on STATE) the primtive for
LITERAL. The behavior is much like CONSTANT's run-time behavior,
except it uses its own token for the value.

500 normal constants would take up 12 bytes each, or 6000 bytes of Code
space in the dictionary. 500 MACENUM words take up NO extra CODE area
except for the code to support the special vocabulary (about 800 bytes).

This makes no practical difference with the 2G virtual memory allotment
in OS X during development, but can make a big difference in the size of
a turnkeyed application, since all of a Turnkey's vocabs are discarded
when it is built.


Besides #DEFINE words, "Mac Enums" can handle assembler EQU's by
surrounding them with ADEFINES: ... ;ADEFINES like this:

ADEFINES:
kAEViewsFontChanged EQU 'vfnt' ;asm type cpmment
kAHInternetConfigPrefErr EQU -10791
kasselectinit equ $1001
;ADEFINES


and enum's are pretty easy also:

enum {
kMouseTrackingMouseDown = 1 , \ forth style comment
kMouseTrackingMouseUp = 2 , /* trailing C-style comment*/
kMouseTrackingMouseExited = 3 ,
\ CommentedConstant = 9876 ,
kMouseTrackingMouseEntered = 4, \ no space before the ','
kMouseTrackingMouseDragged = 5,
kMouseTrackingKeyModifiersChanged = 6, // other style C constant
kMouseTrackingUserCancelled = 7,
kMouseTrackingTimedOut = 8,
kMouseTrackingMouseMoved = 9
kAlphamericTest = FOUR_CHAR_CODE('wind'), \ 2003398244
kHexTest1 = 0x999 \ 2457
kHexTest2 = $123 \ 291
kHexTest3 = 0x-1, \ not an expected format
kHexTest4 = $-1, \ not an expected format
\ also can handle 'EQU' form
kMouseTrackingMouseMovedTest1 equ 0x999 \ 2457
kMouseTrackingMouseMovedTest2 equ $123 \ 291
};

and

/* we can handle
a multiline
C-style
Comment
*/

as long as white space surrounds the /* and */


Some of the primitive Mf words for this:

: #DEFINE ( -- )
blword false ParseOneEnum
;

: ENUM ( -- )
postpone \ \ skip the rest of the line
AddEnums ;


: ENUM{ ( -- ) \ handle this common C-ism
enum ;

: AddEnums ( -- ) \ add all ENUM's or EQU's until done
BEGIN
blword \ get next word
" };" =pocket \ ? end of a 'C' ENUM
" ;ADEFINES" =pocket \ ? end of an Assembler ADEFINES:
OR
not
WHILE \ blword returned a presumed new Constant Name
true ParseOneEnum \ so parse the line and create a new Constant
REPEAT
drop
;



Hope this answers your question.

-- w
Charles Turner
2006-07-15 12:41:36 UTC
Permalink
Really nice, Ward!

I'll take a look at this today. I assume that STRUCTS and MACHOFUNCS
would have to be declared/defined in a separate file? If so, do they
end up in a similar 'Actel vocabulary' area or do they end up in
CODE/DATA space?

Best and thanks, Charles
ward mcfarland
2006-07-15 13:26:31 UTC
Permalink
Post by Charles Turner
I'll take a look at this today. I assume that STRUCTS and MACHOFUNCS
would have to be declared/defined in a separate file? If so, do they
end up in a similar 'Actel vocabulary' area or do they end up in
CODE/DATA space?
No need for a separate file. Only constants defined with the C-style
format are added to MacEnums.

All our vocabs are Actels. And all "normal" vocabs we use all have the
same actions for vocab-related functions, like adding/removing an entry,
searching, looking up a token, etc, and the action that INTERPRET should
take when it finds a token in a given vocab.


There are two ways to add words to the MacEnums vocabulary.
One would be to explicitly do it:
ALSO MacEnums DEFINITIONS
but this should NEVER be done, because MacEnums is not a "normal" vocab
and you should not add words to it with normal Forth defining words. In
fact, think of MacEnums as a special name-value association list that
behaves a lot like a standard Forth wordlist, but not entirely so.
INTERPRET with a normal Forth wordlist/vocab would compile or execute an
execution token. INTERPRET with MacEnums takes the word's token and
does what LITERAL would do with it (compiles the token as a constant or
puts the token on the stack)


ParseOneEnum is the primitive that decodes the line of C and adds the
named constant to MacEnums. It is the ONLY word that modifes the
contents of MacEnums.

MacEnums *can* be added to the search order so its words are found and
compiled/executed by INTERPRET as described above.

Continue reading on narkive:
Loading...