Cleanup and useful builtins

This commit is contained in:
K. Lange 2021-01-09 10:12:50 +09:00
parent a8f95c22a8
commit 656942f612
6 changed files with 76 additions and 17 deletions

View File

@ -842,7 +842,9 @@ There is a single, shared VM state. `krk_initVM()` will initialize the compiler
`krk_interpret` compiles and executes a block of code and takes the following arguments:
```c
KrkValue krk_interpret(const char *sourceText, int newModuleScope, char *fromName, char *fromFile);
```
If `newModuleScope` is non-zero, the interpreter will parse code in the context of a new _module_ and the `KrkValue` returned will be a `module` object.
@ -948,8 +950,8 @@ Here we have created a new class named `MyNameClass` and exposed it through the
```c
myNewClass->base = vm.objectClass; \
krk_tableAddAll(&vm.objectClass->methods, &myNewClass->methods); \
myNewClass->base = vm.objectClass;
krk_tableAddAll(&vm.objectClass->methods, &myNewClass->methods);
```
We also want to make sure that our new class fits into the general inheritence hierarchy, which typically means inheriting from `vm.objectClass` - we do this by setting our new class's `base` pointer to `vm.objectClass` and copying `vm.objectClass`'s method table. Now we can start customizing our class with its own methods.

View File

@ -46,6 +46,38 @@ const char krk_builtinsSrc[] =
" def items(self):\n"
" return [(k,self[k]) for k in self.keys()]\n"
"\n"
"class set():\n"
" def __init__(self, iter=[]):\n"
" self._dict = {}\n"
" self.__inrepr = 0\n"
" for v in iter:\n"
" self._dict[v] = 1\n"
" def __contains__(self, v):\n"
" return v in self._dict\n"
" def __repr__(self):\n"
" if self.__inrepr: return '{}' # sets are supposed to be unhashable, but whatever\n"
" let b='{'+', '.join([repr(k) for k in self._dict.keys()])+'}'\n"
" self.__inrepr = 0\n"
" return b\n"
" def add(self,v):\n"
" self._dict[v] = 1\n"
" def __iter__(self):\n"
" return self._dict.keys().__iter__()\n"
"\n"
"__builtins__.set = set\n"
"\n"
"def any(iter):\n"
" for v in iter:\n"
" if v: return True\n"
" return False\n"
"__builtins__.any = any\n"
"\n"
"def all(iter):\n"
" for v in iter:\n"
" if not v: return False\n"
" return True\n"
"__builtins__.all = all\n"
"\n"
"class Helper():\n"
" '''You seem to already know how to use this.'''\n"
" def __call__(self,obj=None):\n"

View File

@ -45,6 +45,38 @@ class dict():
def items(self):
return [(k,self[k]) for k in self.keys()]
class set():
def __init__(self, iter=[]):
self._dict = {}
self.__inrepr = 0
for v in iter:
self._dict[v] = 1
def __contains__(self, v):
return v in self._dict
def __repr__(self):
if self.__inrepr: return '{}' # sets are supposed to be unhashable, but whatever
let b='{'+', '.join([repr(k) for k in self._dict.keys()])+'}'
self.__inrepr = 0
return b
def add(self,v):
self._dict[v] = 1
def __iter__(self):
return self._dict.keys().__iter__()
__builtins__.set = set
def any(iter):
for v in iter:
if v: return True
return False
__builtins__.any = any
def all(iter):
for v in iter:
if not v: return False
return True
__builtins__.all = all
class Helper():
'''You seem to already know how to use this.'''
def __call__(self,obj=None):

View File

@ -2,16 +2,6 @@ from fileio import open
let f = open('test/day4.in')
let lines = f.read().split('\n')[:-1]
def any(iterator):
for v in iterator:
if v: return True
return False
def all(iterator):
for v in iterator:
if not v: return False
return True
def is_digits(val, cnt):
if len(val) != cnt:
return False

View File

@ -1 +1 @@
['', 'Kuroko is a bytecode-interpreted, dynamic, strongly-typed language with syntax similar to Python.', '', 'The bytecode VM / compiler is substantially based on Robert Nystrom\'s [_Crafting Interpreters_](https://craftinginterpreters.com/).']
['# Kuroko - A bytecode-compiled scripting language', '', 'Kuroko is a bytecode-interpreted, dynamic, strongly-typed language with syntax similar to Python.', '']

9
vm.c
View File

@ -1120,8 +1120,6 @@ _finishArg:
*
* If callValue returns 0, the VM should already be in the exception state
* and it is not necessary to raise another exception.
*
* TODO: Instances with __call__ method.
*/
int krk_callValue(KrkValue callee, int argCount, int extra) {
if (IS_OBJECT(callee)) {
@ -1700,7 +1698,7 @@ static KrkValue _string_join(int argc, KrkValue argv[], int hasKw) {
/* TODO: Support any object with an __iter__ - kinda need an internal method to do that well. */
if (!IS_INSTANCE(argv[1]) || !AS_INSTANCE(argv[1])->_internal || !((KrkObj*)AS_INSTANCE(argv[1])->_internal)->type == OBJ_FUNCTION) {
krk_runtimeError(vm.exceptions.typeError, "*expresssion value is not a list.");
krk_runtimeError(vm.exceptions.typeError, "str.join(): expected a list");
return NONE_VAL();
}
@ -1774,6 +1772,10 @@ static int charIn(char c, const char * str) {
return 0;
}
/**
* Implements all three of strip, lstrip, rstrip.
* Set which = 0, 1, 2 respectively
*/
static KrkValue _string_strip_shared(int argc, KrkValue argv[], int which) {
if (!IS_STRING(argv[0])) return NONE_VAL();
size_t start = 0;
@ -2181,6 +2183,7 @@ static KrkValue _repr_str(int argc, KrkValue argv[]) {
case '\r': *(tmp++) = '\\'; *(tmp++) = 'r'; break;
case '\t': *(tmp++) = '\\'; *(tmp++) = 't'; break;
case '\'': *(tmp++) = '\\'; *(tmp++) = '\''; break;
case '\\': *(tmp++) = '\\'; *(tmp++) = '\\'; break;
case 27: *(tmp++) = '\\'; *(tmp++) = '['; break;
default: *(tmp++) = *c; break;
}