mirror of
https://github.com/justinethier/cyclone.git
synced 2025-07-07 05:06:36 +02:00
More integer_type conversions
This commit is contained in:
parent
d0efac2035
commit
33b56d24ea
2 changed files with 83 additions and 32 deletions
|
@ -208,6 +208,8 @@ typedef long tag_type;
|
||||||
* 0x01 - integer (in progress)
|
* 0x01 - integer (in progress)
|
||||||
* 0x10 - char
|
* 0x10 - char
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO: does this break negative numbers (IE, overwrite sign bit in 2's comp?)? may need a more sophisticated scheme to handle 31-bit numbers. also, ideally want to use 63 bits on a 64-bit system
|
||||||
#define obj_is_int(x) ((unsigned long)(x) & (unsigned long)1)
|
#define obj_is_int(x) ((unsigned long)(x) & (unsigned long)1)
|
||||||
#define obj_obj2int(x) ((int)(x)>>1)
|
#define obj_obj2int(x) ((int)(x)>>1)
|
||||||
#define obj_int2obj(c) ((void *)((((int)c)<<1) | 1))
|
#define obj_int2obj(c) ((void *)((((int)c)<<1) | 1))
|
||||||
|
|
113
runtime.c
113
runtime.c
|
@ -949,17 +949,23 @@ object Cyc_vector_set(void *data, object v, object k, object obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
object Cyc_vector_ref(void *data, object v, object k) {
|
object Cyc_vector_ref(void *data, object v, object k) {
|
||||||
|
int idx;
|
||||||
if (nullp(v) || is_value_type(v) || ((list)v)->tag != vector_tag) {
|
if (nullp(v) || is_value_type(v) || ((list)v)->tag != vector_tag) {
|
||||||
Cyc_rt_raise_msg(data, "vector-ref - invalid parameter, expected vector\n");
|
Cyc_rt_raise_msg(data, "vector-ref - invalid parameter, expected vector\n");
|
||||||
}
|
}
|
||||||
if (nullp(k) || is_value_type(k) || ((list)k)->tag != integer_tag) {
|
if ((!obj_is_int(k)) && (nullp(k) || is_value_type(k) || ((list)k)->tag != integer_tag)) {
|
||||||
Cyc_rt_raise_msg(data, "vector-ref - invalid parameter, expected integer\n");
|
Cyc_rt_raise_msg(data, "vector-ref - invalid parameter, expected integer\n");
|
||||||
}
|
}
|
||||||
if (integer_value(k) < 0 || integer_value(k) >= ((vector)v)->num_elt) {
|
if (obj_is_int(k)) {
|
||||||
Cyc_rt_raise2(data, "vector-ref - invalid index", k);
|
idx = obj_obj2int(k);
|
||||||
|
} else {
|
||||||
|
idx = integer_value(k);
|
||||||
|
}
|
||||||
|
if (idx < 0 || idx >= ((vector)v)->num_elt) {
|
||||||
|
Cyc_rt_raise2(data, "vector-ref - invalid index", obj_int2obj(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((vector)v)->elts[((integer_type *)k)->value];
|
return ((vector)v)->elts[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
integer_type Cyc_vector_length(void *data, object v) {
|
integer_type Cyc_vector_length(void *data, object v) {
|
||||||
|
@ -981,10 +987,30 @@ integer_type Cyc_length(void *data, object l){
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Cyc_vector_length2(void *data, object v) {
|
||||||
|
if (!nullp(v) && !is_value_type(v) && ((list)v)->tag == vector_tag) {
|
||||||
|
return obj_int2obj(((vector)v)->num_elt);
|
||||||
|
}
|
||||||
|
Cyc_rt_raise_msg(data, "vector-length - invalid parameter, expected vector\n"); }
|
||||||
|
|
||||||
|
object Cyc_length2(void *data, object l){
|
||||||
|
int len = 0;
|
||||||
|
while(!nullp(l)){
|
||||||
|
if (is_value_type(l) || ((list)l)->tag != cons_tag){
|
||||||
|
Cyc_rt_raise_msg(data, "length - invalid parameter, expected list\n");
|
||||||
|
}
|
||||||
|
l = cdr(l);
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
return obj_int2obj(len);
|
||||||
|
}
|
||||||
|
|
||||||
object Cyc_number2string(void *data, object cont, object n) {
|
object Cyc_number2string(void *data, object cont, object n) {
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
Cyc_check_num(data, n);
|
Cyc_check_num(data, n);
|
||||||
if (type_of(n) == integer_tag) {
|
if (obj_is_int(n)) {
|
||||||
|
snprintf(buffer, 1024, "%d", obj_obj2int(n));
|
||||||
|
}else if (type_of(n) == integer_tag) {
|
||||||
snprintf(buffer, 1024, "%d", ((integer_type *)n)->value);
|
snprintf(buffer, 1024, "%d", ((integer_type *)n)->value);
|
||||||
} else if (type_of(n) == double_tag) {
|
} else if (type_of(n) == double_tag) {
|
||||||
snprintf(buffer, 1024, "%f", ((double_type *)n)->value);
|
snprintf(buffer, 1024, "%f", ((double_type *)n)->value);
|
||||||
|
@ -1015,12 +1041,12 @@ object Cyc_string2symbol(void *data, object str) {
|
||||||
object Cyc_list2string(void *data, object cont, object lst){
|
object Cyc_list2string(void *data, object cont, object lst){
|
||||||
char *buf;
|
char *buf;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
integer_type len;
|
object len;
|
||||||
|
|
||||||
Cyc_check_cons_or_nil(data, lst);
|
Cyc_check_cons_or_nil(data, lst);
|
||||||
|
|
||||||
len = Cyc_length(data, lst); // Inefficient, walks whole list
|
len = Cyc_length2(data, lst); // Inefficient, walks whole list
|
||||||
buf = alloca(sizeof(char) * (len.value + 1));
|
buf = alloca(sizeof(char) * (obj_obj2int(len) + 1));
|
||||||
while(!nullp(lst)){
|
while(!nullp(lst)){
|
||||||
buf[i++] = obj_obj2char(car(lst));
|
buf[i++] = obj_obj2char(car(lst));
|
||||||
lst = cdr(lst);
|
lst = cdr(lst);
|
||||||
|
@ -1032,6 +1058,7 @@ object Cyc_list2string(void *data, object cont, object lst){
|
||||||
return_closcall1(data, cont, &str);}
|
return_closcall1(data, cont, &str);}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: need new versions of string->number that handle int value types
|
||||||
common_type Cyc_string2number2(void *data, int argc, object str, ...)
|
common_type Cyc_string2number2(void *data, int argc, object str, ...)
|
||||||
{
|
{
|
||||||
object base = nil;
|
object base = nil;
|
||||||
|
@ -1138,6 +1165,13 @@ integer_type Cyc_string_cmp(void *data, object str1, object str2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Cyc_string_cmp2(void *data, object str1, object str2) {
|
||||||
|
Cyc_check_str(data, str1);
|
||||||
|
Cyc_check_str(data, str2);
|
||||||
|
return obj_int2obj( strcmp(((string_type *)str1)->str,
|
||||||
|
((string_type *)str2)->str) );
|
||||||
|
}
|
||||||
|
|
||||||
#define Cyc_string_append_va_list(data, argc) { \
|
#define Cyc_string_append_va_list(data, argc) { \
|
||||||
int i = 0, total_len = 1; \
|
int i = 0, total_len = 1; \
|
||||||
int *len = alloca(sizeof(int) * argc); \
|
int *len = alloca(sizeof(int) * argc); \
|
||||||
|
@ -1185,6 +1219,11 @@ integer_type Cyc_string_length(void *data, object str) {
|
||||||
{ make_int(len, strlen(string_str(str)));
|
{ make_int(len, strlen(string_str(str)));
|
||||||
return len; }}
|
return len; }}
|
||||||
|
|
||||||
|
object Cyc_string_length2(void *data, object str) {
|
||||||
|
Cyc_check_obj(data, string_tag, str);
|
||||||
|
Cyc_check_str(data, str);
|
||||||
|
return obj_int2obj(strlen(string_str(str))); }
|
||||||
|
|
||||||
object Cyc_string_set(void *data, object str, object k, object chr) {
|
object Cyc_string_set(void *data, object str, object k, object chr) {
|
||||||
char *raw;
|
char *raw;
|
||||||
int idx, len;
|
int idx, len;
|
||||||
|
@ -1197,7 +1236,7 @@ object Cyc_string_set(void *data, object str, object k, object chr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
raw = string_str(str);
|
raw = string_str(str);
|
||||||
idx = integer_value(k),
|
idx = obj_is_int(k) ? obj_obj2int(k) : integer_value(k),
|
||||||
len = strlen(raw);
|
len = strlen(raw);
|
||||||
|
|
||||||
Cyc_check_bounds(data, "string-set!", len, idx);
|
Cyc_check_bounds(data, "string-set!", len, idx);
|
||||||
|
@ -1213,7 +1252,7 @@ object Cyc_string_ref(void *data, object str, object k) {
|
||||||
Cyc_check_int(data, k);
|
Cyc_check_int(data, k);
|
||||||
|
|
||||||
raw = string_str(str);
|
raw = string_str(str);
|
||||||
idx = integer_value(k),
|
idx = obj_is_int(k) ? obj_obj2int(k) : integer_value(k),
|
||||||
len = strlen(raw);
|
len = strlen(raw);
|
||||||
|
|
||||||
if (idx < 0 || idx >= len) {
|
if (idx < 0 || idx >= len) {
|
||||||
|
@ -1232,8 +1271,8 @@ object Cyc_substring(void *data, object cont, object str, object start, object e
|
||||||
Cyc_check_int(data, end);
|
Cyc_check_int(data, end);
|
||||||
|
|
||||||
raw = string_str(str);
|
raw = string_str(str);
|
||||||
s = integer_value(start),
|
s = obj_is_int(start) ? obj_obj2int(start) : integer_value(start),
|
||||||
e = integer_value(end),
|
e = obj_is_int(end) ? obj_obj2int(end) : integer_value(end),
|
||||||
len = strlen(raw);
|
len = strlen(raw);
|
||||||
|
|
||||||
if (s > e) {
|
if (s > e) {
|
||||||
|
@ -1317,7 +1356,7 @@ object Cyc_make_vector(void *data, object cont, object len, object fill) {
|
||||||
((vector)v)->hdr.mark = gc_color_red;
|
((vector)v)->hdr.mark = gc_color_red;
|
||||||
((vector)v)->hdr.grayed = 0;
|
((vector)v)->hdr.grayed = 0;
|
||||||
((vector)v)->tag = vector_tag;
|
((vector)v)->tag = vector_tag;
|
||||||
((vector)v)->num_elt = ((integer_type *)len)->value;
|
((vector)v)->num_elt = obj_is_int(len) ? obj_obj2int(len) : ((integer_type *)len)->value;
|
||||||
((vector)v)->elts =
|
((vector)v)->elts =
|
||||||
(((vector)v)->num_elt > 0) ?
|
(((vector)v)->num_elt > 0) ?
|
||||||
(object *)alloca(sizeof(object) * ((vector)v)->num_elt) :
|
(object *)alloca(sizeof(object) * ((vector)v)->num_elt) :
|
||||||
|
@ -1330,17 +1369,17 @@ object Cyc_make_vector(void *data, object cont, object len, object fill) {
|
||||||
|
|
||||||
object Cyc_list2vector(void *data, object cont, object l) {
|
object Cyc_list2vector(void *data, object cont, object l) {
|
||||||
object v = nil;
|
object v = nil;
|
||||||
integer_type len;
|
object len;
|
||||||
object lst = l;
|
object lst = l;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
Cyc_check_cons_or_nil(data, l);
|
Cyc_check_cons_or_nil(data, l);
|
||||||
len = Cyc_length(data, l);
|
len = Cyc_length2(data, l);
|
||||||
v = alloca(sizeof(vector_type));
|
v = alloca(sizeof(vector_type));
|
||||||
((vector)v)->hdr.mark = gc_color_red;
|
((vector)v)->hdr.mark = gc_color_red;
|
||||||
((vector)v)->hdr.grayed = 0;
|
((vector)v)->hdr.grayed = 0;
|
||||||
((vector)v)->tag = vector_tag;
|
((vector)v)->tag = vector_tag;
|
||||||
((vector)v)->num_elt = len.value;
|
((vector)v)->num_elt = obj_obj2int(len);
|
||||||
((vector)v)->elts =
|
((vector)v)->elts =
|
||||||
(((vector)v)->num_elt > 0) ?
|
(((vector)v)->num_elt > 0) ?
|
||||||
(object *)alloca(sizeof(object) * ((vector)v)->num_elt) :
|
(object *)alloca(sizeof(object) * ((vector)v)->num_elt) :
|
||||||
|
@ -1362,19 +1401,27 @@ integer_type Cyc_system(object cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Cyc_system2(object cmd) {
|
||||||
|
if (nullp(cmd) || is_value_type(cmd) || type_of(cmd) != string_tag) {
|
||||||
|
return obj_int2obj(-1);
|
||||||
|
}
|
||||||
|
return obj_int2obj(system(((string_type *)cmd)->str));
|
||||||
|
}
|
||||||
|
|
||||||
integer_type Cyc_char2integer(object chr){
|
integer_type Cyc_char2integer(object chr){
|
||||||
make_int(n, obj_obj2char(chr));
|
make_int(n, obj_obj2char(chr));
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Cyc_char2integer2(object chr){
|
||||||
|
return obj_int2obj(obj_obj2char(chr));
|
||||||
|
}
|
||||||
|
|
||||||
object Cyc_integer2char(void *data, object n){
|
object Cyc_integer2char(void *data, object n){
|
||||||
int val = 0;
|
int val = 0;
|
||||||
|
|
||||||
Cyc_check_int(data, n);
|
Cyc_check_int(data, n);
|
||||||
if (!nullp(n)) {
|
val = (obj_is_int(n) ? obj_obj2int(n) : integer_value(n));
|
||||||
val = ((integer_type *) n)->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj_char2obj(val);
|
return obj_char2obj(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1392,6 +1439,7 @@ object __halt(object obj) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: support for integer value types
|
||||||
#define declare_num_op(FUNC, FUNC_OP, FUNC_APPLY, OP, DIV) \
|
#define declare_num_op(FUNC, FUNC_OP, FUNC_APPLY, OP, DIV) \
|
||||||
common_type FUNC_OP(void *data, object x, object y) { \
|
common_type FUNC_OP(void *data, object x, object y) { \
|
||||||
common_type s; \
|
common_type s; \
|
||||||
|
@ -1981,12 +2029,12 @@ void _string_91cmp(void *data, object cont, object args) {
|
||||||
{ integer_type cmp = Cyc_string_cmp(data, car(args), cadr(args));
|
{ integer_type cmp = Cyc_string_cmp(data, car(args), cadr(args));
|
||||||
return_closcall1(data, cont, &cmp);}}
|
return_closcall1(data, cont, &cmp);}}
|
||||||
void _string_91append(void *data, object cont, object args) {
|
void _string_91append(void *data, object cont, object args) {
|
||||||
integer_type argc = Cyc_length(data, args);
|
object argc = Cyc_length2(data, args);
|
||||||
dispatch(data, argc.value, (function_type)dispatch_string_91append, cont, cont, args); }
|
dispatch(data, obj_obj2int(argc), (function_type)dispatch_string_91append, cont, cont, args); }
|
||||||
void _make_91vector(void *data, object cont, object args) {
|
void _make_91vector(void *data, object cont, object args) {
|
||||||
Cyc_check_num_args(data, "make-vector", 1, args);
|
Cyc_check_num_args(data, "make-vector", 1, args);
|
||||||
{ integer_type argc = Cyc_length(data, args);
|
{ object argc = Cyc_length2(data, args);
|
||||||
if (argc.value >= 2) {
|
if (obj_obj2int(argc) >= 2) {
|
||||||
Cyc_make_vector(data, cont, car(args), cadr(args));}
|
Cyc_make_vector(data, cont, car(args), cadr(args));}
|
||||||
else {
|
else {
|
||||||
Cyc_make_vector(data, cont, car(args), boolean_f);}}}
|
Cyc_make_vector(data, cont, car(args), boolean_f);}}}
|
||||||
|
@ -2053,12 +2101,12 @@ void _Cyc_91write_91char(void *data, object cont, object args) {
|
||||||
return_closcall1(data, cont, Cyc_write_char(data, car(args), cadr(args)));}
|
return_closcall1(data, cont, Cyc_write_char(data, car(args), cadr(args)));}
|
||||||
void _Cyc_91write(void *data, object cont, object args) {
|
void _Cyc_91write(void *data, object cont, object args) {
|
||||||
Cyc_check_num_args(data, "write", 1, args);
|
Cyc_check_num_args(data, "write", 1, args);
|
||||||
{ integer_type argc = Cyc_length(data, args);
|
{ object argc = Cyc_length2(data, args);
|
||||||
dispatch(data, argc.value, (function_type)dispatch_write_va, cont, cont, args); }}
|
dispatch(data, obj_obj2int(argc), (function_type)dispatch_write_va, cont, cont, args); }}
|
||||||
void _display(void *data, object cont, object args) {
|
void _display(void *data, object cont, object args) {
|
||||||
Cyc_check_num_args(data, "display", 1, args);
|
Cyc_check_num_args(data, "display", 1, args);
|
||||||
{ integer_type argc = Cyc_length(data, args);
|
{ object argc = Cyc_length2(data, args);
|
||||||
dispatch(data, argc.value, (function_type)dispatch_display_va, cont, cont, args); }}
|
dispatch(data, obj_obj2int(argc), (function_type)dispatch_display_va, cont, cont, args); }}
|
||||||
void _call_95cc(void *data, object cont, object args){
|
void _call_95cc(void *data, object cont, object args){
|
||||||
Cyc_check_num_args(data, "call/cc", 1, args);
|
Cyc_check_num_args(data, "call/cc", 1, args);
|
||||||
if (eq(boolean_f, Cyc_is_procedure(data, car(args)))) {
|
if (eq(boolean_f, Cyc_is_procedure(data, car(args)))) {
|
||||||
|
@ -2074,6 +2122,7 @@ void _call_95cc(void *data, object cont, object args){
|
||||||
*/
|
*/
|
||||||
object apply(void *data, object cont, object func, object args){
|
object apply(void *data, object cont, object func, object args){
|
||||||
common_type buf;
|
common_type buf;
|
||||||
|
object count;
|
||||||
|
|
||||||
//printf("DEBUG apply: ");
|
//printf("DEBUG apply: ");
|
||||||
//Cyc_display(args);
|
//Cyc_display(args);
|
||||||
|
@ -2097,10 +2146,10 @@ object apply(void *data, object cont, object func, object args){
|
||||||
case closure3_tag:
|
case closure3_tag:
|
||||||
case closure4_tag:
|
case closure4_tag:
|
||||||
case closureN_tag:
|
case closureN_tag:
|
||||||
buf.integer_t = Cyc_length(data, args);
|
count = Cyc_length2(data, args);
|
||||||
// TODO: validate number of args provided:
|
// TODO: validate number of args provided:
|
||||||
Cyc_check_num_args(data, "<procedure>", ((closure)func)->num_args, args); // TODO: could be more efficient, eg: cyc_length(args) is called twice.
|
Cyc_check_num_args(data, "<procedure>", ((closure)func)->num_args, args); // TODO: could be more efficient, eg: cyc_length(args) is called twice.
|
||||||
dispatch(data, buf.integer_t.value, ((closure)func)->fn, func, cont, args);
|
dispatch(data, obj_obj2int(count), ((closure)func)->fn, func, cont, args);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cons_tag:
|
case cons_tag:
|
||||||
|
@ -2866,8 +2915,8 @@ object Cyc_thread_sleep(void *data, object timeout)
|
||||||
{
|
{
|
||||||
struct timespec tim;
|
struct timespec tim;
|
||||||
long value;
|
long value;
|
||||||
Cyc_check_num(data, timeout);
|
Cyc_check_int(data, timeout);
|
||||||
value = ((integer_type *)timeout)->value;
|
value = (obj_is_int(timeout) ? obj_obj2int(timeout) : integer_value(timeout));
|
||||||
tim.tv_sec = value / 1000;
|
tim.tv_sec = value / 1000;
|
||||||
tim.tv_nsec = (value % 1000) * NANOSECONDS_PER_MILLISECOND;
|
tim.tv_nsec = (value % 1000) * NANOSECONDS_PER_MILLISECOND;
|
||||||
nanosleep(&tim, NULL);
|
nanosleep(&tim, NULL);
|
||||||
|
|
Loading…
Add table
Reference in a new issue