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)
|
2021-01-12 13:23:14 +03:00
|
|
|
#define IS_BYTES(value) isObjType(value, OBJ_BYTES)
|
|
|
|
#define AS_BYTES(value) ((KrkBytes*)AS_OBJECT(value))
|
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
|
|
|
|
2021-01-05 05:38:11 +03:00
|
|
|
#define IS_TUPLE(value) isObjType(value, OBJ_TUPLE)
|
|
|
|
#define AS_TUPLE(value) ((KrkTuple *)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,
|
2021-01-05 05:38:11 +03:00
|
|
|
OBJ_TUPLE,
|
2021-01-12 13:23:14 +03:00
|
|
|
OBJ_BYTES,
|
2020-12-26 03:32:21 +03:00
|
|
|
} ObjType;
|
|
|
|
|
|
|
|
struct Obj {
|
|
|
|
ObjType type;
|
2021-01-19 16:27:05 +03:00
|
|
|
unsigned char isMarked:1;
|
|
|
|
unsigned char inRepr:1;
|
2020-12-26 03:32:21 +03:00
|
|
|
struct Obj * next;
|
|
|
|
};
|
|
|
|
|
2021-01-12 13:23:14 +03:00
|
|
|
typedef enum {
|
|
|
|
KRK_STRING_ASCII = 0,
|
|
|
|
KRK_STRING_UCS1 = 1,
|
|
|
|
KRK_STRING_UCS2 = 2,
|
|
|
|
KRK_STRING_UCS4 = 4,
|
|
|
|
} KrkStringType;
|
|
|
|
|
2020-12-26 03:32:21 +03:00
|
|
|
struct ObjString {
|
|
|
|
KrkObj obj;
|
2021-01-12 13:23:14 +03:00
|
|
|
KrkStringType type;
|
|
|
|
uint32_t hash;
|
2020-12-26 03:32:21 +03:00
|
|
|
size_t length;
|
2021-01-12 13:23:14 +03:00
|
|
|
size_t codesLength;
|
2020-12-26 03:32:21 +03:00
|
|
|
char * chars;
|
2021-01-12 13:23:14 +03:00
|
|
|
void * codes;
|
2020-12-26 03:32:21 +03:00
|
|
|
};
|
|
|
|
|
2021-01-12 13:23:14 +03:00
|
|
|
typedef struct {
|
|
|
|
KrkObj obj;
|
|
|
|
uint32_t hash;
|
|
|
|
size_t length;
|
|
|
|
uint8_t * bytes;
|
|
|
|
} KrkBytes;
|
|
|
|
|
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;
|
|
|
|
|
2021-01-06 09:03:56 +03:00
|
|
|
typedef struct {
|
|
|
|
size_t id;
|
|
|
|
size_t birthday;
|
|
|
|
size_t deathday;
|
|
|
|
KrkString * name;
|
|
|
|
} KrkLocalEntry;
|
|
|
|
|
2021-01-07 04:39:09 +03:00
|
|
|
struct KrkInstance;
|
|
|
|
|
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-06 09:03:56 +03:00
|
|
|
size_t localNameCapacity;
|
|
|
|
size_t localNameCount;
|
|
|
|
KrkLocalEntry * localNames;
|
2021-01-03 10:02:50 +03:00
|
|
|
unsigned char collectsArguments:1;
|
|
|
|
unsigned char collectsKeywords:1;
|
2021-01-07 04:39:09 +03:00
|
|
|
struct KrkInstance * globalsContext;
|
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-11 10:31:34 +03:00
|
|
|
KrkTable fields;
|
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;
|
2021-01-05 11:41:32 +03:00
|
|
|
KrkObj * _eq;
|
2021-01-09 07:58:46 +03:00
|
|
|
KrkObj * _len;
|
2021-01-10 17:39:05 +03:00
|
|
|
KrkObj * _enter;
|
|
|
|
KrkObj * _exit;
|
2021-01-14 10:00:43 +03:00
|
|
|
KrkObj * _delitem;
|
2021-01-14 15:38:06 +03:00
|
|
|
KrkObj * _iter;
|
2021-01-14 17:16:13 +03:00
|
|
|
KrkObj * _getattr;
|
|
|
|
KrkObj * _dir;
|
2020-12-27 10:45:34 +03:00
|
|
|
} KrkClass;
|
|
|
|
|
2021-01-07 04:39:09 +03:00
|
|
|
typedef struct KrkInstance {
|
2020-12-27 10:45:34 +03:00
|
|
|
KrkObj obj;
|
|
|
|
KrkClass * _class;
|
|
|
|
KrkTable fields;
|
2021-01-05 05:39:20 +03:00
|
|
|
void * _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-05 05:38:11 +03:00
|
|
|
typedef struct {
|
|
|
|
KrkObj obj;
|
|
|
|
KrkValueArray values;
|
|
|
|
int inrepr;
|
|
|
|
} KrkTuple;
|
|
|
|
|
2021-01-20 13:46:00 +03:00
|
|
|
#define AS_LIST(value) (&AS_TUPLE(value)->values)
|
|
|
|
#define AS_DICT(value) (&AS_INSTANCE(value)->fields)
|
2021-01-02 13:41:51 +03:00
|
|
|
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);
|
2021-01-14 03:15:18 +03:00
|
|
|
extern KrkFunction * krk_newFunction(void);
|
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);
|
2021-01-05 05:38:11 +03:00
|
|
|
extern KrkTuple * krk_newTuple(size_t length);
|
2021-01-12 13:23:14 +03:00
|
|
|
|
|
|
|
extern void * krk_unicodeString(KrkString * string);
|
|
|
|
extern uint32_t krk_unicodeCodepoint(KrkString * string, size_t index);
|
|
|
|
|
|
|
|
#define KRK_STRING_FAST(string,offset) (uint32_t)\
|
|
|
|
(string->type == 1 ? ((uint8_t*)string->codes)[offset] : \
|
|
|
|
(string->type == 2 ? ((uint16_t*)string->codes)[offset] : \
|
|
|
|
((uint32_t*)string->codes)[offset]))
|
|
|
|
|
|
|
|
#define CODEPOINT_BYTES(cp) (cp < 0x80 ? 1 : (cp < 0x800 ? 2 : (cp < 0x10000 ? 3 : 4)))
|
|
|
|
|
|
|
|
extern KrkBytes * krk_newBytes(size_t length, uint8_t * source);
|
|
|
|
extern void krk_bytesUpdateHash(KrkBytes * bytes);
|
2021-01-19 07:58:55 +03:00
|
|
|
extern size_t krk_codepointToBytes(krk_integer_type value, unsigned char * out);
|