瀏覽代碼

Add String.bitSet, .bitClear, .bitInvert, bitTest, .charClass, .compareFrom.

master
Ian Piumarta 11 月之前
父節點
當前提交
f2e790cb26
共有 1 個檔案被更改,包括 155 行新增28 行删除
  1. +155
    -28
      minproto.leg

+ 155
- 28
minproto.leg 查看文件

@ -1,6 +1,6 @@
# minproto.leg -- minimal prototype langauge for semantic experiments
#
# last edited: 2024-05-30 14:46:11 by piumarta on zora
# last edited: 2024-05-30 18:02:51 by piumarta on zora
%{
;
@ -342,7 +342,8 @@ oop newStringLen(char *value, int length)
{
oop obj = make(String);
char *str = xmallocAtomic(length+1);
memcpy(str, value, length);
if (value) memcpy(str, value, length);
else if (length) memset(str, 0, length);
str[length] = 0;
_set(obj, String,length, length);
_set(obj, String,value, str);
@ -3710,6 +3711,126 @@ char *strnstr(char *s, char *t, int slen)
#endif
oop String_bitSet(oop string, int bit)
{
int index = bit / 8, shift = bit % 8;
while (index >= _get(string, String,length)) String_append(string, 0);
_get(string, String,value)[index] |= (1 << shift);
return string;
}
oop prim_String_bitSet(oop func, oop self, oop args, oop env)
{
return String_bitSet(self, _integerValue(getArgType(args, 0, Integer, "String.bitSet")));
}
oop String_bitClear(oop string, int bit)
{
int index = bit / 8, shift = bit % 8;
while (index >= _get(string, String,length)) String_append(string, 0);
_get(string, String,value)[index] &= ~(1 << shift);
return string;
}
oop prim_String_bitClear(oop func, oop self, oop args, oop env)
{
return String_bitClear(self, _integerValue(getArgType(args, 0, Integer, "String.bitClear")));
}
oop String_bitInvert(oop string, int bit)
{
int index = bit / 8, shift = bit % 8;
while (index >= _get(string, String,length)) String_append(string, 0);
_get(string, String,value)[index] ^ (1 << shift);
return string;
}
oop prim_String_bitInvert(oop func, oop self, oop args, oop env)
{
return String_bitInvert(self, _integerValue(getArgType(args, 0, Integer, "String.bitInvert")));
}
int String_bitTest(oop string, int bit)
{
int index = bit / 8, shift = bit % 8;
if (index >= _get(string, String,length)) return 0;
return (_get(string, String,value)[index] >> shift) & 1;
}
oop prim_String_bitTest(oop func, oop self, oop args, oop env)
{
return newBoolean(String_bitTest(self, _integerValue(getArgType(args, 0, Integer, "String.bitTest"))));
}
// a bit silly having this as a primitive...
int charClassNext(char **ppc)
{
int c = *(*ppc)++;
if ('\\' == c && **ppc) {
c = *(*ppc)++;
switch (c) {
case 'a': return '\a';
case 'b': return '\b';
case 'f': return '\f';
case 'n': return '\n';
case 'r': return '\r';
case 't': return '\t';
case 'v': return '\v';
case '0'...'7': {
c &= 7;
if ('0' <= **ppc && **ppc <= '7') c = (c << 3) | (*(*ppc)++ & 7);
if ('0' <= **ppc && **ppc <= '7') c = (c << 3) | (*(*ppc)++ & 7);
return c;
}
case 'x': {
c = 0;
int d;
while ((d = digitValue(**ppc, 16)) >= 0) c = (c << 4) | d, ++*ppc;
return c;
}
}
}
return c;
}
oop prim_String_charClass(oop func, oop self, oop args, oop env)
{
oop bits = newStringLen(0, 0);
char *spec = String_content(self);
int invert = 0;
if ((invert = ('^' == spec[0]))) ++spec;
while (*spec) {
int c = charClassNext(&spec);
if ('-' == spec[0] && spec[1]) {
++spec;
int d = charClassNext(&spec);
for (int i = c; i <= d; ++i) String_bitSet(bits, i);
continue;
}
String_bitSet(bits, c);
}
if (invert) {
int length = _get(bits, String,length);
while (length < 16) String_append(bits, 0), ++length;
char *value = _get(bits, String,value);
for (int i = 0; i < length; ++i) value[i] ^= 0xff;
}
return bits;
}
oop prim_String_compareFrom(oop func, oop self, oop args, oop env)
{
int off = _integerValue(getArgType(args, 0, Integer, "String.compareFrom"));
oop str = getArgType(args, 1, String, "String.compareFrom");
char *myval = _get(self, String,value);
int mylen = _get(self, String,length);
char *qqval = _get(str, String,value);
int qqlen = _get(str, String,length);
if (off + qqlen > mylen) return nil;
return newInteger(strncmp(myval + off, qqval, qqlen));
}
oop prim_Object_includes(oop func, oop self, oop args, oop env)
{ assert(is(Object, args));
if (!is(Object, self)) return nil;
@ -4204,32 +4325,38 @@ int main(int argc, char **argv)
# define method(CLASS, NAME, FUNC) Object_put(p##CLASS, intern(#NAME), newPrimitive(FUNC, newString(#CLASS"."#NAME)))
method(Object,new, prim_new );
method(Object,push, prim_Object_push );
method(Object,pop, prim_Object_pop );
method(Object,length, prim_length );
method(Object,keys, prim_keys );
method(Object,allKeys, prim_allKeys );
method(Object,findKey, prim_findKey );
method(Object,sorted, prim_sorted );
method(Object,reversed, prim_reversed );
method(Object,includes, prim_Object_includes );
method(String,new, prim_String_new );
method(String,escaped, prim_String_escaped );
method(String,unescaped, prim_String_unescaped);
method(String,push, prim_String_push );
method(String,pop, prim_String_pop );
method(String,asInteger, prim_String_asInteger);
method(String,asFloat, prim_String_asFloat );
method(String,asSymbol, prim_String_asSymbol );
method(String,includes, prim_String_includes );
method(String,sliced, prim_String_sliced );
method(Symbol,asString, prim_Symbol_asString );
method(Symbol,setopt, prim_Symbol_setopt );
method(Symbol,getopt, prim_Symbol_getopt );
method(Symbol,defined, prim_Symbol_defined );
method(Symbol,define, prim_Symbol_define );
method(Symbol,value, prim_Symbol_value );
method(Object,new, prim_new );
method(Object,push, prim_Object_push );
method(Object,pop, prim_Object_pop );
method(Object,length, prim_length );
method(Object,keys, prim_keys );
method(Object,allKeys, prim_allKeys );
method(Object,findKey, prim_findKey );
method(Object,sorted, prim_sorted );
method(Object,reversed, prim_reversed );
method(Object,includes, prim_Object_includes );
method(String,new, prim_String_new );
method(String,escaped, prim_String_escaped );
method(String,unescaped, prim_String_unescaped );
method(String,push, prim_String_push );
method(String,pop, prim_String_pop );
method(String,asInteger, prim_String_asInteger );
method(String,asFloat, prim_String_asFloat );
method(String,asSymbol, prim_String_asSymbol );
method(String,includes, prim_String_includes );
method(String,sliced, prim_String_sliced );
method(String,bitSet, prim_String_bitSet );
method(String,bitClear, prim_String_bitClear );
method(String,bitInvert, prim_String_bitInvert );
method(String,bitTest, prim_String_bitTest );
method(String,charClass, prim_String_charClass );
method(String,compareFrom, prim_String_compareFrom );
method(Symbol,asString, prim_Symbol_asString );
method(Symbol,setopt, prim_Symbol_setopt );
method(Symbol,getopt, prim_Symbol_getopt );
method(Symbol,defined, prim_Symbol_defined );
method(Symbol,define, prim_Symbol_define );
method(Symbol,value, prim_Symbol_value );
method(Symbol,allInstances, prim_Symbol_allInstances);
# undef method

Loading…
取消
儲存