// Reconstructed interface, NOT a recovered historical header. See docs/LINEAGE.md. #pragma once #include #include #include #include #include #include #include #include #include #include #include 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 code; std::vector stack; }; struct CodeLine { Source source; std::vector arg; std::size_t match = 0, alternate = 0, loop = static_cast(-1); std::vector scope; mutable MathCache math; }; struct Structured; struct variable { std::string value; std::vector 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 structured{}; std::size_t structuredBytes = 0; }; struct vFunc { std::string name; std::size_t argc = 0; std::vector parameters; Source source; std::vector line; }; struct Frame { std::map vars; std::vector args; std::size_t extraBytes = 0; std::map 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 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 functions; std::set loading; std::size_t sourceBytes = 0, sourceLines = 0, outputBytes = 0, fileBytes = 0; Source outputSource{"",0}; std::map changedEnvironment; std::uint64_t steps = 0; std::mt19937 randomEngine{0}; std::chrono::steady_clock::time_point started; std::map> 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> databases; unsigned long nextDatabase = 1; std::size_t databaseBytes = 0; bool worklog(Frame&, const CodeLine&); struct RemoteDatabase; std::map> 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> webHeaders; std::string webBody; struct Socket; std::map> 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&, 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&, MathCache&); } // namespace vanilla