example: adds a basic extern method example
authorAlexis Laferrière <alexis.laf@xymus.net>
Sat, 25 Feb 2012 17:41:05 +0000 (12:41 -0500)
committerAlexis Laferrière <alexis.laf@xymus.net>
Thu, 12 Apr 2012 19:38:16 +0000 (15:38 -0400)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

examples/README
examples/extern_methods.nit [new file with mode: 0644]
examples/extern_methods.nit.c [new file with mode: 0644]
examples/extern_methods.nit.h [new file with mode: 0644]
tests/sav/extern_methods.sav [new file with mode: 0644]

index 809a118..bd6e6b2 100644 (file)
@@ -6,4 +6,5 @@
 * int_stack.nit: simple class for a stack of integers implemented with a linked list.
 * clock_more.nit: refine clock to add comparability between clocks.
 * circular_list.nit: simple use of generic classes and nullable types to implement a double-linked circular list.
+* extern_methods.nit: basic use of extern methods, Nit methods implemented in C code
 
diff --git a/examples/extern_methods.nit b/examples/extern_methods.nit
new file mode 100644 (file)
index 0000000..c080348
--- /dev/null
@@ -0,0 +1,60 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2012 Alexis Laferrière <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.
+
+# This module illustrates some uses of the native interface, specifically
+# how to use extern methods. Which means to implement a Nit method in C.
+#
+# Steps to use extern methods:
+# 1. Write the Nit module (like this file), define extern methods
+#    with "is extern" and identify possible callbacks with "import".
+# 2. Run ithe "nits" program on the Nit module, it will generate
+#    two files, extern_methods.stub.[ch] files.
+# 3. Modify those files to implement Nit methods in C.
+# 4. Rename the stub files to extern_methods.nit.c and extern_methods.nit.h.
+module extern_methods
+
+redef enum Int
+       # Returns self'th fibonnaci number
+       # implemented here in C for optimization purposes
+       fun fib : Int is extern
+
+       # System call to sleep for "self" seconds
+       fun sleep is extern
+
+       # Return atan2l( self, x ) from libmath
+       fun atan_with( x : Int ) : Float is extern
+
+       # This method callback to Nit methods from C code
+       # It will use from C code:
+       # * the local fib method
+       # * the + operator, a method of Int
+       # * to_s, a method of all objects
+       # * String::to_cstring, a method of String to return an equivalent char*
+       fun foo is extern import fib, +, to_s, String::to_cstring
+
+       # Equivalent to foo but written in pure Nit
+       fun bar do print "from Nit: self + fib(self) = {self+self.fib}"
+end
+
+print 12.fib
+
+print "sleeping 1 second..."
+1.sleep
+
+print 100.atan_with( 200 )
+8.foo
+8.bar
+
diff --git a/examples/extern_methods.nit.c b/examples/extern_methods.nit.c
new file mode 100644 (file)
index 0000000..22ef5fc
--- /dev/null
@@ -0,0 +1,60 @@
+/* This file is part of NIT ( http://www.nitlanguage.org ).
+ *
+ * Copyright 2012 Alexis Laferrière <alexis.laf@xymus.net>
+ *
+ * This file is free software, which comes along with NIT.  This software is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without  even  the implied warranty of  MERCHANTABILITY or  FITNESS FOR A
+ * PARTICULAR PURPOSE.  You can modify it is you want,  provided this header
+ * is kept unaltered, and a notification of the changes is added.
+ * You  are  allowed  to  redistribute it and sell it, alone or is a part of
+ * another product.
+ */
+
+#include "extern_methods.nit.h"
+
+#include <math.h>
+
+/*
+C implementation of extern_methods::Int::fib
+*/
+bigint Int_fib___impl( bigint recv ) {
+       if ( recv < 2 )
+               return recv;
+       else
+               return Int_fib___impl( recv-1 ) + Int_fib___impl( recv-2 );
+}
+
+/*
+C implementation of extern_methods::Int::sleep
+*/
+void Int_sleep___impl( bigint recv ) {
+       sleep( recv );
+}
+
+/*
+C implementation of extern_methods::Int::atan_with
+*/
+float Int_atan_with___impl( bigint recv, bigint x ) {
+       return atan2( recv, x );
+}
+
+/*
+C implementation of extern_methods::Int::foo
+
+Imported methods signatures:
+       bigint Int_fib( bigint recv ) for extern_methods::Int::fib
+       bigint Int__plus( bigint recv, bigint i ) for kernel::Int::(kernel::Discrete::+)
+       String Int_to_s( bigint recv ) for string::Int::(string::Object::to_s)
+       char * String_to_cstring( String recv ) for string::String::to_cstring
+*/
+void Int_foo___impl( bigint recv ) {
+       bigint recv_fib = Int_fib( recv );
+       bigint recv_plus_fib = Int__plus( recv, recv_fib );
+
+       String nit_string = Int_to_s( recv_plus_fib );
+       char *c_string = String_to_cstring( nit_string );
+
+       printf( "from C: self + fib(self) = %s\n", c_string );
+}
+
diff --git a/examples/extern_methods.nit.h b/examples/extern_methods.nit.h
new file mode 100644 (file)
index 0000000..af89584
--- /dev/null
@@ -0,0 +1,24 @@
+/* This file is part of NIT ( http://www.nitlanguage.org ).
+ *
+ * Copyright 2012 Alexis Laferrière <alexis.laf@xymus.net>
+ *
+ * This file is free software, which comes along with NIT.  This software is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without  even  the implied warranty of  MERCHANTABILITY or  FITNESS FOR A
+ * PARTICULAR PURPOSE.  You can modify it is you want,  provided this header
+ * is kept unaltered, and a notification of the changes is added.
+ * You  are  allowed  to  redistribute it and sell it, alone or is a part of
+ * another product.
+ */
+
+#ifndef EXTERN_METHODS_NIT_H
+#define EXTERN_METHODS_NIT_H
+
+#include <extern_methods._nitni.h>
+
+bigint Int_fib___impl( bigint recv );
+void Int_sleep___impl( bigint recv );
+float Int_atan_with___impl( bigint recv, bigint x );
+void Int_foo___impl( bigint recv );
+
+#endif
diff --git a/tests/sav/extern_methods.sav b/tests/sav/extern_methods.sav
new file mode 100644 (file)
index 0000000..3134c54
--- /dev/null
@@ -0,0 +1,5 @@
+144
+sleeping 1 second...
+0.463647
+from C: self + fib(self) = 29
+from Nit: self + fib(self) = 29