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: `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); 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. 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 ```c
myNewClass->base = vm.objectClass; \ myNewClass->base = vm.objectClass;
krk_tableAddAll(&vm.objectClass->methods, &myNewClass->methods); \ 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. 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" " def items(self):\n"
" return [(k,self[k]) for k in self.keys()]\n" " return [(k,self[k]) for k in self.keys()]\n"
"\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" "class Helper():\n"
" '''You seem to already know how to use this.'''\n" " '''You seem to already know how to use this.'''\n"
" def __call__(self,obj=None):\n" " def __call__(self,obj=None):\n"

View File

@ -45,6 +45,38 @@ class dict():
def items(self): def items(self):
return [(k,self[k]) for k in self.keys()] 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(): class Helper():
'''You seem to already know how to use this.''' '''You seem to already know how to use this.'''
def __call__(self,obj=None): def __call__(self,obj=None):

View File

@ -2,16 +2,6 @@ from fileio import open
let f = open('test/day4.in') let f = open('test/day4.in')
let lines = f.read().split('\n')[:-1] 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): def is_digits(val, cnt):
if len(val) != cnt: if len(val) != cnt:
return False 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.', '']

11
vm.c
View File

@ -1120,8 +1120,6 @@ _finishArg:
* *
* If callValue returns 0, the VM should already be in the exception state * If callValue returns 0, the VM should already be in the exception state
* and it is not necessary to raise another exception. * and it is not necessary to raise another exception.
*
* TODO: Instances with __call__ method.
*/ */
int krk_callValue(KrkValue callee, int argCount, int extra) { int krk_callValue(KrkValue callee, int argCount, int extra) {
if (IS_OBJECT(callee)) { 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. */ /* 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) { 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(); return NONE_VAL();
} }
@ -1774,6 +1772,10 @@ static int charIn(char c, const char * str) {
return 0; 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) { static KrkValue _string_strip_shared(int argc, KrkValue argv[], int which) {
if (!IS_STRING(argv[0])) return NONE_VAL(); if (!IS_STRING(argv[0])) return NONE_VAL();
size_t start = 0; size_t start = 0;
@ -2180,7 +2182,8 @@ static KrkValue _repr_str(int argc, KrkValue argv[]) {
case '\n': *(tmp++) = '\\'; *(tmp++) = 'n'; break; case '\n': *(tmp++) = '\\'; *(tmp++) = 'n'; break;
case '\r': *(tmp++) = '\\'; *(tmp++) = 'r'; break; case '\r': *(tmp++) = '\\'; *(tmp++) = 'r'; break;
case '\t': *(tmp++) = '\\'; *(tmp++) = 't'; break; case '\t': *(tmp++) = '\\'; *(tmp++) = 't'; break;
case '\'': *(tmp++) = '\\'; *(tmp++) = '\''; break; case '\'': *(tmp++) = '\\'; *(tmp++) = '\''; break;
case '\\': *(tmp++) = '\\'; *(tmp++) = '\\'; break;
case 27: *(tmp++) = '\\'; *(tmp++) = '['; break; case 27: *(tmp++) = '\\'; *(tmp++) = '['; break;
default: *(tmp++) = *c; break; default: *(tmp++) = *c; break;
} }