[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
goo interoperability with c
i wanted to let people know about some recent goo developments. first
of all, andrew sutherland has completed his master's thesis on a viral
computing dialect of goo. i've made his thesis available through
www.googoogaga.org
secondly, after doing a bunch of multimedia apps in C i'm now starting
to integrate them back into goo in order to realize the dream of making
goo a multimedia-capable language. one big challenge (and age old
problem) is how best to interface to c code. i will describe some new
goo c interfacing mechanisms that i'm readying for release, but first
let's consider very briefly four c extension facilities available in
python: swig, ctypes, c-inline, and pyrex.
swig is a language-neutral semi-automatic header parsing mechanism that
produces separate c files that get compiled and linked into your
application. users are allowed tailor the type mapping according to
their application. ctypes is a python facility that allows one to
import dlls, to enumerate their exported symbols, and to manually
specify their type interfaces with a special python-based c type
system. c-inline permits the definition of c code fragments as python
objects to be executed later. c snippets are specified as python
strings. finally, pyrex allows the intermixing of c and python code
implicitly requesting c code by defining python variables with c types.
in this way, loops can be completely performed in low overhead c if
all loop related variables are defined with c types. the following
presents a pros/cons evaluation of these four facilities:
name pros cons
------------------------------------------------------------------
swig semi-automatic heavyweight
ctypes loads dlls another c type system
c-inline lighter weight cumbersome and no python escapes
pyrex even lighter weight whole other python dialect
in summary, either the solutions are too heavyweight or too
complicated, where the weight is measured in terms of space and speed
as well as amount of extra glue code and the complication is measured
in terms of amount extra mechanism and nuisance to use. pyrex is the
most similar in spirit in terms of mixing c and python code, but it
introduces a whole other c type system and makes compilation dependent
on their the types of variables.
what i think you really want to do is quite simply be able to inline c
code directly into goo, escaping back into goo when necessary, relying
on c for its type system instead of having to mirror it in goo. this
approach is simpler than pyrex in that the execution proceeds either
entirely in c or goo and the distinction is syntactically obvious.
inlining c turns out to be quite straightforward and appropriate for
goo because goo relies heavily on a C backend (including during dynamic
evaluation).
we consider the construction of a simple goo layer on top of a 2d
subset of opengl. as the first example consider the definition of a
goo method for a simplified version of initializing the graphics system:
(dm gl-setup () #{ glutInitWindowSize( 640, 480 ); })
where the #{ ... } form escapes to C executing a series of C statements
and evaluates to false.
from here let's consider graphics functions themselves. for example,
(dm gl-vertex (x|<flo> y|<flo>) #{ glVertex3f($x, $y); })
shows how the $ operator escapes back into goo evaluating the
subsequent sexpression (ala unquote in a quasiquote expression).
unfortunately, in this case, the x and y variables contain goo style
floats and must first be exported (unboxed) to c style as follows:
(dm gl-vertex (x|<flo> y|<flo>)
#{ glVertex3f($(c-export x), $(c-export y)); })
where c-export unboxes the float. c-export methods are defined for all
the basic goo value types (e.g., <log>, <chr>, <int>, <flo> and <str>).
furthermore, users can define their own c-export methods.
unfortunately, embedding direct calls to c-export is verbose and thus
we introduce a shorthand '@s' which is equivalent to $(c-export s).
now gl-vertex becomes:
(dm gl-vertex (x|<flo> y|<flo>) #{ glVertex3f(@x, @y); })
in more advanced situations, the $ operator can also be used to assign
and create pointers to goo variables.
often times users will need to get values back from c in a functional
style. for this we introduce the c expression form #x( ... ) which is
the same as the c statement form except that its value is the value of
the enclosed c expression and where the x modifier in the #x( ... )
specifies the way to interpret the expression as a goo value. valid
modifiers are i for <int>, f for <flo>, s for <str>, c for <chr>, b for
<log>, and l for <loc>. for example, one can grab an integer C macro
constant as follows:
(dv $gl-line-loop #i( GL_LINE_LOOP ))
from here, top level c definitions can be defined at top level with #{
}. for example, a callback can be defined as follows:
#{ int gl_idle(int x) { $(gl-idle); } }
this can also be used to introduce structure definitions, typedefs,
includes, etc.
i'm getting ready to release a new version of goo with this facility
but would appreciate any feedback on it before then.
jonathan