1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-26 00:10:27 +00:00

Add all and line option to file-read

This commit is contained in:
Calvin Rose 2018-02-04 00:54:38 -05:00
parent f3b2c29580
commit 4b89789f69
3 changed files with 42 additions and 127 deletions

116
3
View File

@ -1,116 +0,0 @@
(def defmacro macro
(fn [name & more] (tuple 'def name 'macro (tuple-prepend (tuple-prepend more name) 'fn))))
(defmacro defn
[name & more]
(tuple 'def name (tuple-prepend (tuple-prepend more name) 'fn)))
(defmacro when
[cond & body]
(tuple 'if cond (tuple-prepend body 'do)))
(def seq (do
(defn array-seq [x]
(def len (length x))
(var i 0)
{
:more (fn [] (< i len))
:next (fn []
(def ret (get x i))
(varset! i (+ i 1))
ret)
})
(def seqs {
:array array-seq
:tuple array-seq
:struct (fn [x] x)})
(fn [x]
(def makeseq (get seqs (type x)))
(if makeseq (makeseq x) (error "expected sequence")))))
(defn range [top]
(var i 0)
{
:more (fn [] (< i top))
:next (fn []
(def ret i)
(varset! i (+ i 1))
ret)
})
(defn doseq [s]
(def s (seq s))
(def more? (get s :more))
(def getnext (get s :next))
(while (more?)
(getnext)))
(defn map [f s]
(def s (seq s))
(def more (get s :more))
(def getnext (get s :next))
{
:more more
:next (fn [] (f (getnext)))
})
(defn reduce [f start s]
(def s (seq s))
(def more? (get s :more))
(def getnext (get s :next))
(var ret start)
(while (more?)
(varset! ret (f ret (getnext))))
ret)
(defmacro for [head & body]
(def head (ast-unwrap1 head))
(def sym (get head 0))
(def start (get head 1))
(def end (get head 2))
(def _inc (get head 3))
(def inc (if _inc _inc 1))
(tuple 'do
(tuple 'var sym start)
(tuple 'while (tuple '< sym end)
(tuple-prepend body 'do)
(tuple 'varset! sym (tuple '+ sym 1))
)))
(defn pp-seq [pp buf a start end]
(def len (length a))
(buffer-push-string buf start)
(for [i 0 len]
(when (not= i 0) (buffer-push-string buf " "))
(pp buf (get a i)))
(buffer-push-string buf end)
buf)
(defn pp-dict [pp buf a start end]
(var k (next a nil))
(buffer-push-string buf start)
(while k
(def v (get a k))
(pp buf k)
(buffer-push-string buf " ")
(pp buf v)
(buffer-push-string buf "\n")
(varset! k (next a k))
)
(buffer-push-string buf end)
buf)
(def _printers {
:array (fn [pp buf x] (pp-seq pp buf x "[" "]"))
:tuple (fn [pp buf x] (pp-seq pp buf x "(" ")"))
:table (fn [pp buf x] (pp-dict pp buf x "@{" "}"))
:struct (fn [pp buf x] (pp-dict pp buf x "{" "}"))
})
(defn _default_printer [_ buf x] (buffer-push-string buf (string x)) buf)
(defn pp [buf x]
(def pmaybe (get _printers (type x)))
(def p (if pmaybe pmaybe _default_printer))
(p pp buf x))

View File

@ -169,11 +169,37 @@ static int dst_io_fread(DstArgs args) {
size_t ntoread, nread; size_t ntoread, nread;
IOFile *iof = checkfile(args, 0); IOFile *iof = checkfile(args, 0);
if (!iof) return 1; if (!iof) return 1;
if (!dst_checktype(args.v[1], DST_INTEGER)) return dst_throw(args, "expected positive integer");
len = dst_unwrap_integer(args.v[1]);
if (len < 0) return dst_throw(args, "expected positive integer");
b = checkbuffer(args, 2, 1); b = checkbuffer(args, 2, 1);
if (!b) return 1; if (!b) return 1;
if (dst_checktype(args.v[1], DST_SYMBOL)) {
const uint8_t *sym = dst_unwrap_symbol(args.v[1]);
if (!dst_cstrcmp(sym, ":all")) {
/* Read whole file */
long fsize;
fseek(iof->file, 0, SEEK_END);
fsize = ftell(iof->file);
fseek(iof->file, 0, SEEK_SET);
if (fsize > INT32_MAX) return dst_throw(args, "buffer overflow");
len = fsize;
/* Fall through to normal code */
} else if (!dst_cstrcmp(sym, ":line")) {
for (;;) {
int x = fgetc(iof->file);
if (x == EOF || x == '\n') {
break;
}
if (dst_buffer_push_u8(b, (uint8_t)x)) return dst_throw(args, "buffer overflow");
}
return dst_return(args, dst_wrap_buffer(b));
} else {
return dst_throw(args, "expected one of :all, :line");
}
} else if (!dst_checktype(args.v[1], DST_INTEGER)) {
return dst_throw(args, "expected positive integer");
} else {
len = dst_unwrap_integer(args.v[1]);
if (len < 0) return dst_throw(args, "expected positive integer");
}
if (!(iof->flags & (IO_READ | IO_UPDATE))) return dst_throw(args, "file is not readable"); if (!(iof->flags & (IO_READ | IO_UPDATE))) return dst_throw(args, "file is not readable");
/* Ensure buffer size */ /* Ensure buffer size */
if (dst_buffer_extra(b, len)) return dst_throw(args, "buffer overflow"); if (dst_buffer_extra(b, len)) return dst_throw(args, "buffer overflow");

View File

@ -308,9 +308,12 @@ const uint8_t *dst_short_description(Dst x) {
case DST_STRING: case DST_STRING:
return dst_escape_string(dst_unwrap_string(x)); return dst_escape_string(dst_unwrap_string(x));
case DST_ABSTRACT: case DST_ABSTRACT:
return string_description( {
dst_abstract_type(dst_unwrap_abstract(x))->name, const char *n = dst_abstract_type(dst_unwrap_abstract(x))->name;
dst_unwrap_abstract(x)); return string_description(
n[0] == ':' ? n + 1 : n,
dst_unwrap_abstract(x));
}
default: default:
return string_description(dst_type_names[dst_type(x)] + 1, dst_unwrap_pointer(x)); return string_description(dst_type_names[dst_type(x)] + 1, dst_unwrap_pointer(x));
} }
@ -345,10 +348,12 @@ void dst_short_description_b(DstBuffer *buffer, Dst x) {
dst_escape_buffer_b(buffer, dst_unwrap_buffer(x)); dst_escape_buffer_b(buffer, dst_unwrap_buffer(x));
return; return;
case DST_ABSTRACT: case DST_ABSTRACT:
string_description_b(buffer, {
dst_abstract_type(dst_unwrap_abstract(x))->name, const char *n = dst_abstract_type(dst_unwrap_abstract(x))->name;
dst_unwrap_abstract(x)); return string_description_b(buffer,
return; n[0] == ':' ? n + 1 : n,
dst_unwrap_abstract(x));
}
default: default:
string_description_b(buffer, dst_type_names[dst_type(x)] + 1, dst_unwrap_pointer(x)); string_description_b(buffer, dst_type_names[dst_type(x)] + 1, dst_unwrap_pointer(x));
break; break;