123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- /* Declarations for high-level IO functions.
- This file is part of khipu.
- khipu is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>. */
- #ifndef __KP_IO__
- #define __KP_IO__ 1
- #include "interp.hpp"
- #include "stream.hpp"
- #include "initop.hpp"
- #include "str.hpp"
- #include "function.hpp"
- #include "symbol.hpp"
- #include "array.hpp"
- #include "utils/lazy.hpp"
- KP_DECLS_BEGIN
- struct reader
- {
- interpreter *interp;
- valref pairs_valref;
- local_varobj<array> pairs;
- object stpairs[16];
- uint32_t pair_cnt;
- char stbuf[256];
- char *bufp;
- int bufcnt;
- int bufmax;
- int toktype;
- stream *src;
- uint32_t lineno = 0;
- int bq_level = 0;
- bool unquoted = false;
- package *ipkg;
- reader (interpreter *interp, object input, package *ipkg = nullptr);
- bool readable_p () const
- {
- return (!this->src->eos_p () && !this->src->err_p ());
- }
- void take ();
- result<void> handle_sym (object pkg, object name);
- result<bool> read_token (schar& ch, int digs);
- void expand ();
- object getlbl (object label) const;
- object* putlbl (object label);
- result<bool> nextc (schar& ch);
- void push_ch (const schar& ch);
- result<uint32_t> peek ();
- result<object> read_sexpr ();
- result<object> read_sexpr (object label);
- result<object> read_list (object label);
- result<object> read_bq (object label);
- result<object> read_comma (object label);
- result<object> read_array (object label);
- result<object> read_table (object label);
- result<object> read_tuple (object label);
- result<object> read_bvector ();
- result<object> read_str ();
- result<object> read_char ();
- ~reader ();
- };
- // Expand a string (With possible interpolation).
- KP_EXPORT result<object> expand_str (interpreter *interp, object str);
- // Expand a backquote expression.
- KP_EXPORT result<object> expand_bq (interpreter *interp, object form);
- // Write an object to a stream, using the parameters in INFO.
- KP_EXPORT result<int64_t> xwrite (interpreter *interp, stream *strm,
- object obj, io_info& info);
- inline result<int64_t>
- xwrite (interpreter *interp, stream *strm, object obj)
- {
- io_info info;
- return (xwrite (interp, strm, obj, info));
- }
- template <typename ...Args>
- result<object> sprintf_helper (interpreter *interp, const char *fmt,
- Args... args)
- {
- local_varobj<string> sf;
- uint32_t sp = interp->stklen ();
- sf.local_init (fmt);
- KP_VTRY (interp->growstk (2 + sizeof... (args)),
- intern (interp, "%fmt-str", as_package (root_package)));
- *interp->stkend++ = symval (interp->retval);
- *interp->stkend++ = sf.as_obj ();
- KP_VTRY (push_all_helper (interp, args...));
- return (call_n (interp, interp->stklen () - sp - 1));
- }
- #define KP_SPRINTF(Interp, Fmt, ...) \
- KP_CALL_DISP (KP_CALL, (Interp), khipu::sprintf_helper, (Fmt), ##__VA_ARGS__)
- // Object (de)serialization.
- enum
- {
- PACK_NIL = 0x74,
- PACK_EMPTY_ARRAY = 0x75,
- PACK_EMPTY_BVECTOR = 0x76,
- PACK_EMPTY_STR = 0x77,
- PACK_INT8 = 0x78,
- PACK_FIXINT = 0x79,
- PACK_CHAR8 = 0x7a,
- PACK_REF_INT32 = 0x7b,
- PACK_REF_OBJ = 0x7c,
- PACK_TYPESPEC = 0x7d,
- PACK_END = 0x7e,
- };
- struct pack_cache
- {
- local_varobj<array> l_obj;
- object st_tab[256];
- valref ref;
- uint32_t n_elem;
- uint32_t n_old;
- bool evict;
- uint32_t size () const;
- object* data ();
- pack_cache (interpreter *interp);
- object get (interpreter *interp, object key);
- result<void> put (interpreter *interp, object key, object val);
- };
- struct pack_info
- {
- valref map;
- valref offset;
- lazy<pack_cache> pcache;
- pack_cache *cache;
- stream *bstream;
- const char *errmsg;
- pack_info (interpreter *interp);
- result<void> init (interpreter *interp, bool cache);
- result<void> add_mapping (interpreter *interp, object key, object val);
- object get (interpreter *interp, object obj);
- void touch (interpreter *interp, int offset);
- exception error (const char *msg)
- {
- this->errmsg = msg;
- return (exception ());
- }
- ~pack_info ()
- {
- if (this->cache)
- destroy (this->cache);
- }
- struct eviction_guard
- {
- bool *oldp;
- eviction_guard (pack_info& info, bool use)
- {
- if (use && info.cache->evict)
- *(this->oldp = &info.cache->evict) = false;
- else
- this->oldp = nullptr;
- }
- ~eviction_guard ()
- {
- if (this->oldp)
- *this->oldp = true;
- }
- };
- };
- KP_EXPORT result<int64_t> xpack (interpreter *interp, stream *strm,
- object obj, pack_info& info);
- KP_EXPORT result<int64_t> xpack (interpreter *interp, stream *strm,
- object obj, object *map, size_t nmap);
- template <typename ...Args>
- inline result<int64_t> xpack_with (interpreter *interp, stream *strm,
- object obj, Args... args)
- {
- object tmp[] = { args..., 0 };
- return (xpack (interp, strm, obj, tmp, KP_NELEM (tmp) - 1));
- }
- inline result<int64_t> xpack (interpreter *interp, stream *strm, object obj)
- {
- return (xpack (interp, strm, obj, nullptr, 0));
- }
- KP_EXPORT result<object> xunpack (interpreter *interp,
- stream *strm, pack_info& info);
- inline result<object> xunpack (interpreter *interp, stream *strm)
- {
- pack_info info { interp };
- KP_VTRY (info.init (interp, false));
- return (xunpack (interp, strm, info));
- }
- // Print a full backtrace starting from FRAME to stream STRMP.
- KP_EXPORT result<void> print_backtrace (interpreter *interp, uint32_t frame,
- stream *strmp, io_info& info);
- // Safely write a raised object to a stream.
- KP_EXPORT void write_exc (interpreter *interp, stream *strm,
- object exc, io_info& info);
- KP_EXPORT init_op init_io;
- KP_DECLS_END
- #endif
|