On Friday, December 26, 2014 7:30:53 AM UTC-6, fir wrote:
> W dniu piątek, 26 grudnia 2014 06:05:43 UTC+1 użytkownik luser droog napisał:
> > I fear to some I may already have cried wolf a time too many.
> > But, this time, it's not some crazy golfed-up jazz. Rather,
> > it's the other thing I've been doing wherein I really did
> > follow all your collective advices.
> >
> > The project homepage:
> >
http://code.google.com/p/xpost
<snip>
> i may only say on code lookin, looks clean, not bad (though i seen codes looking better - but judging the style of code is a bit inexact ;/ this seem like a 10% or so 'too long' (inexact feeling ;/)
>
A lot of the code has become longer to conform to the coding conventions.
My earlier versions were written in a much more compact style. But this
proved to be distracting to my earlier reviewers.
https://groups.google.com/d/topic/comp.lang.c/l6xjtiIfrfI/discussion
> this im saying, moderately experienced
> programmer coding in much chaotic and dirty style ;/
>
> If authar want to say with own words what is this code doing, what was hard part etc i would also like to hear, talking on specyfic projects in depth it is always the thing i like
Ok. Well, so far it's mostly a clone of ghostscript for simple uses.
If you run `xpost` without arguments, it will open a graphics window
(letter dimensions, 1 point-per-pixel), print some initialization messages
and then a prompt, expecting postscript language commands to be typed.
$ xpost
geom 1 : (null)
geom 2 : -1x-1+0+0
loading init.ps...
DATA_DIR =/usr/local/share/xpost
loading err.ps...
$error installed....error installed...errordict installed...
eof
err.ps
eof
init.ps
loading graphics.ps...
loading device.ps...
loading image.ps...
loading pgmimage.ps...eof
pgmimage.ps
loading ppmimage.ps...eof
ppmimage.ps
eof
image.ps
loading nulldev.ps...eof
nulldev.ps
eof
device.ps
loading gstate.ps...eof
gstate.ps
loading color.ps...eof color
loading path.ps...eof
path.ps
loading clip.ps...eof
clip.ps
loading paint.ps...eof
paint.ps
loading font.ps...eof
font.ps
eof
graphics.ps
graphics loaded, calling initgraphics
[ 1 0 0 -1 0 792 ]
Xpost version 0.0.1
PS>
You can see from the init messages that a lot of the graphics is
implemented in the postscript language. So there is a "core"
interpreter which is written in C, and then an upper layer which
is written in postscript. It is my understanding that Forth is
often implemented similarly, with an "inner loop" and an "outer
loop".
The "outer loop" is in /data/init.ps:/executive . It uses the
postscript "special file" %statementedit to read from the keyboard.
The %statementedit special file is implemented in
src/lib/xpost_file.c:statementedit() . It is responsible for
reading lines until a complete "statement" is read, with all
braces and parens (but not square brackets) balanced.
After this, the outer loop uses the sequence `cvx exec` to pass
the file-object representing the statement over to the "inner
loop" which is implemented in /src/lib/xpost_interpreter.c:eval() .
The eval() function executes a file by calling evalfile() which
uses the postscript `token` operator to read the first object
from the file and construct the internal postscript object
which represents it. For more background on the token operator,
see the old clc discussion "embarrassing spaghetti code needs
stylistic advice"
https://groups.google.com/d/topic/comp.lang.c/_m0DEiFqCv0/discussion
The basics of the behavior described so far were all present in
the first version I posted four years ago. The "hard part" has
always been memory management. Postscript has a very different
way of using memory than the C standard library directly
supports. So I had to design my own memory architecture and
the algorithms to support it. The overall story of the memory
management saga is in:
http://code.google.com/p/xpost/wiki/EvolutionOfXpost
So early versions are discussed in
https://groups.google.com/d/topic/comp.lang.c/0r0GyJA1bnA/discussion
https://groups.google.com/d/topic/comp.lang.postscript/tpSevlR1BJ8/discussion (beginning with the message "A Working Prototype VM")
and
https://groups.google.com/d/topic/comp.lang.postscript/VsFzRwnuM_E/discussion (beginning with the message "prototype save-restore mechanism")
From another angle, "how it works" is it describes a sort of "byte code"
or internal representation for all the various types of object it needs to
manipulate. This is described in the same thread as the "prototype save-
restore mechanism" mentioned above, and also in /doc/NEWINTERNALS.
But basically, it squeezes all objects into 8 bytes. So 2 machine words
on a 32bit machine or 1 machine word on a 64bit machine.
Simple objects such as integers, booleans and reals fit into the 8-byte
structure. But composite objects such as strings and arrays and dicts
contain references to data elsewhere in memory. 19 bits are used to
specify an index into the memory table (which contains a pointer to
the actual data) and 16bits are used to specify and offset in that data
and 16bits for the size (in whatever units are appropriate for the type:
bytes for strings, objects for arrays, pairs for dicts).
This is convenient for operators such as `getinterval` which returns
a substring or subarray of a given string or array. It can be implemented
without actually looking into memory, just by manipulating the fields
of the 8-byte object.
After getting all of the above working, a further "hardest part" was
a collaborative effort with a volunteer, Vincent Torri, who wrote
the autotools files and tested building on various systems.
After that, still another "hardest part" was migrating the interpreter
into the library. This involved expanding many of my terse identifiers
into longer, name-spaced names. But it also meant unraveling the
inter-dependencies among my various "modules", as I liked to call them.
And eliminating my use of setjmp and longjmp for error handling,
upon being informed that this was inappropriate for a library.
But of course, there were immediate benefits from all of this work.
Most of the code is pretty solid, though I say so myself (and am
quite biased). But there are some infelicities.
In the operator table, src/lib/xpost_operator.c, I originally
used un-prototyped function pointers to hold pointers to the
various operator functions which may received different numbers
of arguments. The number is tracked separately and a function
is only called with the correct number, but we kept getting
warnings from the compiler. So I went ahead and added a prototype
and lots of casts everywhere. But it feels iffy. Like lying
to the compiler is worse that keeping secrets from it.
I dunno. After the change I haven't really run into it enough
to have accumulated any actual irritation about it.
Umm. I think I forgot the question some time ago.
Hope this made some kind of sense!
--
droog