nitc/ffi: adds the extern_inline module to manage foreign code blocks
authorAlexis Laferrière <alexis.laf@xymus.net>
Tue, 5 Feb 2013 23:37:13 +0000 (18:37 -0500)
committerAlexis Laferrière <alexis.laf@xymus.net>
Wed, 6 Feb 2013 23:09:29 +0000 (18:09 -0500)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

src/syntax/extern_inline.nit [new file with mode: 0644]
src/syntax/syntax.nit

diff --git a/src/syntax/extern_inline.nit b/src/syntax/extern_inline.nit
new file mode 100644 (file)
index 0000000..d2ee779
--- /dev/null
@@ -0,0 +1,115 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2012 <alexis.laf@xymus.net>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Manages foreign code blocks using the Nit FFI
+module extern_inline
+
+intrude import mmbuilder
+import syntax_base
+import primitive_info
+
+# Extern code segment
+class ExternCode
+       var language : nullable String
+       var code : String
+       var location : nullable Location
+end
+
+redef class MMModule
+       # extern code blocks in module
+       var extern_code_blocks : Set[ExternCode] = new HashSet[ExternCode]
+end
+
+redef class MMLocalClass
+       # extern equivalent of class
+       var extern_type : nullable ExternCode = null
+end
+
+redef class MMMethod
+       # extern code bodu of extern method
+       var extern_implementation : nullable ExternCode = null
+end
+
+redef class TExternCodeSegment
+       # removes `{ and `} and return code of interest
+       fun code : String do
+               return text.substring( 2, text.length-4 )
+       end
+end
+
+redef class AExternCodeBlock
+       fun to_extern_code : ExternCode
+       do
+               var language
+               if n_in_language == null then
+                       language = null
+               else
+                       var text = n_in_language.n_string.text
+                       language = text.substring( 1, text.length-2 )
+               end
+               return new ExternCode( language, n_extern_code_segment.code, n_extern_code_segment.location )
+       end
+end
+
+redef class AExternPropdef
+       redef fun accept_property_verifier(v)
+       do
+               super
+
+               # Extern method implementation
+               var n_extern_code_block = self.n_extern_code_block
+               if n_extern_code_block != null then
+                       if not method.is_extern then
+                               v.error( n_extern_code_block,
+                                       "Cannot implement the non extern method {method.full_name} with extern code" )
+                       else
+                               method.extern_implementation = n_extern_code_block.to_extern_code
+                       end
+               end
+       end
+end
+
+redef class AStdClassdef
+       redef fun accept_property_verifier(v)
+       do
+               super
+
+               # Extern type of extern classes
+               var extern_code_block = self.n_extern_code_block
+               if extern_code_block != null then
+                       if not local_class.global.is_extern then
+                               v.error( extern_code_block,
+                                       "Cannot define an extern equivalent in the non extern class {local_class.name}" )
+                       else
+                               local_class.extern_type = extern_code_block.to_extern_code
+                       end
+               end
+       end
+end
+
+redef class MMSrcModule
+       # Syntax analysis and MM construction for the module
+       # Require that supermodules are processed
+       redef fun do_mmbuilder(tc: ToolContext)
+       do
+               super
+
+               # extern code blocks
+               for n_extern_code_block in node.n_extern_code_blocks do
+                       extern_code_blocks.add( n_extern_code_block.to_extern_code )
+               end
+       end
+end
index aa17066..86f01c2 100644 (file)
@@ -22,6 +22,7 @@ import mmloader
 import mmbuilder
 import typing
 import icode_generation
+import extern_inline
 
 # Loader of nit source files
 class SrcModuleLoader