luke2k4_at_gmail.com wrote: > Hi Eclipse users, > I have a question about macro expansion, is there a way to make macro > expansion work while creating terms or calling a goal via the C interface ? Macro expansion normally happens in the parser, i.e. immediately when text (from a file, string, etc) is converted into term structures. When you use the C interface, then there is no parsing, thus no macro expansion. > If I compile the code below and call the main/2 (like in the commented > line) through the TCL/Tk gui or command line it works fine, > but if I load the code by the C interface, construct the very same goal > and invoke it, the macro expansion does not get triggered. > Is there a way to make it work without explicit macro expansion or > explicitly calling update_struct/4? No, the C interface has no way of constructing a declared structure "directly". But I suppose you are aware that something like test_struct{field2:foo} is just pretty syntax for test_struct(_,foo), and the transformation is done according to the struct-declaration. Although it is possible to make your code work (see below), I'd recommend that for the interfacing between C and ECLiPSe you choose simple data structures, list flat lists or arrays of numbers. These are easy to construct and analyse in C, and can then be easily converted from/to more complex ECLiPSe structures on the ECLiPSe side. In your example, you may want to pass a list of field1 parameters, and a list of field2 parameters, and create a list of structures on the ECLiPSe side. Our standard advice on this mailing list: do not try to program ECLiPSe through the C/Java/etc interface - use it only to pass parameters in and results out. > :-module(main). > tr_structure(structure(StructName,FieldList),Struct):- > update_struct(StructName, FieldList, _Old, Struct), true. > :- export macro(structure/2, tr_structure/2, []). > :- export struct(test_struct(field1,field2)). > %main(structure(test_struct, [field1 : 1, field2 : 2]), Out) > main(TestStruct,Field2):- > writeln(TestStruct), > TestStruct = test_struct{ field2:Field2 }. Although not recommended, you could make this work with an explicit call to expand_macros/2 in the following way: :- export struct(test_struct(field1,field2)). %main(structure(test_struct, [field1 : 1, field2 : 2]), Out) main(StructName, Fields, Field2) :- expand_macros(no_macro_expansion(with(StructName,Fields)), TestStruct), writeln(TestStruct), TestStruct = test_struct{ field2:Field2 }. [see http://eclipseclp.org/doc/userman/umsroot145.html for an explanation of with/2] However, this is not very different from what I recommended above, because you have to construct an auxiliary list [field1 : 1, field2 : 2] on the C side, which then needs to be converted to a list of structures on the ECLiPSe side. If you really wanted to construct the structures directly in the C code, you would have to query the struct declaration: ?- current_struct(test_struct, Prototype). Prototype = test_struct(field1, field2) and use that information in your C code to construct test_struct structures with correct arity and argument positions according to the prototype. -- JoachimReceived on Mon Jul 26 2010 - 04:36:14 CEST
This archive was generated by hypermail 2.2.0 : Thu Feb 02 2012 - 02:31:58 CET