Skip to content

Commit

Permalink
Added methods for table: clone, slice, keys, values...
Browse files Browse the repository at this point in the history
For tuple: slice. For bytes and string: clone
Added support for negative arguments for string.slice
Changed API's for potion_type_error_want
  • Loading branch information
Reini Urban committed Oct 20, 2013
1 parent d0316fa commit c2314c7
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 59 deletions.
5 changes: 4 additions & 1 deletion ChangeLog
Original file line number Original file line Diff line number Diff line change
@@ -1,7 +1,10 @@
v0.2 planned: Dec 21 2013 rurban v0.2 planned: Dec 21 2013 rurban


* print and say methods return "" instead of nil. * print and say methods return "" instead of nil.
* Added methods for table: clone, slice, keys, values. For tuple: slice * Added methods for table: clone, slice, keys, values.
For tuple: slice. For bytes and string: clone
* Added support for negative arguments for string.slice
* Changed API's for potion_type_error_want


v0.1 Wed Oct 16 13:08:38 2013 rurban v0.1 Wed Oct 16 13:08:38 2013 rurban


Expand Down
6 changes: 3 additions & 3 deletions core/internal.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -261,9 +261,9 @@ PN potion_type_error(Potion *P, PN obj) {
return potion_error(P, potion_str_format(P, "Invalid type %s", potion_type_name(P, obj)), return potion_error(P, potion_str_format(P, "Invalid type %s", potion_type_name(P, obj)),
0, 0, 0); 0, 0, 0);
} }
PN potion_type_error_want(Potion *P, PN obj, const char *name) { PN potion_type_error_want(Potion *P, const char *param, PN obj, const char *type) {
return potion_error(P, potion_str_format(P, "Invalid type %s, expected %s", return potion_error(P, potion_str_format(P, "Invalid type %s for %s, expected %s",
potion_type_name(P, obj), name), potion_type_name(P, obj), param, type),
0, 0, 0); 0, 0, 0);
} }


Expand Down
18 changes: 10 additions & 8 deletions core/potion.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -184,17 +184,19 @@ struct PNVtable;
#define PN_IS_FFIPTR(p) ((PN_IS_PTR(p) && !(p >= (_PN)P->mem && p <= (_PN)P->mem->birth_hi)) \ #define PN_IS_FFIPTR(p) ((PN_IS_PTR(p) && !(p >= (_PN)P->mem && p <= (_PN)P->mem->birth_hi)) \
|| (!PN_IS_PTR(p) && p > (_PN)P->mem->birth_hi)) || (!PN_IS_PTR(p) && p > (_PN)P->mem->birth_hi))


#define PN_CHECK_STR(obj) if (!PN_IS_STR(obj)) return potion_type_error_want(P, obj, "String") #define PN_CHECK_STR(obj) if (!PN_IS_STR(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "String")
#define PN_CHECK_INT(obj) if (!PN_IS_NUM(obj)) return potion_type_error_want(P, obj, "Integer") #define PN_CHECK_INT(obj) if (!PN_IS_NUM(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "Integer")
#define PN_CHECK_BOOL(obj) if (!PN_IS_BOOL(obj)) return potion_type_error_want(P, obj, "Bool") #define PN_CHECK_BOOL(obj) if (!PN_IS_BOOL(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "Bool")
#define PN_CHECK_TUPLE(obj) if (!PN_IS_TUPLE(obj)) return potion_type_error_want(P, obj, "Tuple") #define PN_CHECK_TUPLE(obj) if (!PN_IS_TUPLE(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "Tuple")
#define PN_CHECK_CLOSURE(obj) if (!PN_IS_CLOSURE(obj)) return potion_type_error_want(P, obj, "Closure") #define PN_CHECK_CLOSURE(obj) if (!PN_IS_CLOSURE(obj)) return potion_type_error_want(P, ""#obj, (PN)obj, "Closure")
//TODO: check parents and mixins via bind //TODO: check parents and mixins via bind
#define PN_CHECK_TYPE(obj,type) if (type != PN_TYPE(obj)) return potion_type_error(P, obj) #define PN_CHECK_TYPE(obj,type) if (type != PN_TYPE(obj)) return potion_type_error(P, (PN)obj)
#ifdef DEBUG #ifdef DEBUG
#define DBG_CHECK_TYPE(obj,type) PN_CHECK_TYPE((PN)obj,type) #define DBG_CHECK_TYPE(obj,type) PN_CHECK_TYPE(obj,type)
#define DBG_CHECK_INT(obj) PN_CHECK_INT(obj)
#else #else
#define DBG_CHECK_TYPE(obj,type) #define DBG_CHECK_TYPE(obj,type)
#define DBG_CHECK_INT(obj)
#endif #endif


///\class PNNumber ///\class PNNumber
Expand Down Expand Up @@ -785,7 +787,7 @@ void potion_fatal(char *);
void potion_allocation_error(void); void potion_allocation_error(void);
PN potion_io_error(Potion *, const char *); PN potion_io_error(Potion *, const char *);
PN potion_type_error(Potion *, PN); PN potion_type_error(Potion *, PN);
PN potion_type_error_want(Potion *, PN, const char *); PN potion_type_error_want(Potion *, const char *, PN, const char *);
void potion_syntax_error(Potion *, const char *, ...) void potion_syntax_error(Potion *, const char *, ...)
__attribute__ ((format (printf, 2, 3))); __attribute__ ((format (printf, 2, 3)));
PNType potion_kind_of(PN); PNType potion_kind_of(PN);
Expand Down
33 changes: 31 additions & 2 deletions core/string.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ static PN potion_str_string(Potion *P, PN cl, PN self) {
return self; return self;
} }


///\memberof PNString
/// "clone" method. Returns self, strings are immutable.
static PN potion_str_clone(Potion *P, PN cl, PN self) {
return self;
}

///\memberof PNString ///\memberof PNString
/// "print" method. fwrite to stdout /// "print" method. fwrite to stdout
///\returns nil ///\returns nil
Expand Down Expand Up @@ -221,8 +227,18 @@ inline static PN potion_str_slice_index(PN index, size_t len, int nilvalue) {
static PN potion_str_slice(Potion *P, PN cl, PN self, PN start, PN end) { static PN potion_str_slice(Potion *P, PN cl, PN self, PN start, PN end) {
char *str = PN_STR_PTR(self); char *str = PN_STR_PTR(self);
size_t len = potion_cp_strlen_utf8(str); size_t len = potion_cp_strlen_utf8(str);
size_t startoffset = potion_utf8char_offset(str, PN_INT(potion_str_slice_index(start, len, 0)));
size_t endoffset; size_t endoffset;
if (!start)
return self;
else {
DBG_CHECK_TYPE(start, PN_TNUMBER);
}
size_t startoffset = potion_utf8char_offset(str, PN_INT(potion_str_slice_index(start, len, 0)));
if (!end)
end = PN_NUM(len);
else {
DBG_CHECK_INT(end);
}
if (end < start) { if (end < start) {
endoffset = potion_utf8char_offset(str, PN_INT(potion_str_slice_index(start+end, len, len))); endoffset = potion_utf8char_offset(str, PN_INT(potion_str_slice_index(start+end, len, len)));
} else { } else {
Expand Down Expand Up @@ -297,6 +313,17 @@ PN potion_bytes(Potion *P, size_t len) {
return (PN)s; return (PN)s;
} }


///\memberof PNBytes
/// "clone" returns a copy of the byte buffer
///\return PNBytes
PN potion_bytes_clone(Potion *P, PN cl, PN self) {
vPN(Bytes) b = (struct PNBytes *)potion_fwd(self);
vPN(Bytes) s = PN_ALLOC_N(PN_TBYTES, struct PNBytes, b->siz);
s->siz = b->siz;
s->len = b->len;
return (PN)s;
}

PN_SIZE pn_printf(Potion *P, PN bytes, const char *format, ...) { PN_SIZE pn_printf(Potion *P, PN bytes, const char *format, ...) {
PN_SIZE len; PN_SIZE len;
va_list args; va_list args;
Expand Down Expand Up @@ -434,7 +461,8 @@ void potion_str_init(Potion *P) {
potion_method(str_vt, "number", potion_str_number, 0); potion_method(str_vt, "number", potion_str_number, 0);
potion_method(str_vt, "print", potion_str_print, 0); potion_method(str_vt, "print", potion_str_print, 0);
potion_method(str_vt, "string", potion_str_string, 0); potion_method(str_vt, "string", potion_str_string, 0);
potion_method(str_vt, "slice", potion_str_slice, "start=N,end=N"); potion_method(str_vt, "clone", potion_str_clone, 0);
potion_method(str_vt, "slice", potion_str_slice, "start=N|end=N");
potion_method(str_vt, "bytes", potion_str_bytes, 0); potion_method(str_vt, "bytes", potion_str_bytes, 0);
potion_method(str_vt, "+", potion_str_add, "str=S"); potion_method(str_vt, "+", potion_str_add, "str=S");
potion_method(str_vt, "ord", potion_str_ord, "|index=N"); potion_method(str_vt, "ord", potion_str_ord, "|index=N");
Expand All @@ -445,6 +473,7 @@ void potion_str_init(Potion *P) {
potion_method(byt_vt, "length", potion_bytes_length, 0); potion_method(byt_vt, "length", potion_bytes_length, 0);
potion_method(byt_vt, "print", potion_bytes_print, 0); potion_method(byt_vt, "print", potion_bytes_print, 0);
potion_method(byt_vt, "string", potion_bytes_string, 0); potion_method(byt_vt, "string", potion_bytes_string, 0);
potion_method(byt_vt, "clone", potion_bytes_clone, 0);
potion_method(byt_vt, "ord", potion_str_ord, 0); potion_method(byt_vt, "ord", potion_str_ord, 0);
potion_method(byt_vt, "each", potion_bytes_each, "block=&"); potion_method(byt_vt, "each", potion_bytes_each, "block=&");
} }
53 changes: 29 additions & 24 deletions core/table.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -175,14 +175,16 @@ PN potion_table_slice(Potion *P, PN cl, PN self, PN keys) {
DBG_CHECK_TYPE(keys,PN_TTUPLE); DBG_CHECK_TYPE(keys,PN_TTUPLE);
} }
vPN(Table) t2 = (vPN(Table))PN_ALLOC_N(PN_TTABLE, struct PNTable, 0); vPN(Table) t2 = (vPN(Table))PN_ALLOC_N(PN_TTABLE, struct PNTable, 0);
t2 = kh_resize_PN(P, t2, PN_TUPLE_LEN(keys)); t2 = kh_resize_PN(P, t2, PN_TUPLE_LEN(keys)); //ca, could overshoot for dupl and outliers
int ret;
PN_TUPLE_EACH(keys, i, v, { PN_TUPLE_EACH(keys, i, v, {
if (kh_exist(PN, t, v)) { DBG_vt("%d:%ld ", i, PN_INT(v));
unsigned key = kh_put(PN, t2, kh_key(PN, t, v), &ret); unsigned k = kh_get(PN, t, v);
if (k != kh_end(t)) {
int ret;
unsigned k2 = kh_put(PN, t2, v, &ret);
PN_QUICK_FWD(struct PNTable *, t); PN_QUICK_FWD(struct PNTable *, t);
PN_QUICK_FWD(struct PNTable *, t2); PN_QUICK_FWD(struct PNTable *, t2);
kh_val(PN, t2, key) = kh_val(PN, t, v); kh_val(PN, t2, k2) = kh_val(PN, t, k);
} }
}); });
PN_TOUCH(t2); PN_TOUCH(t2);
Expand Down Expand Up @@ -327,42 +329,45 @@ PN potion_tuple_clone(Potion *P, PN cl, PN self) {
} }


/**\memberof PNTuple /**\memberof PNTuple
Extract slice copy of a tuple Extract slice copy of a tuple, similar to strings. Supports negative indices and end<start.
\code \code
(0,1,2) slice #=> (0,1,2) (0,1,2) slice #=> (0,1,2)
(0,1,2) slice(1) #=> (1,2) (0,1,2) slice(1) #=> (1,2)
(0,1,2) slice(0,2) #=> (0,1) (0,1,2) slice(0,1) #=> (0,1)
(0,1,2) slice(-1) #=> (2) (0,1,2) slice(-1) #=> (2)
(0,1,2) slice(1,1) #=> (1) (0,1,2) slice(1,1) #=> (1)
(0,1,2) slice(1,-1) #=> (0) (0,1,2) slice(1,-1) #=> (0,1)
(0,1,2) slice(2,-1) #=> (1) (0,1,2) slice(2,-1) #=> (2)
(0,1,2) slice(-1,-1) #=> (1) (0,1,2) slice(-1,-2) #=> (0,1)
\endcode \endcode
\param index PNNumber. Optional offset, default 0. If negative, count from end. If too large, return nil. \param start PNNumber. Default 0. If negative, count from end. If too large, return nil.
\param length PNNumber. Optional, default to the end. If negative, count reverse. If too large, return nil. \param end PNNumber. Optional, default last index. If negative, count from end. If too large, return nil.
\return new PNTuple */ \return new PNTuple */
static static
PN potion_tuple_slice(Potion *P, PN cl, PN self, PN index, PN length) { PN potion_tuple_slice(Potion *P, PN cl, PN self, PN start, PN end) {
vPN(Tuple) t1 = PN_GET_TUPLE(self); vPN(Tuple) t1 = PN_GET_TUPLE(self);
long i, l; long i, l;
DBG_CHECK_TYPE(t1,PN_TTUPLE); DBG_CHECK_TYPE(t1,PN_TTUPLE);
if (!index) if (!start)
return potion_tuple_clone(P, cl, self); return potion_tuple_clone(P, cl, self);
else { else {
DBG_CHECK_TYPE(index,PN_TNUMBER); DBG_CHECK_INT(start);
i = PN_INT(index); i = PN_INT(start);
if (i < 0) i = t1->len + i; if (i < 0) i = t1->len + i;
} }
if (!length || length == PN_NUM(0)) { if (!end)
l = t1->len - i; l = t1->len - i;
}
else { else {
DBG_CHECK_TYPE(length,PN_TNUMBER); long e = PN_INT(end);
l = PN_INT(length); DBG_CHECK_INT(end);
if (l < 0) { i += l; l = abs(l); } if (e < 0) e = t1->len + e;
l = e - i;
if (l < 0) { i = e; l = abs(l) + 1; }
else l++;
if (l > t1->len) l = t1->len; // permit overshoots
} }
DBG_v("; splice(%ld,%ld)\n", i, l); DBG_vt("; splice(i=%ld,len=%ld)\n", i, l);
if (l > t1->len || i > t1->len) return PN_NIL; if (!l || i >= t1->len) return PN_NIL;
NEW_TUPLE(t2, l); NEW_TUPLE(t2, l);
PN_MEMCPY_N(&t2->set[0], &t1->set[i], PN, l); PN_MEMCPY_N(&t2->set[0], &t1->set[i], PN, l);
t2->alloc = l; t2->alloc = l;
Expand Down Expand Up @@ -849,7 +854,7 @@ void potion_table_init(Potion *P) {
potion_method(tpl_vt, "nreverse", potion_tuple_nreverse, 0); potion_method(tpl_vt, "nreverse", potion_tuple_nreverse, 0);
potion_method(tpl_vt, "remove", potion_tuple_remove, "index=N"); potion_method(tpl_vt, "remove", potion_tuple_remove, "index=N");
potion_method(tpl_vt, "delete", potion_tuple_delete, "index=N"); potion_method(tpl_vt, "delete", potion_tuple_delete, "index=N");
potion_method(tpl_vt, "slice", potion_tuple_slice, "|from=N,to=N"); potion_method(tpl_vt, "slice", potion_tuple_slice, "start:=0,end:=nil");
potion_method(tpl_vt, "unshift", potion_tuple_unshift, "value=o"); potion_method(tpl_vt, "unshift", potion_tuple_unshift, "value=o");
potion_method(tpl_vt, "shift", potion_tuple_shift, 0); potion_method(tpl_vt, "shift", potion_tuple_shift, 0);
potion_method(tpl_vt, "bsearch", potion_tuple_bsearch, "value=o"); potion_method(tpl_vt, "bsearch", potion_tuple_bsearch, "value=o");
Expand Down
24 changes: 12 additions & 12 deletions lib/aio.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ static PN aio_error(Potion *P, char *name, int status) {


//checks inheritence //checks inheritence
#define CHECK_AIO_TYPE(self, T) \ #define CHECK_AIO_TYPE(self, T) \
if (!potion_bind(P, self, PN_STR("Aio_"_XSTR(T)))) return potion_type_error_want(P, self, ""_XSTR(T)) if (!potion_bind(P, self, PN_STR("Aio_"_XSTR(T)))) return potion_type_error_want(P, "self", self, ""_XSTR(T))
#define CHECK_AIO_STREAM(stream) \ #define CHECK_AIO_STREAM(stream) \
{ \ { \
PNType _t = PN_VTYPE(stream); \ PNType _t = PN_VTYPE(stream); \
Expand All @@ -156,7 +156,7 @@ static PN aio_error(Potion *P, char *name, int status) {
_t != aio_pipe_type && \ _t != aio_pipe_type && \
_t != aio_tty_type && \ _t != aio_tty_type && \
!potion_bind(P, stream, PN_STR("listen"))) \ !potion_bind(P, stream, PN_STR("listen"))) \
return potion_type_error_want(P, stream, "Aio_stream");\ return potion_type_error_want(P, "stream", stream, "Aio_stream"); \
} }
//if (PN_VTYPE(self) != aio_##T##_type) { //if (PN_VTYPE(self) != aio_##T##_type) {
#define FATAL_AIO_TYPE(self, T) \ #define FATAL_AIO_TYPE(self, T) \
Expand Down Expand Up @@ -187,10 +187,10 @@ static PN aio_error(Potion *P, char *name, int status) {


#define AIO_DATA(T,ARG) \ #define AIO_DATA(T,ARG) \
(aio_##T##_t*)PN_DATA(potion_fwd(ARG)); \ (aio_##T##_t*)PN_DATA(potion_fwd(ARG)); \
CHECK_AIO_TYPE(potion_fwd(ARG),T) CHECK_AIO_TYPE(ARG,T)
#define AIO_STREAM(ARG) \ #define AIO_STREAM(ARG) \
(aio_stream_t*)PN_DATA(potion_fwd(ARG)); \ (aio_stream_t*)PN_DATA(potion_fwd(ARG)); \
CHECK_AIO_STREAM(potion_fwd(ARG)) CHECK_AIO_STREAM(ARG)


//cb wrappers //cb wrappers
#define DEF_AIO_CB(T) \ #define DEF_AIO_CB(T) \
Expand Down Expand Up @@ -267,7 +267,7 @@ static PN aio_udp_new(Potion *P, PN cl, PN self, PN loop) {
\param key PNString, One of "broadcast", "multicast_loop", "multicast_ttl", "ttl" \param key PNString, One of "broadcast", "multicast_loop", "multicast_ttl", "ttl"
\see http://nikhilm.github.io/uvbook/networking.html#udp */ \see http://nikhilm.github.io/uvbook/networking.html#udp */
static PN aio_udp_get(Potion *P, PN cl, PN self, PN key, PN value) { static PN aio_udp_get(Potion *P, PN cl, PN self, PN key, PN value) {
CHECK_AIO_TYPE(potion_fwd(self),udp); CHECK_AIO_TYPE(self,udp);
PN_CHECK_STR(key); PN_CHECK_STR(key);
PN v = potion_obj_get(P, 0, self, key); PN v = potion_obj_get(P, 0, self, key);
return v ? v : potion_error(P, potion_str_format(P, "Invalid key %s", return v ? v : potion_error(P, potion_str_format(P, "Invalid key %s",
Expand All @@ -282,7 +282,7 @@ static PN aio_udp_get(Potion *P, PN cl, PN self, PN key, PN value) {
static PN aio_udp_set(Potion *P, PN cl, PN self, PN key, PN value) { static PN aio_udp_set(Potion *P, PN cl, PN self, PN key, PN value) {
uv_udp_t *udp; uv_udp_t *udp;
udp = (uv_udp_t*)PN_DATA(potion_fwd(self)); udp = (uv_udp_t*)PN_DATA(potion_fwd(self));
CHECK_AIO_TYPE(potion_fwd(self),udp); CHECK_AIO_TYPE(self,udp);
PN_CHECK_STR(key); PN_CHECK_STR(key);
char *k = PN_STR_PTR(key); char *k = PN_STR_PTR(key);
if (!strcmp(k, "broadcast")) { if (!strcmp(k, "broadcast")) {
Expand Down Expand Up @@ -499,7 +499,7 @@ static PN aio_getaddrinfo_new(Potion *P, PN cl, PN self,
const char *service_c = PN_IS_STR(service) ? PN_STR_PTR(service) : NULL; const char *service_c = PN_IS_STR(service) ? PN_STR_PTR(service) : NULL;
struct addrinfo* hints_c = (struct addrinfo*)PN_DATA(hints); struct addrinfo* hints_c = (struct addrinfo*)PN_DATA(hints);
if (!node_c && !service_c) { if (!node_c && !service_c) {
return potion_type_error_want(P, !node_c ? node : service, "String"); return potion_type_error_want(P, "node or service", !node_c ? node : service, "String");
} }
int r = uv_getaddrinfo(l, handle, getaddrinfo_cb, node_c, service_c, (const struct addrinfo*)hints_c); int r = uv_getaddrinfo(l, handle, getaddrinfo_cb, node_c, service_c, (const struct addrinfo*)hints_c);
if (r) return aio_error(P, "Aio_getaddrinfo", r); if (r) return aio_error(P, "Aio_getaddrinfo", r);
Expand Down Expand Up @@ -1476,7 +1476,7 @@ aio_signal_stop(Potion *P, PN cl, PN self) {
"gid", "stdio_count", "stdio", "uid" "gid", "stdio_count", "stdio", "uid"
\see http://nikhilm.github.io/uvbook/networking.html#process_options */ \see http://nikhilm.github.io/uvbook/networking.html#process_options */
static PN aio_process_options_get(Potion *P, PN cl, PN self, PN key) { static PN aio_process_options_get(Potion *P, PN cl, PN self, PN key) {
CHECK_AIO_TYPE(potion_fwd(self),process_options); CHECK_AIO_TYPE(self,process_options);
PN_CHECK_STR(key); PN_CHECK_STR(key);
PN v = potion_obj_get(P, 0, self, key); PN v = potion_obj_get(P, 0, self, key);
return v ? v : potion_error(P, potion_str_format(P, "Invalid key %s", return v ? v : potion_error(P, potion_str_format(P, "Invalid key %s",
Expand All @@ -1490,7 +1490,7 @@ static PN aio_process_options_get(Potion *P, PN cl, PN self, PN key) {
\param value \param value
\see http://nikhilm.github.io/uvbook/processes.html#spawning-child-processes */ \see http://nikhilm.github.io/uvbook/processes.html#spawning-child-processes */
static PN aio_process_options_set(Potion *P, PN cl, PN self, PN key, PN value) { static PN aio_process_options_set(Potion *P, PN cl, PN self, PN key, PN value) {
CHECK_AIO_TYPE(potion_fwd(self),process_options); CHECK_AIO_TYPE(self,process_options);
PN_CHECK_STR(key); PN_CHECK_STR(key);
char *k = PN_STR_PTR(key); char *k = PN_STR_PTR(key);
if (!strcmp(k, "file")) { PN_CHECK_STR(value); } if (!strcmp(k, "file")) { PN_CHECK_STR(value); }
Expand All @@ -1499,17 +1499,17 @@ static PN aio_process_options_set(Potion *P, PN cl, PN self, PN key, PN value) {
else if (!strcmp(k, "uid")) { PN_CHECK_INT(value); } //fails on windows! else if (!strcmp(k, "uid")) { PN_CHECK_INT(value); } //fails on windows!
else if (!strcmp(k, "flags")) { PN_CHECK_INT(value); } else if (!strcmp(k, "flags")) { PN_CHECK_INT(value); }
else if (!strcmp(k, "args")) { else if (!strcmp(k, "args")) {
if (!value || !PN_IS_TUPLE(value)) return potion_type_error_want(P, value, "Tuple"); if (!value || !PN_IS_TUPLE(value)) return potion_type_error_want(P, "value", value, "Tuple");
vPN(Tuple) t = PN_GET_TUPLE(value); vPN(Tuple) t = PN_GET_TUPLE(value);
PN_TUPLE_EACH(t, i, v, { PN_CHECK_STR(v); }); PN_TUPLE_EACH(t, i, v, { PN_CHECK_STR(v); });
} }
else if (!strcmp(k, "env")) { else if (!strcmp(k, "env")) {
if (!value || !PN_IS_TUPLE(value)) return potion_type_error_want(P, value, "Tuple"); if (!value || !PN_IS_TUPLE(value)) return potion_type_error_want(P, "value", value, "Tuple");
vPN(Tuple) t = PN_GET_TUPLE(value); vPN(Tuple) t = PN_GET_TUPLE(value);
PN_TUPLE_EACH(t, i, v, { PN_CHECK_STR(v); }); PN_TUPLE_EACH(t, i, v, { PN_CHECK_STR(v); });
} }
else if (!strcmp(k, "stdio")) { else if (!strcmp(k, "stdio")) {
if (!value || !PN_IS_TUPLE(value)) return potion_type_error_want(P, value, "Tuple"); if (!value || !PN_IS_TUPLE(value)) return potion_type_error_want(P, "value", value, "Tuple");
vPN(Tuple) t = PN_GET_TUPLE(value); //all must be numbers vPN(Tuple) t = PN_GET_TUPLE(value); //all must be numbers
PN_TUPLE_EACH(t, i, v, { PN_CHECK_INT(v); }); PN_TUPLE_EACH(t, i, v, { PN_CHECK_INT(v); });
} }
Expand Down
23 changes: 14 additions & 9 deletions test/tables/slice.pn
Original file line number Original file line Diff line number Diff line change
@@ -1,10 +1,15 @@
t = (0,1,2) t = (0,1,2)
(t slice, t slice(0,nil) say #=> (0, 1, 2)
t slice(1), t slice(1,nil) say #=> (1, 2)
t slice(0,2), t slice(0,1) say #=> (0, 1)
t slice(-1), t slice(-1,nil) say #=> (2)
t slice(1,1), t slice(1,1) say #=> (1)
t slice(1,-1), t slice(1,-1) say #=> (1, 2)
t slice(2,-1), t slice(2,-1) say #=> (2)
t slice(-1,-1)) join(",") print t slice(-1,-2) say #=> (1, 2)
#=> (0, 1, 2),(1, 2),(0, 1),(2),(1),(0),(1),(1)nil
t = (0="a", 1="b", 2="c")
t slice say #=> (0=a, 2=c, 1=b)
t slice((1,2,3)) keys sort(true) say #=> (1, 2)
t slice(()) say #=> ()
#=> nil

0 comments on commit c2314c7

Please sign in to comment.