cactus-react-native 0.0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +20 -0
- package/README.md +3 -1
- package/android/src/main/CMakeLists.txt +58 -23
- package/android/src/main/java/com/cactus/Cactus.java +484 -16
- package/android/src/main/java/com/cactus/LlamaContext.java +199 -0
- package/android/src/main/jni.cpp +325 -10
- package/android/src/main/jniLibs/arm64-v8a/libcactus.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus_v8.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_dotprod.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_dotprod_i8mm.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_i8mm.so +0 -0
- package/android/src/main/jniLibs/x86_64/libcactus.so +0 -0
- package/android/src/main/jniLibs/x86_64/libcactus_x86_64.so +0 -0
- package/android/src/newarch/java/com/cactus/CactusModule.java +79 -7
- package/android/src/oldarch/java/com/cactus/CactusModule.java +70 -0
- package/cactus-react-native.podspec +0 -3
- package/ios/CMakeLists.txt +58 -36
- package/ios/Cactus.mm +243 -2
- package/ios/CactusContext.h +22 -0
- package/ios/CactusContext.mm +176 -1
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus.h +92 -5
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/cactus_ffi.h +268 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/chat.h +2 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/common.h +42 -51
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-backend.h +4 -4
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-common.h +12 -6
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-cpp.h +1 -1
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-cpu.h +5 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-impl.h +52 -18
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-metal-impl.h +106 -14
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-opt.h +49 -28
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml.h +87 -106
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-arch.h +16 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-batch.h +2 -1
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-chat.h +7 -2
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-context.h +44 -33
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-cparams.h +1 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-graph.h +83 -17
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-hparams.h +44 -2
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-kv-cache.h +407 -179
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-memory.h +13 -2
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-model-loader.h +5 -3
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-model-saver.h +37 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-model.h +24 -2
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama-vocab.h +6 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/llama.h +102 -142
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/minja/chat-template.hpp +23 -11
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/minja/minja.hpp +186 -127
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Info.plist +0 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/cactus +0 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/ggml-llama.metallib +0 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/cactus.h +92 -5
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/cactus_ffi.h +268 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/chat.h +2 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/common.h +42 -51
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-backend.h +4 -4
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-common.h +12 -6
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpp.h +1 -1
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpu.h +5 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-impl.h +52 -18
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-metal-impl.h +106 -14
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-opt.h +49 -28
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml.h +87 -106
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-arch.h +16 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-batch.h +2 -1
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-chat.h +7 -2
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-context.h +44 -33
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-cparams.h +1 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-graph.h +83 -17
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-hparams.h +44 -2
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-kv-cache.h +407 -179
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-memory.h +13 -2
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-model-loader.h +5 -3
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-model-saver.h +37 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-model.h +24 -2
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama-vocab.h +6 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/llama.h +102 -142
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/minja/chat-template.hpp +23 -11
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/minja/minja.hpp +186 -127
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Info.plist +0 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/_CodeSignature/CodeResources +1 -1
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/cactus +0 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/ggml-llama-sim.metallib +0 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/cactus.h +92 -5
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/cactus_ffi.h +268 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/chat.h +2 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/common.h +42 -51
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-backend.h +4 -4
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-common.h +12 -6
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-cpp.h +1 -1
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-cpu.h +5 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-impl.h +52 -18
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-metal-impl.h +106 -14
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-opt.h +49 -28
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml.h +87 -106
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-arch.h +16 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-batch.h +2 -1
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-chat.h +7 -2
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-context.h +44 -33
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-cparams.h +1 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-graph.h +83 -17
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-hparams.h +44 -2
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-kv-cache.h +407 -179
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-memory.h +13 -2
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-model-loader.h +5 -3
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-model-saver.h +37 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-model.h +24 -2
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama-vocab.h +6 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/llama.h +102 -142
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/minja/chat-template.hpp +23 -11
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/minja/minja.hpp +186 -127
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Info.plist +0 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/cactus +0 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/ggml-llama.metallib +0 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/cactus.h +92 -5
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/cactus_ffi.h +268 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/chat.h +2 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/common.h +42 -51
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-backend.h +4 -4
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-common.h +12 -6
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpp.h +1 -1
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpu.h +5 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-impl.h +52 -18
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-metal-impl.h +106 -14
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-opt.h +49 -28
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml.h +87 -106
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-arch.h +16 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-batch.h +2 -1
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-chat.h +7 -2
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-context.h +44 -33
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-cparams.h +1 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-graph.h +83 -17
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-hparams.h +44 -2
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-kv-cache.h +407 -179
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-memory.h +13 -2
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-model-loader.h +5 -3
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-model-saver.h +37 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-model.h +24 -2
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama-vocab.h +6 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/llama.h +102 -142
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/minja/chat-template.hpp +23 -11
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/minja/minja.hpp +186 -127
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Info.plist +0 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/_CodeSignature/CodeResources +1 -1
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/cactus +0 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/ggml-llama-sim.metallib +0 -0
- package/lib/commonjs/NativeCactus.js +1 -0
- package/lib/commonjs/NativeCactus.js.map +1 -1
- package/lib/commonjs/index.js +112 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/tools.js +118 -0
- package/lib/commonjs/tools.js.map +1 -0
- package/lib/module/NativeCactus.js +3 -0
- package/lib/module/NativeCactus.js.map +1 -1
- package/lib/module/index.js +87 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/tools.js +110 -0
- package/lib/module/tools.js.map +1 -0
- package/lib/typescript/NativeCactus.d.ts +30 -1
- package/lib/typescript/NativeCactus.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +21 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/tools.d.ts +38 -0
- package/lib/typescript/tools.d.ts.map +1 -0
- package/package.json +6 -3
- package/src/NativeCactus.ts +62 -1
- package/src/index.ts +113 -2
- package/src/tools.ts +127 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-cpu-aarch64.h +0 -8
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-cpu-impl.h +0 -531
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-cpu-quants.h +0 -63
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/ggml-cpu-traits.h +0 -38
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/sgemm.h +0 -14
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpu-aarch64.h +0 -8
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpu-impl.h +0 -531
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpu-quants.h +0 -63
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpu-traits.h +0 -38
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/sgemm.h +0 -14
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-cpu-aarch64.h +0 -8
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-cpu-impl.h +0 -531
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-cpu-quants.h +0 -63
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/ggml-cpu-traits.h +0 -38
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/sgemm.h +0 -14
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpu-aarch64.h +0 -8
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpu-impl.h +0 -531
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpu-quants.h +0 -63
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/ggml-cpu-traits.h +0 -38
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/sgemm.h +0 -14
package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/minja/minja.hpp
CHANGED
|
@@ -8,14 +8,27 @@
|
|
|
8
8
|
// SPDX-License-Identifier: MIT
|
|
9
9
|
#pragma once
|
|
10
10
|
|
|
11
|
+
#include <algorithm>
|
|
12
|
+
#include <cctype>
|
|
13
|
+
#include <cstddef>
|
|
14
|
+
#include <cstdint>
|
|
15
|
+
#include <cmath>
|
|
16
|
+
#include <exception>
|
|
17
|
+
#include <functional>
|
|
11
18
|
#include <iostream>
|
|
12
|
-
#include <
|
|
13
|
-
#include <
|
|
14
|
-
#include <
|
|
19
|
+
#include <iterator>
|
|
20
|
+
#include <limits>
|
|
21
|
+
#include <map>
|
|
15
22
|
#include <memory>
|
|
16
|
-
#include <
|
|
23
|
+
#include <regex>
|
|
17
24
|
#include <sstream>
|
|
25
|
+
#include <string>
|
|
26
|
+
#include <stdexcept>
|
|
27
|
+
#include <unordered_map>
|
|
18
28
|
#include <unordered_set>
|
|
29
|
+
#include <utility>
|
|
30
|
+
#include <vector>
|
|
31
|
+
|
|
19
32
|
#include "../json.hpp"
|
|
20
33
|
|
|
21
34
|
using json = nlohmann::ordered_json;
|
|
@@ -221,7 +234,7 @@ public:
|
|
|
221
234
|
}
|
|
222
235
|
} else if (is_object()) {
|
|
223
236
|
if (!index.is_hashable())
|
|
224
|
-
throw std::runtime_error("
|
|
237
|
+
throw std::runtime_error("Unhashable type: " + index.dump());
|
|
225
238
|
auto it = object_->find(index.primitive_);
|
|
226
239
|
if (it == object_->end())
|
|
227
240
|
throw std::runtime_error("Key not found: " + index.dump());
|
|
@@ -240,7 +253,7 @@ public:
|
|
|
240
253
|
auto index = key.get<int>();
|
|
241
254
|
return array_->at(index < 0 ? array_->size() + index : index);
|
|
242
255
|
} else if (object_) {
|
|
243
|
-
if (!key.is_hashable()) throw std::runtime_error("
|
|
256
|
+
if (!key.is_hashable()) throw std::runtime_error("Unhashable type: " + dump());
|
|
244
257
|
auto it = object_->find(key.primitive_);
|
|
245
258
|
if (it == object_->end()) return Value();
|
|
246
259
|
return it->second;
|
|
@@ -249,7 +262,7 @@ public:
|
|
|
249
262
|
}
|
|
250
263
|
void set(const Value& key, const Value& value) {
|
|
251
264
|
if (!object_) throw std::runtime_error("Value is not an object: " + dump());
|
|
252
|
-
if (!key.is_hashable()) throw std::runtime_error("
|
|
265
|
+
if (!key.is_hashable()) throw std::runtime_error("Unhashable type: " + dump());
|
|
253
266
|
(*object_)[key.primitive_] = value;
|
|
254
267
|
}
|
|
255
268
|
Value call(const std::shared_ptr<Context> & context, ArgumentsValue & args) const {
|
|
@@ -386,7 +399,7 @@ public:
|
|
|
386
399
|
}
|
|
387
400
|
return false;
|
|
388
401
|
} else if (object_) {
|
|
389
|
-
if (!value.is_hashable()) throw std::runtime_error("
|
|
402
|
+
if (!value.is_hashable()) throw std::runtime_error("Unhashable type: " + value.dump());
|
|
390
403
|
return object_->find(value.primitive_) != object_->end();
|
|
391
404
|
} else {
|
|
392
405
|
throw std::runtime_error("contains can only be called on arrays and objects: " + dump());
|
|
@@ -404,7 +417,7 @@ public:
|
|
|
404
417
|
return const_cast<Value*>(this)->at(index);
|
|
405
418
|
}
|
|
406
419
|
Value& at(const Value & index) {
|
|
407
|
-
if (!index.is_hashable()) throw std::runtime_error("
|
|
420
|
+
if (!index.is_hashable()) throw std::runtime_error("Unhashable type: " + dump());
|
|
408
421
|
if (is_array()) return array_->at(index.get<int>());
|
|
409
422
|
if (is_object()) return object_->at(index.primitive_);
|
|
410
423
|
throw std::runtime_error("Value is not an array or object: " + dump());
|
|
@@ -664,8 +677,8 @@ public:
|
|
|
664
677
|
class VariableExpr : public Expression {
|
|
665
678
|
std::string name;
|
|
666
679
|
public:
|
|
667
|
-
VariableExpr(const Location &
|
|
668
|
-
: Expression(
|
|
680
|
+
VariableExpr(const Location & loc, const std::string& n)
|
|
681
|
+
: Expression(loc), name(n) {}
|
|
669
682
|
std::string get_name() const { return name; }
|
|
670
683
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
|
671
684
|
if (!context->contains(name)) {
|
|
@@ -731,51 +744,51 @@ public:
|
|
|
731
744
|
|
|
732
745
|
struct TextTemplateToken : public TemplateToken {
|
|
733
746
|
std::string text;
|
|
734
|
-
TextTemplateToken(const Location &
|
|
747
|
+
TextTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, const std::string& t) : TemplateToken(Type::Text, loc, pre, post), text(t) {}
|
|
735
748
|
};
|
|
736
749
|
|
|
737
750
|
struct ExpressionTemplateToken : public TemplateToken {
|
|
738
751
|
std::shared_ptr<Expression> expr;
|
|
739
|
-
ExpressionTemplateToken(const Location &
|
|
752
|
+
ExpressionTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, std::shared_ptr<Expression> && e) : TemplateToken(Type::Expression, loc, pre, post), expr(std::move(e)) {}
|
|
740
753
|
};
|
|
741
754
|
|
|
742
755
|
struct IfTemplateToken : public TemplateToken {
|
|
743
756
|
std::shared_ptr<Expression> condition;
|
|
744
|
-
IfTemplateToken(const Location &
|
|
757
|
+
IfTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, std::shared_ptr<Expression> && c) : TemplateToken(Type::If, loc, pre, post), condition(std::move(c)) {}
|
|
745
758
|
};
|
|
746
759
|
|
|
747
760
|
struct ElifTemplateToken : public TemplateToken {
|
|
748
761
|
std::shared_ptr<Expression> condition;
|
|
749
|
-
ElifTemplateToken(const Location &
|
|
762
|
+
ElifTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, std::shared_ptr<Expression> && c) : TemplateToken(Type::Elif, loc, pre, post), condition(std::move(c)) {}
|
|
750
763
|
};
|
|
751
764
|
|
|
752
765
|
struct ElseTemplateToken : public TemplateToken {
|
|
753
|
-
ElseTemplateToken(const Location &
|
|
766
|
+
ElseTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::Else, loc, pre, post) {}
|
|
754
767
|
};
|
|
755
768
|
|
|
756
769
|
struct EndIfTemplateToken : public TemplateToken {
|
|
757
|
-
EndIfTemplateToken(const Location &
|
|
770
|
+
EndIfTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndIf, loc, pre, post) {}
|
|
758
771
|
};
|
|
759
772
|
|
|
760
773
|
struct MacroTemplateToken : public TemplateToken {
|
|
761
774
|
std::shared_ptr<VariableExpr> name;
|
|
762
775
|
Expression::Parameters params;
|
|
763
|
-
MacroTemplateToken(const Location &
|
|
764
|
-
: TemplateToken(Type::Macro,
|
|
776
|
+
MacroTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, std::shared_ptr<VariableExpr> && n, Expression::Parameters && p)
|
|
777
|
+
: TemplateToken(Type::Macro, loc, pre, post), name(std::move(n)), params(std::move(p)) {}
|
|
765
778
|
};
|
|
766
779
|
|
|
767
780
|
struct EndMacroTemplateToken : public TemplateToken {
|
|
768
|
-
EndMacroTemplateToken(const Location &
|
|
781
|
+
EndMacroTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndMacro, loc, pre, post) {}
|
|
769
782
|
};
|
|
770
783
|
|
|
771
784
|
struct FilterTemplateToken : public TemplateToken {
|
|
772
785
|
std::shared_ptr<Expression> filter;
|
|
773
|
-
FilterTemplateToken(const Location &
|
|
774
|
-
: TemplateToken(Type::Filter,
|
|
786
|
+
FilterTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, std::shared_ptr<Expression> && filter)
|
|
787
|
+
: TemplateToken(Type::Filter, loc, pre, post), filter(std::move(filter)) {}
|
|
775
788
|
};
|
|
776
789
|
|
|
777
790
|
struct EndFilterTemplateToken : public TemplateToken {
|
|
778
|
-
EndFilterTemplateToken(const Location &
|
|
791
|
+
EndFilterTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndFilter, loc, pre, post) {}
|
|
779
792
|
};
|
|
780
793
|
|
|
781
794
|
struct ForTemplateToken : public TemplateToken {
|
|
@@ -783,38 +796,38 @@ struct ForTemplateToken : public TemplateToken {
|
|
|
783
796
|
std::shared_ptr<Expression> iterable;
|
|
784
797
|
std::shared_ptr<Expression> condition;
|
|
785
798
|
bool recursive;
|
|
786
|
-
ForTemplateToken(const Location &
|
|
799
|
+
ForTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, const std::vector<std::string> & vns, std::shared_ptr<Expression> && iter,
|
|
787
800
|
std::shared_ptr<Expression> && c, bool r)
|
|
788
|
-
: TemplateToken(Type::For,
|
|
801
|
+
: TemplateToken(Type::For, loc, pre, post), var_names(vns), iterable(std::move(iter)), condition(std::move(c)), recursive(r) {}
|
|
789
802
|
};
|
|
790
803
|
|
|
791
804
|
struct EndForTemplateToken : public TemplateToken {
|
|
792
|
-
EndForTemplateToken(const Location &
|
|
805
|
+
EndForTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndFor, loc, pre, post) {}
|
|
793
806
|
};
|
|
794
807
|
|
|
795
808
|
struct GenerationTemplateToken : public TemplateToken {
|
|
796
|
-
GenerationTemplateToken(const Location &
|
|
809
|
+
GenerationTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::Generation, loc, pre, post) {}
|
|
797
810
|
};
|
|
798
811
|
|
|
799
812
|
struct EndGenerationTemplateToken : public TemplateToken {
|
|
800
|
-
EndGenerationTemplateToken(const Location &
|
|
813
|
+
EndGenerationTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndGeneration, loc, pre, post) {}
|
|
801
814
|
};
|
|
802
815
|
|
|
803
816
|
struct SetTemplateToken : public TemplateToken {
|
|
804
817
|
std::string ns;
|
|
805
818
|
std::vector<std::string> var_names;
|
|
806
819
|
std::shared_ptr<Expression> value;
|
|
807
|
-
SetTemplateToken(const Location &
|
|
808
|
-
: TemplateToken(Type::Set,
|
|
820
|
+
SetTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, const std::string & ns, const std::vector<std::string> & vns, std::shared_ptr<Expression> && v)
|
|
821
|
+
: TemplateToken(Type::Set, loc, pre, post), ns(ns), var_names(vns), value(std::move(v)) {}
|
|
809
822
|
};
|
|
810
823
|
|
|
811
824
|
struct EndSetTemplateToken : public TemplateToken {
|
|
812
|
-
EndSetTemplateToken(const Location &
|
|
825
|
+
EndSetTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndSet, loc, pre, post) {}
|
|
813
826
|
};
|
|
814
827
|
|
|
815
828
|
struct CommentTemplateToken : public TemplateToken {
|
|
816
829
|
std::string text;
|
|
817
|
-
CommentTemplateToken(const Location &
|
|
830
|
+
CommentTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, const std::string& t) : TemplateToken(Type::Comment, loc, pre, post), text(t) {}
|
|
818
831
|
};
|
|
819
832
|
|
|
820
833
|
enum class LoopControlType { Break, Continue };
|
|
@@ -830,7 +843,7 @@ public:
|
|
|
830
843
|
|
|
831
844
|
struct LoopControlTemplateToken : public TemplateToken {
|
|
832
845
|
LoopControlType control_type;
|
|
833
|
-
LoopControlTemplateToken(const Location &
|
|
846
|
+
LoopControlTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, LoopControlType control_type) : TemplateToken(Type::Break, loc, pre, post), control_type(control_type) {}
|
|
834
847
|
};
|
|
835
848
|
|
|
836
849
|
class TemplateNode {
|
|
@@ -868,8 +881,8 @@ public:
|
|
|
868
881
|
class SequenceNode : public TemplateNode {
|
|
869
882
|
std::vector<std::shared_ptr<TemplateNode>> children;
|
|
870
883
|
public:
|
|
871
|
-
SequenceNode(const Location &
|
|
872
|
-
: TemplateNode(
|
|
884
|
+
SequenceNode(const Location & loc, std::vector<std::shared_ptr<TemplateNode>> && c)
|
|
885
|
+
: TemplateNode(loc), children(std::move(c)) {}
|
|
873
886
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> & context) const override {
|
|
874
887
|
for (const auto& child : children) child->render(out, context);
|
|
875
888
|
}
|
|
@@ -878,7 +891,7 @@ public:
|
|
|
878
891
|
class TextNode : public TemplateNode {
|
|
879
892
|
std::string text;
|
|
880
893
|
public:
|
|
881
|
-
TextNode(const Location &
|
|
894
|
+
TextNode(const Location & loc, const std::string& t) : TemplateNode(loc), text(t) {}
|
|
882
895
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> &) const override {
|
|
883
896
|
out << text;
|
|
884
897
|
}
|
|
@@ -887,7 +900,7 @@ public:
|
|
|
887
900
|
class ExpressionNode : public TemplateNode {
|
|
888
901
|
std::shared_ptr<Expression> expr;
|
|
889
902
|
public:
|
|
890
|
-
ExpressionNode(const Location &
|
|
903
|
+
ExpressionNode(const Location & loc, std::shared_ptr<Expression> && e) : TemplateNode(loc), expr(std::move(e)) {}
|
|
891
904
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> & context) const override {
|
|
892
905
|
if (!expr) throw std::runtime_error("ExpressionNode.expr is null");
|
|
893
906
|
auto result = expr->evaluate(context);
|
|
@@ -904,8 +917,8 @@ public:
|
|
|
904
917
|
class IfNode : public TemplateNode {
|
|
905
918
|
std::vector<std::pair<std::shared_ptr<Expression>, std::shared_ptr<TemplateNode>>> cascade;
|
|
906
919
|
public:
|
|
907
|
-
IfNode(const Location &
|
|
908
|
-
: TemplateNode(
|
|
920
|
+
IfNode(const Location & loc, std::vector<std::pair<std::shared_ptr<Expression>, std::shared_ptr<TemplateNode>>> && c)
|
|
921
|
+
: TemplateNode(loc), cascade(std::move(c)) {}
|
|
909
922
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> & context) const override {
|
|
910
923
|
for (const auto& branch : cascade) {
|
|
911
924
|
auto enter_branch = true;
|
|
@@ -924,7 +937,7 @@ public:
|
|
|
924
937
|
class LoopControlNode : public TemplateNode {
|
|
925
938
|
LoopControlType control_type_;
|
|
926
939
|
public:
|
|
927
|
-
LoopControlNode(const Location &
|
|
940
|
+
LoopControlNode(const Location & loc, LoopControlType control_type) : TemplateNode(loc), control_type_(control_type) {}
|
|
928
941
|
void do_render(std::ostringstream &, const std::shared_ptr<Context> &) const override {
|
|
929
942
|
throw LoopControlException(control_type_);
|
|
930
943
|
}
|
|
@@ -938,9 +951,9 @@ class ForNode : public TemplateNode {
|
|
|
938
951
|
bool recursive;
|
|
939
952
|
std::shared_ptr<TemplateNode> else_body;
|
|
940
953
|
public:
|
|
941
|
-
ForNode(const Location &
|
|
954
|
+
ForNode(const Location & loc, std::vector<std::string> && var_names, std::shared_ptr<Expression> && iterable,
|
|
942
955
|
std::shared_ptr<Expression> && condition, std::shared_ptr<TemplateNode> && body, bool recursive, std::shared_ptr<TemplateNode> && else_body)
|
|
943
|
-
: TemplateNode(
|
|
956
|
+
: TemplateNode(loc), var_names(var_names), iterable(std::move(iterable)), condition(std::move(condition)), body(std::move(body)), recursive(recursive), else_body(std::move(else_body)) {}
|
|
944
957
|
|
|
945
958
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> & context) const override {
|
|
946
959
|
// https://jinja.palletsprojects.com/en/3.0.x/templates/#for
|
|
@@ -1025,8 +1038,8 @@ class MacroNode : public TemplateNode {
|
|
|
1025
1038
|
std::shared_ptr<TemplateNode> body;
|
|
1026
1039
|
std::unordered_map<std::string, size_t> named_param_positions;
|
|
1027
1040
|
public:
|
|
1028
|
-
MacroNode(const Location &
|
|
1029
|
-
: TemplateNode(
|
|
1041
|
+
MacroNode(const Location & loc, std::shared_ptr<VariableExpr> && n, Expression::Parameters && p, std::shared_ptr<TemplateNode> && b)
|
|
1042
|
+
: TemplateNode(loc), name(std::move(n)), params(std::move(p)), body(std::move(b)) {
|
|
1030
1043
|
for (size_t i = 0; i < params.size(); ++i) {
|
|
1031
1044
|
const auto & name = params[i].first;
|
|
1032
1045
|
if (!name.empty()) {
|
|
@@ -1072,8 +1085,8 @@ class FilterNode : public TemplateNode {
|
|
|
1072
1085
|
std::shared_ptr<TemplateNode> body;
|
|
1073
1086
|
|
|
1074
1087
|
public:
|
|
1075
|
-
FilterNode(const Location &
|
|
1076
|
-
: TemplateNode(
|
|
1088
|
+
FilterNode(const Location & loc, std::shared_ptr<Expression> && f, std::shared_ptr<TemplateNode> && b)
|
|
1089
|
+
: TemplateNode(loc), filter(std::move(f)), body(std::move(b)) {}
|
|
1077
1090
|
|
|
1078
1091
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> & context) const override {
|
|
1079
1092
|
if (!filter) throw std::runtime_error("FilterNode.filter is null");
|
|
@@ -1095,8 +1108,8 @@ class SetNode : public TemplateNode {
|
|
|
1095
1108
|
std::vector<std::string> var_names;
|
|
1096
1109
|
std::shared_ptr<Expression> value;
|
|
1097
1110
|
public:
|
|
1098
|
-
SetNode(const Location &
|
|
1099
|
-
: TemplateNode(
|
|
1111
|
+
SetNode(const Location & loc, const std::string & ns, const std::vector<std::string> & vns, std::shared_ptr<Expression> && v)
|
|
1112
|
+
: TemplateNode(loc), ns(ns), var_names(vns), value(std::move(v)) {}
|
|
1100
1113
|
void do_render(std::ostringstream &, const std::shared_ptr<Context> & context) const override {
|
|
1101
1114
|
if (!value) throw std::runtime_error("SetNode.value is null");
|
|
1102
1115
|
if (!ns.empty()) {
|
|
@@ -1118,8 +1131,8 @@ class SetTemplateNode : public TemplateNode {
|
|
|
1118
1131
|
std::string name;
|
|
1119
1132
|
std::shared_ptr<TemplateNode> template_value;
|
|
1120
1133
|
public:
|
|
1121
|
-
SetTemplateNode(const Location &
|
|
1122
|
-
: TemplateNode(
|
|
1134
|
+
SetTemplateNode(const Location & loc, const std::string & name, std::shared_ptr<TemplateNode> && tv)
|
|
1135
|
+
: TemplateNode(loc), name(name), template_value(std::move(tv)) {}
|
|
1123
1136
|
void do_render(std::ostringstream &, const std::shared_ptr<Context> & context) const override {
|
|
1124
1137
|
if (!template_value) throw std::runtime_error("SetTemplateNode.template_value is null");
|
|
1125
1138
|
Value value { template_value->render(context) };
|
|
@@ -1132,8 +1145,8 @@ class IfExpr : public Expression {
|
|
|
1132
1145
|
std::shared_ptr<Expression> then_expr;
|
|
1133
1146
|
std::shared_ptr<Expression> else_expr;
|
|
1134
1147
|
public:
|
|
1135
|
-
IfExpr(const Location &
|
|
1136
|
-
: Expression(
|
|
1148
|
+
IfExpr(const Location & loc, std::shared_ptr<Expression> && c, std::shared_ptr<Expression> && t, std::shared_ptr<Expression> && e)
|
|
1149
|
+
: Expression(loc), condition(std::move(c)), then_expr(std::move(t)), else_expr(std::move(e)) {}
|
|
1137
1150
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
|
1138
1151
|
if (!condition) throw std::runtime_error("IfExpr.condition is null");
|
|
1139
1152
|
if (!then_expr) throw std::runtime_error("IfExpr.then_expr is null");
|
|
@@ -1150,16 +1163,16 @@ public:
|
|
|
1150
1163
|
class LiteralExpr : public Expression {
|
|
1151
1164
|
Value value;
|
|
1152
1165
|
public:
|
|
1153
|
-
LiteralExpr(const Location &
|
|
1154
|
-
: Expression(
|
|
1166
|
+
LiteralExpr(const Location & loc, const Value& v)
|
|
1167
|
+
: Expression(loc), value(v) {}
|
|
1155
1168
|
Value do_evaluate(const std::shared_ptr<Context> &) const override { return value; }
|
|
1156
1169
|
};
|
|
1157
1170
|
|
|
1158
1171
|
class ArrayExpr : public Expression {
|
|
1159
1172
|
std::vector<std::shared_ptr<Expression>> elements;
|
|
1160
1173
|
public:
|
|
1161
|
-
ArrayExpr(const Location &
|
|
1162
|
-
: Expression(
|
|
1174
|
+
ArrayExpr(const Location & loc, std::vector<std::shared_ptr<Expression>> && e)
|
|
1175
|
+
: Expression(loc), elements(std::move(e)) {}
|
|
1163
1176
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
|
1164
1177
|
auto result = Value::array();
|
|
1165
1178
|
for (const auto& e : elements) {
|
|
@@ -1173,8 +1186,8 @@ public:
|
|
|
1173
1186
|
class DictExpr : public Expression {
|
|
1174
1187
|
std::vector<std::pair<std::shared_ptr<Expression>, std::shared_ptr<Expression>>> elements;
|
|
1175
1188
|
public:
|
|
1176
|
-
DictExpr(const Location &
|
|
1177
|
-
: Expression(
|
|
1189
|
+
DictExpr(const Location & loc, std::vector<std::pair<std::shared_ptr<Expression>, std::shared_ptr<Expression>>> && e)
|
|
1190
|
+
: Expression(loc), elements(std::move(e)) {}
|
|
1178
1191
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
|
1179
1192
|
auto result = Value::object();
|
|
1180
1193
|
for (const auto& [key, value] : elements) {
|
|
@@ -1188,9 +1201,9 @@ public:
|
|
|
1188
1201
|
|
|
1189
1202
|
class SliceExpr : public Expression {
|
|
1190
1203
|
public:
|
|
1191
|
-
std::shared_ptr<Expression> start, end;
|
|
1192
|
-
SliceExpr(const Location &
|
|
1193
|
-
: Expression(
|
|
1204
|
+
std::shared_ptr<Expression> start, end, step;
|
|
1205
|
+
SliceExpr(const Location & loc, std::shared_ptr<Expression> && s, std::shared_ptr<Expression> && e, std::shared_ptr<Expression> && st = nullptr)
|
|
1206
|
+
: Expression(loc), start(std::move(s)), end(std::move(e)), step(std::move(st)) {}
|
|
1194
1207
|
Value do_evaluate(const std::shared_ptr<Context> &) const override {
|
|
1195
1208
|
throw std::runtime_error("SliceExpr not implemented");
|
|
1196
1209
|
}
|
|
@@ -1200,25 +1213,42 @@ class SubscriptExpr : public Expression {
|
|
|
1200
1213
|
std::shared_ptr<Expression> base;
|
|
1201
1214
|
std::shared_ptr<Expression> index;
|
|
1202
1215
|
public:
|
|
1203
|
-
SubscriptExpr(const Location &
|
|
1204
|
-
: Expression(
|
|
1216
|
+
SubscriptExpr(const Location & loc, std::shared_ptr<Expression> && b, std::shared_ptr<Expression> && i)
|
|
1217
|
+
: Expression(loc), base(std::move(b)), index(std::move(i)) {}
|
|
1205
1218
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
|
1206
1219
|
if (!base) throw std::runtime_error("SubscriptExpr.base is null");
|
|
1207
1220
|
if (!index) throw std::runtime_error("SubscriptExpr.index is null");
|
|
1208
1221
|
auto target_value = base->evaluate(context);
|
|
1209
1222
|
if (auto slice = dynamic_cast<SliceExpr*>(index.get())) {
|
|
1210
|
-
auto
|
|
1211
|
-
auto
|
|
1223
|
+
auto len = target_value.size();
|
|
1224
|
+
auto wrap = [len](int64_t i) -> int64_t {
|
|
1225
|
+
if (i < 0) {
|
|
1226
|
+
return i + len;
|
|
1227
|
+
}
|
|
1228
|
+
return i;
|
|
1229
|
+
};
|
|
1230
|
+
int64_t step = slice->step ? slice->step->evaluate(context).get<int64_t>() : 1;
|
|
1231
|
+
if (!step) {
|
|
1232
|
+
throw std::runtime_error("slice step cannot be zero");
|
|
1233
|
+
}
|
|
1234
|
+
int64_t start = slice->start ? wrap(slice->start->evaluate(context).get<int64_t>()) : (step < 0 ? len - 1 : 0);
|
|
1235
|
+
int64_t end = slice->end ? wrap(slice->end->evaluate(context).get<int64_t>()) : (step < 0 ? -1 : len);
|
|
1212
1236
|
if (target_value.is_string()) {
|
|
1213
1237
|
std::string s = target_value.get<std::string>();
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1238
|
+
|
|
1239
|
+
std::string result;
|
|
1240
|
+
if (start < end && step == 1) {
|
|
1241
|
+
result = s.substr(start, end - start);
|
|
1242
|
+
} else {
|
|
1243
|
+
for (int64_t i = start; step > 0 ? i < end : i > end; i += step) {
|
|
1244
|
+
result += s[i];
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
return result;
|
|
1248
|
+
|
|
1217
1249
|
} else if (target_value.is_array()) {
|
|
1218
|
-
if (start < 0) start = target_value.size() + start;
|
|
1219
|
-
if (end < 0) end = target_value.size() + end;
|
|
1220
1250
|
auto result = Value::array();
|
|
1221
|
-
for (
|
|
1251
|
+
for (int64_t i = start; step > 0 ? i < end : i > end; i += step) {
|
|
1222
1252
|
result.push_back(target_value.at(i));
|
|
1223
1253
|
}
|
|
1224
1254
|
return result;
|
|
@@ -1243,8 +1273,8 @@ public:
|
|
|
1243
1273
|
enum class Op { Plus, Minus, LogicalNot, Expansion, ExpansionDict };
|
|
1244
1274
|
std::shared_ptr<Expression> expr;
|
|
1245
1275
|
Op op;
|
|
1246
|
-
UnaryOpExpr(const Location &
|
|
1247
|
-
: Expression(
|
|
1276
|
+
UnaryOpExpr(const Location & loc, std::shared_ptr<Expression> && e, Op o)
|
|
1277
|
+
: Expression(loc), expr(std::move(e)), op(o) {}
|
|
1248
1278
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
|
1249
1279
|
if (!expr) throw std::runtime_error("UnaryOpExpr.expr is null");
|
|
1250
1280
|
auto e = expr->evaluate(context);
|
|
@@ -1269,8 +1299,8 @@ private:
|
|
|
1269
1299
|
std::shared_ptr<Expression> right;
|
|
1270
1300
|
Op op;
|
|
1271
1301
|
public:
|
|
1272
|
-
BinaryOpExpr(const Location &
|
|
1273
|
-
: Expression(
|
|
1302
|
+
BinaryOpExpr(const Location & loc, std::shared_ptr<Expression> && l, std::shared_ptr<Expression> && r, Op o)
|
|
1303
|
+
: Expression(loc), left(std::move(l)), right(std::move(r)), op(o) {}
|
|
1274
1304
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
|
1275
1305
|
if (!left) throw std::runtime_error("BinaryOpExpr.left is null");
|
|
1276
1306
|
if (!right) throw std::runtime_error("BinaryOpExpr.right is null");
|
|
@@ -1293,6 +1323,8 @@ public:
|
|
|
1293
1323
|
if (name == "iterable") return l.is_iterable();
|
|
1294
1324
|
if (name == "sequence") return l.is_array();
|
|
1295
1325
|
if (name == "defined") return !l.is_null();
|
|
1326
|
+
if (name == "true") return l.to_bool();
|
|
1327
|
+
if (name == "false") return !l.to_bool();
|
|
1296
1328
|
throw std::runtime_error("Unknown type for 'is' operator: " + name);
|
|
1297
1329
|
};
|
|
1298
1330
|
auto value = eval();
|
|
@@ -1427,8 +1459,8 @@ class MethodCallExpr : public Expression {
|
|
|
1427
1459
|
std::shared_ptr<VariableExpr> method;
|
|
1428
1460
|
ArgumentsExpression args;
|
|
1429
1461
|
public:
|
|
1430
|
-
MethodCallExpr(const Location &
|
|
1431
|
-
: Expression(
|
|
1462
|
+
MethodCallExpr(const Location & loc, std::shared_ptr<Expression> && obj, std::shared_ptr<VariableExpr> && m, ArgumentsExpression && a)
|
|
1463
|
+
: Expression(loc), object(std::move(obj)), method(std::move(m)), args(std::move(a)) {}
|
|
1432
1464
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
|
1433
1465
|
if (!object) throw std::runtime_error("MethodCallExpr.object is null");
|
|
1434
1466
|
if (!method) throw std::runtime_error("MethodCallExpr.method is null");
|
|
@@ -1508,6 +1540,10 @@ public:
|
|
|
1508
1540
|
vargs.expectArgs("endswith method", {1, 1}, {0, 0});
|
|
1509
1541
|
auto suffix = vargs.args[0].get<std::string>();
|
|
1510
1542
|
return suffix.length() <= str.length() && std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
|
|
1543
|
+
} else if (method->get_name() == "startswith") {
|
|
1544
|
+
vargs.expectArgs("startswith method", {1, 1}, {0, 0});
|
|
1545
|
+
auto prefix = vargs.args[0].get<std::string>();
|
|
1546
|
+
return prefix.length() <= str.length() && std::equal(prefix.begin(), prefix.end(), str.begin());
|
|
1511
1547
|
} else if (method->get_name() == "title") {
|
|
1512
1548
|
vargs.expectArgs("title method", {0, 0}, {0, 0});
|
|
1513
1549
|
auto res = str;
|
|
@@ -1526,8 +1562,8 @@ class CallExpr : public Expression {
|
|
|
1526
1562
|
public:
|
|
1527
1563
|
std::shared_ptr<Expression> object;
|
|
1528
1564
|
ArgumentsExpression args;
|
|
1529
|
-
CallExpr(const Location &
|
|
1530
|
-
: Expression(
|
|
1565
|
+
CallExpr(const Location & loc, std::shared_ptr<Expression> && obj, ArgumentsExpression && a)
|
|
1566
|
+
: Expression(loc), object(std::move(obj)), args(std::move(a)) {}
|
|
1531
1567
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
|
1532
1568
|
if (!object) throw std::runtime_error("CallExpr.object is null");
|
|
1533
1569
|
auto obj = object->evaluate(context);
|
|
@@ -1542,8 +1578,8 @@ public:
|
|
|
1542
1578
|
class FilterExpr : public Expression {
|
|
1543
1579
|
std::vector<std::shared_ptr<Expression>> parts;
|
|
1544
1580
|
public:
|
|
1545
|
-
FilterExpr(const Location &
|
|
1546
|
-
: Expression(
|
|
1581
|
+
FilterExpr(const Location & loc, std::vector<std::shared_ptr<Expression>> && p)
|
|
1582
|
+
: Expression(loc), parts(std::move(p)) {}
|
|
1547
1583
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
|
1548
1584
|
Value result;
|
|
1549
1585
|
bool first = true;
|
|
@@ -2070,28 +2106,37 @@ private:
|
|
|
2070
2106
|
|
|
2071
2107
|
while (it != end && consumeSpaces() && peekSymbols({ "[", "." })) {
|
|
2072
2108
|
if (!consumeToken("[").empty()) {
|
|
2073
|
-
|
|
2109
|
+
std::shared_ptr<Expression> index;
|
|
2110
|
+
auto slice_loc = get_location();
|
|
2111
|
+
std::shared_ptr<Expression> start, end, step;
|
|
2112
|
+
bool has_first_colon = false, has_second_colon = false;
|
|
2113
|
+
|
|
2114
|
+
if (!peekSymbols({ ":" })) {
|
|
2115
|
+
start = parseExpression();
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2118
|
+
if (!consumeToken(":").empty()) {
|
|
2119
|
+
has_first_colon = true;
|
|
2120
|
+
if (!peekSymbols({ ":", "]" })) {
|
|
2121
|
+
end = parseExpression();
|
|
2122
|
+
}
|
|
2074
2123
|
if (!consumeToken(":").empty()) {
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
auto slice_start = parseExpression();
|
|
2079
|
-
if (!consumeToken(":").empty()) {
|
|
2080
|
-
consumeSpaces();
|
|
2081
|
-
if (peekSymbols({ "]" })) {
|
|
2082
|
-
index = std::make_shared<SliceExpr>(slice_start->location, std::move(slice_start), nullptr);
|
|
2083
|
-
} else {
|
|
2084
|
-
auto slice_end = parseExpression();
|
|
2085
|
-
index = std::make_shared<SliceExpr>(slice_start->location, std::move(slice_start), std::move(slice_end));
|
|
2086
|
-
}
|
|
2087
|
-
} else {
|
|
2088
|
-
index = std::move(slice_start);
|
|
2124
|
+
has_second_colon = true;
|
|
2125
|
+
if (!peekSymbols({ "]" })) {
|
|
2126
|
+
step = parseExpression();
|
|
2089
2127
|
}
|
|
2090
2128
|
}
|
|
2091
|
-
|
|
2092
|
-
|
|
2129
|
+
}
|
|
2130
|
+
|
|
2131
|
+
if ((has_first_colon || has_second_colon) && (start || end || step)) {
|
|
2132
|
+
index = std::make_shared<SliceExpr>(slice_loc, std::move(start), std::move(end), std::move(step));
|
|
2133
|
+
} else {
|
|
2134
|
+
index = std::move(start);
|
|
2135
|
+
}
|
|
2136
|
+
if (!index) throw std::runtime_error("Empty index in subscript");
|
|
2137
|
+
if (consumeToken("]").empty()) throw std::runtime_error("Expected closing bracket in subscript");
|
|
2093
2138
|
|
|
2094
|
-
|
|
2139
|
+
value = std::make_shared<SubscriptExpr>(value->location, std::move(value), std::move(index));
|
|
2095
2140
|
} else if (!consumeToken(".").empty()) {
|
|
2096
2141
|
auto identifier = parseIdentifier();
|
|
2097
2142
|
if (!identifier) throw std::runtime_error("Expected identifier in subscript");
|
|
@@ -2460,7 +2505,7 @@ private:
|
|
|
2460
2505
|
static std::regex leading_space_regex(R"(^\s+)");
|
|
2461
2506
|
text = std::regex_replace(text, leading_space_regex, "");
|
|
2462
2507
|
} else if (options.trim_blocks && (it - 1) != begin && !dynamic_cast<ExpressionTemplateToken*>((*(it - 2)).get())) {
|
|
2463
|
-
if (text.
|
|
2508
|
+
if (!text.empty() && text[0] == '\n') {
|
|
2464
2509
|
text.erase(0, 1);
|
|
2465
2510
|
}
|
|
2466
2511
|
}
|
|
@@ -2538,7 +2583,7 @@ public:
|
|
|
2538
2583
|
TemplateTokenIterator begin = tokens.begin();
|
|
2539
2584
|
auto it = begin;
|
|
2540
2585
|
TemplateTokenIterator end = tokens.end();
|
|
2541
|
-
return parser.parseTemplate(begin, it, end, /*
|
|
2586
|
+
return parser.parseTemplate(begin, it, end, /* fully= */ true);
|
|
2542
2587
|
}
|
|
2543
2588
|
};
|
|
2544
2589
|
|
|
@@ -2577,7 +2622,7 @@ inline std::shared_ptr<Context> Context::builtins() {
|
|
|
2577
2622
|
throw std::runtime_error(args.at("message").get<std::string>());
|
|
2578
2623
|
}));
|
|
2579
2624
|
globals.set("tojson", simple_function("tojson", { "value", "indent" }, [](const std::shared_ptr<Context> &, Value & args) {
|
|
2580
|
-
return Value(args.at("value").dump(args.get<int64_t>("indent", -1), /*
|
|
2625
|
+
return Value(args.at("value").dump(args.get<int64_t>("indent", -1), /* to_json= */ true));
|
|
2581
2626
|
}));
|
|
2582
2627
|
globals.set("items", simple_function("items", { "object" }, [](const std::shared_ptr<Context> &, Value & args) {
|
|
2583
2628
|
auto items = Value::array();
|
|
@@ -2599,21 +2644,25 @@ inline std::shared_ptr<Context> Context::builtins() {
|
|
|
2599
2644
|
globals.set("last", simple_function("last", { "items" }, [](const std::shared_ptr<Context> &, Value & args) {
|
|
2600
2645
|
auto items = args.at("items");
|
|
2601
2646
|
if (!items.is_array()) throw std::runtime_error("object is not a list");
|
|
2602
|
-
if (items.
|
|
2647
|
+
if (items.empty()) return Value();
|
|
2603
2648
|
return items.at(items.size() - 1);
|
|
2604
2649
|
}));
|
|
2605
2650
|
globals.set("trim", simple_function("trim", { "text" }, [](const std::shared_ptr<Context> &, Value & args) {
|
|
2606
2651
|
auto & text = args.at("text");
|
|
2607
2652
|
return text.is_null() ? text : Value(strip(text.get<std::string>()));
|
|
2608
2653
|
}));
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2654
|
+
auto char_transform_function = [](const std::string & name, const std::function<char(char)> & fn) {
|
|
2655
|
+
return simple_function(name, { "text" }, [=](const std::shared_ptr<Context> &, Value & args) {
|
|
2656
|
+
auto text = args.at("text");
|
|
2657
|
+
if (text.is_null()) return text;
|
|
2658
|
+
std::string res;
|
|
2659
|
+
auto str = text.get<std::string>();
|
|
2660
|
+
std::transform(str.begin(), str.end(), std::back_inserter(res), fn);
|
|
2661
|
+
return Value(res);
|
|
2662
|
+
});
|
|
2663
|
+
};
|
|
2664
|
+
globals.set("lower", char_transform_function("lower", ::tolower));
|
|
2665
|
+
globals.set("upper", char_transform_function("upper", ::toupper));
|
|
2617
2666
|
globals.set("default", Value::callable([=](const std::shared_ptr<Context> &, ArgumentsValue & args) {
|
|
2618
2667
|
args.expectArgs("default", {2, 3}, {0, 1});
|
|
2619
2668
|
auto & value = args.args[0];
|
|
@@ -2743,12 +2792,17 @@ inline std::shared_ptr<Context> Context::builtins() {
|
|
|
2743
2792
|
return Value::callable([=](const std::shared_ptr<Context> & context, ArgumentsValue & args) {
|
|
2744
2793
|
args.expectArgs(is_select ? "select" : "reject", {2, (std::numeric_limits<size_t>::max)()}, {0, 0});
|
|
2745
2794
|
auto & items = args.args[0];
|
|
2746
|
-
if (items.is_null())
|
|
2795
|
+
if (items.is_null()) {
|
|
2747
2796
|
return Value::array();
|
|
2748
|
-
|
|
2797
|
+
}
|
|
2798
|
+
if (!items.is_array()) {
|
|
2799
|
+
throw std::runtime_error("object is not iterable: " + items.dump());
|
|
2800
|
+
}
|
|
2749
2801
|
|
|
2750
2802
|
auto filter_fn = context->get(args.args[1]);
|
|
2751
|
-
if (filter_fn.is_null())
|
|
2803
|
+
if (filter_fn.is_null()) {
|
|
2804
|
+
throw std::runtime_error("Undefined filter: " + args.args[1].dump());
|
|
2805
|
+
}
|
|
2752
2806
|
|
|
2753
2807
|
auto filter_args = Value::array();
|
|
2754
2808
|
for (size_t i = 2, n = args.args.size(); i < n; i++) {
|
|
@@ -2870,20 +2924,25 @@ inline std::shared_ptr<Context> Context::builtins() {
|
|
|
2870
2924
|
auto v = arg.get<int64_t>();
|
|
2871
2925
|
startEndStep[i] = v;
|
|
2872
2926
|
param_set[i] = true;
|
|
2873
|
-
}
|
|
2874
2927
|
}
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2928
|
+
}
|
|
2929
|
+
for (auto & [name, value] : args.kwargs) {
|
|
2930
|
+
size_t i;
|
|
2931
|
+
if (name == "start") {
|
|
2932
|
+
i = 0;
|
|
2933
|
+
} else if (name == "end") {
|
|
2934
|
+
i = 1;
|
|
2935
|
+
} else if (name == "step") {
|
|
2936
|
+
i = 2;
|
|
2937
|
+
} else {
|
|
2938
|
+
throw std::runtime_error("Unknown argument " + name + " for function range");
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2941
|
+
if (param_set[i]) {
|
|
2942
|
+
throw std::runtime_error("Duplicate argument " + name + " for function range");
|
|
2943
|
+
}
|
|
2944
|
+
startEndStep[i] = value.get<int64_t>();
|
|
2945
|
+
param_set[i] = true;
|
|
2887
2946
|
}
|
|
2888
2947
|
if (!param_set[1]) {
|
|
2889
2948
|
throw std::runtime_error("Missing required argument 'end' for function range");
|