spudplate
Template scaffolding compiler for spudlang .spud files
Loading...
Searching...
No Matches
interpreter.h
1#ifndef SPUDPLATE_INTERPRETER_H
2#define SPUDPLATE_INTERPRETER_H
3
4#include <cstdint>
5#include <iosfwd>
6#include <optional>
7#include <stdexcept>
8#include <string>
9#include <string_view>
10#include <unordered_map>
11#include <utility>
12#include <variant>
13#include <vector>
14
15#include "spudplate/ast.h"
16#include "spudplate/spudpack.h"
17
18namespace spudplate {
19
26class RuntimeError : public std::runtime_error {
27 public:
29 RuntimeError(const std::string& message, int line, int column)
30 : std::runtime_error(message), line_(line), column_(column) {}
31
33 [[nodiscard]] int line() const { return line_; }
35 [[nodiscard]] int column() const { return column_; }
36
37 private:
38 int line_;
39 int column_;
40};
41
49using Value = std::variant<std::string, std::int64_t, bool>;
50
62 public:
65
67 void push() { frames_.emplace_back(); }
69 void pop() { frames_.pop_back(); }
70
77 void declare(const std::string& name, Value value);
78
85 void assign(const std::string& name, Value value);
86
88 [[nodiscard]] std::optional<Value> lookup(const std::string& name) const;
89
90 private:
91 std::vector<std::unordered_map<std::string, Value>> frames_;
92};
93
103 std::string text;
104 VarType type;
105 std::vector<std::string> options;
106 std::optional<std::string> default_value;
107 std::optional<std::string> previous_error;
111 std::vector<std::pair<std::int64_t, std::int64_t>> iterations;
112};
113
117class Prompter {
118 public:
119 virtual ~Prompter() = default;
120
128 virtual std::string prompt(const PromptRequest& req) = 0;
129
138 virtual bool authorize(const std::string& summary) = 0;
139};
140
148class StdinPrompter : public Prompter {
149 public:
154 StdinPrompter(std::istream& in, std::ostream& out, bool use_colour);
155
156 std::string prompt(const PromptRequest& req) override;
157 bool authorize(const std::string& summary) override;
158
159 private:
160 std::istream& in_;
161 std::ostream& out_;
162 bool use_colour_;
163};
164
173 public:
175 explicit ScriptedPrompter(std::vector<std::string> answers)
176 : answers_(std::move(answers)) {}
177
178 std::string prompt(const PromptRequest& req) override;
179 bool authorize(const std::string& summary) override;
180
182 [[nodiscard]] const std::optional<PromptRequest>& last_request() const {
183 return last_;
184 }
185
188 [[nodiscard]] const std::vector<PromptRequest>& requests() const {
189 return requests_;
190 }
191
193 void set_authorize_response(bool value) { authorize_response_ = value; }
194
196 [[nodiscard]] const std::optional<std::string>& last_authorize_summary() const {
197 return last_authorize_summary_;
198 }
199
200 private:
201 std::vector<std::string> answers_;
202 std::size_t index_{0};
203 std::optional<PromptRequest> last_;
204 std::vector<PromptRequest> requests_;
205 bool authorize_response_{true};
206 std::optional<std::string> last_authorize_summary_;
207};
208
226 public:
227 virtual ~SourceProvider() = default;
228
230 struct Entry {
231 std::string path;
233 std::uint16_t mode;
234 };
235
242 virtual std::pair<std::vector<std::uint8_t>, std::uint16_t> read(
243 std::string_view path) const = 0;
244
253 virtual std::vector<Entry> list_under(std::string_view prefix) const = 0;
254};
255
266 public:
268 explicit AssetMapSourceProvider(const std::vector<SpudpackAsset>& assets);
269
270 std::pair<std::vector<std::uint8_t>, std::uint16_t> read(
271 std::string_view path) const override;
272 std::vector<Entry> list_under(std::string_view prefix) const override;
273
274 private:
275 const std::vector<SpudpackAsset>& assets_;
276 std::unordered_map<std::string, std::size_t> index_;
277};
278
309void run(const Program& program, Prompter& prompter,
310 bool skip_authorization = false,
311 const SourceProvider* source = nullptr,
312 bool timeouts_disabled = false,
313 const std::vector<SpudpackDep>* deps = nullptr);
314
321Environment run_for_tests(const Program& program, Prompter& prompter,
322 const SourceProvider* source = nullptr,
323 const std::vector<SpudpackDep>* deps = nullptr);
324
341void dry_run(const Program& program, Prompter& prompter, std::ostream& out,
342 bool ascii_only = false,
343 const SourceProvider* source = nullptr,
344 const std::vector<SpudpackDep>* deps = nullptr);
345
354bool locale_is_utf8();
355
365Value evaluate_expr(const Expr& expr, const Environment& env);
366
373std::string value_to_string(const Value& value);
374
382using AliasMap = std::unordered_map<std::string, std::string>;
383
394std::string evaluate_path(const PathExpr& path, const Environment& env,
395 const AliasMap& aliases);
396
397} // namespace spudplate
398
399#endif // SPUDPLATE_INTERPRETER_H
SourceProvider backed by a borrowed asset map.
Definition interpreter.h:265
std::vector< Entry > list_under(std::string_view prefix) const override
List every entry under the given prefix, including synthesised intermediate directories.
Definition interpreter.cpp:2129
std::pair< std::vector< std::uint8_t >, std::uint16_t > read(std::string_view path) const override
Read the bytes of an asset by its normalised path.
Definition interpreter.cpp:2118
Variable storage for a running interpreter.
Definition interpreter.h:61
void pop()
Pop the innermost frame, discarding any bindings it held.
Definition interpreter.h:69
void declare(const std::string &name, Value value)
Bind name to value in the innermost frame.
Definition interpreter.cpp:39
void assign(const std::string &name, Value value)
Replace the value of an existing binding, innermost first.
Definition interpreter.cpp:57
Environment()
Start with one program-level frame already on the stack.
Definition interpreter.h:64
void push()
Push a fresh frame for a nested scope (e.g.
Definition interpreter.h:67
std::optional< Value > lookup(const std::string &name) const
Find name in any frame, innermost first.
Definition interpreter.cpp:47
Abstract source of user input for ask statements.
Definition interpreter.h:117
virtual std::string prompt(const PromptRequest &req)=0
Display the prompt described by req and return the user's raw answer.
virtual bool authorize(const std::string &summary)=0
Display a security summary and return whether to proceed.
Exception thrown when the interpreter encounters a runtime failure.
Definition interpreter.h:26
int line() const
1-based line number of the offending statement or expression.
Definition interpreter.h:33
RuntimeError(const std::string &message, int line, int column)
Construct an error tagged with the offending source position.
Definition interpreter.h:29
int column() const
1-based column number of the offending statement or expression.
Definition interpreter.h:35
Test prompter: replays a fixed sequence of canned answers.
Definition interpreter.h:172
const std::vector< PromptRequest > & requests() const
Every request seen so far, in order.
Definition interpreter.h:188
void set_authorize_response(bool value)
Set what authorize returns.
Definition interpreter.h:193
ScriptedPrompter(std::vector< std::string > answers)
Construct with the canned answers prompt will replay in order.
Definition interpreter.h:175
std::string prompt(const PromptRequest &req) override
Display the prompt described by req and return the user's raw answer.
Definition interpreter.cpp:1781
bool authorize(const std::string &summary) override
Display a security summary and return whether to proceed.
Definition interpreter.cpp:1790
const std::optional< std::string > & last_authorize_summary() const
Most recent authorize summary seen, for assertions.
Definition interpreter.h:196
const std::optional< PromptRequest > & last_request() const
Most recent request seen, for assertions on rendering inputs.
Definition interpreter.h:182
Source of bundled assets the interpreter draws from for from/copy.
Definition interpreter.h:225
virtual std::pair< std::vector< std::uint8_t >, std::uint16_t > read(std::string_view path) const =0
Read the bytes of an asset by its normalised path.
virtual std::vector< Entry > list_under(std::string_view prefix) const =0
List every entry under the given prefix, including synthesised intermediate directories.
Production prompter: writes to a stream and reads a line from another.
Definition interpreter.h:148
std::string prompt(const PromptRequest &req) override
Display the prompt described by req and return the user's raw answer.
Definition interpreter.cpp:1761
StdinPrompter()
Default constructor: read from std::cin, write to std::cout, auto-detect colour support.
Definition interpreter.cpp:1755
bool authorize(const std::string &summary) override
Display a security summary and return whether to proceed.
Definition interpreter.cpp:1768
An expression node wrapping an ExprData variant.
Definition ast.h:104
A path expression - an ordered sequence of segments.
Definition ast.h:146
The top-level AST node representing a complete .spud program.
Definition ast.h:374
Structured description of an ask prompt for the prompter to render.
Definition interpreter.h:102
std::string text
The question text from the .spud source.
Definition interpreter.h:103
int question_index
1-based position of this question among presented ones; 0 suppresses the counter.
Definition interpreter.h:108
VarType type
Expected answer type.
Definition interpreter.h:104
int indent_level
Number of nested repeat blocks above this prompt; renders as 2 spaces per level.
Definition interpreter.h:110
std::optional< std::string > default_value
Stringified default; empty means required.
Definition interpreter.h:106
std::vector< std::string > options
Stringified allowed answers; empty means any.
Definition interpreter.h:105
int question_total
Total static ask statements in the program; 0 suppresses the counter.
Definition interpreter.h:109
std::optional< std::string > previous_error
Set on retry; describes why the prior answer was rejected.
Definition interpreter.h:107
std::vector< std::pair< std::int64_t, std::int64_t > > iterations
One {current, total} pair per enclosing repeat block, outermost first. Empty outside any repeat.
Definition interpreter.h:111
One entry returned by list_under.
Definition interpreter.h:230
std::string path
Normalised bundle-root-relative path.
Definition interpreter.h:231
bool is_directory
True for directories (intermediate or empty leaf).
Definition interpreter.h:232
std::uint16_t mode
Permission bits, or 0 for "no mode information".
Definition interpreter.h:233