git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Revert "Revert "C++: revamp arrays""

This reverts commit e35596a531e23f2013c767bed6dcc9b984bcbd5d.

commit41678bc05b5bff7449b7016d0fad8b25f6e85379 authorAndy Arvanitis <andyarvanitis@gmail.com> dateSun 14 Feb 2016, 21:36 (11 years ago) parente35596a
7 files changed+60−17
pcc/include/purescript.cc+15−8 pcc/include/purescript.hh+23−4 src/Language/PureScript/CodeGen/Cpp.hs+4−4 src/Language/PureScript/CodeGen/Cpp/AST.hs+7 src/Language/PureScript/CodeGen/Cpp/Optimizer/Inliner.hs+1 src/Language/PureScript/CodeGen/Cpp/Types.hs+4−1 src/Language/PureScript/Pretty/Cpp.hs+6
pcc/include/purescript.cc+15−8
@@ -27,6 +27,7 @@ namespace PureScript {
2727 case Type::String: new (&s) shared<std::string>(src.s); break; \
2828 case Type::Map: new (&m) shared<map>(src.m); break; \
2929 case Type::Vector: new (&v) shared<vector>(src.v); break; \
30+ case Type::Array: new (&a) shared<array>(src.a); break; \
3031 case Type::Function: f = src.f; break; \
3132 case Type::Closure: new (&l) shared<closure>(src.l); break; \
3233 case Type::EffFunction: new (&e) shared<eff_fn>(src.e); break; \
@@ -46,6 +47,7 @@ namespace PureScript {
4647 case Type::String: new (&s) shared<std::string>(std::move(src.s)); break; \
4748 case Type::Map: new (&m) shared<map>(std::move(src.m)); break; \
4849 case Type::Vector: new (&v) shared<vector>(std::move(src.v)); break; \
50+ case Type::Array: new (&a) shared<array>(std::move(src.a)); break; \
4951 case Type::Function: f = src.f; break; \
5052 case Type::Closure: new (&l) shared<closure>(std::move(src.l)); break; \
5153 case Type::EffFunction: new (&e) shared<eff_fn>(std::move(src.e)); break; \
@@ -92,6 +94,7 @@ any::~any() {
9294 case Type::String: s.~shared<std::string>(); break;
9395 case Type::Map: m.~shared<map>(); break;
9496 case Type::Vector: v.~shared<vector>(); break;
97+ case Type::Array: a.~shared<array>(); break;
9598 case Type::Function: ; break;
9699 case Type::Closure: l.~shared<closure>(); break;
97100 case Type::EffFunction: e.~shared<eff_fn>(); break;
@@ -149,10 +152,10 @@ auto any::cast() const -> typename std::enable_if<std::is_same<T, map>::value, c
149152template auto any::cast<any::map>() const -> const map&;
150153
151154template <typename T>
152−auto any::cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
153− RETURN_VALUE(Type::Vector, v, *)
155+auto any::cast() const -> typename std::enable_if<std::is_same<T, array>::value, const T&>::type {
156+ RETURN_VALUE(Type::Array, a, *)
154157}
155−template auto any::cast<any::vector>() const -> const vector&;
158+template auto any::cast<any::array>() const -> const array&;
156159
157160auto any::operator()(const any& arg) const -> any {
158161 const any& variant = unthunkVariant(*this);
@@ -198,6 +201,10 @@ any::operator const vector&() const {
198201 return cast<vector>();
199202}
200203
204+any::operator const array&() const {
205+ return cast<array>();
206+}
207+
201208auto any::extractPointer() const -> void* {
202209 RETURN_VALUE(Type::Pointer, p.get(),)
203210}
@@ -228,16 +235,16 @@ auto any::operator[](const char rhs[]) const -> const any& {
228235 throw runtime_error("map key not found");
229236}
230237
231−auto any::operator[](const vector::size_type rhs) const -> const any& {
238+auto any::operator[](const size_t rhs) const -> const any& {
232239 const any& variant = unthunkVariant(*this);
233− assert(variant.type == Type::Vector);
234− return (*variant.v)[rhs];
240+ assert(variant.type == Type::Array);
241+ return (*variant.a)[rhs];
235242}
236243
237244auto any::operator[](const any& rhs) const -> const any& {
238245 const any& variant = unthunkVariant(*this);
239− assert(variant.type == Type::Vector);
240− return (*variant.v)[rhs.cast<long>()];
246+ assert(variant.type == Type::Array);
247+ return (*variant.a)[rhs.cast<long>()];
241248}
242249
243250auto any::contains(const char key[]) const -> bool {
pcc/include/purescript.hh+23−4
@@ -29,6 +29,7 @@
2929#include <functional>
3030#include <string>
3131#include <vector>
32+#include <deque>
3233#include <utility>
3334#include <stdexcept>
3435
@@ -56,7 +57,7 @@ public:
5657};
5758
5859const bool undefined = false;
59−const std::vector<int>::size_type kDataCtor = 0;
60+const size_t kDataCtor = 0;
6061
6162// A variant data class designed to provide some features of dynamic typing.
6263//
@@ -73,6 +74,7 @@ class any {
7374 String,
7475 Map,
7576 Vector,
77+ Array,
7678 Function,
7779 Closure,
7880 EffFunction,
@@ -80,17 +82,22 @@ class any {
8082 Pointer
8183 };
8284
85+ private:
8386 mutable Type type = Type::Unknown;
87+ using vector = std::vector<any>;
8488
89+ public:
8590 struct as_thunk {
8691 };
8792 static constexpr as_thunk unthunk = as_thunk{};
8893
8994 using map = std::vector<std::pair<const char * const, const any>>;
90− using vector = std::vector<any>;
95+ using data = vector;
96+ using array = std::deque<any>;
9197 using fn = auto (*)(const any&) -> any;
9298 using thunk = auto (*)(const as_thunk) -> const any&;
9399
100+ private:
94101 class closure {
95102 public:
96103 virtual auto operator()(const any&) const -> any = 0;
@@ -121,6 +128,7 @@ class any {
121128 }
122129 };
123130
131+ public:
124132 template <typename T>
125133 using shared = std::shared_ptr<T>;
126134
@@ -139,6 +147,7 @@ class any {
139147 mutable shared<std::string> s;
140148 mutable shared<map> m;
141149 mutable shared<vector> v;
150+ mutable shared<array> a;
142151 mutable fn f;
143152 mutable shared<closure> l;
144153 mutable shared<eff_fn> e;
@@ -173,6 +182,9 @@ class any {
173182 any(const vector& val) : type(Type::Vector), v(make_shared<vector>(val)) {}
174183 any(vector&& val) noexcept : type(Type::Vector), v(make_shared<vector>(std::move(val))) {}
175184
185+ any(const array& val) : type(Type::Array), a(make_shared<array>(val)) {}
186+ any(array&& val) noexcept : type(Type::Array), a(make_shared<array>(std::move(val))) {}
187+
176188 template <typename T>
177189 any(const T& val, typename std::enable_if<std::is_convertible<T,fn>::value>::type* = 0)
178190 : type(Type::Function), f(val) {}
@@ -228,8 +240,14 @@ class any {
228240 template <typename T>
229241 auto cast() const -> typename std::enable_if<std::is_same<T, map>::value, const T&>::type;
230242
243+ // These cannot be thunked
244+ template <typename T>
245+ inline auto cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type {
246+ return *v;
247+ }
248+
231249 template <typename T>
232− auto cast() const -> typename std::enable_if<std::is_same<T, vector>::value, const T&>::type;
250+ auto cast() const -> typename std::enable_if<std::is_same<T, array>::value, const T&>::type;
233251
234252 template <typename T>
235253 auto cast() const -> typename std::enable_if<std::is_assignable<shared<void>,T>::value, typename T::element_type*>::type {
@@ -249,9 +267,10 @@ class any {
249267 operator string() const;
250268 operator const map&() const;
251269 operator const vector&() const;
270+ operator const array&() const;
252271
253272 auto operator[](const char[]) const -> const any&;
254− auto operator[](const vector::size_type) const -> const any&;
273+ auto operator[](const size_t) const -> const any&;
255274 auto operator[](const any&) const -> const any&;
256275
257276 auto contains(const char[]) const -> bool;
src/Language/PureScript/CodeGen/Cpp.hs+4−4
@@ -135,7 +135,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
135135 CppFunction (identToCpp ident)
136136 [] (Just $ CppAny [])
137137 [CppInline]
138− (CppBlock [CppReturn (CppArrayLiteral [CppStringLiteral (identToCpp ident)])])
138+ (CppBlock [CppReturn (CppDataLiteral [CppStringLiteral (identToCpp ident)])])
139139
140140 declToCpp _ ident (Constructor _ _ (ProperName _) fields) = return . CppNamespace [] $
141141 [ CppFunction ('$' : identToCpp ident) (farg <$> fields')
@@ -159,7 +159,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
159159 (Just $ CppAny [])
160160 (CppBlock $ fieldLambdas fs')]
161161 | otherwise = fullyConstructed
162− fullyConstructed = [CppReturn (CppArrayLiteral (CppStringLiteral name : (CppVar <$> fields')))]
162+ fullyConstructed = [CppReturn (CppDataLiteral (CppStringLiteral name : (CppVar <$> fields')))]
163163
164164 declToCpp _ ident val = do
165165 val' <- valueToCpp val
@@ -421,7 +421,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
421421 return $ case ctorType of
422422 ProductType -> cpps
423423 SumType ->
424− [ CppIfElse (CppBinary Equal (CppIndexer (CppVar ctorKey) (CppVar varName))
424+ [ CppIfElse (CppBinary Equal (CppIndexer (CppVar ctorKey) (CppCast dataType $ CppVar varName))
425425 (CppStringLiteral ctor))
426426 (CppBlock cpps)
427427 Nothing ]
@@ -434,7 +434,7 @@ moduleToCpp env (Module _ mn imps _ foreigns decls) = do
434434 cpps <- binderToCpp argVar done'' binder
435435 return (CppVariableIntroduction (argVar, Nothing)
436436 []
437− (Just (CppIndexer (fieldToIndex field) (CppVar varName)))
437+ (Just (CppIndexer (fieldToIndex field) (CppCast dataType $ CppVar varName)))
438438 : cpps)
439439 fieldToIndex :: Ident -> Cpp
440440 fieldToIndex = CppNumericLiteral . Left . (+1) . read . dropWhile isLetter . runIdent
src/Language/PureScript/CodeGen/Cpp/AST.hs+7
@@ -170,6 +170,10 @@ data Cpp
170170 --
171171 | CppArrayLiteral [Cpp]
172172 -- |
173+ -- A data literal
174+ --
175+ | CppDataLiteral [Cpp]
176+ -- |
173177 -- An array indexer expression
174178 --
175179 | CppIndexer Cpp Cpp
@@ -282,6 +286,7 @@ everywhereOnCpp f = go
282286 go (CppUnary op j) = f (CppUnary op (go j))
283287 go (CppBinary op j1 j2) = f (CppBinary op (go j1) (go j2))
284288 go (CppArrayLiteral cpp) = f (CppArrayLiteral (map go cpp))
289+ go (CppDataLiteral cpp) = f (CppDataLiteral (map go cpp))
285290 go (CppIndexer j1 j2) = f (CppIndexer (go j1) (go j2))
286291 go (CppObjectLiteral cpp) = f (CppObjectLiteral (map (fmap go) cpp))
287292 go (CppAccessor prop j) = f (CppAccessor (go prop) (go j))
@@ -311,6 +316,7 @@ everywhereOnCppTopDownM f = f >=> go
311316 go (CppUnary op j) = CppUnary op <$> f' j
312317 go (CppBinary op j1 j2) = CppBinary op <$> f' j1 <*> f' j2
313318 go (CppArrayLiteral cpp) = CppArrayLiteral <$> traverse f' cpp
319+ go (CppDataLiteral cpp) = CppDataLiteral <$> traverse f' cpp
314320 go (CppIndexer j1 j2) = CppIndexer <$> f' j1 <*> f' j2
315321 go (CppObjectLiteral cpp) = CppObjectLiteral <$> traverse (sndM f') cpp
316322 go (CppAccessor prop j) = CppAccessor prop <$> f' j
@@ -336,6 +342,7 @@ everythingOnCpp (<>) f = go
336342 go j@(CppUnary _ j1) = f j <> go j1
337343 go j@(CppBinary _ j1 j2) = f j <> go j1 <> go j2
338344 go j@(CppArrayLiteral cpp) = foldl (<>) (f j) (map go cpp)
345+ go j@(CppDataLiteral cpp) = foldl (<>) (f j) (map go cpp)
339346 go j@(CppIndexer j1 j2) = f j <> go j1 <> go j2
340347 go j@(CppObjectLiteral cpp) = foldl (<>) (f j) (map (go . snd) cpp)
341348 go j@(CppAccessor j1 j2) = f j <> go j1 <> go j2
src/Language/PureScript/CodeGen/Cpp/Optimizer/Inliner.hs+1
@@ -48,6 +48,7 @@ shouldInline (CppStringLiteral _) = True
4848shouldInline (CppBooleanLiteral _) = True
4949shouldInline (CppAccessor _ val) = shouldInline val
5050shouldInline (CppIndexer index val) = shouldInline index && shouldInline val
51+shouldInline (CppCast _ val) = shouldInline val
5152shouldInline _ = False
5253
5354etaConvert :: Cpp -> Cpp
src/Language/PureScript/CodeGen/Cpp/Types.hs+4−1
@@ -108,8 +108,11 @@ charType = CppPrimitive "char"
108108mapType :: CppType
109109mapType = CppPrimitive "any::map"
110110
111+dataType :: CppType
112+dataType = CppPrimitive "any::data"
113+
111114arrayType :: CppType
112−arrayType = CppPrimitive "any::vector"
115+arrayType = CppPrimitive "any::array"
113116
114117thunkMarkerType :: CppType
115118thunkMarkerType = CppPrimitive "any::as_thunk"
src/Language/PureScript/Pretty/Cpp.hs+6
@@ -71,6 +71,12 @@ literals = mkPattern' match
7171 , fmap (intercalate ", ") $ forM xs prettyPrintCpp'
7272 , return " }"
7373 ]
74+ match (CppDataLiteral xs) = fmap concat $ sequence
75+ [ return $ runType dataType
76+ , return "{ "
77+ , fmap (intercalate ", ") $ forM xs prettyPrintCpp'
78+ , return " }"
79+ ]
7480 match (CppObjectLiteral ps) = fmap concat $ sequence
7581 [ return $ runType mapType ++ "{\n"
7682 , withIndent $ do