added sum types
This commit is contained in:
@@ -307,9 +307,8 @@ static int bin_istypeof(Runtime *runtime, Object **argv, unsigned int argc, Obje
|
|||||||
|
|
||||||
ASSERT(argc == 2);
|
ASSERT(argc == 2);
|
||||||
|
|
||||||
bool yes = Object_IsTypeOf(argv[0], argv[1]);
|
|
||||||
|
|
||||||
Heap *heap = Runtime_GetHeap(runtime);
|
Heap *heap = Runtime_GetHeap(runtime);
|
||||||
|
bool yes = Object_IsTypeOf(argv[0], argv[1], heap, error);
|
||||||
Object *o_yes = Object_FromBool(yes, heap, error);
|
Object *o_yes = Object_FromBool(yes, heap, error);
|
||||||
if (o_yes == NULL)
|
if (o_yes == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -331,6 +330,7 @@ void bins_basic_init(StaticMapSlot slots[])
|
|||||||
slots[8].as_type = Object_GetFileType();
|
slots[8].as_type = Object_GetFileType();
|
||||||
slots[9].as_type = Object_GetDirType();
|
slots[9].as_type = Object_GetDirType();
|
||||||
slots[10].as_type = Object_GetNullableType();
|
slots[10].as_type = Object_GetNullableType();
|
||||||
|
slots[11].as_type = Object_GetSumType();
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticMapSlot bins_basic[] = {
|
StaticMapSlot bins_basic[] = {
|
||||||
@@ -345,6 +345,7 @@ StaticMapSlot bins_basic[] = {
|
|||||||
{ TYPENAME_FILE, SM_TYPE, .as_type = NULL /* Until bins_basic_init is called */ },
|
{ TYPENAME_FILE, SM_TYPE, .as_type = NULL /* Until bins_basic_init is called */ },
|
||||||
{ TYPENAME_DIRECTORY, SM_TYPE, .as_type = NULL /* Until bins_basic_init is called */ },
|
{ TYPENAME_DIRECTORY, SM_TYPE, .as_type = NULL /* Until bins_basic_init is called */ },
|
||||||
{ TYPENAME_NULLABLE, SM_TYPE, .as_type = NULL },
|
{ TYPENAME_NULLABLE, SM_TYPE, .as_type = NULL },
|
||||||
|
{ TYPENAME_SUM, SM_TYPE, .as_type = NULL },
|
||||||
|
|
||||||
{ "math", SM_SMAP, .as_smap = bins_math, },
|
{ "math", SM_SMAP, .as_smap = bins_math, },
|
||||||
{ "files", SM_SMAP, .as_smap = bins_files, },
|
{ "files", SM_SMAP, .as_smap = bins_files, },
|
||||||
|
|||||||
@@ -15,3 +15,4 @@
|
|||||||
#define TYPENAME_DIRECTORY "Directory"
|
#define TYPENAME_DIRECTORY "Directory"
|
||||||
|
|
||||||
#define TYPENAME_NULLABLE "NullableType"
|
#define TYPENAME_NULLABLE "NullableType"
|
||||||
|
#define TYPENAME_SUM "SumType"
|
||||||
@@ -83,6 +83,7 @@ static const InstrInfo instr_table[] = {
|
|||||||
[OPCODE_LEQ] = {"LEQ", 0, NULL},
|
[OPCODE_LEQ] = {"LEQ", 0, NULL},
|
||||||
[OPCODE_GEQ] = {"GEQ", 0, NULL},
|
[OPCODE_GEQ] = {"GEQ", 0, NULL},
|
||||||
[OPCODE_NLB] = {"NLB", 0, NULL},
|
[OPCODE_NLB] = {"NLB", 0, NULL},
|
||||||
|
[OPCODE_STP] = {"STP", 0, NULL},
|
||||||
[OPCODE_ASS] = {"ASS", 1, (OperandType[]) {OPTP_STRING}},
|
[OPCODE_ASS] = {"ASS", 1, (OperandType[]) {OPTP_STRING}},
|
||||||
[OPCODE_POP] = {"POP", 1, (OperandType[]) {OPTP_INT}},
|
[OPCODE_POP] = {"POP", 1, (OperandType[]) {OPTP_INT}},
|
||||||
[OPCODE_CALL] = {"CALL", 2, (OperandType[]) {OPTP_INT, OPTP_INT}},
|
[OPCODE_CALL] = {"CALL", 2, (OperandType[]) {OPTP_INT, OPTP_INT}},
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ typedef enum {
|
|||||||
OPCODE_LEQ,
|
OPCODE_LEQ,
|
||||||
OPCODE_GEQ,
|
OPCODE_GEQ,
|
||||||
OPCODE_NLB,
|
OPCODE_NLB,
|
||||||
|
OPCODE_STP,
|
||||||
OPCODE_ASS,
|
OPCODE_ASS,
|
||||||
OPCODE_POP,
|
OPCODE_POP,
|
||||||
OPCODE_CALL,
|
OPCODE_CALL,
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ static Opcode exprkind_to_opcode(ExprKind kind)
|
|||||||
switch(kind)
|
switch(kind)
|
||||||
{
|
{
|
||||||
case EXPR_NULLABLETYPE: return OPCODE_NLB;
|
case EXPR_NULLABLETYPE: return OPCODE_NLB;
|
||||||
|
case EXPR_SUMTYPE: return OPCODE_STP;
|
||||||
case EXPR_NOT: return OPCODE_NOT;
|
case EXPR_NOT: return OPCODE_NOT;
|
||||||
case EXPR_POS: return OPCODE_POS;
|
case EXPR_POS: return OPCODE_POS;
|
||||||
case EXPR_NEG: return OPCODE_NEG;
|
case EXPR_NEG: return OPCODE_NEG;
|
||||||
@@ -483,6 +484,7 @@ static void emitInstrForExprNode(CodegenContext *ctx, ExprNode *expr,
|
|||||||
return; // For the compiler warning.
|
return; // For the compiler warning.
|
||||||
|
|
||||||
case EXPR_NULLABLETYPE:
|
case EXPR_NULLABLETYPE:
|
||||||
|
case EXPR_SUMTYPE:
|
||||||
case EXPR_NOT:
|
case EXPR_NOT:
|
||||||
case EXPR_POS: case EXPR_NEG:
|
case EXPR_POS: case EXPR_NEG:
|
||||||
case EXPR_ADD: case EXPR_SUB:
|
case EXPR_ADD: case EXPR_SUB:
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ typedef enum {
|
|||||||
TGRT = '>',
|
TGRT = '>',
|
||||||
|
|
||||||
TASS = '=',
|
TASS = '=',
|
||||||
|
TSMT = '|',
|
||||||
|
|
||||||
TLBRK = '(',
|
TLBRK = '(',
|
||||||
TRBRK = ')',
|
TRBRK = ')',
|
||||||
@@ -144,7 +145,7 @@ static inline _Bool isoper(char c)
|
|||||||
c == '*' || c == '/' ||
|
c == '*' || c == '/' ||
|
||||||
c == '<' || c == '>' ||
|
c == '<' || c == '>' ||
|
||||||
c == '!' || c == '=' ||
|
c == '!' || c == '=' ||
|
||||||
c == ',';
|
c == ',' || c == '|';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Symbol: tokenize
|
/* Symbol: tokenize
|
||||||
@@ -326,6 +327,7 @@ static Token *tokenize(Source *src, BPAlloc *alloc, Error *error)
|
|||||||
{ TGEQ, 2, ">=" },
|
{ TGEQ, 2, ">=" },
|
||||||
{ TASS, 1, "=" },
|
{ TASS, 1, "=" },
|
||||||
{ TCOMMA, 1, "," },
|
{ TCOMMA, 1, "," },
|
||||||
|
{ TSMT, 1, "|" },
|
||||||
};
|
};
|
||||||
|
|
||||||
_Bool found = 0;
|
_Bool found = 0;
|
||||||
@@ -1600,7 +1602,8 @@ static inline _Bool isbinop(Token *tok)
|
|||||||
tok->kind == TLEQ || tok->kind == TGEQ ||
|
tok->kind == TLEQ || tok->kind == TGEQ ||
|
||||||
tok->kind == TEQL || tok->kind == TNQL ||
|
tok->kind == TEQL || tok->kind == TNQL ||
|
||||||
tok->kind == TKWAND || tok->kind == TKWOR ||
|
tok->kind == TKWAND || tok->kind == TKWOR ||
|
||||||
tok->kind == '=' || tok->kind == ',';
|
tok->kind == '=' || tok->kind == ',' ||
|
||||||
|
tok->kind == '|';
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline _Bool isrightassoc(Token *tok)
|
static inline _Bool isrightassoc(Token *tok)
|
||||||
@@ -1619,30 +1622,33 @@ static inline int precedenceof(Token *tok)
|
|||||||
case '=':
|
case '=':
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case TKWOR:
|
case '|':
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case TKWAND:
|
case TKWOR:
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
|
case TKWAND:
|
||||||
|
return 3;
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
case '>':
|
case '>':
|
||||||
case TLEQ:
|
case TLEQ:
|
||||||
case TGEQ:
|
case TGEQ:
|
||||||
case TEQL:
|
case TEQL:
|
||||||
case TNQL:
|
case TNQL:
|
||||||
return 3;
|
return 4;
|
||||||
|
|
||||||
case '+':
|
case '+':
|
||||||
case '-':
|
case '-':
|
||||||
return 4;
|
return 5;
|
||||||
|
|
||||||
case '*':
|
case '*':
|
||||||
case '/':
|
case '/':
|
||||||
return 5;
|
return 6;
|
||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
return 6;
|
return 7;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -100000000;
|
return -100000000;
|
||||||
@@ -1710,6 +1716,7 @@ static Node *parse_expression_2(Context *ctx, Node *left_expr, int min_prec, _Bo
|
|||||||
case TKWAND: temp->base.kind = EXPR_AND; break;
|
case TKWAND: temp->base.kind = EXPR_AND; break;
|
||||||
case TKWOR: temp->base.kind = EXPR_OR; break;
|
case TKWOR: temp->base.kind = EXPR_OR; break;
|
||||||
case '=': temp->base.kind = EXPR_ASS; break;
|
case '=': temp->base.kind = EXPR_ASS; break;
|
||||||
|
case '|': temp->base.kind = EXPR_SUMTYPE; break;
|
||||||
case ',': temp->base.kind = EXPR_PAIR; break;
|
case ',': temp->base.kind = EXPR_PAIR; break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ static void walk(Object *self, void (*callback)(Object **referer, void *userp
|
|||||||
static void walkexts(Object *self, void (*callback)(void **referer, unsigned int size, void *userp), void *userp);
|
static void walkexts(Object *self, void (*callback)(void **referer, unsigned int size, void *userp), void *userp);
|
||||||
static Object *copy(Object *self, Heap *heap, Error *err);
|
static Object *copy(Object *self, Heap *heap, Error *err);
|
||||||
static int hash(Object *self);
|
static int hash(Object *self);
|
||||||
|
static bool istypeof(Object *self, Object *other, Heap *heap, Error *error);
|
||||||
|
|
||||||
static TypeObject t_list = {
|
static TypeObject t_list = {
|
||||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||||
@@ -58,10 +59,39 @@ static TypeObject t_list = {
|
|||||||
.insert = insert,
|
.insert = insert,
|
||||||
.count = count,
|
.count = count,
|
||||||
.print = print,
|
.print = print,
|
||||||
|
.istypeof = istypeof,
|
||||||
.walk = walk,
|
.walk = walk,
|
||||||
.walkexts = walkexts,
|
.walkexts = walkexts,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
istypeof(Object *self,
|
||||||
|
Object *other,
|
||||||
|
Heap *heap,
|
||||||
|
Error *error)
|
||||||
|
{
|
||||||
|
ListObject *list = (ListObject*) self;
|
||||||
|
if (!Object_IsList(other))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < list->count; i++) {
|
||||||
|
|
||||||
|
Object *key = Object_FromInt(i, heap, error);
|
||||||
|
if (key == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Object *val = list->vals[i];
|
||||||
|
|
||||||
|
Object *val2 = Object_Select(other, key, heap, error);
|
||||||
|
if (val2 == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!Object_IsTypeOf(val, val2, heap, error))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int hash(Object *self)
|
static int hash(Object *self)
|
||||||
{
|
{
|
||||||
ASSERT(self != NULL);
|
ASSERT(self != NULL);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ static void walk(Object *self, void (*callback)(Object **referer, void *userp),
|
|||||||
static void walkexts(Object *self, void (*callback)(void **referer, unsigned int size, void *userp), void *userp);
|
static void walkexts(Object *self, void (*callback)(void **referer, unsigned int size, void *userp), void *userp);
|
||||||
static Object *copy(Object *self, Heap *heap, Error *err);
|
static Object *copy(Object *self, Heap *heap, Error *err);
|
||||||
static int hash(Object *self);
|
static int hash(Object *self);
|
||||||
|
static bool istypeof(Object *self, Object *other, Heap *heap, Error *error);
|
||||||
|
|
||||||
static TypeObject t_map = {
|
static TypeObject t_map = {
|
||||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||||
@@ -59,10 +60,36 @@ static TypeObject t_map = {
|
|||||||
.insert = insert,
|
.insert = insert,
|
||||||
.count = count,
|
.count = count,
|
||||||
.print = print,
|
.print = print,
|
||||||
|
.istypeof = istypeof,
|
||||||
.walk = walk,
|
.walk = walk,
|
||||||
.walkexts = walkexts,
|
.walkexts = walkexts,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
istypeof(Object *self,
|
||||||
|
Object *other,
|
||||||
|
Heap *heap,
|
||||||
|
Error *error)
|
||||||
|
{
|
||||||
|
MapObject *map = (MapObject*) self;
|
||||||
|
if (!Object_IsMap(other))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < map->count; i++) {
|
||||||
|
|
||||||
|
Object *key = map->keys[i];
|
||||||
|
Object *val = map->vals[i];
|
||||||
|
|
||||||
|
Object *val2 = Object_Select(other, key, heap, error);
|
||||||
|
if (val2 == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!Object_IsTypeOf(val, val2, heap, error))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int calc_capacity(int mapper_size)
|
static inline int calc_capacity(int mapper_size)
|
||||||
{
|
{
|
||||||
return mapper_size * 2.0 / 3.0;
|
return mapper_size * 2.0 / 3.0;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
|
|
||||||
static void walk(Object *self, void (*callback)(Object **referer, void *userp), void *userp);
|
static void walk(Object *self, void (*callback)(Object **referer, void *userp), void *userp);
|
||||||
static bool istypeof(Object *self, Object *other);
|
static bool istypeof(Object *self, Object *other, Heap *heap, Error *error);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Object base;
|
Object base;
|
||||||
@@ -47,12 +47,14 @@ Object *Object_NewNullable(Object *item, Heap *heap, Error *error)
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
istypeof(Object *self,
|
istypeof(Object *self,
|
||||||
Object *other)
|
Object *other,
|
||||||
|
Heap *heap,
|
||||||
|
Error *error)
|
||||||
{
|
{
|
||||||
NullableObject *nullable = (NullableObject*) self;
|
NullableObject *nullable = (NullableObject*) self;
|
||||||
if (Object_IsNone(other))
|
if (Object_IsNone(other))
|
||||||
return true;
|
return true;
|
||||||
return Object_IsTypeOf(nullable->item, other);
|
return Object_IsTypeOf(nullable->item, other, heap, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void walk(Object *self, void (*callback)(Object **referer, void *userp), void *userp)
|
static void walk(Object *self, void (*callback)(Object **referer, void *userp), void *userp)
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#include "../common/defs.h"
|
||||||
|
#include "objects.h"
|
||||||
|
|
||||||
|
static void walk(Object *self, void (*callback)(Object **referer, void *userp), void *userp);
|
||||||
|
static bool istypeof(Object *self, Object *other, Heap *heap, Error *error);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Object base;
|
||||||
|
Object *items[2];
|
||||||
|
} SumObject;
|
||||||
|
|
||||||
|
static TypeObject t_sum = {
|
||||||
|
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||||
|
.name = TYPENAME_SUM,
|
||||||
|
.size = sizeof(SumObject),
|
||||||
|
.init = NULL,
|
||||||
|
.free = NULL,
|
||||||
|
.hash = NULL,
|
||||||
|
.copy = NULL,
|
||||||
|
.call = NULL,
|
||||||
|
.print = NULL,
|
||||||
|
|
||||||
|
.select = NULL,
|
||||||
|
.delete = NULL,
|
||||||
|
.insert = NULL,
|
||||||
|
.count = NULL,
|
||||||
|
|
||||||
|
.istypeof = istypeof,
|
||||||
|
|
||||||
|
.op_eql = NULL,
|
||||||
|
.walk = walk,
|
||||||
|
.walkexts = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
TypeObject *Object_GetSumType()
|
||||||
|
{
|
||||||
|
return &t_sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *Object_NewSum(Object *item0, Object *item1, Heap *heap, Error *error)
|
||||||
|
{
|
||||||
|
SumObject *sum = (SumObject*) Heap_Malloc(heap, &t_sum, error);
|
||||||
|
if (sum != NULL) {
|
||||||
|
sum->items[0] = item0;
|
||||||
|
sum->items[1] = item1;
|
||||||
|
}
|
||||||
|
return (Object*) sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
istypeof(Object *self,
|
||||||
|
Object *other,
|
||||||
|
Heap *heap,
|
||||||
|
Error *error)
|
||||||
|
{
|
||||||
|
SumObject *sum = (SumObject*) self;
|
||||||
|
return Object_IsTypeOf(sum->items[0], other, heap, error)
|
||||||
|
|| Object_IsTypeOf(sum->items[1], other, heap, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void walk(Object *self, void (*callback)(Object **referer, void *userp), void *userp)
|
||||||
|
{
|
||||||
|
SumObject *sum = (SumObject*) self;
|
||||||
|
callback(sum->items + 0, userp);
|
||||||
|
callback(sum->items + 1, userp);
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
#include "../common/defs.h"
|
#include "../common/defs.h"
|
||||||
|
|
||||||
static _Bool op_eql(Object *self, Object *other);
|
static _Bool op_eql(Object *self, Object *other);
|
||||||
static bool istypeof(Object *self, Object *other);
|
static bool istypeof(Object *self, Object *other, Heap *heap, Error *error);
|
||||||
|
|
||||||
TypeObject t_type = {
|
TypeObject t_type = {
|
||||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||||
@@ -43,8 +43,10 @@ TypeObject t_type = {
|
|||||||
.op_eql = op_eql,
|
.op_eql = op_eql,
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool istypeof(Object *self, Object *other)
|
static bool istypeof(Object *self, Object *other, Heap *heap, Error *error)
|
||||||
{
|
{
|
||||||
|
UNUSED(heap);
|
||||||
|
UNUSED(error);
|
||||||
return other->type == (TypeObject*) self;
|
return other->type == (TypeObject*) self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,11 +80,14 @@ const TypeObject *Object_GetType(const Object *obj)
|
|||||||
return obj->type;
|
return obj->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Object_IsTypeOf(Object *typ, Object *obj)
|
bool Object_IsTypeOf(Object *typ,
|
||||||
|
Object *obj,
|
||||||
|
Heap *heap,
|
||||||
|
Error *error)
|
||||||
{
|
{
|
||||||
if (typ->type->istypeof == NULL)
|
if (typ->type->istypeof == NULL)
|
||||||
return false;
|
return false;
|
||||||
return typ->type->istypeof(typ, obj);
|
return typ->type->istypeof(typ, obj, heap, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Object_Hash(Object *obj)
|
int Object_Hash(Object *obj)
|
||||||
@@ -230,6 +235,16 @@ _Bool Object_IsString(Object *obj)
|
|||||||
return Object_GetType(obj) == Object_GetStringType();
|
return Object_GetType(obj) == Object_GetStringType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Object_IsMap(Object *obj)
|
||||||
|
{
|
||||||
|
return Object_GetType(obj) == Object_GetMapType();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Object_IsList(Object *obj)
|
||||||
|
{
|
||||||
|
return Object_GetType(obj) == Object_GetListType();
|
||||||
|
}
|
||||||
|
|
||||||
_Bool Object_Compare(Object *obj1, Object *obj2, Error *error)
|
_Bool Object_Compare(Object *obj1, Object *obj2, Error *error)
|
||||||
{
|
{
|
||||||
ASSERT(obj1 != NULL);
|
ASSERT(obj1 != NULL);
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ struct TypeObject {
|
|||||||
int (*count)(Object *self);
|
int (*count)(Object *self);
|
||||||
|
|
||||||
// Types.
|
// Types.
|
||||||
bool (*istypeof)(Object *self, Object *other);
|
bool (*istypeof)(Object *self, Object *other, Heap *heap, Error *error);
|
||||||
|
|
||||||
bool (*op_eql)(Object *self, Object *other);
|
bool (*op_eql)(Object *self, Object *other);
|
||||||
void (*walk) (Object *self, void (*callback)(Object **referer, void *userp), void *userp);
|
void (*walk) (Object *self, void (*callback)(Object **referer, void *userp), void *userp);
|
||||||
@@ -103,7 +103,7 @@ int Object_Hash (Object *obj);
|
|||||||
Object* Object_Copy (Object *obj, Heap *heap, Error *err);
|
Object* Object_Copy (Object *obj, Heap *heap, Error *err);
|
||||||
int Object_Call (Object *obj, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Heap *heap, Error *err);
|
int Object_Call (Object *obj, Object **argv, unsigned int argc, Object *rets[static MAX_RETS], Heap *heap, Error *err);
|
||||||
void Object_Print(Object *obj, FILE *fp);
|
void Object_Print(Object *obj, FILE *fp);
|
||||||
bool Object_IsTypeOf(Object *typ, Object *obj);
|
bool Object_IsTypeOf(Object *typ, Object *obj, Heap *heap, Error *error);
|
||||||
Object* Object_Select(Object *coll, Object *key, Heap *heap, Error *err);
|
Object* Object_Select(Object *coll, Object *key, Heap *heap, Error *err);
|
||||||
Object* Object_Delete(Object *coll, Object *key, Heap *heap, Error *err);
|
Object* Object_Delete(Object *coll, Object *key, Heap *heap, Error *err);
|
||||||
bool Object_Insert(Object *coll, Object *key, Object *val, Heap *heap, Error *err);
|
bool Object_Insert(Object *coll, Object *key, Object *val, Heap *heap, Error *err);
|
||||||
@@ -119,6 +119,7 @@ Object* Object_NewBuffer(size_t size, Heap *heap, Error *error);
|
|||||||
Object* Object_NewClosure(Object *parent, Object *new_map, Heap *heap, Error *error);
|
Object* Object_NewClosure(Object *parent, Object *new_map, Heap *heap, Error *error);
|
||||||
Object* Object_SliceBuffer(Object *obj, size_t offset, size_t length, Heap *heap, Error *error);
|
Object* Object_SliceBuffer(Object *obj, size_t offset, size_t length, Heap *heap, Error *error);
|
||||||
Object* Object_NewNullable(Object *item, Heap *heap, Error *error);
|
Object* Object_NewNullable(Object *item, Heap *heap, Error *error);
|
||||||
|
Object* Object_NewSum(Object *item0, Object *item1, Heap *heap, Error *error);
|
||||||
|
|
||||||
Object* Object_FromInt (long long int val, Heap *heap, Error *error);
|
Object* Object_FromInt (long long int val, Heap *heap, Error *error);
|
||||||
Object* Object_FromBool (bool val, Heap *heap, Error *error);
|
Object* Object_FromBool (bool val, Heap *heap, Error *error);
|
||||||
@@ -139,6 +140,7 @@ TypeObject *Object_GetBufferType();
|
|||||||
TypeObject *Object_GetFileType();
|
TypeObject *Object_GetFileType();
|
||||||
TypeObject *Object_GetDirType();
|
TypeObject *Object_GetDirType();
|
||||||
TypeObject *Object_GetNullableType();
|
TypeObject *Object_GetNullableType();
|
||||||
|
TypeObject *Object_GetSumType();
|
||||||
|
|
||||||
bool Object_IsNone(Object *obj);
|
bool Object_IsNone(Object *obj);
|
||||||
bool Object_IsInt(Object *obj);
|
bool Object_IsInt(Object *obj);
|
||||||
@@ -148,6 +150,8 @@ bool Object_IsString(Object *obj);
|
|||||||
bool Object_IsBuffer(Object *obj);
|
bool Object_IsBuffer(Object *obj);
|
||||||
bool Object_IsFile(Object *obj);
|
bool Object_IsFile(Object *obj);
|
||||||
bool Object_IsDir(Object *obj);
|
bool Object_IsDir(Object *obj);
|
||||||
|
bool Object_IsMap(Object *obj);
|
||||||
|
bool Object_IsList(Object *obj);
|
||||||
|
|
||||||
long long int Object_GetInt (Object *obj);
|
long long int Object_GetInt (Object *obj);
|
||||||
bool Object_GetBool (Object *obj);
|
bool Object_GetBool (Object *obj);
|
||||||
|
|||||||
@@ -679,6 +679,30 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case OPCODE_STP:
|
||||||
|
{
|
||||||
|
ASSERT(opc == 0);
|
||||||
|
|
||||||
|
Object *rop = Stack_Top(runtime->stack, 0);
|
||||||
|
Object *lop = Stack_Top(runtime->stack, -1);
|
||||||
|
|
||||||
|
if(!Runtime_Pop(runtime, error, 2))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// We managed to pop rop and lop,
|
||||||
|
// so we know they're not NULL.
|
||||||
|
ASSERT(rop != NULL);
|
||||||
|
ASSERT(lop != NULL);
|
||||||
|
|
||||||
|
Object *res = Object_NewSum(lop, rop, runtime->heap, error);
|
||||||
|
if(res == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!Runtime_Push(runtime, error, res))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
case OPCODE_ADD:
|
case OPCODE_ADD:
|
||||||
case OPCODE_SUB:
|
case OPCODE_SUB:
|
||||||
case OPCODE_MUL:
|
case OPCODE_MUL:
|
||||||
|
|||||||
Reference in New Issue
Block a user