git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Switch to string_literal_dict (from std::map)
3d46983Andy Arvanitis
app/Main.hs+2
@@ -101,9 +101,11 @@ transpile opts jsonFile = do
101 putStrLn implPath
101 putStrLn implPath
102 T.writeFile implPath $ conv (implHeader <> implementation <> implFooter)
102 T.writeFile implPath $ conv (implHeader <> implementation <> implFooter)
103 let runtime = baseOutpath </> "purescript.h"
103 let runtime = baseOutpath </> "purescript.h"
104+ dep = baseOutpath </> "string_literal_dict.h"
104 runtimeExists <- doesFileExist runtime
105 runtimeExists <- doesFileExist runtime
105 when (not runtimeExists) $ do
106 when (not runtimeExists) $ do
106 T.writeFile runtime . conv $ T.decodeUtf8 $(embedFile "runtime/purescript.h")
107 T.writeFile runtime . conv $ T.decodeUtf8 $(embedFile "runtime/purescript.h")
108+ T.writeFile dep . conv $ T.decodeUtf8 $(embedFile "runtime/string_literal_dict.h")
107 where
109 where
108 conv :: Text -> Text
110 conv :: Text -> Text
109 conv
111 conv
runtime/purescript.h+6−6
@@ -18,9 +18,10 @@
18#include <memory>
18#include <memory>
19#include <functional>
19#include <functional>
20#include <deque>
20#include <deque>
21−#include <map>
22#include <string>
21#include <string>
23#include <limits>
22#include <limits>
23+#include "string_literal_dict.h"
24+
24
25
25namespace purescript {
26namespace purescript {
26
27
@@ -31,7 +32,7 @@ namespace purescript {
31 public:
32 public:
32 using fn_t = std::function<boxed(const boxed&)>;
33 using fn_t = std::function<boxed(const boxed&)>;
33 using eff_fn_t = std::function<boxed(void)>;
34 using eff_fn_t = std::function<boxed(void)>;
34− using dict_t = std::map<const string, boxed>;
35+ using dict_t = string_literal_dict_t<boxed>;
35 using array_t = std::deque<boxed>;
36 using array_t = std::deque<boxed>;
36
37
37 public:
38 public:
@@ -107,12 +108,12 @@ namespace purescript {
107 return f();
108 return f();
108 }
109 }
109
110
110− auto operator[](const string& key) const -> const boxed& {
111+ auto operator[](const char key[]) const -> const boxed& {
111 const auto& dict = *static_cast<const dict_t*>(get());
112 const auto& dict = *static_cast<const dict_t*>(get());
112− return dict.at(key);
113+ return dict[key];
113 }
114 }
114
115
115− auto operator[](const string& key) -> boxed& {
116+ auto operator[](const char key[]) -> boxed& {
116 auto& dict = *static_cast<dict_t*>(get());
117 auto& dict = *static_cast<dict_t*>(get());
117 return dict[key];
118 return dict[key];
118 }
119 }
@@ -137,7 +138,6 @@ namespace purescript {
137 auto& array = *static_cast<array_t*>(get());
138 auto& array = *static_cast<array_t*>(get());
138 return array.at(index);
139 return array.at(index);
139 }
140 }
140−
141#endif // NDEBUG
141#endif // NDEBUG
142
142
143 }; // class boxed
143 }; // class boxed
runtime/string_literal_dict.hnew file+58
@@ -0,0 +1,58 @@
1+#ifndef string_literal_dict_H
2+#define string_literal_dict_H
3+
4+#include <cstring>
5+#include <string>
6+#include <vector>
7+#include <utility>
8+
9+
10+template <typename T>
11+class string_literal_dict_t : private std::vector<std::pair<const char *, T>> {
12+
13+ static auto null() -> const T& {
14+ static const T value;
15+ return value;
16+ }
17+
18+ public:
19+ using std::vector<std::pair<const char *, T>>::vector;
20+
21+ auto operator[](const char key[]) const -> const T& {
22+ for (auto it = this->cbegin(), end=this->cend(); it != end; it++) {
23+ const auto& elem_key = it->first;
24+ if (elem_key == key || !std::strcmp(elem_key, key)) {
25+ return it->second;
26+ }
27+ }
28+#ifndef NDEBUG
29+ throw std::runtime_error("dictionary key \"" + std::string(key) + "\" not found");
30+#endif
31+ return null();
32+ }
33+
34+ auto operator[](const char key[]) -> T& {
35+ const auto end = this->end();
36+ for (auto it = this->begin(); it != end; it++) {
37+ const auto& elem_key = it->first;
38+ if (elem_key == key || !std::strcmp(elem_key, key)) {
39+ return it->second;
40+ }
41+ }
42+ return this->emplace(end, key, T())->second;
43+ }
44+
45+ auto contains(const char key[]) const -> bool {
46+ for (auto it = this->cbegin(), end=this->cend(); it != end; it++) {
47+ const auto& elem_key = it->first;
48+ if (elem_key == key || !std::strcmp(elem_key, key)) {
49+ return true;
50+ }
51+ }
52+ return false;
53+ }
54+
55+};
56+
57+
58+#endif // string_literal_dict_H
src/CodeGen/Cpp/Printer.hs+4−4
@@ -199,9 +199,9 @@ literals = mkPattern' match'
199 ]
199 ]
200 match (InstanceOf _ val ty) = mconcat <$> sequence
200 match (InstanceOf _ val ty) = mconcat <$> sequence
201 [ return . emit $ unbox dictType val
201 [ return . emit $ unbox dictType val
202− , return $ emit ".count("
202+ , return $ emit ".contains("
203 , prettyPrintCpp' ty
203 , prettyPrintCpp' ty
204− , return $ emit ") == 1"
204+ , return $ emit ")"
205 ]
205 ]
206 match (While _ cond sts) = mconcat <$> sequence
206 match (While _ cond sts) = mconcat <$> sequence
207 [ return $ emit "while ("
207 [ return $ emit "while ("
@@ -456,8 +456,8 @@ interfaceSource mn exports foreigns =
456 identToCpp foreign' <>
456 identToCpp foreign' <>
457 "() -> " <> varDecl <> " { " <>
457 "() -> " <> varDecl <> " { " <>
458 dispatchOnceBegin <>
458 dispatchOnceBegin <>
459− foreignDict <> "().at(" <>
459+ foreignDict <> "()[" <>
460− (stringLiteral . mkString $ runIdent foreign') <> "); " <>
460+ (stringLiteral . mkString $ runIdent foreign') <> "]; " <>
461 dispatchOnceEnd <>
461 dispatchOnceEnd <>
462 " };\n") <$> foreigns) <>
462 " };\n") <$> foreigns) <>
463 "\n" <>
463 "\n" <>