nakkaya/ferret

calling function in another package produces C++ compiler error

esp1 opened this issue · 10 comments

esp1 commented

The following code generates a C++ compiler error:

; other.clj
(defn foo [] "hi")

; main.clj
(require 'other)
(print (other/foo))

Compiling the generated C++ code results in this error:

src/main.ino: In function 'void ferret::program::run()':
src/main.ino:1819:28: error: 'other_foo' was not declared in this scope
            run(print(),run(other_foo));
                            ^
esp1 commented

Urgh. This is really a separate issue, but even this by itself in a single file produces an error:

(defn foo [] "hi")

Here's the C++ compiler error:

src/main.ino: In member function 'virtual ferret::var ferret::foo::invoke(const ferret::var&) const':
src/main.ino:1796:26: error: 'hi' was not declared in this scope
                          hi;
                          ^

I can open a separate issue for this if you like.

Changing the original example to return a number instead of a string still runs afoul of the original compiler error tho:

; other.clj
(defn foo [] 1)

; main.clj
(require 'other)
(print (other/foo))
src/main.ino: In function 'void ferret::program::run()':
src/main.ino:1819:28: error: 'other_foo' was not declared in this scope
            run(print(),run(other_foo));
                            ^
esp1 commented

This is with ferret-lisp build: 24fca80, compiling for Arduino Uno, btw.

This is related to how FFI is handled. When a function contains only a string it is assumed to be a embedded C,C++.

(defn foo [] "hi")

hi in this case is assumed to be C++ snippet not a string. There used to be a separate reader macro for FFI but with newer versions of Clojure it is no longer possible.

(defn foo [] 1 "hi")

If you add some more operations to the function it would actually work. Also some lisp forms such as let, do etc. actually are represented as functions both in Clojure and Ferret, same applies to them.

esp1 commented

Ah that's right, I forgot. What about the second example where foo returns 1 tho? That also produces the same error where other/foo cannot be found.

Sorry I missed the second example that one I can reproduce on Linux/GCC.

esp1 commented

This doesn't fix the issue for me. I am still seeing the same compiler error with the latest ferret build: 425fc03

We are talking about this example right,

; other.clj
(defn foo [] 1)

; main.clj
(require 'other)
(print (other/foo))

On build 425fc03 compiled cpp file does include other/foo function. I've also added the following unit test to catch this behavior and tests pass. Can you check if this works for you?

;;modules/module-e.clj
(defn foo [] 1)

;;simple_module_main.clj
  (require 'modules.module-e)

   (deftest simple-module-test
    (is (= 1  (modules.module-e/foo))))

  (run-all-tests)
esp1 commented

Yes, that is the example I was referring to.

I tried the test function you mentioned and it also fails for me.

How are you executing the tests? I tried running lein test in the src directory, and I get cppcheck failures.

Also, the simple_module_main.clj file does not show up in the src/test dir after I run the top-level build script, and neither does modules/module-e.clj. I created those files manually and ran ferret against them to test them, but as I said that didn't work. Here is the error/warning output I got:

src/main.ino: In member function 'virtual ferret::var ferret::G__6238::invoke(const ferret::var&) const':
src/main.ino:2011:37: error: 'modules_module_e_foo' was not declared in this scope
                          return run(modules_module_e_foo);
                                     ^
src/main.ino:2012:24: warning: control reaches end of non-void function [-Wreturn-type]
                        }
                        ^

cppcheck is used to statically analyze generated unit tests. At a minimum you need emacs-24.5, gcc and cppcheck. If you are on a *nix based system you can take a look at .travis.yml for requried packages.

Function modules_module_e_foo does not exists in the compiled file at all right?
What OS are you running on? (I have access to OS X and Linux and can not reproduce this on both.)

esp1 commented

Hmm seems to be some kind of build issue on my machine. I downloaded the prebuilt executable on http://ferret-lang.org/ and it worked. I'm on macOS 10.12.5 and I'm using emacs 25.2.1, gcc 7.1.0, and cppcheck 1.79 all installed via homebrew. I'm not sure why it's not working, but for now I'll just stick with using the prebuilt executable. You can close this issue again. Thanks!