restored/script.h
← All source files · Download this file
5,202 bytes · SHA256 7de39bad0b4acddf183f1a4c8b5a1544d4ac3628d1a4c705e39b50843589dac2
// Reconstructed interface, NOT a recovered historical header. See docs/LINEAGE.md.
#pragma once
#include <chrono>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <fstream>
#include <random>
#include <set>
#include <stdexcept>
#include <string>
#include <vector>
namespace vanilla {
constexpr std::size_t valueLimit = 1024 * 1024;
constexpr std::size_t frameLimit = 2 * 1024 * 1024;
constexpr std::size_t itemLimit = 16384;
struct Source { std::string file; std::size_t line = 0; };
struct Error : std::runtime_error {
Source source;
bool fatal;
Error(Source s, const std::string& m, bool resource=false) : std::runtime_error(m), source(std::move(s)), fatal(resource) {}
};
[[noreturn]] void fail(const Source&, const std::string&);
[[noreturn]] void failLimit(const Source&, const std::string&);
void flushOutput(const Source&);
struct Token { std::string text; bool literal = false; };
// Postfix operations are recorded during the first successful evaluation.
// No variable pointers/values are retained: references resolve in the active frame.
enum class MathOp { constant, reference, neg, add, sub, mul, div, mod, power,
minimum, maximum, absolute, root, floor, ceil, round };
struct MathInstruction { MathOp op; double constant = 0; std::string reference; };
struct MathCache {
bool ready = false;
std::vector<MathInstruction> code;
std::vector<double> stack;
};
struct CodeLine {
Source source;
std::vector<Token> arg;
std::size_t match = 0, alternate = 0, loop = static_cast<std::size_t>(-1);
std::vector<std::size_t> scope;
mutable MathCache math;
};
struct Structured;
struct variable {
std::string value;
std::vector<std::string> items;
bool array = false;
// Text assignments retain spelling; numeric assignments format only on read.
double numericValue = 0;
bool numericKnown = false;
bool textPending = false;
std::shared_ptr<const Structured> structured{};
std::size_t structuredBytes = 0;
};
struct vFunc {
std::string name;
std::size_t argc = 0;
std::vector<std::string> parameters;
Source source;
std::vector<CodeLine> line;
};
struct Frame {
std::map<std::string, variable> vars;
std::vector<variable> args;
std::size_t extraBytes = 0;
std::map<std::string, std::size_t> points;
};
struct Options {
bool allowDb = false, testMode = false;
bool allowFiles = false;
std::uint64_t maxSteps = 1000000;
bool allowNetwork = false, allowListen = false;
std::string dnsServer, tlsCAFile, tlsCertFile, tlsKeyFile;
std::string sqlConfig;
bool webWorker = false;
std::string webRequest;
std::vector<std::string> arguments;
};
void validateNetworkOptions(const Options&,const Source&);
class vScript {
public:
explicit vScript(Options options = {});
void Load(const std::string& file);
void Run();
bool Test(const std::string& file);
std::string WebResponse() const;
private:
Options options;
std::map<std::string, vFunc> functions;
std::set<std::string> loading;
std::size_t sourceBytes = 0, sourceLines = 0, outputBytes = 0, fileBytes = 0;
Source outputSource{"<runtime>",0};
std::map<std::string,std::string> changedEnvironment;
std::uint64_t steps = 0;
std::mt19937 randomEngine{0};
std::chrono::steady_clock::time_point started;
std::map<unsigned long, std::unique_ptr<std::ifstream>> readers;
unsigned long nextReader = 1;
std::size_t inputBytes = 0, readBytes = 0, networkBytes = 0, networkCalls = 0;
long networkTime = 0;
bool utility(Frame&, const CodeLine&);
struct Database;
std::map<unsigned long, std::shared_ptr<Database>> databases;
unsigned long nextDatabase = 1;
std::size_t databaseBytes = 0;
bool worklog(Frame&, const CodeLine&);
struct RemoteDatabase;
std::map<std::string, std::shared_ptr<RemoteDatabase>> remoteDatabases;
unsigned long nextRemoteDatabase = 1;
std::size_t remoteSqlBytes = 0, remoteSqlCalls = 0;
bool remoteSql(Frame&, const CodeLine&);
bool webCommand(Frame&, const CodeLine&);
void emit(const std::string&,const Source&);
int webStatus = 200;
std::vector<std::pair<std::string,std::string>> webHeaders;
std::string webBody;
struct Socket;
std::map<std::string, std::shared_ptr<Socket>> sockets;
unsigned long nextSocket = 1;
std::size_t socketBytes = 0, socketCalls = 0, socketTime = 0, dnsCalls = 0;
bool socketCommand(Frame&, const CodeLine&);
bool foundationCommand(Frame&, const CodeLine&);
bool websocketCommand(Frame&, const CodeLine&);
void loadFile(const std::string&, const Source&);
void validate(vFunc&);
variable runFunction(const std::string&, const std::vector<variable>&, std::size_t, const Source&);
};
bool numeric(const std::string&, double&);
double number(const std::string&, const Source&);
std::string format(double, const Source&);
long long integer(const std::string&, long long, long long, const Source&);
double expression(const std::string&, const Source&, const std::function<double(const std::string&)>&, MathCache&);
} // namespace vanilla