Until I can spec this out properly, I’ll just quote from “Unwanted Software Thoughts Syndrome”
Type Interface Definition Language (TIDL)
Originally I wrote:
An IDL that is essentially the datatype and interface parts of the full Teufel language, with an accompanying code generator. It will generate stub and skeleton code in C much like CORBA. An extension will generate skeleton code for modules in Ruby, Lua, Python, and other scripting languages, not unlike SWIG.
Instead of a Teufel language, however, it will generate C libraries using memory management under the hood but usable in C’s grab-bag of memory techniques (malloc/free, stack allocation, refcounting, etc.)
Later I wrote:
… language and parser for generating stub code in a hybrid function-oriented/object-oriented multiprocess component model …
The result will probably closely resemble XIDL, originally for
Ideally the only difference is whether the code generated has
refcounting APIs or
MPool APIs. The two projects could be unified
with a simple switch, assuming I implemented both.1
The full language will include the assertion language CDL. Implementing assertions becomes much easier when one is also generating the skeletons and stubs on both ends.
Taking some inspiration from XPCOM, one could introduce an Interface Definition Language to more easily define interfaces, declare classes, and generate function skeletons. A tool could even take an IDL representation, parse the C header files for a library, and output a complete wrapper for that library.
Rather than mimic CORBA IDL or C/C++, XIDL would represent how functions really operate across thread and process boundaries.
For example, here’s one possible function to get a substring from a string.
function substring(s: String, start: int, stop: int) => (ss: String, indexes_ok: boolean)
In the ExO runtime functions can return multiple results.2
Here the second result returns whether the indexes indicated a proper substring
start indicated a character after
In cases where there’s only one return value one can use this syntax:
function substring(s: String, start: integer, stop: integer) => String
If there’s no return value, a function (typically called a procedure) can simply omit an arrow entirely:
function set_char_at(s: Char_Buffer, index: int, value: char)
A small but complete XIDL file might look like this:
module exo.util.string is interface Char_Sequence is char_at(i: int) => char length => integer slice(start: int, stop: int) => (result: Char_Sequence, indexes_ok: boolean) slice_from(start: int) => (result: Char_Sequence, indexes_ok: boolean) slice_to(stop: int) => (result: Char_Sequence, indexes_ok: boolean) to_chars: [char] end class Char_Buffer : Char_Sequence is + new + new_copy(s: Char_Sequence) + new_with_chars(wcs: [char]) - append(c: Char_Sequence) - append_all(cs: [Char_Sequence]) - set_char_at(i: int, value: char) - to_string => String end class String : Char_Sequence is + empty + for_char(c: char) + new(s: Char_Sequence) + new_with_ascii(b: [octet]) + new_with_chars(wcs: [char]) + new_with_encoding(e: Symbol, b: [octet]) + new_with_utf8(b: [octet]) - encoding => symbol end function compare(a: Char_Sequence?, b: Char_Sequence?) => int function join(a: Char_Sequence, b: Char_Sequence) => String function join_all(args: [Char_Sequence]) => String end
] means ‘List of` x.
The syntax to specify Records and Tuples is to be determined.
Note that all “features” of an interface have their receiver
as an implicit first argument.
Constructors all have the implicit return value of a class instance.
Also, no argument may be
null unless the type is marked with a