aa85bbd2b5a6c47a0488db07974eb06e5d94f023
[nit.git] / src / ffi / ffi.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2012-2013 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # This module implements the FFI with different languages
18 module ffi
19
20 import c
21
22 redef class MMSrcModule
23 redef fun compile_separate_module(cprogram: CProgram)
24 do
25 super
26
27 if is_extern_hybrid then
28 var visitor = new FFIVisitor( cprogram.program.tc, self )
29 # TODO use cprogram to add generated files?
30
31 # actually compile stub
32 accept_ffi_visitor( visitor )
33
34 # write to file
35 if uses_ffi then
36 visitor.compile
37 end
38 end
39 end
40 end
41
42 redef class FFIVisitor
43 fun compile
44 do
45 var compdir = tc.compdir.as(not null)
46 var base_name = "{mmmodule.cname}._ffi"
47 var c_file = "{base_name}.c"
48 var h_file = "{base_name}.h"
49
50 # header comments
51 var module_info = "/*\n\tExtern implementation of Nit module {mmmodule.name}\n*/\n"
52
53 # header file guard
54 var guard = "{mmmodule.cname.to_s.to_upper}_NIT_H"
55
56 # .h
57 var stream = new OFStream.open( "{compdir}/{h_file}" )
58 stream.write( module_info )
59 stream.write( "#include <{mmmodule.name}._nitni.h>\n\n" )
60 stream.write( "#ifndef {guard}\n" )
61 stream.write( "#define {guard}\n\n" )
62 compilation_unit.header_c_base.write_to_stream( stream )
63 compilation_unit.header_custom.write_to_stream( stream )
64 compilation_unit.header_c_types.write_to_stream( stream )
65 compilation_unit.header_decl.write_to_stream( stream )
66 stream.write( "#endif\n" )
67 stream.close
68
69 # .c
70 stream = new OFStream.open( "{compdir}/{c_file}" )
71 stream.write( module_info )
72 stream.write( "#include \"{h_file}\"\n" )
73 compilation_unit.body_decl.write_to_stream( stream )
74 compilation_unit.body_custom.write_to_stream( stream )
75 compilation_unit.body_impl.write_to_stream( stream )
76 stream.close
77 end
78 end