Add string iterators

This commit is contained in:
K. Lange 2021-01-04 19:34:56 +09:00
parent 7b8df5d4da
commit f1ebada908
4 changed files with 1097 additions and 0 deletions

1000
test/day2.in Normal file

File diff suppressed because it is too large Load Diff

34
test/day2.krk Normal file
View File

@ -0,0 +1,34 @@
from fileio import open
let f = open('test/day2.in')
let lines = f.read().split('\n')[:-1]
def check_first(policy_low, policy_high, letter, password):
let count = 0
for l in password:
if l == letter:
count += 1
return count >= policy_low and count <= policy_high
def check_second(policy_low, policy_high, letter, password):
let count = 0
if password[policy_low-1] == letter:
count += 1
if password[policy_high-1] == letter:
count += 1
return count == 1
let valid = 0
for line in lines:
let s = line.split(': ',1)
let password = s[1]
let policy = s[0]
s = policy.split('-',1)
let policy_low = int(s[0])
s = s[1].split(' ',1)
let policy_high = int(s[0])
let letter = s[1]
let is_valid = check_second(policy_low, policy_high, letter, password)
print policy_low, policy_high, letter, password, is_valid
if is_valid:
valid += 1
print valid

62
vm.c
View File

@ -1926,6 +1926,63 @@ static KrkValue _repr(int argc, KrkValue argv[]) {
return krk_callSimple(krk_peek(0), 0, 1);
}
static KrkValue _striter_init(int argc, KrkValue argv[]) {
if (!IS_INSTANCE(argv[0]) || AS_INSTANCE(argv[0])->_class != vm.baseClasses.striteratorClass) {
krk_runtimeError(vm.exceptions.typeError, "Tried to call striterator.__init__() on something not a str iterator");
}
if (argc < 2 || !IS_STRING(argv[1])) {
krk_runtimeError(vm.exceptions.argumentError, "Expected a str.");
}
KrkInstance * self = AS_INSTANCE(argv[0]);
krk_push(argv[0]);
krk_attachNamedValue(&self->fields, "s", argv[1]);
krk_attachNamedValue(&self->fields, "i", INTEGER_VAL(0));
krk_pop();
return argv[0];
}
static KrkValue _striter_call(int argc, KrkValue argv[]) {
if (!IS_INSTANCE(argv[0]) || AS_INSTANCE(argv[0])->_class != vm.baseClasses.striteratorClass) {
krk_runtimeError(vm.exceptions.typeError, "Tried to call striterator.__call__() on something not a str iterator");
}
KrkInstance * self = AS_INSTANCE(argv[0]);
KrkValue _str;
KrkValue _counter;
const char * errorStr = NULL;
if (!krk_tableGet(&self->fields, OBJECT_VAL(S("s")), &_str)) {
errorStr = "no str pointer";
goto _corrupt;
}
if (!krk_tableGet(&self->fields, OBJECT_VAL(S("i")), &_counter)) {
errorStr = "no index";
goto _corrupt;
}
if ((size_t)AS_INTEGER(_counter) >= AS_STRING(_str)->length) {
return argv[0];
} else {
krk_attachNamedValue(&self->fields, "i", INTEGER_VAL(AS_INTEGER(_counter)+1));
return OBJECT_VAL(krk_copyString(&AS_CSTRING(_str)[AS_INTEGER(_counter)],1));
}
_corrupt:
krk_runtimeError(vm.exceptions.typeError, "Corrupt str iterator: %s", errorStr);
return NONE_VAL();
}
static KrkValue _str_iter(int argc, KrkValue argv[]) {
KrkInstance * output = krk_newInstance(vm.baseClasses.striteratorClass);
krk_push(OBJECT_VAL(output));
_striter_init(3, (KrkValue[]){krk_peek(0), argv[0]});
krk_pop();
return OBJECT_VAL(output);
}
static KrkValue _listiter_init(int argc, KrkValue argv[]) {
if (!IS_INSTANCE(argv[0]) || AS_INSTANCE(argv[0])->_class != vm.baseClasses.listiteratorClass) {
krk_runtimeError(vm.exceptions.typeError, "Tried to call listiterator.__init__() on something not a list iterator");
@ -2172,6 +2229,7 @@ void krk_initVM(int flags) {
krk_defineNative(&vm.baseClasses.strClass->methods, ".__getslice__", _string_get_slice);
krk_defineNative(&vm.baseClasses.strClass->methods, ".__ord__", _char_to_int);
krk_defineNative(&vm.baseClasses.strClass->methods, ".__contains__", _string_contains);
krk_defineNative(&vm.baseClasses.strClass->methods, ".__iter__", _str_iter);
krk_defineNative(&vm.baseClasses.strClass->methods, ".format", _string_format);
krk_defineNative(&vm.baseClasses.strClass->methods, ".join", _string_join);
krk_defineNative(&vm.baseClasses.strClass->methods, ".split", _string_split);
@ -2204,6 +2262,10 @@ void krk_initVM(int flags) {
krk_defineNative(&vm.baseClasses.listiteratorClass->methods, ".__init__", _listiter_init);
krk_defineNative(&vm.baseClasses.listiteratorClass->methods, ".__call__", _listiter_call);
ADD_BASE_CLASS(vm.baseClasses.striteratorClass, "striterator", vm.objectClass);
krk_defineNative(&vm.baseClasses.striteratorClass->methods, ".__init__", _striter_init);
krk_defineNative(&vm.baseClasses.striteratorClass->methods, ".__call__", _striter_call);
ADD_BASE_CLASS(vm.baseClasses.rangeClass, "range", vm.objectClass);
krk_attachNamedObject(&vm.globals, "range", (KrkObj*)vm.baseClasses.rangeClass);
krk_defineNative(&vm.baseClasses.rangeClass->methods, ".__init__", _range_init);

1
vm.h
View File

@ -90,6 +90,7 @@ typedef struct {
KrkClass * listiteratorClass;
KrkClass * rangeClass;
KrkClass * rangeiteratorClass;
KrkClass * striteratorClass;
} baseClasses;
KrkValue currentException;