rego-cpp 1.0.0
A C++ implementation of the Rego language and runtime
Loading...
Searching...
No Matches
rego.hh
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#pragma once
5
6#include "rego_c.h"
7#include "trieste/logging.h"
8#include "trieste/token.h"
9
10#include <initializer_list>
11#include <trieste/trieste.h>
12
17namespace rego
18{
19 using namespace trieste;
20 using namespace wf::ops;
21
23 inline const auto Module =
24 TokenDef("rego-module", flag::lookup | flag::symtab);
25 inline const auto Package = TokenDef("rego-package");
26 inline const auto Policy = TokenDef("rego-policy");
27 inline const auto Rule = TokenDef(
28 "rego-rule",
29 flag::lookup | flag::lookdown | flag::symtab | flag::defbeforeuse);
30 inline const auto RuleHead = TokenDef("rego-rulehead");
31 inline const auto RuleHeadComp = TokenDef("rego-ruleheadcomp");
32 inline const auto RuleHeadFunc = TokenDef("rego-ruleheadfunc");
33 inline const auto RuleHeadSet = TokenDef("rego-ruleheadset");
34 inline const auto RuleHeadObj = TokenDef("rego-ruleheadobj");
35 inline const auto RuleArgs = TokenDef("rego-ruleargs");
36 inline const auto Query = TokenDef("rego-query");
37 inline const auto Literal = TokenDef("rego-literal");
38 inline const auto Expr = TokenDef("rego-expr");
39 inline const auto ExprInfix = TokenDef("rego-exprinfix");
40 inline const auto ExprCall = TokenDef("rego-exprcall");
41 inline const auto ExprEvery = TokenDef("rego-exprevery", flag::symtab);
42 inline const auto ExprParens = TokenDef("rego-exprparens");
43 inline const auto UnaryExpr = TokenDef("rego-unaryexpr");
44 inline const auto NotExpr = TokenDef("rego-not-expr");
45 inline const auto Term = TokenDef("rego-term");
46 inline const auto InfixOperator = TokenDef("rego-infixoperator");
47 inline const auto BoolOperator = TokenDef("rego-booloperator");
48 inline const auto ArithOperator = TokenDef("rego-arithoperator");
49 inline const auto AssignOperator = TokenDef("rego-assignoperator");
50 inline const auto BinOperator = TokenDef("rego-binoperator");
51 inline const auto Ref = TokenDef("rego-ref");
52 inline const auto RefArgBrack = TokenDef("rego-refargbrack");
53 inline const auto RefArgDot = TokenDef("rego-refargdot");
54 inline const auto Var = TokenDef("rego-var", flag::print);
55 inline const auto Scalar = TokenDef("rego-scalar");
56 inline const auto String = TokenDef("rego-string");
57 inline const auto Array = TokenDef("rego-array");
58 inline const auto Object = TokenDef("rego-object");
59 inline const auto Set = TokenDef("rego-set");
60 inline const auto ObjectItem = TokenDef("rego-objectitem");
61 inline const auto RawString = TokenDef("rego-rawstring", flag::print);
62 inline const auto JSONString = TokenDef("rego-STRING", flag::print);
63 inline const auto Int = TokenDef("rego-INT", flag::print);
64 inline const auto Float = TokenDef("rego-FLOAT", flag::print);
65 inline const auto True = TokenDef("rego-true");
66 inline const auto False = TokenDef("rego-false");
67 inline const auto Null = TokenDef("rego-null");
68 inline const auto Equals = TokenDef("rego-equals");
69 inline const auto NotEquals = TokenDef("rego-notequals");
70 inline const auto LessThan = TokenDef("rego-lessthan");
71 inline const auto GreaterThan = TokenDef("rego-greaterthan");
72 inline const auto LessThanOrEquals = TokenDef("rego-lessthanorequals");
73 inline const auto GreaterThanOrEquals = TokenDef("rego-greaterthanorequals");
74 inline const auto Add = TokenDef("rego-add");
75 inline const auto Subtract = TokenDef("rego-subtract");
76 inline const auto Multiply = TokenDef("rego-multiply");
77 inline const auto Divide = TokenDef("rego-divide");
78 inline const auto Modulo = TokenDef("rego-modulo");
79 inline const auto And = TokenDef("rego-and");
80 inline const auto Or = TokenDef("rego-or");
81 inline const auto Assign = TokenDef("rego-assign");
82 inline const auto Unify = TokenDef("rego-unify");
83 inline const auto Default = TokenDef("rego-default");
84 inline const auto Some = TokenDef("rego-some");
85 inline const auto SomeDecl = TokenDef("rego-somedecl");
86 inline const auto If = TokenDef("rego-if");
87 inline const auto IsIn = TokenDef("rego-in");
88 inline const auto Contains = TokenDef("rego-contains");
89 inline const auto Else = TokenDef("rego-else");
90 inline const auto As = TokenDef("rego-as");
91 inline const auto With = TokenDef("rego-with");
92 inline const auto Every = TokenDef("rego-every");
93 inline const auto ArrayCompr = TokenDef("rego-arraycompr", flag::symtab);
94 inline const auto ObjectCompr = TokenDef("rego-objectcompr", flag::symtab);
95 inline const auto SetCompr = TokenDef("rego-setcompr", flag::symtab);
96 inline const auto Membership = TokenDef("rego-membership");
97 inline const auto Not = TokenDef("rego-not");
98 inline const auto Import =
99 TokenDef("rego-import", flag::lookdown | flag::lookup | flag::shadowing);
100 inline const auto Placeholder = TokenDef("rego-placeholder");
101 inline const auto Version = TokenDef("rego-version", flag::print);
102
103 // intermediate tokens
104 inline const auto RuleBodySeq = TokenDef("rego-rulebodyseq");
105 inline const auto ImportSeq = TokenDef("rego-importseq");
106 inline const auto RuleRef = TokenDef("rego-ruleref");
107 inline const auto RuleHeadType = TokenDef("rego-ruleheadtype");
108 inline const auto WithSeq = TokenDef("rego-withseq");
109 inline const auto TermSeq = TokenDef("rego-termseq");
110 inline const auto ExprSeq = TokenDef("rego-exprseq");
111 inline const auto VarSeq = TokenDef("rego-varseq");
112 inline const auto RefHead = TokenDef("rego-refhead");
113 inline const auto RefArgSeq = TokenDef("rego-refargseq");
114 inline const auto Key = TokenDef("rego-key", flag::print);
115 inline const auto Val = TokenDef("rego-value");
116 inline const auto Undefined = TokenDef("rego-undefined");
117 inline const auto Name = TokenDef("rego-name");
118 inline const auto Return = TokenDef("rego-return");
119 inline const auto Target = TokenDef("rego-target");
120 inline const auto Lhs = TokenDef("rego-lhs");
121 inline const auto Rhs = TokenDef("rego-rhs");
122 inline const auto Src = TokenDef("rego-src");
123 inline const auto Args = TokenDef("rego-args");
124 inline const auto Idx = TokenDef("rego-idx");
125 inline const auto Row = TokenDef("rego-row");
126 inline const auto Col = TokenDef("rego-col");
127
128 // other tokens
129 inline const auto Results = TokenDef("rego-results", flag::symtab);
130 inline const auto Result = TokenDef("rego-result", flag::symtab);
131 inline const auto Bindings = TokenDef("rego-bindings");
132 inline const auto Terms = TokenDef("rego-terms");
133 inline const auto Binding = TokenDef("rego-binding", flag::lookdown);
134 inline const auto ErrorCode = TokenDef("rego-errorcode");
135 inline const auto ErrorSeq = TokenDef("rego-errorseq");
136 inline const auto Line = TokenDef("rego-line", flag::print);
137
138 inline const auto wf_assign_op = Assign | Unify;
139 inline const auto wf_arith_op = Add | Subtract | Multiply | Divide | Modulo;
140 inline const auto wf_bin_op = And | Or | Subtract;
141 inline const auto wf_bool_op = Equals | NotEquals | LessThan |
142 LessThanOrEquals | GreaterThan | GreaterThanOrEquals | Not;
143 inline const auto wf_exprs =
144 Term | ExprCall | ExprInfix | ExprEvery | ExprParens | UnaryExpr;
145
146 // clang-format off
147 inline const auto wf =
148 (Top <<= Query | Module)
149 | (Module <<= Package * Version * ImportSeq * Policy)
150 | (ImportSeq <<= Import++)
151 | (Import <<= Ref * Var)
152 | (Package <<= Ref)
153 | (Policy <<= Rule++)
154 | (Rule <<= (Default >>= True | False) * RuleHead * RuleBodySeq)
155 | (RuleHead <<= RuleRef * (RuleHeadType >>= (RuleHeadSet | RuleHeadObj | RuleHeadFunc | RuleHeadComp)))
156 | (RuleRef <<= Var | Ref)
157 | (RuleHeadComp <<= Expr)
158 | (RuleHeadObj <<= Expr * Expr)
159 | (RuleHeadFunc <<= RuleArgs * Expr)
160 | (RuleHeadSet <<= Expr)
161 | (RuleArgs <<= Term++)
162 | (RuleBodySeq <<= (Else | Query)++)
163 | (Else <<= Expr * Query)
164 | (Query <<= Literal++)
165 | (Literal <<= (Expr >>= SomeDecl | Expr | NotExpr) * WithSeq)
166 | (WithSeq <<= With++)
167 | (With <<= Term * Expr)
168 | (SomeDecl <<= ExprSeq * (IsIn >>= Expr | Undefined))
169 | (NotExpr <<= Expr)
170 | (Expr <<= (Term | ExprCall | ExprInfix | ExprEvery | ExprParens | UnaryExpr))
171 | (ExprCall <<= Ref * ExprSeq)
172 | (ExprSeq <<= Expr++)
173 | (ExprInfix <<= Expr * InfixOperator * Expr)
174 | (ExprEvery <<= VarSeq * (IsIn >>= Term | ExprCall | ExprInfix) * Query)
175 | (VarSeq <<= Var++[1])
176 | (ExprParens <<= Expr)
177 | (UnaryExpr <<= Expr)
178 | (Membership <<= ExprSeq * Expr)
179 | (Term <<= Ref | Var | Scalar | Array | Object | Set | Membership | ArrayCompr | ObjectCompr | SetCompr)
180 | (ArrayCompr <<= Expr * Query)
181 | (SetCompr <<= Expr * Query)
182 | (ObjectCompr <<= Expr * Expr * Query)
183 | (InfixOperator <<= AssignOperator | BoolOperator | ArithOperator | BinOperator)
184 | (BoolOperator <<= Equals | NotEquals | LessThan | GreaterThan | LessThanOrEquals | GreaterThanOrEquals)
185 | (ArithOperator <<= Add | Subtract | Multiply | Divide | Modulo)
186 | (BinOperator <<= And | Or)
187 | (AssignOperator <<= Assign | Unify)
188 | (Ref <<= RefHead * RefArgSeq)
189 | (RefHead <<= Var | Array | Object | Set | ArrayCompr | ObjectCompr | SetCompr | ExprCall)
190 | (RefArgSeq <<= (RefArgDot | RefArgBrack)++)
191 | (RefArgBrack <<= Expr | Placeholder)
192 | (RefArgDot <<= Var)
193 | (Scalar <<= String | Int | Float | True | False | Null)
194 | (String <<= JSONString | RawString)
195 | (Array <<= Expr++)
196 | (Object <<= ObjectItem++)
197 | (ObjectItem <<= (Key >>= Expr) * (Val >>= Expr))
198 | (Set <<= Expr++)
199 ;
200 // clang-format on
201
202 // clang-format off
203 inline const auto wf_result =
204 (Top <<= Results | Undefined)
205 | (Results <<= Result++[1])
206 | (Result <<= Terms * Bindings)
207 | (Terms <<= Term++)
208 | (Bindings <<= Binding++)
209 | (Binding <<= (Key >>= Var) * (Val >>= Term))[Key]
210 | (Term <<= Scalar | Array | Object | Set)
211 | (Array <<= Term++)
212 | (Set <<= Term++)
213 | (Object <<= ObjectItem++)
214 | (ObjectItem <<= (Key >>= Term) * (Val >>= Term))
215 | (Scalar <<= JSONString | Int | Float | True | False | Null)
216 | (Error <<= ErrorMsg * ErrorAst * ErrorCode)
217 ;
218 // clang-format on
219
221
222 struct BuiltInDef;
223
225 using BuiltIn = std::shared_ptr<BuiltInDef>;
226
228 using BuiltInBehavior = std::function<Node(const Nodes&)>;
229
232 // This is a basic, non-optimized implementation of a big integer
239 class BigInt
240 {
241 public:
247 BigInt(const Location& value);
250 BigInt(std::int64_t value);
253 BigInt(std::size_t value);
254
257 const Location& loc() const;
261 std::optional<std::int64_t> to_int() const;
265 std::optional<std::size_t> to_size() const;
266
269 bool is_negative() const;
270
273 bool is_zero() const;
274
283 BigInt abs() const;
286 BigInt negate() const;
287
292 static bool is_int(const Location& loc);
293
298 friend BigInt operator+(const BigInt& lhs, const BigInt& rhs);
299
304 friend BigInt operator-(const BigInt& lhs, const BigInt& rhs);
305
310 friend BigInt operator*(const BigInt& lhs, const BigInt& rhs);
311
316 friend BigInt operator/(const BigInt& lhs, const BigInt& rhs);
317
322 friend BigInt operator%(const BigInt& lhs, const BigInt& rhs);
323
328 friend bool operator>(const BigInt& lhs, const BigInt& rhs);
329
334 friend bool operator<(const BigInt& lhs, const BigInt& rhs);
335
340 friend bool operator<=(const BigInt& lhs, const BigInt& rhs);
341
346 friend bool operator>=(const BigInt& lhs, const BigInt& rhs);
347
352 friend bool operator==(const BigInt& lhs, const BigInt& rhs);
353
358 friend bool operator!=(const BigInt& lhs, const BigInt& rhs);
359
364 friend std::ostream& operator<<(std::ostream& os, const BigInt& value);
365
366 private:
367 struct DivideResult
368 {
369 std::string quotient;
370 std::string remainder;
371 };
372
373 static bool less_than(
374 const std::string_view& lhs, const std::string_view& rhs);
375 static bool greater_than(
376 const std::string_view& lhs, const std::string_view& rhs);
377 static bool equal(const std::string_view& lhs, const std::string_view& rhs);
378 static std::string add(
379 const std::string_view& lhs, const std::string_view& rhs, bool negative);
380 static std::string subtract(
381 const std::string_view& lhs, const std::string_view& rhs, bool negative);
382 static DivideResult divide(
383 const std::string_view& lhs, const std::string_view& rhs);
384 static std::string multiply(
385 const std::string_view& lhs, const std::string_view& rhs);
386 std::string_view digits() const;
387 Location m_loc;
388 static Location Zero;
389 static Location One;
390 };
391
394 {
396 Node node;
397
400 };
401
419 {
420 public:
424 UnwrapOpt(std::size_t index);
425
428 bool exclude_got() const;
429
435
438 bool specify_number() const;
439
446
449 const std::string& code() const;
450
454 UnwrapOpt& code(const std::string& value);
455
459 const std::string& pre() const;
460
464 UnwrapOpt& pre(const std::string& value);
465
469 const std::string& message() const;
470
476 UnwrapOpt& message(const std::string& value);
477
481 const std::string& func() const;
482
486 UnwrapOpt& func(const std::string& value);
487
492 const std::vector<Token>& types() const;
493
499 UnwrapOpt& types(const std::vector<Token>& value);
500
503 const Token& type() const;
504
509 UnwrapOpt& type(const Token& value);
510
514 Node unwrap(const Nodes& args) const;
515
516 private:
517 bool m_exclude_got;
518 bool m_specify_number;
519 std::string m_code;
520 std::string m_prefix;
521 std::string m_message;
522 std::string m_func;
523 std::vector<Token> m_types;
524 Token m_type;
525 std::size_t m_index;
526 };
527
532 Node unwrap_arg(const Nodes& args, const UnwrapOpt& options);
533
538 UnwrapResult unwrap(const Node& term, const Token& type);
539
544 UnwrapResult unwrap(const Node& term, const std::set<Token>& types);
545
549 BigInt get_int(const Node& node);
550
554 double get_double(const Node& node);
555
561 std::optional<BigInt> try_get_int(const Node& node);
562
567 std::string get_string(const Node& node);
568
572 bool get_bool(const Node& node);
573
578 std::optional<Node> try_get_item(
579 const Node& node, const std::string_view& key);
580
584 Node scalar(BigInt value);
585
589 Node scalar(double value);
590
594 Node scalar(bool value);
595
599 Node scalar(const char* value);
600
604 Node scalar(const std::string& value);
605
608 Node scalar();
609
614 Node object_item(const Node& key_term, const Node& val_term);
615
619 Node object(const std::initializer_list<Node>& object_items);
620
624 Node array(const std::initializer_list<Node>& array_members);
625
629 Node set(const std::initializer_list<Node>& set_members);
630
631 namespace builtins
632 {
634 const std::size_t AnyArity = std::numeric_limits<std::size_t>::max();
635
636 inline const auto Decl = TokenDef("rego-builtin-decl");
637 inline const auto Arg = TokenDef("rego-builtin-arg");
638 inline const auto Args = TokenDef("rego-builtin-args");
639 inline const auto VarArgs = TokenDef("rego-builtin-varargs");
640 inline const auto Result = TokenDef("rego-builtin-result");
641 inline const auto Void = TokenDef("rego-builtin-void");
642 inline const auto Return = TokenDef("rego-builtins-return");
643 inline const auto Name = TokenDef("rego-builtin-name", flag::print);
644 inline const auto Description =
645 TokenDef("rego-builtin-description", flag::print);
646 inline const auto Type = TokenDef("rego-builtin-type");
647 inline const auto ArgSeq = TokenDef("rego-builtin-argseq");
648 inline const auto MemberType = TokenDef("rego-builtin-membertype");
649 inline const auto TypeSeq = TokenDef("rego-builtin-typeseq");
650 inline const auto DynamicArray = TokenDef("rego-builtin-dynamicarray");
651 inline const auto StaticArray = TokenDef("rego-builtin-staticarray");
652 inline const auto Set = TokenDef("rego-builtin-set");
653 inline const auto DynamicObject = TokenDef("rego-builtin-dynamicobject");
654 inline const auto StaticObject = TokenDef("rego-builtin-staticobject");
655 inline const auto HybridObject = TokenDef("rego-builtin-hybridobject");
656 inline const auto ObjectItem = TokenDef("rego-builtin-objectitem");
657 inline const auto Any = TokenDef("rego-builtin-any");
658 inline const auto String = TokenDef("rego-builtin-string");
659 inline const auto Number = TokenDef("rego-builtin-number");
660 inline const auto Boolean = TokenDef("rego-builtin-boolean");
661 inline const auto Null = TokenDef("rego-builtin-null");
662
663 // clang-format off
664 inline const auto wf_decl =
665 (Decl <<= (Args >>= ArgSeq | VarArgs) * (Return >>= Result | Void))
666 | (ArgSeq <<= Arg++)
667 | (Arg <<= Name * Description * Type)
668 | (Type <<= Any | String | Number | Boolean | Null | DynamicArray | StaticArray | DynamicObject | StaticObject | HybridObject | Set | TypeSeq)
669 | (TypeSeq <<= Type++)
670 | (DynamicArray <<= Type)
671 | (StaticArray <<= Type++)
672 | (Set <<= Type)
673 | (DynamicObject <<= (Key >>= Type) * (Val >>= Type))
674 | (StaticObject <<= ObjectItem++)
675 | (HybridObject <<= DynamicObject * StaticObject)
676 | (ObjectItem <<= Name * Type)
677 | (Result <<= Name * Description * Type)
678 ;
679 // clang-format on
681 }
682
738 {
741 Location name;
742
745 Node decl;
746
750 std::size_t arity;
751
754
757
760 Location name_, Node decl_, BuiltInBehavior behavior_, bool available_);
761
762 virtual ~BuiltInDef() = default;
763
765 virtual void clear();
766
777 const Location& name, Node decl, BuiltInBehavior behavior);
778
790 const Location& name, size_t arity, BuiltInBehavior behavior);
791
804 const Location& name, Node decl, const std::string& message);
805 };
806
810 {
811 public:
813 BuiltInsDef() noexcept;
814
818 bool is_builtin(const Location& name) const;
819
824 Node decl(const Location& name) const;
825
832 bool is_deprecated(const Location& version, const Location& name) const;
833
839 Node call(const Location& name, const Location& version, const Nodes& args);
840
842 void clear();
843
848
852 const BuiltIn& at(const Location& name) const;
853
858 bool strict_errors() const;
859
865
869 template <typename T>
870 BuiltInsDef& register_builtins(const T& built_ins)
871 {
872 for (auto& built_in : built_ins)
873 {
874 register_builtin(built_in);
875 }
876
877 return *this;
878 }
879
887
890 static std::shared_ptr<BuiltInsDef> create();
891
894 std::map<Location, BuiltIn>::const_iterator begin() const;
895
898 std::map<Location, BuiltIn>::const_iterator end() const;
899
900 private:
901 std::map<Location, BuiltIn> m_builtins;
902 bool m_strict_errors;
903 };
904
906 using BuiltIns = std::shared_ptr<BuiltInsDef>;
907
908 const std::string UnknownError = "unknown_error";
909 const std::string EvalTypeError = "eval_type_error";
910 const std::string EvalBuiltInError = "eval_builtin_error";
911 const std::string RegoTypeError = "rego_type_error";
912 const std::string RegoParseError = "rego_parse_error";
913 const std::string RegoCompileError = "rego_compile_error";
914 const std::string EvalConflictError = "eval_conflict_error";
915 const std::string WellFormedError = "wellformed_error";
916 const std::string RuntimeError = "runtime_error";
917 const std::string RecursionError = "rego_recursion_error";
918 const std::string DefaultVersion = "v1";
920
926 Node err(
927 NodeRange& r,
928 const std::string& msg,
929 const std::string& code = UnknownError);
930
936 Node err(
937 Node node, const std::string& msg, const std::string& code = UnknownError);
938
947 Node version();
948
956 std::string to_key(
957 const trieste::Node& node,
958 bool set_as_array = false,
959 bool sort_arrays = false,
960 const char* list_delim = ",");
961
963 enum class LogLevel : regoEnum
964 {
965 None = REGO_LOG_LEVEL_NONE,
966 Error = REGO_LOG_LEVEL_ERROR,
967 Output = REGO_LOG_LEVEL_OUTPUT,
968 Warn = REGO_LOG_LEVEL_WARN,
969 Info = REGO_LOG_LEVEL_INFO,
970 Debug = REGO_LOG_LEVEL_DEBUG,
971 Trace = REGO_LOG_LEVEL_TRACE
972 };
973
976 namespace bundle
977 {
979 enum class OperandType
980 {
981 None,
982 Local = 1,
983 String = 2,
984 True = 3,
985 False = 4,
986 Index,
987 Value
988 };
989
999 struct Operand
1000 {
1003 union
1004 {
1006 std::int64_t value;
1008 size_t index;
1009 };
1010
1013
1018 static Operand from_op(const Node& n);
1019
1025 static Operand from_index(const Node& n);
1026
1032 static Operand from_value(const Node& n);
1033
1038 friend std::ostream& operator<<(std::ostream& stream, const Operand& op);
1039 };
1040
1045 enum class StatementType
1046 {
1047 Nop = 0,
1048 ArrayAppend = 1,
1049 AssignInt = 2,
1050 AssignVarOnce = 3,
1051 AssignVar = 4,
1052 Block = 5,
1053 Break = 6,
1054 CallDynamic = 7,
1055 Call = 8,
1056 Dot = 9,
1057 Equal = 10,
1058 IsArray = 11,
1059 IsDefined = 12,
1060 IsObject = 13,
1061 IsSet = 14,
1062 IsUndefined = 15,
1063 Len = 16,
1064 MakeArray = 17,
1065 MakeNull = 18,
1066 MakeNumberInt = 19,
1067 MakeNumberRef = 20,
1068 MakeObject = 21,
1069 MakeSet = 22,
1070 NotEqual = 23,
1071 Not = 24,
1072 ObjectInsert = 25,
1073 ObjectInsertOnce = 26,
1074 ObjectMerge = 27,
1075 ResetLocal = 28,
1076 ResultSetAdd = 29,
1077 ReturnLocal = 30,
1078 Scan = 31,
1079 SetAdd = 32,
1080 With = 33
1081 };
1082
1083 struct Statement;
1084
1086 typedef std::vector<Statement> Block;
1087
1089 struct CallExt
1090 {
1092 Location func;
1094 std::vector<Operand> ops;
1095 };
1096
1099 {
1101 std::vector<Operand> path;
1103 std::vector<Operand> ops;
1104 };
1105
1107 struct WithExt
1108 {
1110 std::vector<size_t> path;
1113 };
1114
1118 {
1120 std::variant<CallExt, CallDynamicExt, WithExt, std::vector<Block>, Block>
1122
1125 const CallExt& call() const;
1131 const WithExt& with() const;
1134 const std::vector<Block>& blocks() const;
1137 const Block& block() const;
1138
1146 StatementExt(std::vector<Block>&& blocks);
1149 };
1150
1160 {
1164 Location location;
1165
1168
1171
1173 std::int32_t target;
1174
1176 std::shared_ptr<const StatementExt> ext;
1177
1180
1185 friend std::ostream& operator<<(
1186 std::ostream& stream, const Statement& stmt);
1187 };
1188
1190 struct Plan
1191 {
1193 Location name;
1195 std::vector<Block> blocks;
1196 };
1197
1200 {
1202 Location name;
1204 size_t arity;
1206 std::vector<Location> path;
1208 std::vector<size_t> parameters;
1210 size_t result;
1212 std::vector<Block> blocks;
1215 };
1216 }
1217
1218 struct BundleDef;
1219
1221 typedef std::shared_ptr<BundleDef> Bundle;
1222
1225 {
1227 Node data;
1229 std::map<Location, Node> builtin_functions;
1231 std::map<Location, size_t> name_to_func;
1233 std::map<Location, size_t> name_to_plan;
1235 std::vector<bundle::Plan> plans;
1237 std::vector<bundle::Function> functions;
1239 std::vector<Location> strings;
1241 std::vector<Source> files;
1245 std::optional<size_t> query_plan;
1246
1248 Source query;
1249
1253 std::optional<size_t> find_plan(const Location& name) const;
1254
1258 std::optional<size_t> find_function(const Location& name) const;
1259
1263 bool is_function(const Location& name) const;
1264
1270 void save(std::ostream& stream) const;
1271
1277 void save(const std::filesystem::path& path) const;
1278
1286 static Bundle from_node(Node bundle);
1287
1294 static Bundle load(std::istream& stream);
1295
1302 static Bundle load(const std::filesystem::path& path);
1303 };
1304
1311 {
1312 public:
1314
1323 Node run_entrypoint(const Location& entrypoint, Node input) const;
1324
1331 Node run_query(Node input) const;
1332
1337
1340 BuiltIns builtins() const;
1341
1346
1349
1350 private:
1351 typedef std::vector<Node> Frame;
1352
1353 enum class Code
1354 {
1355 Break,
1356 Continue,
1357 Undefined,
1358 MultipleOutputs,
1359 Return,
1360 Error
1361 };
1362
1363 class State
1364 {
1365 public:
1366 State(Node input, Node data, size_t num_locals);
1367 Node read_local(size_t index) const;
1368 void write_local(size_t index, Node value);
1369 bool is_defined(size_t key) const;
1370 void reset_local(size_t key);
1371 void add_result(Node node);
1372 const Nodes& result_set() const;
1373 bool is_in_call_stack(const Location& func_name) const;
1374 std::string_view root_function_name() const;
1375 void push_function(const Location& func_name, size_t num_args);
1376 void pop_function(const Location& func_name);
1377 const Nodes& errors() const;
1378 void add_error(Node error);
1379 void add_error_multiple_output(Node inst);
1380 void add_error_object_insert(Node inst);
1381 void put_function_result(const Location& func_name, Node result);
1382 Node get_function_result(const Location& func_name) const;
1383 bool in_with() const;
1384 void push_with();
1385 void pop_with();
1386 bool in_break() const;
1387 void push_break(size_t levels);
1388 void pop_break();
1389
1390 private:
1391 Frame m_frame;
1392 Nodes m_errors;
1393 BuiltIns m_builtins;
1394 std::vector<Location> m_call_stack;
1395 std::vector<size_t> m_num_args;
1396 std::map<Location, Node> m_function_cache;
1397 Nodes m_result_set;
1398 size_t m_with_count;
1399 size_t m_break_count;
1400 };
1401
1402 void run_plan(const bundle::Plan& plan, State& state) const;
1403 Code run_block(State& state, const bundle::Block& block) const;
1404 Code run_stmt(
1405 State& state, size_t index, const bundle::Statement& stmt) const;
1406 Code run_scan(State& state, const bundle::Statement& stmt) const;
1407 Code run_with(State& state, const bundle::Statement& stmt) const;
1408 Code run_call(
1409 State& state,
1410 const Location& func,
1411 const std::vector<bundle::Operand>& args,
1412 size_t target) const;
1413 Node dot(const Node& source, const Node& key) const;
1414 Node merge_objects(const Node& a, const Node& b) const;
1415 Node merge_sets(const Node& a, const Node& b) const;
1416 bool insert_into_object(
1417 const Node& a, const Node& key, const Node& value, bool once) const;
1418 Node to_term(const Node& value) const;
1419 Node unpack_operand(
1420 const State& state, const bundle::Operand& operand) const;
1421 Node write_and_swap(
1422 State& state,
1423 size_t key,
1424 const std::vector<size_t>& path,
1425 Node value) const;
1426
1427 Bundle m_bundle;
1428 BuiltIns m_builtins;
1429 RE2 m_int_regex;
1430 };
1431
1445 {
1446 public:
1449
1456 Node add_module_file(const std::filesystem::path& path);
1457
1465 Node add_module(const std::string& name, const std::string& contents);
1466
1473 Node add_data_json_file(const std::filesystem::path& path);
1474
1481 Node add_data_json(const std::string& json);
1482
1488 Node add_data(const Node& node);
1489
1497 Node set_input_json_file(const std::filesystem::path& path);
1498
1506 Node set_input_json(const std::string& json);
1507
1513 Node set_input_term(const std::string& term);
1514
1521 Node set_input(const Node& node);
1522
1529 Node set_query(const std::string& query);
1530
1535 const std::initializer_list<std::string>& entrypoints);
1536
1540 Interpreter& entrypoints(const std::vector<std::string>& entrypoints);
1541
1544 const std::vector<std::string>& entrypoints() const;
1545
1548 std::vector<std::string>& entrypoints();
1549
1555 std::string query();
1556
1563 std::string query(const std::string& query_expr);
1564
1572 Node query_node(const std::string& query_expr);
1573
1581
1582 // clang-format off
1583
1610 Node build();
1611
1612 // clang-format on
1613
1625 Node save_bundle(const std::filesystem::path& dir, const Node& bundle);
1626
1635 Node load_bundle(const std::filesystem::path& dir);
1636
1646 Node query_bundle(const Bundle& bundle);
1647
1658 Node query_bundle(const Bundle& bundle, const std::string& endpoint);
1659
1665 Interpreter& debug_path(const std::filesystem::path& prefix);
1666
1669 const std::filesystem::path& debug_path() const;
1670
1678
1681 bool debug_enabled() const;
1682
1690
1693 bool wf_check_enabled() const;
1694
1700 BuiltIns builtins() const;
1701
1706 std::string output_to_string(const Node& output) const;
1707
1711
1716
1722 Interpreter& log_level(const std::string& level);
1723
1727 const std::string& c_error() const;
1728
1733 Interpreter& c_error(const std::string& error);
1734
1735 private:
1736 Reader& reader();
1737 Reader& json();
1738 Rewriter& data_from_json();
1739 Rewriter& input_from_json();
1740 Rewriter& to_input();
1741 Rewriter& bundle();
1742 Rewriter& write_bundle();
1743 Rewriter& read_bundle();
1744
1745 void merge(const Node& ast);
1746
1747 Node m_dataseq;
1748 Node m_moduleseq;
1749 Node m_input;
1750 Node m_query;
1751 std::vector<std::string> m_entrypoints;
1752 std::filesystem::path m_debug_path;
1753 bool m_debug_enabled;
1754 bool m_wf_check_enabled;
1755 LogLevel m_log_level;
1756
1757 BuiltIns m_builtins;
1758 std::unique_ptr<Reader> m_reader;
1759 std::unique_ptr<Reader> m_json;
1760 std::unique_ptr<Rewriter> m_data_from_json;
1761 std::unique_ptr<Rewriter> m_input_from_json;
1762 std::unique_ptr<Rewriter> m_to_input;
1763 std::unique_ptr<Rewriter> m_bundle;
1764 std::unique_ptr<Rewriter> m_write_bundle;
1765 std::unique_ptr<Rewriter> m_read_bundle;
1766 VirtualMachine m_vm;
1767 std::size_t m_data_count;
1768 std::map<std::string, Node> m_cache;
1769
1770 std::string m_c_error;
1771 };
1772
1776 LogLevel log_level_from_string(const std::string& value);
1777
1780 inline const auto RegoBundle = TokenDef("rego-bundle", flag::symtab);
1781 inline const auto Data = TokenDef("rego-data");
1782 inline const auto ModuleFile = TokenDef("rego-modulefile");
1783 inline const auto Static = TokenDef("rego-static");
1784 inline const auto BuiltInFunction = TokenDef("rego-builtinfunction");
1785 inline const auto Plan = TokenDef("rego-plan", flag::lookup | flag::symtab);
1786 inline const auto Block = TokenDef("rego-block");
1787 inline const auto Function =
1788 TokenDef("rego-function", flag::lookup | flag::symtab);
1789 inline const auto LocalIndex = TokenDef("rego-localindex", flag::print);
1790 inline const auto Operand = TokenDef("rego-operand");
1791 inline const auto Int32 = TokenDef("rego-int32", flag::print);
1792 inline const auto Int64 = TokenDef("rego-int64", flag::print);
1793 inline const auto UInt32 = TokenDef("rego-uint32", flag::print);
1794 inline const auto StringIndex = TokenDef("rego-stringindex", flag::print);
1795 inline const auto Boolean = TokenDef("rego-boolean", flag::print);
1796 inline const auto IRString = TokenDef("rego-irstring", flag::print);
1797 inline const auto IRQuery = TokenDef("rego-irquery");
1798 inline const auto IRPath = TokenDef("rego-irpath");
1799
1800 // sequences
1801 inline const auto BlockSeq = TokenDef("rego-blockseq");
1802 inline const auto ParameterSeq = TokenDef("rego-parameterseq");
1803 inline const auto PlanSeq = TokenDef("rego-planseq");
1804 inline const auto FunctionSeq = TokenDef("rego-functionseq");
1805 inline const auto BuiltInFunctionSeq = TokenDef("rego-builtinfunctionseq");
1806 inline const auto StringSeq = TokenDef("rego-stringseq");
1807 inline const auto PathSeq = TokenDef("rego-pathseq");
1808 inline const auto OperandSeq = TokenDef("rego-operandseq");
1809 inline const auto Int32Seq = TokenDef("rego-int32seq");
1810 inline const auto EntryPointSeq = TokenDef("rego-entrypointseq");
1811 inline const auto ModuleFileSeq = TokenDef("rego-modulefileseq");
1812
1813 // Statements
1814 inline const auto ArrayAppendStmt = TokenDef("rego-arrayappendstmt");
1815 inline const auto AssignIntStmt = TokenDef("rego-assignintstmt");
1816 inline const auto AssignVarOnceStmt = TokenDef("rego-assignvaroncestmt");
1817 inline const auto AssignVarStmt = TokenDef("rego-assignvarstmt");
1818 inline const auto BlockStmt = TokenDef("rego-blockstmt");
1819 inline const auto BreakStmt = TokenDef("rego-breakstmt");
1820 inline const auto CallDynamicStmt = TokenDef("rego-calldynamicstmt");
1821 inline const auto CallStmt = TokenDef("rego-callstmt");
1822 inline const auto DotStmt = TokenDef("rego-dotstmt");
1823 inline const auto EqualStmt = TokenDef("rego-equalstmt");
1824 inline const auto IsArrayStmt = TokenDef("rego-isarraystmt");
1825 inline const auto IsDefinedStmt = TokenDef("rego-isdefinedstmt");
1826 inline const auto IsObjectStmt = TokenDef("rego-isobjectstmt");
1827 inline const auto IsSetStmt = TokenDef("rego-issetstmt");
1828 inline const auto IsUndefinedStmt = TokenDef("rego-isundefinedstmt");
1829 inline const auto LenStmt = TokenDef("rego-lenstmt");
1830 inline const auto MakeArrayStmt = TokenDef("rego-makearraystmt");
1831 inline const auto MakeNullStmt = TokenDef("rego-makenullstmt");
1832 inline const auto MakeNumberIntStmt = TokenDef("rego-makenumberintstmt");
1833 inline const auto MakeNumberRefStmt = TokenDef("rego-makenumberrefstmt");
1834 inline const auto MakeObjectStmt = TokenDef("rego-makeobjectstmt");
1835 inline const auto MakeSetStmt = TokenDef("rego-makesetstmt");
1836 inline const auto NotEqualStmt = TokenDef("rego-notequalstmt");
1837 inline const auto NotStmt = TokenDef("rego-notstmt");
1838 inline const auto ObjectInsertOnceStmt =
1839 TokenDef("rego-objectinsertoncestmt");
1840 inline const auto ObjectInsertStmt = TokenDef("rego-objectinsertstmt");
1841 inline const auto ObjectMergeStmt = TokenDef("rego-objectmergestmt");
1842 inline const auto ResetLocalStmt = TokenDef("rego-resetlocalstmt");
1843 inline const auto ResultSetAddStmt = TokenDef("rego-resultsetaddstmt");
1844 inline const auto ReturnLocalStmt = TokenDef("rego-returnlocalstmt");
1845 inline const auto ScanStmt = TokenDef("rego-scanstmt");
1846 inline const auto SetAddStmt = TokenDef("rego-setaddstmt");
1847 inline const auto WithStmt = TokenDef("rego-withstmt");
1848
1849 // other tokens
1850 inline const auto Blocks = TokenDef("rego-blocks");
1851 inline const auto Func = TokenDef("rego-func");
1852 inline const auto Capacity = TokenDef("rego-capacity");
1853 inline const auto Stmt = TokenDef("rego-stmt");
1854
1855 inline const auto wf_ir_statements = ArrayAppendStmt | AssignIntStmt |
1856 AssignVarOnceStmt | AssignVarStmt | BlockStmt | BreakStmt |
1857 CallDynamicStmt | CallStmt | DotStmt | EqualStmt | IsArrayStmt |
1858 IsDefinedStmt | IsObjectStmt | IsSetStmt | IsUndefinedStmt | LenStmt |
1859 MakeArrayStmt | MakeNullStmt | MakeNumberIntStmt | MakeNumberRefStmt |
1860 MakeObjectStmt | MakeSetStmt | NotEqualStmt | NotStmt |
1861 ObjectInsertOnceStmt | ObjectInsertStmt | ObjectMergeStmt | ResetLocalStmt |
1862 ResultSetAddStmt | ReturnLocalStmt | ScanStmt | SetAddStmt | WithStmt;
1863
1864 // clang-format off
1865 inline const auto wf_bundle =
1866 builtins::wf_decl
1867 | wf_result
1868 | (Top <<= RegoBundle)
1869 | (RegoBundle <<= Data * Policy * ModuleFileSeq)
1870 | (ModuleFileSeq <<= ModuleFile++)
1871 | (ModuleFile <<= (Name >>= IRString) * (Contents >>= IRString))
1872 | (Data <<= rego::Object)
1873 | (Policy <<= Static * PlanSeq * IRQuery * FunctionSeq)
1874 | (IRQuery <<= (IRString|Undefined))
1875 | (Static <<= StringSeq * PathSeq * BuiltInFunctionSeq)
1876 | (StringSeq <<= IRString++)
1877 | (BuiltInFunctionSeq <<= BuiltInFunction++)
1878 | (BuiltInFunction <<= (Name >>= IRString) * builtins::Decl)
1879 | (PathSeq <<= IRString++)
1880 | (PlanSeq <<= Plan++[1])
1881 | (Plan <<= (Name >>= IRString) * BlockSeq)
1882 | (BlockSeq <<= Block++)
1883 | (Block <<= wf_ir_statements++)
1884 | (FunctionSeq <<= Function++)
1885 | (Function <<= (Name >>= IRString) * IRPath * ParameterSeq * (Return >>= LocalIndex) * BlockSeq)[Name]
1886 | (IRPath <<= IRString++[1])
1887 | (ParameterSeq <<= LocalIndex++)
1888 | (ArrayAppendStmt <<= (Array >>= LocalIndex) * (Val >>= Operand))
1889 | (AssignIntStmt <<= (Val >>= Int64) * (Target >>= LocalIndex))
1890 | (AssignVarOnceStmt <<= (Src >>= Operand) * (Target >>= LocalIndex))
1891 | (AssignVarStmt <<= (Src >>= Operand) * (Target >>= LocalIndex))
1892 | (BlockStmt <<= (Blocks >>= BlockSeq))
1893 | (BreakStmt <<= (Idx >>= UInt32))
1894 | (CallDynamicStmt <<= (Func >>= OperandSeq) * (Args >>= OperandSeq) * (Result >>= LocalIndex))
1895 | (CallStmt <<= (Func >>= IRString) * (Args >>= OperandSeq) * (Result >>= LocalIndex))
1896 | (DotStmt <<= (Src >>= Operand) * (Key >>= Operand) * (Target >>= LocalIndex))
1897 | (EqualStmt <<= (Lhs >>= Operand) * (Rhs >>= Operand))
1898 | (IsArrayStmt <<= (Src >>= Operand))
1899 | (IsDefinedStmt <<= (Src >>= LocalIndex))
1900 | (IsObjectStmt <<= (Src >>= Operand))
1901 | (IsSetStmt <<= (Src >>= Operand))
1902 | (IsUndefinedStmt <<= (Src >>= LocalIndex))
1903 | (LenStmt <<= (Src >>= Operand) * (Target >>= LocalIndex))
1904 | (MakeArrayStmt <<= (Capacity >>= Int32) * (Target >>= LocalIndex))
1905 | (MakeNullStmt <<= (Target >>= LocalIndex))
1906 | (MakeNumberIntStmt <<= (Val >>= Int64) * (Target >>= LocalIndex))
1907 | (MakeNumberRefStmt <<= (Idx >>= Int32) * (Target >>= LocalIndex))
1908 | (MakeObjectStmt <<= (Target >>= LocalIndex))
1909 | (MakeSetStmt <<= (Target >>= LocalIndex))
1910 | (NotEqualStmt <<= (Lhs >>= Operand) * (Rhs >>= Operand))
1911 | (NotStmt <<= Block)
1912 | (ObjectInsertOnceStmt <<= (Key >>= Operand) * (Val >>= Operand) * (Object >>= LocalIndex))
1913 | (ObjectInsertStmt <<= (Key >>= Operand) * (Val >>= Operand) * (Object >>= LocalIndex))
1914 | (ObjectMergeStmt <<= (Lhs >>= LocalIndex) * (Rhs >>= LocalIndex) * (Target >>= LocalIndex))
1915 | (ResetLocalStmt <<= (Target >>= LocalIndex))
1916 | (ResultSetAddStmt <<= (Val >>= LocalIndex))
1917 | (ReturnLocalStmt <<= (Src >>= LocalIndex))
1918 | (ScanStmt <<= (Src >>= LocalIndex) * (Key >>= LocalIndex) * (Val >>= LocalIndex) * Block)
1919 | (SetAddStmt <<= (Val >>= Operand) * (Set >>= LocalIndex))
1920 | (WithStmt <<= LocalIndex * (Path >>= Int32Seq) * (Val >>= Operand) * Block)
1921 | (Operand <<= LocalIndex | Boolean | StringIndex)
1922 | (OperandSeq <<= Operand++)
1923 | (Int32Seq <<= Int32++)
1924 ;
1925 // clang-format on
1927
1930
1932 Rewriter rego_to_input();
1933
1935 Rewriter json_to_rego(bool as_term = false);
1936
1938 Rewriter rego_to_json();
1939
1941 Rewriter rego_to_yaml();
1942
1944 Rewriter json_to_bundle();
1945
1947 Rewriter bundle_to_json();
1948
1950 Rewriter rego_to_bundle(BuiltIns builtins = BuiltInsDef::create());
1951}
Big Integer implemention based on strings.
Definition rego.hh:240
friend BigInt operator+(const BigInt &lhs, const BigInt &rhs)
Adds two BigInts.
BigInt(std::size_t value)
Constructs a BigInt from a size_t integer.
std::optional< std::size_t > to_size() const
Attempts to convert the BigInt to a size_t integer.
friend BigInt operator*(const BigInt &lhs, const BigInt &rhs)
Multiplies two BigInts.
friend bool operator<(const BigInt &lhs, const BigInt &rhs)
Compares two BigInts for less-than.
friend bool operator>(const BigInt &lhs, const BigInt &rhs)
Compares two BigInts for greater-than.
std::optional< std::int64_t > to_int() const
Attempts to convert the BigInt to a 64-bit integer.
friend BigInt operator-(const BigInt &lhs, const BigInt &rhs)
Subtracts two BigInts.
BigInt negate() const
Negates the BigInt.
friend bool operator!=(const BigInt &lhs, const BigInt &rhs)
Compares two BigInts for inequality.
bool is_negative() const
Checks if the BigInt is negative.
friend bool operator<=(const BigInt &lhs, const BigInt &rhs)
Compares two BigInts for less-than-or-equal.
static bool is_int(const Location &loc)
Checks if a Location represents a valid integer string.
friend BigInt operator%(const BigInt &lhs, const BigInt &rhs)
Computes the remainder of dividing two BigInts.
bool is_zero() const
Checks if the BigInt is zero.
friend bool operator==(const BigInt &lhs, const BigInt &rhs)
Compares two BigInts for equality.
BigInt increment() const
Increments the BigInt by one.
BigInt(std::int64_t value)
Constructs a BigInt from a 64-bit integer.
BigInt()
Default constructor, initializes to zero.
BigInt(const Location &value)
Constructs a BigInt from a Location representing a arbitrary precision integer string.
const Location & loc() const
Gets the Location representing the integer string.
friend BigInt operator/(const BigInt &lhs, const BigInt &rhs)
Divides two BigInts.
BigInt decrement() const
Decrements the BigInt by one.
friend std::ostream & operator<<(std::ostream &os, const BigInt &value)
Outputs a BigInt to a stream.
BigInt abs() const
Gets the absolute value of the BigInt.
friend bool operator>=(const BigInt &lhs, const BigInt &rhs)
Compares two BigInts for greater-than-or-equal.
Manages the set of builtins used by an interpreter to resolve built-in calls.
Definition rego.hh:810
static std::shared_ptr< BuiltInsDef > create()
Creates the standard builtin set.
bool is_deprecated(const Location &version, const Location &name) const
Determines whether the provided builtin name is deprecated in the provided version.
bool strict_errors() const
Whether to throw built-in errors.
Node call(const Location &name, const Location &version, const Nodes &args)
Calls the built-in with the provided name and arguments.
void clear()
Called to clear any persistent state or caching.
BuiltInsDef & register_builtins(const T &built_ins)
Registers a set of built-ins.
Definition rego.hh:870
BuiltInsDef & register_standard_builtins()
This registers the "standard library" of built-ins.
std::map< Location, BuiltIn >::const_iterator end() const
Gets the ending iterator for the built-ins map.
BuiltInsDef() noexcept
Constructor.
BuiltInsDef & register_builtin(const BuiltIn &built_in)
Registers a built-in.
Node decl(const Location &name) const
Gets the declaration node for the specified built-in.
std::map< Location, BuiltIn >::const_iterator begin() const
Gets the beginning iterator for the built-ins map.
const BuiltIn & at(const Location &name) const
Gets the built-in with the provided name.
bool is_builtin(const Location &name) const
Determines whether the provided name refers to a built-in.
This class forms the main interface to the Rego library.
Definition rego.hh:1445
Node query_bundle(const Bundle &bundle)
Performs a query against a bundle.
Interpreter & debug_path(const std::filesystem::path &prefix)
The path to the debug directory.
std::string query(const std::string &query_expr)
Executes a query against the interpreter.
Node add_module(const std::string &name, const std::string &contents)
Adds a module (i.e. virtual document) to the interpreter.
const std::filesystem::path & debug_path() const
Gets the debug path.
Node set_input_term(const std::string &term)
Sets the input term of the interpreter.
std::string query()
Executes the documents against the interpreter.
Node add_data_json_file(const std::filesystem::path &path)
Adds a base document to the interpreter.
Node set_input_json_file(const std::filesystem::path &path)
Sets the input document to the interpreter.
Interpreter & entrypoints(const std::initializer_list< std::string > &entrypoints)
Sets the entrypoints to include when building a bundle.
Node save_bundle(const std::filesystem::path &dir, const Node &bundle)
Saves a bundle to a directory in JSON format.
Node query_bundle(const Bundle &bundle, const std::string &endpoint)
Performs a query against a bundle.
LogLevel log_level() const
Returns the current log level of this interpreter.
Node set_input_json(const std::string &json)
Sets the input document to the interpreter.
bool wf_check_enabled() const
Checks if well-formedness checks are enabled.
Interpreter & log_level(LogLevel level)
Sets the log level of the interpreter.
Node set_input(const Node &node)
Sets the input document to the interpreter.
BuiltIns builtins() const
The built-ins used by the interpreter.
std::vector< std::string > & entrypoints()
Gets the entrypoints to include when building a bundle.
std::string output_to_string(const Node &output) const
Converts an output node into a human-readable string.
Interpreter & c_error(const std::string &error)
Sets the most recent error message.
Node add_data_json(const std::string &json)
Adds a base document to the interpreter.
Interpreter()
Constructor.
Node query_node()
Executes a query against the interpreter.
Interpreter & log_level(const std::string &level)
Sets the logging level for the interpreter from a string.
const std::vector< std::string > & entrypoints() const
Gets the entrypoints to include when building a bundle.
Node query_node(const std::string &query_expr)
Executes a query against the interpreter.
Interpreter & wf_check_enabled(bool enabled)
Sets whether well-formedness checks are enabled.
Node load_bundle(const std::filesystem::path &dir)
Loads a bundle in JSON format from a direction.
Interpreter & entrypoints(const std::vector< std::string > &entrypoints)
Sets the entrypoints to include when building a bundle.
Node build()
Builds a bundle from the current state of the interpreter.
bool debug_enabled() const
Checks if debug mode is enabled.
Node add_data(const Node &node)
Adds a base document to the interpreter.
Interpreter & debug_enabled(bool enabled)
Sets whether debug mode is enabled.
const std::string & c_error() const
Returns a string representing the most recent error message.
Node add_module_file(const std::filesystem::path &path)
Adds a module (i.e. virtual document) file to the interpreter.
Node set_query(const std::string &query)
Sets the query expression of the interpreter.
Options for unwrapping an argument.
Definition rego.hh:419
bool exclude_got() const
Whether the statement indicating what was received instead of the expected type should be excluded.
const std::string & func() const
The name of the function. If provide, will be a prefix on the message as "<func-name>:".
const Token & type() const
The singular type to match against.
UnwrapOpt & type(const Token &value)
Sets the singular type to match against.
UnwrapOpt & pre(const std::string &value)
Sets the error preamble.
UnwrapOpt & exclude_got(bool exclude_got)
Sets whether to exclude the "got" statement in the error message.
UnwrapOpt & specify_number(bool specify_number)
Sets whether to specify in the error message which kind of number was received.
UnwrapOpt(std::size_t index)
Construct an UnwrapOpt.
bool specify_number() const
Whether to specify in the error message which kind of number was received (i.e. integer or floating p...
UnwrapOpt & code(const std::string &value)
Sets the error code for the error message.
const std::string & pre() const
The error preamble. If omitted, a default preamble will be constructed from the operation metadata in...
const std::string & code() const
The error code for the error message. Default value if omitted is EvalTypeError.
const std::string & message() const
The full error message. If this is set, no message will be generated and instead this will be returne...
Node unwrap(const Nodes &args) const
Unwraps an argument from the provided vector of nodes.
UnwrapOpt & message(const std::string &value)
Sets the full error message. If this is set, no message will be generated and instead this will be re...
UnwrapOpt & func(const std::string &value)
Sets the name of the function.
UnwrapOpt & types(const std::vector< Token > &value)
Sets the types to match against.
const std::vector< Token > & types() const
The types to match against. The operand must be one of the provided types or else an error node will ...
This class implements a virtual machine that can execute compiled Rego bundles.
Definition rego.hh:1311
BuiltIns builtins() const
Gets the built-in functions used during execution.
VirtualMachine & bundle(Bundle bundle)
Sets the bundle to use during execution.
Node run_query(Node input) const
Executes the query plan in the bundle with the provided input.
Bundle bundle() const
Gets the bundle used during execution.
VirtualMachine & builtins(BuiltIns builtins)
Sets the built-in functions to use during execution.
Node run_entrypoint(const Location &entrypoint, Node input) const
Executes the entrypoint plan in the bundle with the provided input.
OperandType
The type of an operand.
Definition rego.hh:980
StatementType
The type of an IR statement.
Definition rego.hh:1046
std::vector< Statement > Block
A block of statements.
Definition rego.hh:1086
Definition rego.hh:18
bool get_bool(const Node &node)
Extracts the value of a node as a boolean.
std::optional< Node > try_get_item(const Node &node, const std::string_view &key)
Tries to get an item within an object using its key.
Node scalar()
Creates a null scalar.
std::string to_key(const trieste::Node &node, bool set_as_array=false, bool sort_arrays=false, const char *list_delim=",")
Converts a node to a unique key representation that can be used for comparison.
Node object_item(const Node &key_term, const Node &val_term)
Converts the key and val terms to an object item.
Node array(const std::initializer_list< Node > &array_members)
Converts the value to an array node.
BigInt get_int(const Node &node)
Extracts the value of a node as an integer.
double get_double(const Node &node)
Extracts the value of a node as an double.
Node unwrap_arg(const Nodes &args, const UnwrapOpt &options)
Unwraps an argument from the provided vector of nodes.
Rewriter json_to_bundle()
Rewrites an OPA bundle JSON to a Bundle AST.
Node err(NodeRange &r, const std::string &msg, const std::string &code=UnknownError)
Generates an error node.
std::optional< BigInt > try_get_int(const Node &node)
Attempts to extract the value of a node as an integer. In the case that the node is a double,...
Reader file_to_rego()
Parses Rego queries and virtual documents.
Rewriter bundle_to_json()
Rewrites a Bundle AST to a JSON AST in OPA bundle JSON format.
Rewriter rego_to_bundle(BuiltIns builtins=BuiltInsDef::create())
Rewrites a Rego AST to a Bundle AST.
std::shared_ptr< BundleDef > Bundle
A pointer to a BundleDef.
Definition rego.hh:1221
std::shared_ptr< BuiltInDef > BuiltIn
A pointer to a BuiltInDef.
Definition rego.hh:225
std::function< Node(const Nodes &)> BuiltInBehavior
The function pointer to the behavior of the built-in.
Definition rego.hh:228
Node version()
Returns a node representing the version of the library.
UnwrapResult unwrap(const Node &term, const Token &type)
Attempts to unwrap a node to a specified type.
LogLevel log_level_from_string(const std::string &value)
Converts a string to a log level (case insensitive).
LogLevel
The logging level.
Definition rego.hh:964
Rewriter rego_to_input()
Rewrites a Query AST to an input term.
Node set(const std::initializer_list< Node > &set_members)
Converts the value to a set node.
Rewriter json_to_rego(bool as_term=false)
Rewrites a JSON AST to a Rego data input AST.
std::string get_string(const Node &node)
Extracts the value of a node as a string. The resulting string will have any enclosing quotes removed...
Rewriter rego_to_yaml()
Rewrites a Rego binding term to a YAML AST.
Rewriter rego_to_json()
Rewrites a Rego binding term to a JSON AST.
Node object(const std::initializer_list< Node > &object_items)
Converts the value to an object node.
uint_least32_t regoEnum
Enum type.
Definition rego_c.h:32
Struct which defines a built-in function.
Definition rego.hh:738
bool available
Whether the builtin is available.
Definition rego.hh:756
Node decl
The declaration node which adheres to the builtins::wf_decl well-formedness definition.
Definition rego.hh:745
static BuiltIn create(const Location &name, size_t arity, BuiltInBehavior behavior)
Creates a new built-in.
virtual void clear()
Called to clear any persistent state or caching.
static BuiltIn placeholder(const Location &name, Node decl, const std::string &message)
Creates a placeholder for a built-in which is not available on this platform.
BuiltInDef(Location name_, Node decl_, BuiltInBehavior behavior_, bool available_)
Constructor.
BuiltInBehavior behavior
The function which will be called when the built-in is evaluated.
Definition rego.hh:753
static BuiltIn create(const Location &name, Node decl, BuiltInBehavior behavior)
Creates a new built-in.
std::size_t arity
The number of expected arguments.
Definition rego.hh:750
Location name
The name used to match against expression calls in the rego program.
Definition rego.hh:741
Represents a compiled Rego bundle.
Definition rego.hh:1225
std::map< Location, size_t > name_to_plan
Map from function names to their indices.
Definition rego.hh:1233
std::vector< bundle::Function > functions
The functions in the bundle.
Definition rego.hh:1237
std::map< Location, size_t > name_to_func
Map from plan names to their indices.
Definition rego.hh:1231
static Bundle load(const std::filesystem::path &path)
Loads a bundle from a file.
std::vector< Location > strings
The string table for the bundle.
Definition rego.hh:1239
std::vector< Source > files
The module source files which were compiled into the bundle.
Definition rego.hh:1241
static Bundle from_node(Node bundle)
Constructs a bundle from an AST node.
std::vector< bundle::Plan > plans
The plans in the bundle.
Definition rego.hh:1235
void save(const std::filesystem::path &path) const
Saves the bundle to a file.
Source query
The query, if one was included.
Definition rego.hh:1248
Node data
The merged base data document.
Definition rego.hh:1227
std::optional< size_t > find_function(const Location &name) const
Finds a function by name.
std::optional< size_t > find_plan(const Location &name) const
Finds a plan by name.
std::map< Location, Node > builtin_functions
The built-in functions required by the bundle.
Definition rego.hh:1229
static Bundle load(std::istream &stream)
Loads a bundle from a stream.
size_t local_count
The number of local variables required by the bundle.
Definition rego.hh:1243
std::optional< size_t > query_plan
The index of the query plan, if one was included.
Definition rego.hh:1245
bool is_function(const Location &name) const
Determines whether the provided name refers to a function.
void save(std::ostream &stream) const
Saves the bundle to a stream.
Result of unwrapping a node.
Definition rego.hh:394
bool success
True if the argument was unwrapped successfully.
Definition rego.hh:399
Node node
The unwrapped argument or nullptr (if unsuccessful).
Definition rego.hh:396
Additional information for CallDynamic statements.
Definition rego.hh:1099
std::vector< Operand > ops
The arguments to the function.
Definition rego.hh:1103
std::vector< Operand > path
The path to the function being called.
Definition rego.hh:1101
Additional information for Call statements.
Definition rego.hh:1090
std::vector< Operand > ops
The arguments to the function.
Definition rego.hh:1094
Location func
The function being called.
Definition rego.hh:1092
Represents a function in the IR.
Definition rego.hh:1200
std::vector< size_t > parameters
The local indices of the function parameters.
Definition rego.hh:1208
std::vector< Block > blocks
The blocks which make up the function.
Definition rego.hh:1212
Location name
The name of the function.
Definition rego.hh:1202
size_t arity
The arity of the function.
Definition rego.hh:1204
size_t result
The index of the result local.
Definition rego.hh:1210
std::vector< Location > path
The path of the function (the name broken into segments)
Definition rego.hh:1206
bool cacheable
Whether the function result can be cached.
Definition rego.hh:1214
Represents an operand in the IR.
Definition rego.hh:1000
size_t index
A local index (if type is Local, String, or Index).
Definition rego.hh:1008
std::int64_t value
An integer value (if type is Value).
Definition rego.hh:1006
OperandType type
The type of the operand.
Definition rego.hh:1002
Operand()
Constructs an Operand with type None.
static Operand from_op(const Node &n)
Constructs an Operand from the specified node.
friend std::ostream & operator<<(std::ostream &stream, const Operand &op)
Writes the operand to a stream (used for debugging purposes).
static Operand from_index(const Node &n)
Constructs an Operand from the specified node. Will have a type of Index.
static Operand from_value(const Node &n)
Constructs an Operand from the specified node. Will have a type of Value.
Represents a plan in the IR.
Definition rego.hh:1191
Location name
The name of the plan.
Definition rego.hh:1193
std::vector< Block > blocks
The blocks which make up the plan.
Definition rego.hh:1195
Additional information for Call, CallDynamic, With, Block, Not, and Scan statements.
Definition rego.hh:1118
const WithExt & with() const
Returns this extension as a WithExt.
const CallDynamicExt & call_dynamic() const
Returns this extension as a CallDynamicExt.
std::variant< CallExt, CallDynamicExt, WithExt, std::vector< Block >, Block > contents
The contents of the extension.
Definition rego.hh:1121
StatementExt(CallExt &&ext)
Constructs a StatementExt from a CallExt.
const std::vector< Block > & blocks() const
Returns this extension as a vector of Blocks.
const Block & block() const
Returns this extension as a Block.
StatementExt(Block &&block)
Constructs a StatementExt from a Block.
const CallExt & call() const
Returns this extension as a CallExt.
StatementExt(WithExt &&ext)
Constructs a StatementExt from a WithExt.
StatementExt(std::vector< Block > &&blocks)
Constructs a StatementExt from a vector of Blocks.
StatementExt(CallDynamicExt &&ext)
Constructs a StatementExt from a CallDynamicExt.
Represents a single IR statement.
Definition rego.hh:1160
std::int32_t target
The target of the statement.
Definition rego.hh:1173
StatementType type
The type of statement.
Definition rego.hh:1162
std::shared_ptr< const StatementExt > ext
The (optional) extended information for the statement.
Definition rego.hh:1176
Location location
The location of the statement in the source document.
Definition rego.hh:1164
friend std::ostream & operator<<(std::ostream &stream, const Statement &stmt)
Writes the statement to a stream (used for debugging purposes)
Operand op1
The second operand of the statement.
Definition rego.hh:1170
Statement()
Default constructor.
Operand op0
The first operand of the statement.
Definition rego.hh:1167
Additional information for With statements.
Definition rego.hh:1108
std::vector< size_t > path
The path to the value being replaced.
Definition rego.hh:1110
Block block
The block to execute with the replacement.
Definition rego.hh:1112