git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Various additions/fixes
bd6f345Andy Arvanitis
runtime/purescript.h+45−21
@@ -29,8 +29,11 @@ namespace purescript {
29
29
30 class boxed : public std::shared_ptr<void> {
30 class boxed : public std::shared_ptr<void> {
31
31
32+ public:
32− using fn = std::function<boxed(const boxed&)>;
33+ using fn_t = std::function<boxed(const boxed&)>;
33− using eff_fn = std::function<boxed(void)>;
34+ using eff_fn_t = std::function<boxed(void)>;
35+ using dict_t = std::map<const string, boxed>;
36+ using array_t = std::deque<boxed>;
34
37
35 public:
38 public:
36 using std::shared_ptr<void>::shared_ptr;
39 using std::shared_ptr<void>::shared_ptr;
@@ -52,54 +55,71 @@ namespace purescript {
52
55
53 boxed(const std::nullptr_t) : std::shared_ptr<void>() {
56 boxed(const std::nullptr_t) : std::shared_ptr<void>() {
54 }
57 }
55−
58+
56− boxed(std::initializer_list<boxed> l) : std::shared_ptr<void>(std::make_shared<std::deque<boxed>>(l)) {
59+ boxed(array_t&& l) : std::shared_ptr<void>(std::make_shared<array_t>(std::move(l))) {
57 }
60 }
58
61
59− boxed(std::initializer_list<std::pair<const string, boxed>> m) : std::shared_ptr<void>(std::make_shared<std::map<string, boxed>>(m)) {
62+ boxed(dict_t&& m) : std::shared_ptr<void>(std::make_shared<dict_t>(std::move(m))) {
60 }
63 }
61
64
62 template <typename T,
65 template <typename T,
63 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
66 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
64 boxed(const T& f,
67 boxed(const T& f,
65− typename std::enable_if<std::is_assignable<std::function<boxed(boxed)>,T>::value>::type* = 0) : std::shared_ptr<void>(std::make_shared<fn>(f)) {
68+ typename std::enable_if<std::is_assignable<std::function<boxed(boxed)>,T>::value>::type* = 0) : std::shared_ptr<void>(std::make_shared<fn_t>(f)) {
66 }
69 }
67
70
68 template <typename T,
71 template <typename T,
69 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
72 typename = typename std::enable_if<!std::is_same<boxed,T>::value>::type>
70 boxed(const T& f,
73 boxed(const T& f,
71− typename std::enable_if<std::is_assignable<std::function<boxed(void)>,T>::value>::type* = 0) : std::shared_ptr<void>(std::make_shared<eff_fn>(f)) {
74+ typename std::enable_if<std::is_assignable<std::function<boxed(void)>,T>::value>::type* = 0) : std::shared_ptr<void>(std::make_shared<eff_fn_t>(f)) {
72 }
75 }
73
76
74 template <typename T,
77 template <typename T,
75 typename = typename std::enable_if<!std::is_same<boxed,T>::value &&
78 typename = typename std::enable_if<!std::is_same<boxed,T>::value &&
76− std::is_convertible<T,fn>::value>::type>
79+ std::is_convertible<T,fn_t>::value>::type>
77 auto operator=(const T& right) -> boxed& {
80 auto operator=(const T& right) -> boxed& {
78 if (std::shared_ptr<void>::operator bool()) {
81 if (std::shared_ptr<void>::operator bool()) {
79− auto& f = *static_cast<fn*>(get());
82+ auto& f = *static_cast<fn_t*>(get());
80 f = right;
83 f = right;
81 } else {
84 } else {
82− reset(new fn(right));
85+ reset(new fn_t(right));
83 }
86 }
84 return *this;
87 return *this;
85 }
88 }
86
89
87 auto operator()(const boxed& arg) const -> boxed {
90 auto operator()(const boxed& arg) const -> boxed {
88− auto& f = *static_cast<fn*>(get());
91+ auto& f = *static_cast<fn_t*>(get());
89 return f(arg);
92 return f(arg);
90 }
93 }
91
94
92 auto operator()() const -> boxed {
95 auto operator()() const -> boxed {
93− auto& f = *static_cast<eff_fn*>(get());
96+ auto& f = *static_cast<eff_fn_t*>(get());
94 return f();
97 return f();
95 }
98 }
96
99
97− auto operator[](const char key[]) const -> boxed {
100+ auto operator[](const char key[]) const -> const boxed& {
98− const auto& dict = *static_cast<const std::map<const string, boxed>*>(get());
101+ const auto& dict = *static_cast<const dict_t*>(get());
99 return dict.at(key);
102 return dict.at(key);
100 }
103 }
101
104
102− };
105+ auto operator[](const char key[]) -> boxed& {
106+ auto& dict = *static_cast<dict_t*>(get());
107+ return dict[key];
108+ }
109+
110+#ifdef NDEBUG
111+ auto operator[](const int index) const -> const boxed& {
112+ const auto& array = *static_cast<const array_t*>(get());
113+ return array[index];
114+ }
115+#else
116+ auto operator[](const int index) const -> const boxed& {
117+ const auto& array = *static_cast<const array_t*>(get());
118+ return array.at(index);
119+ }
120+#endif // NDEBUG
121+
122+ }; // class boxed
103
123
104 template <typename T, typename... Args>
124 template <typename T, typename... Args>
105 inline auto box(Args&&... args) -> boxed {
125 inline auto box(Args&&... args) -> boxed {
@@ -112,6 +132,12 @@ namespace purescript {
112 return unboxed;
132 return unboxed;
113 }
133 }
114
134
135+ template <typename T,
136+ typename = typename std::enable_if<!std::is_same<T, const boxed&>::value>::type>
137+ constexpr auto unbox(const T value) -> T {
138+ return value;
139+ }
140+
115 template <typename T>
141 template <typename T>
116 inline auto peek(boxed& b) -> T& {
142 inline auto peek(boxed& b) -> T& {
117 auto& unboxed = *static_cast<T*>(b.get());
143 auto& unboxed = *static_cast<T*>(b.get());
@@ -123,12 +149,10 @@ namespace purescript {
123 return box<T>(unbox<T>(b));
149 return box<T>(unbox<T>(b));
124 }
150 }
125
151
126− using fn_t = std::function<boxed(const boxed&)>;
152+ using fn_t = boxed::fn_t;
127− using dict_t = std::map<const string, boxed>;
153+ using eff_fn_t = boxed::eff_fn_t;
128− using array_t = std::deque<boxed>;
154+ using dict_t = boxed::dict_t;
129−
155+ using array_t = boxed::array_t;
130− using as_array = std::initializer_list<boxed>;
131− using as_dict = std::initializer_list<std::pair<const string, boxed>>;
132
156
133 constexpr auto undefined = nullptr;
157 constexpr auto undefined = nullptr;
134
158
src/CodeGen/Cpp/Printer.hs+24−8
@@ -52,13 +52,13 @@ literals = mkPattern' match'
52 match (BooleanLiteral _ False) = return $ emit "false"
52 match (BooleanLiteral _ False) = return $ emit "false"
53 -- match (ArrayLiteral _ []) = return $ emit "std::initializer_list<boxed>{}"
53 -- match (ArrayLiteral _ []) = return $ emit "std::initializer_list<boxed>{}"
54 match (ArrayLiteral _ xs) = mconcat <$> sequence
54 match (ArrayLiteral _ xs) = mconcat <$> sequence
55− [ return $ emit "as_array { "
55+ [ return $ emit "array_t{ {"
56 , intercalate (emit ", ") <$> forM xs prettyPrintCpp'
56 , intercalate (emit ", ") <$> forM xs prettyPrintCpp'
57− , return $ emit " }"
57+ , return $ emit "} }"
58 ]
58 ]
59 -- match (ObjectLiteral _ []) = return $ emit "std::initializer_list<std::pair<const string, boxed>>{}"
59 -- match (ObjectLiteral _ []) = return $ emit "std::initializer_list<std::pair<const string, boxed>>{}"
60 match (ObjectLiteral _ ps) = mconcat <$> sequence
60 match (ObjectLiteral _ ps) = mconcat <$> sequence
61− [ return $ emit "as_dict {\n"
61+ [ return $ emit "dict_t{ {\n"
62 , withIndent $ do
62 , withIndent $ do
63 cpps <- forM ps $ \(key, value) -> do
63 cpps <- forM ps $ \(key, value) -> do
64 value' <- prettyPrintCpp' value
64 value' <- prettyPrintCpp' value
@@ -67,7 +67,7 @@ literals = mkPattern' match'
67 return $ intercalate (emit ",\n") $ map (indentString <>) cpps
67 return $ intercalate (emit ",\n") $ map (indentString <>) cpps
68 , return $ emit "\n"
68 , return $ emit "\n"
69 , currentIndent
69 , currentIndent
70− , return $ emit "}"
70+ , return $ emit "} }"
71 ]
71 ]
72 where
72 where
73 objectPropertyToString :: (Emit gen) => PSString -> gen
73 objectPropertyToString :: (Emit gen) => PSString -> gen
@@ -106,7 +106,7 @@ literals = mkPattern' match'
106 ]
106 ]
107 match (App ss (App _ (App _ (Indexer _ (Var _ fn) (Var _ fnMod)) [Indexer _ (Var _ dict) (Var _ dictMod)]) [x]) [y])
107 match (App ss (App _ (App _ (Indexer _ (Var _ fn) (Var _ fnMod)) [Indexer _ (Var _ dict) (Var _ dictMod)]) [x]) [y])
108 | fnMod == dictMod
108 | fnMod == dictMod
109− , dictMod == C.dataSemiring || dictMod == C.dataRing || dictMod == C.dataEuclideanRing
109+ , dictMod == C.dataEq || dictMod == C.dataSemiring || dictMod == C.dataRing || dictMod == C.dataEuclideanRing
110 , Just t <- unboxType dict
110 , Just t <- unboxType dict
111 = mconcat <$> sequence
111 = mconcat <$> sequence
112 [ return $ emit $ unbox t x
112 [ return $ emit $ unbox t x
@@ -231,7 +231,7 @@ literals = mkPattern' match'
231 , prettyPrintCpp' thens
231 , prettyPrintCpp' thens
232 , maybe (return mempty) (fmap (emit " else " <>) . prettyPrintCpp') elses
232 , maybe (return mempty) (fmap (emit " else " <>) . prettyPrintCpp') elses
233 ]
233 ]
234− match (IfElse _ (Binary _ EqualTo x@Var{} y@(NumericLiteral _ n)) thens elses) = mconcat <$> sequence
234+ match (IfElse _ (Binary _ EqualTo x y@(NumericLiteral _ n)) thens elses) = mconcat <$> sequence
235 [ return $ emit "if ("
235 [ return $ emit "if ("
236 , return $ emit $ unbox t x
236 , return $ emit $ unbox t x
237 , return $ emit $ " == "
237 , return $ emit $ " == "
@@ -243,7 +243,15 @@ literals = mkPattern' match'
243 where
243 where
244 t | Left _ <- n = int
244 t | Left _ <- n = int
245 | Right _ <- n = float
245 | Right _ <- n = float
246−
246+ match (IfElse _ (Binary _ EqualTo a b@StringLiteral{}) thens elses) = mconcat <$> sequence
247+ [ return $ emit "if ("
248+ , return $ emit $ unbox string a
249+ , return $ emit $ " == "
250+ , prettyPrintCpp' b
251+ , return $ emit ") "
252+ , prettyPrintCpp' thens
253+ , maybe (return mempty) (fmap (emit " else " <>) . prettyPrintCpp') elses
254+ ]
247 match (IfElse _ cond thens elses) = mconcat <$> sequence
255 match (IfElse _ cond thens elses) = mconcat <$> sequence
248 [ return $ emit "if ("
256 [ return $ emit "if ("
249 , prettyPrintCpp' cond
257 , prettyPrintCpp' cond
@@ -401,7 +409,8 @@ unbox t v = "unbox<" <> t <> ">(" <> prettyPrintCpp1 v <> ")"
401
409
402unboxType :: Text -> Maybe Text
410unboxType :: Text -> Maybe Text
403unboxType t
411unboxType t
412+ | t == C.eqInt ||
404− | t == C.semiringInt ||
413+ t == C.semiringInt ||
405 t == C.ringInt
414 t == C.ringInt
406 = Just int
415 = Just int
407 | t == C.semiringNumber ||
416 | t == C.semiringNumber ||
@@ -412,6 +421,7 @@ unboxType t
412
421
413renderOp :: Text -> Text
422renderOp :: Text -> Text
414renderOp op
423renderOp op
424+ | op == C.eq = " == "
415 | op == C.add = " + "
425 | op == C.add = " + "
416 | op == C.sub = " - "
426 | op == C.sub = " - "
417 | op == C.mul = " * "
427 | op == C.mul = " * "
@@ -476,6 +486,12 @@ int = "int"
476float :: Text
486float :: Text
477float = "double"
487float = "double"
478
488
489+bool :: Text
490+bool = "bool"
491+
492+string :: Text
493+string = "string"
494+
479foreignDict :: Text
495foreignDict :: Text
480foreignDict = "_foreign_"
496foreignDict = "_foreign_"
481
497
support/Makefile+1−1
@@ -27,7 +27,7 @@ override PURSFLAGS += compile --codegen corefn
27override CFLAGS += --std=c++11
27override CFLAGS += --std=c++11
28
28
29DEBUG := "-DDEBUG -g"
29DEBUG := "-DDEBUG -g"
30−RELEASE := "-O3"
30+RELEASE := "-DNDEBUG -O3"
31
31
32INCLUDES := -I $(CC_SRC)
32INCLUDES := -I $(CC_SRC)
33BIN_DIR := $(OUTPUT)/bin
33BIN_DIR := $(OUTPUT)/bin