2020-12-26 03:32:21 +03:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include "kuroko.h"
|
|
|
|
#include "value.h"
|
2020-12-27 03:33:28 +03:00
|
|
|
#include "chunk.h"
|
2020-12-27 10:45:34 +03:00
|
|
|
#include "table.h"
|
2020-12-26 03:32:21 +03:00
|
|
|
|
|
|
|
#define OBJECT_TYPE(value) (AS_OBJECT(value)->type)
|
|
|
|
#define IS_STRING(value) isObjType(value, OBJ_STRING)
|
|
|
|
#define AS_STRING(value) ((KrkString *)AS_OBJECT(value))
|
|
|
|
#define AS_CSTRING(value) (((KrkString *)AS_OBJECT(value))->chars)
|
2020-12-27 03:33:28 +03:00
|
|
|
#define IS_FUNCTION(value) isObjType(value, OBJ_FUNCTION)
|
|
|
|
#define AS_FUNCTION(value) ((KrkFunction *)AS_OBJECT(value))
|
|
|
|
#define IS_NATIVE(value) isObjType(value, OBJ_NATIVE)
|
|
|
|
#define AS_NATIVE(value) (((KrkNative *)AS_OBJECT(value))->function)
|
2020-12-27 07:02:26 +03:00
|
|
|
#define IS_CLOSURE(value) isObjType(value, OBJ_CLOSURE)
|
|
|
|
#define AS_CLOSURE(value) ((KrkClosure *)AS_OBJECT(value))
|
2020-12-27 10:45:34 +03:00
|
|
|
#define IS_CLASS(value) isObjType(value, OBJ_CLASS)
|
|
|
|
#define AS_CLASS(value) ((KrkClass *)AS_OBJECT(value))
|
|
|
|
#define IS_INSTANCE(value) isObjType(value, OBJ_INSTANCE)
|
|
|
|
#define AS_INSTANCE(value) ((KrkInstance *)AS_OBJECT(value))
|
2020-12-27 11:53:46 +03:00
|
|
|
#define IS_BOUND_METHOD(value) isObjType(value, OBJ_BOUND_METHOD)
|
|
|
|
#define AS_BOUND_METHOD(value) ((KrkBoundMethod*)AS_OBJECT(value))
|
2020-12-26 03:32:21 +03:00
|
|
|
|
|
|
|
typedef enum {
|
2020-12-27 03:33:28 +03:00
|
|
|
OBJ_FUNCTION,
|
|
|
|
OBJ_NATIVE,
|
2020-12-27 07:02:26 +03:00
|
|
|
OBJ_CLOSURE,
|
2020-12-26 03:32:21 +03:00
|
|
|
OBJ_STRING,
|
2020-12-27 07:02:26 +03:00
|
|
|
OBJ_UPVALUE,
|
2020-12-27 10:45:34 +03:00
|
|
|
OBJ_CLASS,
|
|
|
|
OBJ_INSTANCE,
|
2020-12-27 11:53:46 +03:00
|
|
|
OBJ_BOUND_METHOD,
|
2020-12-26 03:32:21 +03:00
|
|
|
} ObjType;
|
|
|
|
|
|
|
|
struct Obj {
|
|
|
|
ObjType type;
|
2020-12-27 09:58:32 +03:00
|
|
|
char isMarked;
|
2020-12-26 03:32:21 +03:00
|
|
|
struct Obj * next;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ObjString {
|
|
|
|
KrkObj obj;
|
|
|
|
size_t length;
|
|
|
|
char * chars;
|
2020-12-26 08:33:34 +03:00
|
|
|
uint32_t hash;
|
2020-12-26 03:32:21 +03:00
|
|
|
};
|
|
|
|
|
2020-12-27 07:02:26 +03:00
|
|
|
typedef struct KrkUpvalue {
|
|
|
|
KrkObj obj;
|
2020-12-28 16:02:39 +03:00
|
|
|
int location;
|
2020-12-27 07:02:26 +03:00
|
|
|
KrkValue closed;
|
|
|
|
struct KrkUpvalue * next;
|
|
|
|
} KrkUpvalue;
|
|
|
|
|
2020-12-27 03:33:28 +03:00
|
|
|
typedef struct {
|
|
|
|
KrkObj obj;
|
2020-12-30 02:00:48 +03:00
|
|
|
short requiredArgs;
|
2021-01-03 06:09:41 +03:00
|
|
|
short keywordArgs;
|
2020-12-27 07:02:26 +03:00
|
|
|
size_t upvalueCount;
|
2020-12-27 03:33:28 +03:00
|
|
|
KrkChunk chunk;
|
|
|
|
KrkString * name;
|
2020-12-30 10:59:21 +03:00
|
|
|
KrkString * docstring;
|
2021-01-03 06:09:41 +03:00
|
|
|
KrkValueArray requiredArgNames;
|
|
|
|
KrkValueArray keywordArgNames;
|
2021-01-03 10:02:50 +03:00
|
|
|
unsigned char collectsArguments:1;
|
|
|
|
unsigned char collectsKeywords:1;
|
2020-12-27 03:33:28 +03:00
|
|
|
} KrkFunction;
|
|
|
|
|
2020-12-27 07:02:26 +03:00
|
|
|
typedef struct {
|
|
|
|
KrkObj obj;
|
|
|
|
KrkFunction * function;
|
|
|
|
KrkUpvalue ** upvalues;
|
|
|
|
size_t upvalueCount;
|
|
|
|
} KrkClosure;
|
|
|
|
|
2020-12-31 03:15:53 +03:00
|
|
|
typedef struct KrkClass {
|
2020-12-27 10:45:34 +03:00
|
|
|
KrkObj obj;
|
|
|
|
KrkString * name;
|
2020-12-28 06:16:44 +03:00
|
|
|
KrkString * filename;
|
2020-12-30 10:59:21 +03:00
|
|
|
KrkString * docstring;
|
2020-12-31 03:15:53 +03:00
|
|
|
struct KrkClass * base;
|
2020-12-27 11:53:46 +03:00
|
|
|
KrkTable methods;
|
2021-01-05 03:30:23 +03:00
|
|
|
|
|
|
|
/* Quick access for common stuff */
|
|
|
|
KrkObj * _getter;
|
|
|
|
KrkObj * _setter;
|
|
|
|
KrkObj * _slicer;
|
|
|
|
KrkObj * _reprer;
|
|
|
|
KrkObj * _tostr;
|
|
|
|
KrkObj * _call;
|
|
|
|
KrkObj * _init;
|
2020-12-27 10:45:34 +03:00
|
|
|
} KrkClass;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
KrkObj obj;
|
|
|
|
KrkClass * _class;
|
|
|
|
KrkTable fields;
|
2021-01-05 03:30:23 +03:00
|
|
|
KrkObj * _internal;
|
2020-12-27 10:45:34 +03:00
|
|
|
} KrkInstance;
|
2020-12-27 07:02:26 +03:00
|
|
|
|
2020-12-27 11:53:46 +03:00
|
|
|
typedef struct {
|
|
|
|
KrkObj obj;
|
|
|
|
KrkValue receiver;
|
2020-12-29 14:25:34 +03:00
|
|
|
KrkObj * method;
|
2020-12-27 11:53:46 +03:00
|
|
|
} KrkBoundMethod;
|
|
|
|
|
2021-01-03 10:23:22 +03:00
|
|
|
typedef KrkValue (*NativeFn)();
|
|
|
|
typedef KrkValue (*NativeFnKw)(int argCount, KrkValue* args, int hasKwargs);
|
2020-12-27 03:33:28 +03:00
|
|
|
typedef struct {
|
|
|
|
KrkObj obj;
|
|
|
|
NativeFn function;
|
2021-01-01 10:01:58 +03:00
|
|
|
const char * name;
|
2020-12-29 14:25:34 +03:00
|
|
|
int isMethod;
|
2020-12-27 03:33:28 +03:00
|
|
|
} KrkNative;
|
|
|
|
|
2021-01-02 13:41:51 +03:00
|
|
|
#define AS_LIST(value) (&AS_FUNCTION(value)->chunk.constants)
|
|
|
|
#define AS_DICT(value) (&AS_CLASS(value)->methods)
|
|
|
|
typedef KrkFunction KrkList;
|
|
|
|
typedef KrkClass KrkDict;
|
|
|
|
#define krk_newList() AS_LIST(krk_list_of(0,(KrkValue[]){}))
|
|
|
|
#define krk_newDict() AS_DICT(krk_dict_of(0,(KrkValue[]){}))
|
|
|
|
|
2020-12-26 03:32:21 +03:00
|
|
|
static inline int isObjType(KrkValue value, ObjType type) {
|
|
|
|
return IS_OBJECT(value) && AS_OBJECT(value)->type == type;
|
|
|
|
}
|
|
|
|
|
2020-12-28 05:11:50 +03:00
|
|
|
extern KrkString * krk_takeString(char * chars, size_t length);
|
|
|
|
extern KrkString * krk_copyString(const char * chars, size_t length);
|
|
|
|
extern KrkFunction * krk_newFunction();
|
2021-01-01 10:01:58 +03:00
|
|
|
extern KrkNative * krk_newNative(NativeFn function, const char * name, int type);
|
2020-12-28 05:11:50 +03:00
|
|
|
extern KrkClosure * krk_newClosure(KrkFunction * function);
|
2020-12-28 16:02:39 +03:00
|
|
|
extern KrkUpvalue * krk_newUpvalue(int slot);
|
2020-12-28 05:11:50 +03:00
|
|
|
extern KrkClass * krk_newClass(KrkString * name);
|
|
|
|
extern KrkInstance * krk_newInstance(KrkClass * _class);
|
2020-12-29 14:25:34 +03:00
|
|
|
extern KrkBoundMethod * krk_newBoundMethod(KrkValue receiver, KrkObj * method);
|