cui-llama.rn 1.4.6 → 1.5.0
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/android/src/main/CMakeLists.txt +9 -2
- package/android/src/main/jni.cpp +52 -34
- package/android/src/main/jniLibs/arm64-v8a/librnllama.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/librnllama_v8.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2_dotprod.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2_dotprod_i8mm.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/librnllama_v8_2_i8mm.so +0 -0
- package/android/src/main/jniLibs/x86_64/librnllama.so +0 -0
- package/android/src/main/jniLibs/x86_64/librnllama_x86_64.so +0 -0
- package/cpp/binary-ops.cpp +158 -0
- package/cpp/binary-ops.h +16 -0
- package/cpp/chat.cpp +1769 -1779
- package/cpp/chat.h +9 -1
- package/cpp/common.cpp +20 -522
- package/cpp/common.h +13 -36
- package/cpp/cpu-common.h +72 -0
- package/cpp/ggml-common.h +12 -6
- package/cpp/ggml-cpu-aarch64.cpp +1557 -80
- package/cpp/ggml-cpu-impl.h +2 -21
- package/cpp/ggml-cpu-quants.c +904 -405
- package/cpp/ggml-cpu.c +909 -13237
- package/cpp/ggml-impl.h +50 -23
- package/cpp/ggml-metal-impl.h +77 -3
- package/cpp/ggml-metal.m +794 -580
- package/cpp/ggml.c +92 -3
- package/cpp/ggml.h +29 -5
- package/cpp/gguf.cpp +1 -0
- package/cpp/llama-adapter.cpp +55 -20
- package/cpp/llama-adapter.h +11 -9
- package/cpp/llama-arch.cpp +217 -16
- package/cpp/llama-arch.h +25 -0
- package/cpp/llama-batch.h +2 -2
- package/cpp/llama-chat.cpp +54 -2
- package/cpp/llama-chat.h +3 -0
- package/cpp/llama-context.cpp +2294 -1238
- package/cpp/llama-context.h +214 -77
- package/cpp/llama-cparams.h +1 -0
- package/cpp/llama-graph.cpp +1695 -0
- package/cpp/llama-graph.h +592 -0
- package/cpp/llama-hparams.cpp +8 -0
- package/cpp/llama-hparams.h +17 -0
- package/cpp/llama-io.cpp +15 -0
- package/cpp/llama-io.h +35 -0
- package/cpp/llama-kv-cache.cpp +965 -303
- package/cpp/llama-kv-cache.h +145 -151
- package/cpp/llama-memory.cpp +1 -0
- package/cpp/llama-memory.h +21 -0
- package/cpp/llama-mmap.cpp +1 -1
- package/cpp/llama-model-loader.cpp +10 -5
- package/cpp/llama-model-loader.h +5 -3
- package/cpp/llama-model.cpp +9194 -201
- package/cpp/llama-model.h +40 -1
- package/cpp/llama-sampling.cpp +5 -0
- package/cpp/llama-vocab.cpp +36 -5
- package/cpp/llama.cpp +51 -9984
- package/cpp/llama.h +102 -22
- package/cpp/log.cpp +34 -0
- package/cpp/minja/chat-template.hpp +15 -7
- package/cpp/minja/minja.hpp +120 -94
- package/cpp/ops.cpp +8723 -0
- package/cpp/ops.h +128 -0
- package/cpp/rn-llama.cpp +44 -53
- package/cpp/rn-llama.h +2 -12
- package/cpp/sampling.cpp +3 -0
- package/cpp/sgemm.cpp +533 -88
- package/cpp/simd-mappings.h +888 -0
- package/cpp/speculative.cpp +4 -4
- package/cpp/unary-ops.cpp +186 -0
- package/cpp/unary-ops.h +28 -0
- package/cpp/vec.cpp +258 -0
- package/cpp/vec.h +802 -0
- package/ios/CMakeLists.txt +5 -2
- package/ios/RNLlama.mm +2 -2
- package/ios/RNLlamaContext.mm +40 -24
- package/package.json +1 -1
- package/src/NativeRNLlama.ts +6 -4
- package/src/index.ts +3 -1
- package/cpp/chat-template.hpp +0 -529
- package/cpp/minja.hpp +0 -2915
package/cpp/minja/minja.hpp
CHANGED
@@ -8,15 +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 <cmath>
|
15
|
+
#include <exception>
|
16
|
+
#include <functional>
|
11
17
|
#include <iostream>
|
12
|
-
#include <
|
13
|
-
#include <
|
14
|
-
#include <
|
18
|
+
#include <iterator>
|
19
|
+
#include <limits>
|
20
|
+
#include <map>
|
15
21
|
#include <memory>
|
16
|
-
#include <
|
22
|
+
#include <regex>
|
17
23
|
#include <sstream>
|
24
|
+
#include <string>
|
25
|
+
#include <stdexcept>
|
26
|
+
#include <unordered_map>
|
18
27
|
#include <unordered_set>
|
19
|
-
#include
|
28
|
+
#include <utility>
|
29
|
+
#include <vector>
|
30
|
+
|
31
|
+
#include <json.hpp>
|
20
32
|
|
21
33
|
using json = nlohmann::ordered_json;
|
22
34
|
|
@@ -731,51 +743,51 @@ public:
|
|
731
743
|
|
732
744
|
struct TextTemplateToken : public TemplateToken {
|
733
745
|
std::string text;
|
734
|
-
TextTemplateToken(const Location &
|
746
|
+
TextTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, const std::string& t) : TemplateToken(Type::Text, loc, pre, post), text(t) {}
|
735
747
|
};
|
736
748
|
|
737
749
|
struct ExpressionTemplateToken : public TemplateToken {
|
738
750
|
std::shared_ptr<Expression> expr;
|
739
|
-
ExpressionTemplateToken(const Location &
|
751
|
+
ExpressionTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, std::shared_ptr<Expression> && e) : TemplateToken(Type::Expression, loc, pre, post), expr(std::move(e)) {}
|
740
752
|
};
|
741
753
|
|
742
754
|
struct IfTemplateToken : public TemplateToken {
|
743
755
|
std::shared_ptr<Expression> condition;
|
744
|
-
IfTemplateToken(const Location &
|
756
|
+
IfTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, std::shared_ptr<Expression> && c) : TemplateToken(Type::If, loc, pre, post), condition(std::move(c)) {}
|
745
757
|
};
|
746
758
|
|
747
759
|
struct ElifTemplateToken : public TemplateToken {
|
748
760
|
std::shared_ptr<Expression> condition;
|
749
|
-
ElifTemplateToken(const Location &
|
761
|
+
ElifTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, std::shared_ptr<Expression> && c) : TemplateToken(Type::Elif, loc, pre, post), condition(std::move(c)) {}
|
750
762
|
};
|
751
763
|
|
752
764
|
struct ElseTemplateToken : public TemplateToken {
|
753
|
-
ElseTemplateToken(const Location &
|
765
|
+
ElseTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::Else, loc, pre, post) {}
|
754
766
|
};
|
755
767
|
|
756
768
|
struct EndIfTemplateToken : public TemplateToken {
|
757
|
-
EndIfTemplateToken(const Location &
|
769
|
+
EndIfTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndIf, loc, pre, post) {}
|
758
770
|
};
|
759
771
|
|
760
772
|
struct MacroTemplateToken : public TemplateToken {
|
761
773
|
std::shared_ptr<VariableExpr> name;
|
762
774
|
Expression::Parameters params;
|
763
|
-
MacroTemplateToken(const Location &
|
764
|
-
: TemplateToken(Type::Macro,
|
775
|
+
MacroTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, std::shared_ptr<VariableExpr> && n, Expression::Parameters && p)
|
776
|
+
: TemplateToken(Type::Macro, loc, pre, post), name(std::move(n)), params(std::move(p)) {}
|
765
777
|
};
|
766
778
|
|
767
779
|
struct EndMacroTemplateToken : public TemplateToken {
|
768
|
-
EndMacroTemplateToken(const Location &
|
780
|
+
EndMacroTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndMacro, loc, pre, post) {}
|
769
781
|
};
|
770
782
|
|
771
783
|
struct FilterTemplateToken : public TemplateToken {
|
772
784
|
std::shared_ptr<Expression> filter;
|
773
|
-
FilterTemplateToken(const Location &
|
774
|
-
: TemplateToken(Type::Filter,
|
785
|
+
FilterTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, std::shared_ptr<Expression> && filter)
|
786
|
+
: TemplateToken(Type::Filter, loc, pre, post), filter(std::move(filter)) {}
|
775
787
|
};
|
776
788
|
|
777
789
|
struct EndFilterTemplateToken : public TemplateToken {
|
778
|
-
EndFilterTemplateToken(const Location &
|
790
|
+
EndFilterTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndFilter, loc, pre, post) {}
|
779
791
|
};
|
780
792
|
|
781
793
|
struct ForTemplateToken : public TemplateToken {
|
@@ -783,38 +795,38 @@ struct ForTemplateToken : public TemplateToken {
|
|
783
795
|
std::shared_ptr<Expression> iterable;
|
784
796
|
std::shared_ptr<Expression> condition;
|
785
797
|
bool recursive;
|
786
|
-
ForTemplateToken(const Location &
|
798
|
+
ForTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, const std::vector<std::string> & vns, std::shared_ptr<Expression> && iter,
|
787
799
|
std::shared_ptr<Expression> && c, bool r)
|
788
|
-
: TemplateToken(Type::For,
|
800
|
+
: TemplateToken(Type::For, loc, pre, post), var_names(vns), iterable(std::move(iter)), condition(std::move(c)), recursive(r) {}
|
789
801
|
};
|
790
802
|
|
791
803
|
struct EndForTemplateToken : public TemplateToken {
|
792
|
-
EndForTemplateToken(const Location &
|
804
|
+
EndForTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndFor, loc, pre, post) {}
|
793
805
|
};
|
794
806
|
|
795
807
|
struct GenerationTemplateToken : public TemplateToken {
|
796
|
-
GenerationTemplateToken(const Location &
|
808
|
+
GenerationTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::Generation, loc, pre, post) {}
|
797
809
|
};
|
798
810
|
|
799
811
|
struct EndGenerationTemplateToken : public TemplateToken {
|
800
|
-
EndGenerationTemplateToken(const Location &
|
812
|
+
EndGenerationTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndGeneration, loc, pre, post) {}
|
801
813
|
};
|
802
814
|
|
803
815
|
struct SetTemplateToken : public TemplateToken {
|
804
816
|
std::string ns;
|
805
817
|
std::vector<std::string> var_names;
|
806
818
|
std::shared_ptr<Expression> value;
|
807
|
-
SetTemplateToken(const Location &
|
808
|
-
: TemplateToken(Type::Set,
|
819
|
+
SetTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, const std::string & ns, const std::vector<std::string> & vns, std::shared_ptr<Expression> && v)
|
820
|
+
: TemplateToken(Type::Set, loc, pre, post), ns(ns), var_names(vns), value(std::move(v)) {}
|
809
821
|
};
|
810
822
|
|
811
823
|
struct EndSetTemplateToken : public TemplateToken {
|
812
|
-
EndSetTemplateToken(const Location &
|
824
|
+
EndSetTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post) : TemplateToken(Type::EndSet, loc, pre, post) {}
|
813
825
|
};
|
814
826
|
|
815
827
|
struct CommentTemplateToken : public TemplateToken {
|
816
828
|
std::string text;
|
817
|
-
CommentTemplateToken(const Location &
|
829
|
+
CommentTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, const std::string& t) : TemplateToken(Type::Comment, loc, pre, post), text(t) {}
|
818
830
|
};
|
819
831
|
|
820
832
|
enum class LoopControlType { Break, Continue };
|
@@ -830,7 +842,7 @@ public:
|
|
830
842
|
|
831
843
|
struct LoopControlTemplateToken : public TemplateToken {
|
832
844
|
LoopControlType control_type;
|
833
|
-
LoopControlTemplateToken(const Location &
|
845
|
+
LoopControlTemplateToken(const Location & loc, SpaceHandling pre, SpaceHandling post, LoopControlType control_type) : TemplateToken(Type::Break, loc, pre, post), control_type(control_type) {}
|
834
846
|
};
|
835
847
|
|
836
848
|
class TemplateNode {
|
@@ -868,8 +880,8 @@ public:
|
|
868
880
|
class SequenceNode : public TemplateNode {
|
869
881
|
std::vector<std::shared_ptr<TemplateNode>> children;
|
870
882
|
public:
|
871
|
-
SequenceNode(const Location &
|
872
|
-
: TemplateNode(
|
883
|
+
SequenceNode(const Location & loc, std::vector<std::shared_ptr<TemplateNode>> && c)
|
884
|
+
: TemplateNode(loc), children(std::move(c)) {}
|
873
885
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> & context) const override {
|
874
886
|
for (const auto& child : children) child->render(out, context);
|
875
887
|
}
|
@@ -878,7 +890,7 @@ public:
|
|
878
890
|
class TextNode : public TemplateNode {
|
879
891
|
std::string text;
|
880
892
|
public:
|
881
|
-
TextNode(const Location &
|
893
|
+
TextNode(const Location & loc, const std::string& t) : TemplateNode(loc), text(t) {}
|
882
894
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> &) const override {
|
883
895
|
out << text;
|
884
896
|
}
|
@@ -887,7 +899,7 @@ public:
|
|
887
899
|
class ExpressionNode : public TemplateNode {
|
888
900
|
std::shared_ptr<Expression> expr;
|
889
901
|
public:
|
890
|
-
ExpressionNode(const Location &
|
902
|
+
ExpressionNode(const Location & loc, std::shared_ptr<Expression> && e) : TemplateNode(loc), expr(std::move(e)) {}
|
891
903
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> & context) const override {
|
892
904
|
if (!expr) throw std::runtime_error("ExpressionNode.expr is null");
|
893
905
|
auto result = expr->evaluate(context);
|
@@ -904,8 +916,8 @@ public:
|
|
904
916
|
class IfNode : public TemplateNode {
|
905
917
|
std::vector<std::pair<std::shared_ptr<Expression>, std::shared_ptr<TemplateNode>>> cascade;
|
906
918
|
public:
|
907
|
-
IfNode(const Location &
|
908
|
-
: TemplateNode(
|
919
|
+
IfNode(const Location & loc, std::vector<std::pair<std::shared_ptr<Expression>, std::shared_ptr<TemplateNode>>> && c)
|
920
|
+
: TemplateNode(loc), cascade(std::move(c)) {}
|
909
921
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> & context) const override {
|
910
922
|
for (const auto& branch : cascade) {
|
911
923
|
auto enter_branch = true;
|
@@ -924,7 +936,7 @@ public:
|
|
924
936
|
class LoopControlNode : public TemplateNode {
|
925
937
|
LoopControlType control_type_;
|
926
938
|
public:
|
927
|
-
LoopControlNode(const Location &
|
939
|
+
LoopControlNode(const Location & loc, LoopControlType control_type) : TemplateNode(loc), control_type_(control_type) {}
|
928
940
|
void do_render(std::ostringstream &, const std::shared_ptr<Context> &) const override {
|
929
941
|
throw LoopControlException(control_type_);
|
930
942
|
}
|
@@ -938,9 +950,9 @@ class ForNode : public TemplateNode {
|
|
938
950
|
bool recursive;
|
939
951
|
std::shared_ptr<TemplateNode> else_body;
|
940
952
|
public:
|
941
|
-
ForNode(const Location &
|
953
|
+
ForNode(const Location & loc, std::vector<std::string> && var_names, std::shared_ptr<Expression> && iterable,
|
942
954
|
std::shared_ptr<Expression> && condition, std::shared_ptr<TemplateNode> && body, bool recursive, std::shared_ptr<TemplateNode> && else_body)
|
943
|
-
: TemplateNode(
|
955
|
+
: 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
956
|
|
945
957
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> & context) const override {
|
946
958
|
// https://jinja.palletsprojects.com/en/3.0.x/templates/#for
|
@@ -1025,8 +1037,8 @@ class MacroNode : public TemplateNode {
|
|
1025
1037
|
std::shared_ptr<TemplateNode> body;
|
1026
1038
|
std::unordered_map<std::string, size_t> named_param_positions;
|
1027
1039
|
public:
|
1028
|
-
MacroNode(const Location &
|
1029
|
-
: TemplateNode(
|
1040
|
+
MacroNode(const Location & loc, std::shared_ptr<VariableExpr> && n, Expression::Parameters && p, std::shared_ptr<TemplateNode> && b)
|
1041
|
+
: TemplateNode(loc), name(std::move(n)), params(std::move(p)), body(std::move(b)) {
|
1030
1042
|
for (size_t i = 0; i < params.size(); ++i) {
|
1031
1043
|
const auto & name = params[i].first;
|
1032
1044
|
if (!name.empty()) {
|
@@ -1072,8 +1084,8 @@ class FilterNode : public TemplateNode {
|
|
1072
1084
|
std::shared_ptr<TemplateNode> body;
|
1073
1085
|
|
1074
1086
|
public:
|
1075
|
-
FilterNode(const Location &
|
1076
|
-
: TemplateNode(
|
1087
|
+
FilterNode(const Location & loc, std::shared_ptr<Expression> && f, std::shared_ptr<TemplateNode> && b)
|
1088
|
+
: TemplateNode(loc), filter(std::move(f)), body(std::move(b)) {}
|
1077
1089
|
|
1078
1090
|
void do_render(std::ostringstream & out, const std::shared_ptr<Context> & context) const override {
|
1079
1091
|
if (!filter) throw std::runtime_error("FilterNode.filter is null");
|
@@ -1095,8 +1107,8 @@ class SetNode : public TemplateNode {
|
|
1095
1107
|
std::vector<std::string> var_names;
|
1096
1108
|
std::shared_ptr<Expression> value;
|
1097
1109
|
public:
|
1098
|
-
SetNode(const Location &
|
1099
|
-
: TemplateNode(
|
1110
|
+
SetNode(const Location & loc, const std::string & ns, const std::vector<std::string> & vns, std::shared_ptr<Expression> && v)
|
1111
|
+
: TemplateNode(loc), ns(ns), var_names(vns), value(std::move(v)) {}
|
1100
1112
|
void do_render(std::ostringstream &, const std::shared_ptr<Context> & context) const override {
|
1101
1113
|
if (!value) throw std::runtime_error("SetNode.value is null");
|
1102
1114
|
if (!ns.empty()) {
|
@@ -1118,8 +1130,8 @@ class SetTemplateNode : public TemplateNode {
|
|
1118
1130
|
std::string name;
|
1119
1131
|
std::shared_ptr<TemplateNode> template_value;
|
1120
1132
|
public:
|
1121
|
-
SetTemplateNode(const Location &
|
1122
|
-
: TemplateNode(
|
1133
|
+
SetTemplateNode(const Location & loc, const std::string & name, std::shared_ptr<TemplateNode> && tv)
|
1134
|
+
: TemplateNode(loc), name(name), template_value(std::move(tv)) {}
|
1123
1135
|
void do_render(std::ostringstream &, const std::shared_ptr<Context> & context) const override {
|
1124
1136
|
if (!template_value) throw std::runtime_error("SetTemplateNode.template_value is null");
|
1125
1137
|
Value value { template_value->render(context) };
|
@@ -1132,8 +1144,8 @@ class IfExpr : public Expression {
|
|
1132
1144
|
std::shared_ptr<Expression> then_expr;
|
1133
1145
|
std::shared_ptr<Expression> else_expr;
|
1134
1146
|
public:
|
1135
|
-
IfExpr(const Location &
|
1136
|
-
: Expression(
|
1147
|
+
IfExpr(const Location & loc, std::shared_ptr<Expression> && c, std::shared_ptr<Expression> && t, std::shared_ptr<Expression> && e)
|
1148
|
+
: Expression(loc), condition(std::move(c)), then_expr(std::move(t)), else_expr(std::move(e)) {}
|
1137
1149
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
1138
1150
|
if (!condition) throw std::runtime_error("IfExpr.condition is null");
|
1139
1151
|
if (!then_expr) throw std::runtime_error("IfExpr.then_expr is null");
|
@@ -1150,16 +1162,16 @@ public:
|
|
1150
1162
|
class LiteralExpr : public Expression {
|
1151
1163
|
Value value;
|
1152
1164
|
public:
|
1153
|
-
LiteralExpr(const Location &
|
1154
|
-
: Expression(
|
1165
|
+
LiteralExpr(const Location & loc, const Value& v)
|
1166
|
+
: Expression(loc), value(v) {}
|
1155
1167
|
Value do_evaluate(const std::shared_ptr<Context> &) const override { return value; }
|
1156
1168
|
};
|
1157
1169
|
|
1158
1170
|
class ArrayExpr : public Expression {
|
1159
1171
|
std::vector<std::shared_ptr<Expression>> elements;
|
1160
1172
|
public:
|
1161
|
-
ArrayExpr(const Location &
|
1162
|
-
: Expression(
|
1173
|
+
ArrayExpr(const Location & loc, std::vector<std::shared_ptr<Expression>> && e)
|
1174
|
+
: Expression(loc), elements(std::move(e)) {}
|
1163
1175
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
1164
1176
|
auto result = Value::array();
|
1165
1177
|
for (const auto& e : elements) {
|
@@ -1173,8 +1185,8 @@ public:
|
|
1173
1185
|
class DictExpr : public Expression {
|
1174
1186
|
std::vector<std::pair<std::shared_ptr<Expression>, std::shared_ptr<Expression>>> elements;
|
1175
1187
|
public:
|
1176
|
-
DictExpr(const Location &
|
1177
|
-
: Expression(
|
1188
|
+
DictExpr(const Location & loc, std::vector<std::pair<std::shared_ptr<Expression>, std::shared_ptr<Expression>>> && e)
|
1189
|
+
: Expression(loc), elements(std::move(e)) {}
|
1178
1190
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
1179
1191
|
auto result = Value::object();
|
1180
1192
|
for (const auto& [key, value] : elements) {
|
@@ -1189,8 +1201,8 @@ public:
|
|
1189
1201
|
class SliceExpr : public Expression {
|
1190
1202
|
public:
|
1191
1203
|
std::shared_ptr<Expression> start, end;
|
1192
|
-
SliceExpr(const Location &
|
1193
|
-
: Expression(
|
1204
|
+
SliceExpr(const Location & loc, std::shared_ptr<Expression> && s, std::shared_ptr<Expression> && e)
|
1205
|
+
: Expression(loc), start(std::move(s)), end(std::move(e)) {}
|
1194
1206
|
Value do_evaluate(const std::shared_ptr<Context> &) const override {
|
1195
1207
|
throw std::runtime_error("SliceExpr not implemented");
|
1196
1208
|
}
|
@@ -1200,8 +1212,8 @@ class SubscriptExpr : public Expression {
|
|
1200
1212
|
std::shared_ptr<Expression> base;
|
1201
1213
|
std::shared_ptr<Expression> index;
|
1202
1214
|
public:
|
1203
|
-
SubscriptExpr(const Location &
|
1204
|
-
: Expression(
|
1215
|
+
SubscriptExpr(const Location & loc, std::shared_ptr<Expression> && b, std::shared_ptr<Expression> && i)
|
1216
|
+
: Expression(loc), base(std::move(b)), index(std::move(i)) {}
|
1205
1217
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
1206
1218
|
if (!base) throw std::runtime_error("SubscriptExpr.base is null");
|
1207
1219
|
if (!index) throw std::runtime_error("SubscriptExpr.index is null");
|
@@ -1243,8 +1255,8 @@ public:
|
|
1243
1255
|
enum class Op { Plus, Minus, LogicalNot, Expansion, ExpansionDict };
|
1244
1256
|
std::shared_ptr<Expression> expr;
|
1245
1257
|
Op op;
|
1246
|
-
UnaryOpExpr(const Location &
|
1247
|
-
: Expression(
|
1258
|
+
UnaryOpExpr(const Location & loc, std::shared_ptr<Expression> && e, Op o)
|
1259
|
+
: Expression(loc), expr(std::move(e)), op(o) {}
|
1248
1260
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
1249
1261
|
if (!expr) throw std::runtime_error("UnaryOpExpr.expr is null");
|
1250
1262
|
auto e = expr->evaluate(context);
|
@@ -1269,8 +1281,8 @@ private:
|
|
1269
1281
|
std::shared_ptr<Expression> right;
|
1270
1282
|
Op op;
|
1271
1283
|
public:
|
1272
|
-
BinaryOpExpr(const Location &
|
1273
|
-
: Expression(
|
1284
|
+
BinaryOpExpr(const Location & loc, std::shared_ptr<Expression> && l, std::shared_ptr<Expression> && r, Op o)
|
1285
|
+
: Expression(loc), left(std::move(l)), right(std::move(r)), op(o) {}
|
1274
1286
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
1275
1287
|
if (!left) throw std::runtime_error("BinaryOpExpr.left is null");
|
1276
1288
|
if (!right) throw std::runtime_error("BinaryOpExpr.right is null");
|
@@ -1427,8 +1439,8 @@ class MethodCallExpr : public Expression {
|
|
1427
1439
|
std::shared_ptr<VariableExpr> method;
|
1428
1440
|
ArgumentsExpression args;
|
1429
1441
|
public:
|
1430
|
-
MethodCallExpr(const Location &
|
1431
|
-
: Expression(
|
1442
|
+
MethodCallExpr(const Location & loc, std::shared_ptr<Expression> && obj, std::shared_ptr<VariableExpr> && m, ArgumentsExpression && a)
|
1443
|
+
: Expression(loc), object(std::move(obj)), method(std::move(m)), args(std::move(a)) {}
|
1432
1444
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
1433
1445
|
if (!object) throw std::runtime_error("MethodCallExpr.object is null");
|
1434
1446
|
if (!method) throw std::runtime_error("MethodCallExpr.method is null");
|
@@ -1526,8 +1538,8 @@ class CallExpr : public Expression {
|
|
1526
1538
|
public:
|
1527
1539
|
std::shared_ptr<Expression> object;
|
1528
1540
|
ArgumentsExpression args;
|
1529
|
-
CallExpr(const Location &
|
1530
|
-
: Expression(
|
1541
|
+
CallExpr(const Location & loc, std::shared_ptr<Expression> && obj, ArgumentsExpression && a)
|
1542
|
+
: Expression(loc), object(std::move(obj)), args(std::move(a)) {}
|
1531
1543
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
1532
1544
|
if (!object) throw std::runtime_error("CallExpr.object is null");
|
1533
1545
|
auto obj = object->evaluate(context);
|
@@ -1542,8 +1554,8 @@ public:
|
|
1542
1554
|
class FilterExpr : public Expression {
|
1543
1555
|
std::vector<std::shared_ptr<Expression>> parts;
|
1544
1556
|
public:
|
1545
|
-
FilterExpr(const Location &
|
1546
|
-
: Expression(
|
1557
|
+
FilterExpr(const Location & loc, std::vector<std::shared_ptr<Expression>> && p)
|
1558
|
+
: Expression(loc), parts(std::move(p)) {}
|
1547
1559
|
Value do_evaluate(const std::shared_ptr<Context> & context) const override {
|
1548
1560
|
Value result;
|
1549
1561
|
bool first = true;
|
@@ -2460,7 +2472,7 @@ private:
|
|
2460
2472
|
static std::regex leading_space_regex(R"(^\s+)");
|
2461
2473
|
text = std::regex_replace(text, leading_space_regex, "");
|
2462
2474
|
} else if (options.trim_blocks && (it - 1) != begin && !dynamic_cast<ExpressionTemplateToken*>((*(it - 2)).get())) {
|
2463
|
-
if (text.
|
2475
|
+
if (!text.empty() && text[0] == '\n') {
|
2464
2476
|
text.erase(0, 1);
|
2465
2477
|
}
|
2466
2478
|
}
|
@@ -2538,7 +2550,7 @@ public:
|
|
2538
2550
|
TemplateTokenIterator begin = tokens.begin();
|
2539
2551
|
auto it = begin;
|
2540
2552
|
TemplateTokenIterator end = tokens.end();
|
2541
|
-
return parser.parseTemplate(begin, it, end, /*
|
2553
|
+
return parser.parseTemplate(begin, it, end, /* fully= */ true);
|
2542
2554
|
}
|
2543
2555
|
};
|
2544
2556
|
|
@@ -2577,7 +2589,7 @@ inline std::shared_ptr<Context> Context::builtins() {
|
|
2577
2589
|
throw std::runtime_error(args.at("message").get<std::string>());
|
2578
2590
|
}));
|
2579
2591
|
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), /*
|
2592
|
+
return Value(args.at("value").dump(args.get<int64_t>("indent", -1), /* to_json= */ true));
|
2581
2593
|
}));
|
2582
2594
|
globals.set("items", simple_function("items", { "object" }, [](const std::shared_ptr<Context> &, Value & args) {
|
2583
2595
|
auto items = Value::array();
|
@@ -2599,21 +2611,25 @@ inline std::shared_ptr<Context> Context::builtins() {
|
|
2599
2611
|
globals.set("last", simple_function("last", { "items" }, [](const std::shared_ptr<Context> &, Value & args) {
|
2600
2612
|
auto items = args.at("items");
|
2601
2613
|
if (!items.is_array()) throw std::runtime_error("object is not a list");
|
2602
|
-
if (items.
|
2614
|
+
if (items.empty()) return Value();
|
2603
2615
|
return items.at(items.size() - 1);
|
2604
2616
|
}));
|
2605
2617
|
globals.set("trim", simple_function("trim", { "text" }, [](const std::shared_ptr<Context> &, Value & args) {
|
2606
2618
|
auto & text = args.at("text");
|
2607
2619
|
return text.is_null() ? text : Value(strip(text.get<std::string>()));
|
2608
2620
|
}));
|
2609
|
-
|
2610
|
-
|
2611
|
-
|
2612
|
-
|
2613
|
-
|
2614
|
-
|
2615
|
-
|
2616
|
-
|
2621
|
+
auto char_transform_function = [](const std::string & name, const std::function<char(char)> & fn) {
|
2622
|
+
return simple_function(name, { "text" }, [=](const std::shared_ptr<Context> &, Value & args) {
|
2623
|
+
auto text = args.at("text");
|
2624
|
+
if (text.is_null()) return text;
|
2625
|
+
std::string res;
|
2626
|
+
auto str = text.get<std::string>();
|
2627
|
+
std::transform(str.begin(), str.end(), std::back_inserter(res), fn);
|
2628
|
+
return Value(res);
|
2629
|
+
});
|
2630
|
+
};
|
2631
|
+
globals.set("lower", char_transform_function("lower", ::tolower));
|
2632
|
+
globals.set("upper", char_transform_function("upper", ::toupper));
|
2617
2633
|
globals.set("default", Value::callable([=](const std::shared_ptr<Context> &, ArgumentsValue & args) {
|
2618
2634
|
args.expectArgs("default", {2, 3}, {0, 1});
|
2619
2635
|
auto & value = args.args[0];
|
@@ -2743,12 +2759,17 @@ inline std::shared_ptr<Context> Context::builtins() {
|
|
2743
2759
|
return Value::callable([=](const std::shared_ptr<Context> & context, ArgumentsValue & args) {
|
2744
2760
|
args.expectArgs(is_select ? "select" : "reject", {2, (std::numeric_limits<size_t>::max)()}, {0, 0});
|
2745
2761
|
auto & items = args.args[0];
|
2746
|
-
if (items.is_null())
|
2762
|
+
if (items.is_null()) {
|
2747
2763
|
return Value::array();
|
2748
|
-
|
2764
|
+
}
|
2765
|
+
if (!items.is_array()) {
|
2766
|
+
throw std::runtime_error("object is not iterable: " + items.dump());
|
2767
|
+
}
|
2749
2768
|
|
2750
2769
|
auto filter_fn = context->get(args.args[1]);
|
2751
|
-
if (filter_fn.is_null())
|
2770
|
+
if (filter_fn.is_null()) {
|
2771
|
+
throw std::runtime_error("Undefined filter: " + args.args[1].dump());
|
2772
|
+
}
|
2752
2773
|
|
2753
2774
|
auto filter_args = Value::array();
|
2754
2775
|
for (size_t i = 2, n = args.args.size(); i < n; i++) {
|
@@ -2870,20 +2891,25 @@ inline std::shared_ptr<Context> Context::builtins() {
|
|
2870
2891
|
auto v = arg.get<int64_t>();
|
2871
2892
|
startEndStep[i] = v;
|
2872
2893
|
param_set[i] = true;
|
2873
|
-
}
|
2874
2894
|
}
|
2875
|
-
|
2876
|
-
|
2877
|
-
|
2878
|
-
|
2879
|
-
|
2880
|
-
|
2881
|
-
|
2882
|
-
|
2883
|
-
|
2884
|
-
|
2885
|
-
|
2886
|
-
|
2895
|
+
}
|
2896
|
+
for (auto & [name, value] : args.kwargs) {
|
2897
|
+
size_t i;
|
2898
|
+
if (name == "start") {
|
2899
|
+
i = 0;
|
2900
|
+
} else if (name == "end") {
|
2901
|
+
i = 1;
|
2902
|
+
} else if (name == "step") {
|
2903
|
+
i = 2;
|
2904
|
+
} else {
|
2905
|
+
throw std::runtime_error("Unknown argument " + name + " for function range");
|
2906
|
+
}
|
2907
|
+
|
2908
|
+
if (param_set[i]) {
|
2909
|
+
throw std::runtime_error("Duplicate argument " + name + " for function range");
|
2910
|
+
}
|
2911
|
+
startEndStep[i] = value.get<int64_t>();
|
2912
|
+
param_set[i] = true;
|
2887
2913
|
}
|
2888
2914
|
if (!param_set[1]) {
|
2889
2915
|
throw std::runtime_error("Missing required argument 'end' for function range");
|