ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
python_consteval.h
Go to the documentation of this file.
1#pragma once
2
3#include <nlohmann/json.hpp>
4#include <optional>
5#include <string>
6#include <unordered_map>
7#include <vector>
8
11{
22
24 bool bool_val = false;
25 long long int_val = 0;
26 double float_val = 0.0;
27 std::string string_val;
28 // Element storage for both TUPLE and LIST values; `kind` disambiguates so
29 // that (1,) and [1] never compare equal (Python semantics).
30 std::vector<PyConstValue> tuple_val;
31
33 {
34 return {NONE, false, 0, 0.0, "", {}};
35 }
36 static PyConstValue make_bool(bool v)
37 {
38 return {BOOL, v, 0, 0.0, "", {}};
39 }
40 static PyConstValue make_int(long long v)
41 {
42 return {INT, false, v, 0.0, "", {}};
43 }
44 static PyConstValue make_float(double v)
45 {
46 return {FLOAT, false, 0, v, "", {}};
47 }
48 static PyConstValue make_string(const std::string &s)
49 {
50 return {STRING, false, 0, 0.0, s, {}};
51 }
52 static PyConstValue make_tuple(const std::vector<PyConstValue> &values)
53 {
54 return {TUPLE, false, 0, 0.0, "", values};
55 }
56 static PyConstValue make_list(const std::vector<PyConstValue> &values)
57 {
58 return {LIST, false, 0, 0.0, "", values};
59 }
60
61 bool is_truthy() const;
62};
63
69{
70public:
71 explicit python_consteval(
72 const nlohmann::json &ast,
73 int max_iterations = 50000);
74
78 std::optional<PyConstValue> try_eval_call(
79 const std::string &func_name,
80 const std::vector<PyConstValue> &args);
81
87 std::optional<PyConstValue> try_eval_global_expr(const nlohmann::json &expr);
88
89private:
90 const nlohmann::json &ast_;
91 int iteration_budget_;
92 int call_depth_ = 0;
93 static constexpr int MAX_CALL_DEPTH = 30;
94
95 // When false (the default, used by the call-site pre-scan in
96 // converter_funcall that folds f(literal) in expression position), functions
97 // containing control flow (If/For/While) are NOT folded, so their branches
98 // stay in the GOTO program for coverage/branch analysis. The whole-assertion
99 // folder (try_eval_global_expr) sets this true: an assert over fully-constant
100 // operands has a deterministic single path, so folding it loses no coverage.
101 bool allow_control_flow_ = false;
102
103 using Env = std::unordered_map<std::string, PyConstValue>;
104
105 struct StmtResult
106 {
107 enum Type
108 {
109 NORMAL,
110 RETURN,
111 BREAK_STMT,
112 CONTINUE_STMT
113 };
114 Type type = NORMAL;
116 };
117
118 // Seed `env` with module-level constant globals (best-effort; non-foldable
119 // assignments are simply skipped).
120 void seed_globals(Env &env);
121
122 std::optional<StmtResult> exec_block(const nlohmann::json &body, Env &env);
123 std::optional<StmtResult> exec_stmt(const nlohmann::json &stmt, Env &env);
124
125 // Bind an assignment target (Name, or Tuple/List for unpacking) to a value.
126 // Returns false on an unsupported target shape or arity mismatch.
127 bool bind_target(
128 const nlohmann::json &target,
129 const PyConstValue &value,
130 Env &env);
131
132 // Resolve the optional (start, end) window arguments of a str method
133 // (args[1], args[2]) for a string of length `sz`, applying Python's
134 // negative-index and clamping rules. Defaults: start=0, end=sz. Returns
135 // false if a present window argument is not a constant int.
136 bool resolve_str_window(
137 const nlohmann::json &args,
138 const Env &env,
139 long long sz,
140 long long &start,
141 long long &end);
142 std::optional<PyConstValue>
143 eval_expr(const nlohmann::json &node, const Env &env);
144 // The values of a user call's arguments; nullopt when one is not foldable.
145 std::optional<std::vector<PyConstValue>>
146 eval_call_args(const nlohmann::json &args, const Env &env);
147
148 // String slice with full Python semantics
149 static std::string slice_string(
150 const std::string &s,
151 std::optional<long long> start,
152 std::optional<long long> stop,
153 long long step);
154
155 // Find function definition in top-level AST body
156 const nlohmann::json *find_function(const std::string &name) const;
157};
std::optional< PyConstValue > try_eval_global_expr(const nlohmann::json &expr)
Try to evaluate an arbitrary expression at module scope, seeding the environment with module-level co...
Definition python_consteval.cpp:671
std::optional< PyConstValue > try_eval_call(const std::string &func_name, const std::vector< PyConstValue > &args)
Try to evaluate a function call with constant arguments.
Definition python_consteval.cpp:239
python_consteval(const nlohmann::json &ast, int max_iterations=50000)
Definition python_consteval.cpp:143
Definition toml.hpp:1531
@ RETURN
Definition goto_program.h:39
Represents a constant Python value for compile-time evaluation.
Definition python_consteval.h:11
std::vector< PyConstValue > tuple_val
Definition python_consteval.h:30
static PyConstValue make_int(long long v)
Definition python_consteval.h:40
double float_val
Definition python_consteval.h:26
static PyConstValue make_float(double v)
Definition python_consteval.h:44
static PyConstValue make_list(const std::vector< PyConstValue > &values)
Definition python_consteval.h:56
static PyConstValue make_bool(bool v)
Definition python_consteval.h:36
bool is_truthy() const
Definition python_consteval.cpp:59
std::string string_val
Definition python_consteval.h:27
Kind kind
Definition python_consteval.h:23
static PyConstValue make_none()
Definition python_consteval.h:32
Kind
Definition python_consteval.h:13
@ STRING
Definition python_consteval.h:18
@ TUPLE
Definition python_consteval.h:19
@ BOOL
Definition python_consteval.h:15
@ INT
Definition python_consteval.h:16
@ NONE
Definition python_consteval.h:14
@ FLOAT
Definition python_consteval.h:17
@ LIST
Definition python_consteval.h:20
long long int_val
Definition python_consteval.h:25
bool bool_val
Definition python_consteval.h:24
static PyConstValue make_string(const std::string &s)
Definition python_consteval.h:48
static PyConstValue make_tuple(const std::vector< PyConstValue > &values)
Definition python_consteval.h:52