factor/native/sbuf.c

148 lines
3.0 KiB
C
Raw Normal View History

2004-07-16 02:26:21 -04:00
#include "factor.h"
SBUF* sbuf(FIXNUM capacity)
{
2004-08-05 16:49:55 -04:00
SBUF* sbuf = allot_object(SBUF_TYPE,sizeof(SBUF));
2004-07-16 02:26:21 -04:00
sbuf->top = 0;
sbuf->string = string(capacity,'\0');
return sbuf;
}
void primitive_sbuf(void)
{
drepl(tag_object(sbuf(to_fixnum(dpeek()))));
2004-07-16 02:26:21 -04:00
}
void primitive_sbuf_length(void)
{
drepl(tag_fixnum(untag_sbuf(dpeek())->top));
2004-07-16 02:26:21 -04:00
}
void primitive_set_sbuf_length(void)
{
SBUF* sbuf = untag_sbuf(dpop());
2004-07-29 17:18:41 -04:00
FIXNUM length = to_fixnum(dpop());
2004-07-16 02:26:21 -04:00
if(length < 0)
range_error(tag_object(sbuf),length,sbuf->top);
2004-08-27 02:09:24 -04:00
sbuf->top = length;
if(length > sbuf->string->capacity)
2004-07-16 02:26:21 -04:00
sbuf->string = grow_string(sbuf->string,length,F);
}
void primitive_sbuf_nth(void)
{
SBUF* sbuf = untag_sbuf(dpop());
2004-07-29 17:18:41 -04:00
CELL index = to_fixnum(dpop());
2004-07-16 02:26:21 -04:00
if(index < 0 || index >= sbuf->top)
range_error(tag_object(sbuf),index,sbuf->top);
dpush(string_nth(sbuf->string,index));
2004-07-16 02:26:21 -04:00
}
2004-08-27 02:09:24 -04:00
void sbuf_ensure_capacity(SBUF* sbuf, FIXNUM top)
2004-07-16 02:26:21 -04:00
{
STRING* string = sbuf->string;
CELL capacity = string->capacity;
if(top >= capacity)
sbuf->string = grow_string(string,top * 2 + 1,F);
sbuf->top = top;
}
void set_sbuf_nth(SBUF* sbuf, CELL index, CHAR value)
{
if(index < 0)
range_error(tag_object(sbuf),index,sbuf->top);
else if(index >= sbuf->top)
sbuf_ensure_capacity(sbuf,index + 1);
/* the following does not check bounds! */
set_string_nth(sbuf->string,index,value);
}
void primitive_set_sbuf_nth(void)
{
SBUF* sbuf = untag_sbuf(dpop());
2004-07-29 17:18:41 -04:00
FIXNUM index = to_fixnum(dpop());
2004-07-16 02:26:21 -04:00
CELL value = dpop();
set_sbuf_nth(sbuf,index,value);
}
void sbuf_append_string(SBUF* sbuf, STRING* string)
{
CELL top = sbuf->top;
CELL strlen = string->capacity;
sbuf_ensure_capacity(sbuf,top + strlen);
2004-08-04 22:43:58 -04:00
memcpy((void*)((CELL)sbuf->string + sizeof(STRING) + top * CHARS),
(void*)((CELL)string + sizeof(STRING)),strlen * CHARS);
2004-07-16 02:26:21 -04:00
}
void primitive_sbuf_append(void)
{
SBUF* sbuf = untag_sbuf(dpop());
2004-07-16 02:26:21 -04:00
CELL object = dpop();
switch(type_of(object))
{
case FIXNUM_TYPE:
2004-07-29 17:18:41 -04:00
case BIGNUM_TYPE:
set_sbuf_nth(sbuf,sbuf->top,to_fixnum(object));
break;
case STRING_TYPE:
2004-07-16 02:26:21 -04:00
sbuf_append_string(sbuf,untag_string(object));
break;
default:
2004-08-29 01:04:42 -04:00
type_error(TEXT_TYPE,object);
break;
}
2004-07-16 02:26:21 -04:00
}
void primitive_sbuf_to_string(void)
{
SBUF* sbuf = untag_sbuf(dpeek());
STRING* s = string_clone(sbuf->string,sbuf->top);
hash_string(s);
drepl(tag_object(s));
2004-07-16 02:26:21 -04:00
}
2004-08-25 20:51:19 -04:00
void primitive_sbuf_reverse(void)
{
SBUF* sbuf = untag_sbuf(dpop());
string_reverse(sbuf->string,sbuf->top);
2004-08-25 20:51:19 -04:00
}
void primitive_sbuf_clone(void)
2004-08-13 18:43:03 -04:00
{
SBUF* s = untag_sbuf(dpeek());
SBUF* new_s = sbuf(s->top);
sbuf_append_string(new_s,s->string);
drepl(tag_object(new_s));
}
bool sbuf_eq(SBUF* s1, SBUF* s2)
{
if(s1->top == s2->top)
2004-08-12 02:13:43 -04:00
return (string_compare_head(s1->string,s2->string,s1->top) == 0);
else
return false;
}
void primitive_sbuf_eq(void)
{
SBUF* s1 = untag_sbuf(dpop());
CELL with = dpop();
if(typep(SBUF_TYPE,with))
dpush(tag_boolean(sbuf_eq(s1,(SBUF*)UNTAG(with))));
else
dpush(F);
}
2004-07-16 02:26:21 -04:00
void fixup_sbuf(SBUF* sbuf)
{
2004-08-12 23:40:28 -04:00
sbuf->string = fixup_untagged_string(sbuf->string);
2004-07-16 02:26:21 -04:00
}
void collect_sbuf(SBUF* sbuf)
{
2004-08-12 23:40:28 -04:00
sbuf->string = copy_untagged_string(sbuf->string);
2004-07-16 02:26:21 -04:00
}