git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: add native-specific README.markdown
9cb1f59Andy Arvanitis
README.markdownnew file+113
@@ -0,0 +1,113 @@
1+[![PureScript](https://raw.githubusercontent.com/purescript/purescript/master/logo.png)](http://purescript.org)
2+
3+This is an experimental native compiler/backend for [PureScript](https://github.com/purescript/purescript). It attempts to generate "sane", performant, and portable C++11 code as an intermediate language, which is then compiled to a native executable binary. This enables easy interoperability with existing C/C++ frameworks and libraries on a number of platforms.
4+
5+---
6+
7+#### Performance
8+
9+* No runtime system (beyond some support classes and the standard C++11 runtime library)
10+* For automatic memory management, uses either native C++11 reference counting (`std::shared_ptr`), or the [Boehm-Demers-Weiser Garbage Collector](http://hboehm.info/gc/) -- **selectable when building** (see instructions below)
11+* Uses PureScript's normal tail call optimizations for generated C++11 code
12+
13+#### Differences from PureScript:
14+
15+* Foreign imports are C++11 (or C) instead of JavaScript ([FFI examples](https://github.com/andyarvanitis/pure11/wiki/FFI_Examples))
16+* Foreign functions are not written as curried functions (any necessary currying is done implicitly by the compiler)
17+* Compiler is `pcc` instead of `psc`, `make` is recommended for building
18+* No purescript-native-specific REPL
19+
20+#### Other notes:
21+
22+* PureScript arrays are implmented using [`std::deque`](http://en.cppreference.com/w/cpp/container/deque) (random access *O(1)*)
23+* `String` types are implmented using either C-strings (for literals) or `std::string`
24+* `Number` is C++ `double`, `Int` is C++ `long`, `Char` is `char`, `Boolean` is `bool`
25+* [Standard packages currently building (lightly tested)](https://github.com/andyarvanitis/pure11/wiki/Packages)
26+
27+#### TO-DO:
28+
29+* Get all automated builds/tests fully up and running [(some work already done)](https://github.com/andyarvanitis/purescript-native/blob/native/pcc/TestMain.hs)
30+* Unicode (UTF-8) support for `String` (possibly use code from my Idris backend)
31+* Lots of testing!
32+
33+#### Future ideas:
34+
35+* Nice facilities (modules) for concurrency/parallelism, using `std::thread`, `std::async`, etc. under the hood
36+* `BigInt` via GNU GMP (or an alternative)
37+* Stricter exports in C++ code
38+
39+#### Requirements
40+
41+* Everything you need to build [PureScript](https://github.com/purescript/purescript)
42+* A C++11-capable toolchain, e.g. recent versions of clang, gcc, Microsoft Visual Studio 2015
43+* GNU Make is the default supported build tool, but you should be able to use your favorite C++ build system, tools, debuggers, etc.
44+
45+#### Examples
46+
47+**`fib.purs`**
48+```PureScript
49+module Main where
50+ import Prelude
51+ import Control.Monad.Eff.Console
52+
53+ fib :: Int -> Int
54+ fib 0 = 0
55+ fib 1 = 1
56+ fib n = fib (n - 2) + fib (n - 1)
57+
58+ main = do
59+ log "Here's the result of fib 10:"
60+ print (fib 10)
61+```
62+**`fib.cc`**
63+```c++
64+#include "Main/Main.hh"
65+namespace Main {
66+ using namespace PureScript;
67+ using namespace Prelude;
68+ using namespace Control_Monad_Eff_Console;
69+ using namespace Control_Monad_Eff;
70+
71+ auto fib(const any& v) -> any {
72+ switch (cast<long>(v)) {
73+ case 0: return 0;
74+ case 1: return 1;
75+ };
76+ return fib(v - 2) + fib(v - 1);
77+ };
78+ auto main() -> any {
79+ Control_Monad_Eff_Console::log("Here's the result of fib 10:")();
80+ return Control_Monad_Eff_Console::print(Prelude::showInt, fib(10))();
81+ };
82+}
83+
84+auto main(int, char *[]) -> int {
85+ using namespace Main;
86+ Main::main();
87+ return 0;
88+};
89+```
90+---
91+#### [FFI examples](https://github.com/andyarvanitis/pure11/wiki/FFI_Examples)
92+---
93+#### Getting Started
94+This assumes you are running OS X or a Unix-like system (Linux, *BSD, etc.), and already have the ability to [build PureScript from source] (http://www.purescript.org/download/) (bottom of the page) -- but instead of cloning and building the repository in the instructions, make sure to use [this project's repo](https://github.com/andyarvanitis/purescript-native).
95+
96+1. Make sure you have developer tools for your system installed. For OS X, you'll need a recent version of Xcode. For Linux, etc., you need gcc 4.9.2 or later, including g++ support. You can also use clang 3.5 or later, but it still requires gcc for its C++ standard libraries.
97+
98+2. If you wish to use the Boehm garbage collector (better runtime performance, in general), install it for your system. For OS X, [brew](http://brew.sh/) is an easy method and recommended (package `bdw-gc`). For linux, it's available under package names such as `libgc-dev` (for Debian/Ubuntu).
99+
100+3. Create a working directory wherever you like, and a `src` subdirectory under it, which will be where you will place your own PureScript source files.
101+
102+4. From your working directory, run the `{installation_path}/pcc` command with no arguments. This will generate a default `Makefile` for you in that directory. You can edit it if needed to change things like the location of the PureScript packages you intend to download and use. There are also some usage notes in the `Makefile` itself.
103+
104+5. Pull in your desired PureScript packages using `git` (bower will be supported later), making sure to use the pure11-specific versions in [this list](https://github.com/andyarvanitis/pure11/wiki/Packages).
105+
106+6. You should now be ready to build a PureScript program.
107+ * As stated above, place your source file(s) in the working directory's `src` subdirectory and execute `make`. If your machine has multiple cores, you might want to use `make -jN`, where `N` is the number of cores.
108+
109+ * To use the garbage collector, add `USE_GC=yes` to the `make` command line (or you can add it to the `Makefile` that you generated in step 4).
110+
111+ * This will generate the C++ source tree for your program and then build an executable binary. The resulting executable will be in the `bin` subdirectory under the output directory and called `main` (so `output/bin/main`, by default).
112+
113+---