do something more straightforward and useful for methods on non-objects
This commit is contained in:
parent
8e5ace5112
commit
ae2e2be15d
12
builtins.krk
12
builtins.krk
@ -16,13 +16,14 @@ class list():
|
||||
for v in i:
|
||||
self.append(v)
|
||||
return self.__len__()
|
||||
def __repr__(self): return self.__str__()
|
||||
def __str__(self):
|
||||
let b="["
|
||||
let l=self.__len__()
|
||||
for i=0,i<l,i=i+1:
|
||||
if i>0:
|
||||
b+=", "
|
||||
b=b+__builtins__.list_get(self._list,i)
|
||||
b+=repr(__builtins__.list_get(self._list,i))
|
||||
return b+"]"
|
||||
def __iter__(self):
|
||||
let m = self
|
||||
@ -47,6 +48,7 @@ class dict():
|
||||
return __builtins__.hash_get(self._map, ind)
|
||||
def __set__(self, ind, val):
|
||||
return __builtins__.hash_set(self._map, ind, val)
|
||||
def __repr__(self): return self.__str__()
|
||||
def __str__(self):
|
||||
let out = "{"
|
||||
let first = True
|
||||
@ -54,7 +56,7 @@ class dict():
|
||||
if not first:
|
||||
out += ", "
|
||||
first = False
|
||||
out = out + v + ": " + self[v]
|
||||
out += repr(v) + ": " + repr(self[v])
|
||||
out += "}"
|
||||
return out
|
||||
def __len__(self):
|
||||
@ -105,9 +107,11 @@ class range:
|
||||
return makeIter(self.min)
|
||||
|
||||
def len(obj=None): return (obj and obj.__len__()) or 0
|
||||
def str(obj=None): return (obj and ("" + obj)) or ""
|
||||
def str(obj=None): return (obj and obj.__str__()) or ""
|
||||
def repr(obj): return obj.__repr__()
|
||||
def int(obj=None): return (obj and obj.__int__()) or 0
|
||||
def float(obj=None): return (obj and obj.__float__()) or 0.0
|
||||
def type(obj): return obj.__class__
|
||||
def dir(obj): return obj.__dir__()
|
||||
|
||||
def help(obj=None):
|
||||
@ -123,7 +127,7 @@ def help(obj=None):
|
||||
except:
|
||||
print "No docstring available for", obj
|
||||
|
||||
export list,dict,range,len,str,int,float,dir,help
|
||||
export list,dict,range,len,str,repr,int,float,dir,help
|
||||
|
||||
__builtins__.module_paths = ["./","./modules/","/home/klange/Projects/kuroko/modules/","/usr/share/kuroko/"]
|
||||
|
||||
|
5
debug.c
5
debug.c
@ -13,14 +13,14 @@ void krk_disassembleChunk(KrkChunk * chunk, const char * name) {
|
||||
#define SIMPLE(opc) case opc: fprintf(stderr, "%s\n", #opc); return offset + 1;
|
||||
#define CONSTANT(opc,more) case opc: { size_t constant = chunk->code[offset + 1]; \
|
||||
fprintf(stderr, "%-16s %4d '", #opc, (int)constant); \
|
||||
krk_printValue(stderr, chunk->constants.values[constant]); \
|
||||
krk_printValueSafe(stderr, chunk->constants.values[constant]); \
|
||||
fprintf(stderr,"' (type=%s)\n", krk_typeName(chunk->constants.values[constant])); \
|
||||
more; \
|
||||
return offset + 2; } \
|
||||
case opc ## _LONG: { size_t constant = (chunk->code[offset + 1] << 16) | \
|
||||
(chunk->code[offset + 2] << 8) | (chunk->code[offset + 3]); \
|
||||
fprintf(stderr, "%-16s %4d '", #opc "_LONG", (int)constant); \
|
||||
krk_printValue(stderr, chunk->constants.values[constant]); \
|
||||
krk_printValueSafe(stderr, chunk->constants.values[constant]); \
|
||||
fprintf(stderr,"' (type=%s)\n", krk_typeName(chunk->constants.values[constant])); \
|
||||
more; \
|
||||
return offset + 4; }
|
||||
@ -81,6 +81,7 @@ size_t krk_disassembleInstruction(KrkChunk * chunk, size_t offset) {
|
||||
SIMPLE(OP_BITAND)
|
||||
SIMPLE(OP_SHIFTLEFT)
|
||||
SIMPLE(OP_SHIFTRIGHT)
|
||||
SIMPLE(OP_BITNEGATE)
|
||||
OPERANDB(OP_DUP)
|
||||
OPERANDB(OP_SWAP)
|
||||
CONSTANT(OP_DEFINE_GLOBAL,(void)0)
|
||||
|
51
object.c
51
object.c
@ -61,52 +61,6 @@ KrkString * krk_copyString(const char * chars, size_t length) {
|
||||
return allocateString(heapChars, length, hash);
|
||||
}
|
||||
|
||||
#define NAME(obj) ((obj)->name ? obj->name->chars : "(unnamed)")
|
||||
void krk_printObject(FILE * f, KrkValue value) {
|
||||
switch (OBJECT_TYPE(value)) {
|
||||
case OBJ_STRING:
|
||||
fprintf(f,"\"");
|
||||
for (char * c = AS_CSTRING(value); *c; ++c) {
|
||||
switch (*c) {
|
||||
/* XXX: Other non-printables should probably be escaped as well. */
|
||||
case '\n': fprintf(f,"\\n"); break;
|
||||
case '\r': fprintf(f,"\\r"); break;
|
||||
case '\t': fprintf(f,"\\t"); break;
|
||||
case '"': fprintf(f,"\\\""); break;
|
||||
case '\033': fprintf(f,"\\["); break;
|
||||
default: fprintf(f,"%c",*c); break;
|
||||
}
|
||||
}
|
||||
fprintf(f,"\"");
|
||||
break;
|
||||
case OBJ_FUNCTION:
|
||||
if (AS_FUNCTION(value)->name == NULL) fprintf(f, "<module>");
|
||||
else fprintf(f, "<def %s>", NAME(AS_FUNCTION(value)));
|
||||
break;
|
||||
case OBJ_NATIVE:
|
||||
fprintf(f, "<native bind>");
|
||||
break;
|
||||
case OBJ_CLOSURE:
|
||||
fprintf(f, "<closure <def %s>>", NAME(AS_CLOSURE(value)->function));
|
||||
break;
|
||||
case OBJ_UPVALUE:
|
||||
fprintf(f, "<upvalue>");
|
||||
break;
|
||||
case OBJ_CLASS:
|
||||
fprintf(f, "<class %s>", NAME(AS_CLASS(value)));
|
||||
break;
|
||||
case OBJ_INSTANCE:
|
||||
fprintf(f, "<instance of %s>", NAME(AS_INSTANCE(value)->_class));
|
||||
break;
|
||||
case OBJ_BOUND_METHOD:
|
||||
fprintf(f, "<bound <def %s>>", (AS_BOUND_METHOD(value)->method->type == OBJ_CLOSURE) ?
|
||||
NAME(((KrkClosure*)AS_BOUND_METHOD(value)->method)->function) : (
|
||||
(AS_BOUND_METHOD(value)->method->type == OBJ_NATIVE) ? "<native>" : "<unknown>"
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
KrkFunction * krk_newFunction() {
|
||||
KrkFunction * function = ALLOCATE_OBJECT(KrkFunction, OBJ_FUNCTION);
|
||||
function->requiredArgs = 0;
|
||||
@ -118,10 +72,11 @@ KrkFunction * krk_newFunction() {
|
||||
return function;
|
||||
}
|
||||
|
||||
KrkNative * krk_newNative(NativeFn function) {
|
||||
KrkNative * krk_newNative(NativeFn function, const char * name, int type) {
|
||||
KrkNative * native = ALLOCATE_OBJECT(KrkNative, OBJ_NATIVE);
|
||||
native->function = function;
|
||||
native->isMethod = 0;
|
||||
native->isMethod = type;
|
||||
native->name = name;
|
||||
return native;
|
||||
}
|
||||
|
||||
|
4
object.h
4
object.h
@ -97,6 +97,7 @@ typedef KrkValue (*NativeFn)(int argCount, KrkValue* args);
|
||||
typedef struct {
|
||||
KrkObj obj;
|
||||
NativeFn function;
|
||||
const char * name;
|
||||
int isMethod;
|
||||
} KrkNative;
|
||||
|
||||
@ -106,9 +107,8 @@ static inline int isObjType(KrkValue value, ObjType type) {
|
||||
|
||||
extern KrkString * krk_takeString(char * chars, size_t length);
|
||||
extern KrkString * krk_copyString(const char * chars, size_t length);
|
||||
extern void krk_printObject(FILE * f, KrkValue value);
|
||||
extern KrkFunction * krk_newFunction();
|
||||
extern KrkNative * krk_newNative(NativeFn function);
|
||||
extern KrkNative * krk_newNative(NativeFn function, const char * name, int type);
|
||||
extern KrkClosure * krk_newClosure(KrkFunction * function);
|
||||
extern KrkUpvalue * krk_newUpvalue(int slot);
|
||||
extern KrkClass * krk_newClass(KrkString * name);
|
||||
|
4
rline.c
4
rline.c
@ -540,9 +540,9 @@ char * syn_krk_keywords[] = {
|
||||
char * syn_krk_types[] = {
|
||||
/* built-in functions */
|
||||
"self", "super", /* implicit in a class method */
|
||||
"len", "str", "int", "float", "dir", /* global functions from __builtins__ */
|
||||
"len", "str", "int", "float", "dir", "repr", /* global functions from __builtins__ */
|
||||
"list","dict","range", /* builtin classes */
|
||||
"object","exception","isinstance",
|
||||
"object","exception","isinstance","type",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
27
src/fileio.c
27
src/fileio.c
@ -41,7 +41,17 @@ KrkValue krk_open(int argc, KrkValue argv[]) {
|
||||
return NONE_VAL();
|
||||
}
|
||||
|
||||
FILE * file = fopen(AS_CSTRING(argv[0]), AS_CSTRING(argv[1]));
|
||||
KrkValue arg;
|
||||
|
||||
if (argc == 1) {
|
||||
arg = OBJECT_VAL(S("r"));
|
||||
krk_push(arg);
|
||||
} else {
|
||||
arg = argv[1];
|
||||
krk_push(argv[1]);
|
||||
}
|
||||
|
||||
FILE * file = fopen(AS_CSTRING(argv[0]), AS_CSTRING(arg));
|
||||
if (!file) {
|
||||
krk_runtimeError(vm.exceptions.ioError, "open: failed to open file; system returned: %s", strerror(errno));
|
||||
return NONE_VAL();
|
||||
@ -53,14 +63,28 @@ KrkValue krk_open(int argc, KrkValue argv[]) {
|
||||
|
||||
/* Let's put the filename in there somewhere... */
|
||||
krk_attachNamedValue(&fileObject->fields, "filename", argv[0]);
|
||||
krk_attachNamedValue(&fileObject->fields, "modestr", arg);
|
||||
krk_attachNamedValue(&fileObject->fields, "_fileptr", INTEGER_VAL((long)(file))); /* Need a KrkNativePrivate or something... */
|
||||
|
||||
krk_pop();
|
||||
krk_pop();
|
||||
return OBJECT_VAL(fileObject);
|
||||
}
|
||||
|
||||
#define BLOCK_SIZE 1024
|
||||
|
||||
static KrkValue krk_file_str(int argc, KrkValue argv[]) {
|
||||
KrkInstance * fileObj = AS_INSTANCE(argv[0]);
|
||||
KrkValue filename, modestr;
|
||||
krk_tableGet(&fileObj->fields, OBJECT_VAL(S("filename")), &filename);
|
||||
krk_tableGet(&fileObj->fields, OBJECT_VAL(S("modestr")), &modestr);
|
||||
char * tmp = malloc(AS_STRING(filename)->length + AS_STRING(modestr)->length + 100); /* safety */
|
||||
sprintf(tmp, "<open file '%s', mode '%s' at %p>", AS_CSTRING(filename), AS_CSTRING(modestr), (void*)fileObj);
|
||||
KrkString * out = krk_copyString(tmp, strlen(tmp));
|
||||
free(tmp);
|
||||
return OBJECT_VAL(out);
|
||||
}
|
||||
|
||||
static FILE * getFilePtr(KrkValue obj) {
|
||||
KrkValue strFilePtr = OBJECT_VAL(S("_fileptr"));
|
||||
krk_push(strFilePtr);
|
||||
@ -243,6 +267,7 @@ KrkValue krk_module_onload_fileio(void) {
|
||||
krk_defineNative(&FileClass->methods, ".close", krk_file_close);
|
||||
krk_defineNative(&FileClass->methods, ".write", krk_file_write);
|
||||
krk_defineNative(&FileClass->methods, ".flush", krk_file_flush);
|
||||
krk_defineNative(&FileClass->methods, ".__str__", krk_file_str);
|
||||
krk_defineNative(&FileClass->methods, ".__init__", krk_file_reject_init);
|
||||
|
||||
/* Make an instance for stdout, stderr, and stdin */
|
||||
|
4
test/testPrintBenchmark.krk
Normal file
4
test/testPrintBenchmark.krk
Normal file
@ -0,0 +1,4 @@
|
||||
let x = 1
|
||||
while x < 1000000:
|
||||
print x
|
||||
x++
|
56
value.c
56
value.c
@ -2,6 +2,7 @@
|
||||
#include "memory.h"
|
||||
#include "value.h"
|
||||
#include "object.h"
|
||||
#include "vm.h"
|
||||
|
||||
void krk_initValueArray(KrkValueArray * array) {
|
||||
array->values = NULL;
|
||||
@ -25,19 +26,48 @@ void krk_freeValueArray(KrkValueArray * array) {
|
||||
krk_initValueArray(array);
|
||||
}
|
||||
|
||||
void krk_printValue(FILE * f, KrkValue value) {
|
||||
if (IS_FLOATING(value)) {
|
||||
fprintf(f, "%g", AS_FLOATING(value));
|
||||
} else if (IS_INTEGER(value)) {
|
||||
fprintf(f, "%ld", (long)AS_INTEGER(value));
|
||||
} else if (IS_BOOLEAN(value)) {
|
||||
fprintf(f, "%s", AS_BOOLEAN(value) ? "True" : "False");
|
||||
} else if (IS_NONE(value)) {
|
||||
fprintf(f, "None");
|
||||
} else if (IS_HANDLER(value)) {
|
||||
fprintf(f, "{try->%ld}", AS_HANDLER(value));
|
||||
} else if (IS_OBJECT(value)) {
|
||||
krk_printObject(f, value);
|
||||
void krk_printValue(FILE * f, KrkValue printable) {
|
||||
if (!IS_OBJECT(printable)) {
|
||||
switch (printable.type) {
|
||||
case VAL_INTEGER: fprintf(f, "%ld", AS_INTEGER(printable)); break;
|
||||
case VAL_BOOLEAN: fprintf(f, "%s", AS_BOOLEAN(printable) ? "True" : "False"); break;
|
||||
case VAL_FLOATING: fprintf(f, "%g", AS_FLOATING(printable)); break;
|
||||
case VAL_NONE: fprintf(f, "None"); break;
|
||||
case VAL_HANDLER: fprintf(f, "{try->%ld}", AS_HANDLER(printable)); break;
|
||||
default: break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
krk_push(printable);
|
||||
if (krk_bindMethod(AS_CLASS(krk_typeOf(1,(KrkValue[]){printable})), AS_STRING(vm.specialMethodNames[METHOD_REPR]))) {
|
||||
switch (krk_callValue(krk_peek(0), 0)) {
|
||||
case 2: printable = krk_pop(); break;
|
||||
case 1: printable = krk_runNext(); break;
|
||||
default: fprintf(f, "[unable to print object at address %p]", (void*)AS_OBJECT(printable)); return;
|
||||
}
|
||||
fprintf(f, "%s", AS_CSTRING(printable));
|
||||
} else {
|
||||
krk_pop();
|
||||
fprintf(f, "%s", krk_typeName(printable));
|
||||
}
|
||||
}
|
||||
|
||||
void krk_printValueSafe(FILE * f, KrkValue printable) {
|
||||
if (!IS_OBJECT(printable)) {
|
||||
krk_printValue(f,printable);
|
||||
} else if (IS_STRING(printable)) {
|
||||
fprintf(f, "\"%s\"", AS_CSTRING(printable));
|
||||
} else {
|
||||
switch (AS_OBJECT(printable)->type) {
|
||||
case OBJ_CLASS: fprintf(f, "<class %s>", AS_CLASS(printable)->name->chars); break;
|
||||
case OBJ_INSTANCE: fprintf(f, "<instance of %s>", AS_INSTANCE(printable)->_class->name->chars); break;
|
||||
case OBJ_NATIVE: fprintf(f, "<nativefn %s>", ((KrkNative*)AS_OBJECT(printable))->name); break;
|
||||
case OBJ_CLOSURE: fprintf(f, "<function %s>", AS_CLOSURE(printable)->function->name->chars); break;
|
||||
case OBJ_BOUND_METHOD: fprintf(f, "<method %s>",
|
||||
AS_BOUND_METHOD(printable)->method->type == OBJ_CLOSURE ? ((KrkClosure*)AS_BOUND_METHOD(printable)->method)->function->name->chars :
|
||||
((KrkNative*)AS_BOUND_METHOD(printable)->method)->name); break;
|
||||
default: fprintf(f, "<%s>", krk_typeName(printable)); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
1
value.h
1
value.h
@ -57,5 +57,6 @@ extern void krk_initValueArray(KrkValueArray * array);
|
||||
extern void krk_writeValueArray(KrkValueArray * array, KrkValue value);
|
||||
extern void krk_freeValueArray(KrkValueArray * array);
|
||||
extern void krk_printValue(FILE * f, KrkValue value);
|
||||
extern void krk_printValueSafe(FILE * f, KrkValue value);
|
||||
extern int krk_valuesEqual(KrkValue a, KrkValue b);
|
||||
|
||||
|
5
vm.h
5
vm.h
@ -19,6 +19,7 @@ typedef struct {
|
||||
typedef enum {
|
||||
METHOD_INIT,
|
||||
METHOD_STR,
|
||||
METHOD_REPR,
|
||||
METHOD_GET,
|
||||
METHOD_SET,
|
||||
METHOD_CLASS,
|
||||
@ -101,6 +102,7 @@ extern KrkValue krk_interpret(const char * src, int newScope, char *, char *);
|
||||
extern KrkValue krk_runfile(const char * fileName, int newScope, char *, char *);
|
||||
extern void krk_push(KrkValue value);
|
||||
extern KrkValue krk_pop(void);
|
||||
extern KrkValue krk_peek(int distance);
|
||||
extern const char * krk_typeName(KrkValue value);
|
||||
extern void krk_defineNative(KrkTable * table, const char * name, NativeFn function);
|
||||
extern void krk_attachNamedObject(KrkTable * table, const char name[], KrkObj * obj);
|
||||
@ -114,3 +116,6 @@ extern KrkValue krk_dictGet(KrkValue dictClass, KrkInstance * dict, KrkValue key
|
||||
extern void krk_dictSet(KrkValue dictClass, KrkInstance * dict, KrkValue key, KrkValue value);
|
||||
extern KrkInstance * krk_dictCreate(KrkValue * outClass);
|
||||
extern KrkValue krk_runNext(void);
|
||||
extern KrkValue krk_typeOf(int argc, KrkValue argv[]);
|
||||
extern int krk_bindMethod(KrkClass * _class, KrkString * name);
|
||||
extern int krk_callValue(KrkValue callee, int argCount);
|
||||
|
Loading…
x
Reference in New Issue
Block a user