|
@ -3,6 +3,8 @@ |
|
|
#include <sysexits.h> |
|
|
#include <sysexits.h> |
|
|
#include <assert.h> |
|
|
#include <assert.h> |
|
|
|
|
|
|
|
|
|
|
|
#define USE_TAG 1 |
|
|
|
|
|
|
|
|
#define USE_GC 1 |
|
|
#define USE_GC 1 |
|
|
|
|
|
|
|
|
#if (USE_GC) |
|
|
#if (USE_GC) |
|
@ -66,7 +68,7 @@ struct Undefined { |
|
|
|
|
|
|
|
|
struct Integer { |
|
|
struct Integer { |
|
|
type_t type; |
|
|
type_t type; |
|
|
int value; |
|
|
|
|
|
|
|
|
int _value; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
struct String { |
|
|
struct String { |
|
@ -120,9 +122,23 @@ union object { |
|
|
union object _null = {.Undefined = {Undefined}}; |
|
|
union object _null = {.Undefined = {Undefined}}; |
|
|
oop null = &_null; |
|
|
oop null = &_null; |
|
|
|
|
|
|
|
|
|
|
|
int isInteger(oop obj) |
|
|
|
|
|
{ |
|
|
|
|
|
#if (USE_TAG) |
|
|
|
|
|
return (intptr_t)obj & 1; |
|
|
|
|
|
#else |
|
|
|
|
|
return is(Integer, obj); |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
type_t getType(oop ptr) |
|
|
type_t getType(oop ptr) |
|
|
{ |
|
|
{ |
|
|
assert(ptr); |
|
|
assert(ptr); |
|
|
|
|
|
#if (USE_TAG) |
|
|
|
|
|
if (isInteger(ptr)) { |
|
|
|
|
|
return Integer; |
|
|
|
|
|
} |
|
|
|
|
|
#endif |
|
|
return ptr->type; |
|
|
return ptr->type; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -157,12 +173,26 @@ void *memcheck(void *ptr) |
|
|
void print(oop ast); |
|
|
void print(oop ast); |
|
|
void println(oop ast); |
|
|
void println(oop ast); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int getInteger(oop obj) |
|
|
|
|
|
{ |
|
|
|
|
|
#if (USE_TAG) |
|
|
|
|
|
return (intptr_t)obj >> 1; |
|
|
|
|
|
#else |
|
|
|
|
|
return get(obj, Integer, _value); |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
oop makeInteger(int value) |
|
|
oop makeInteger(int value) |
|
|
{ |
|
|
{ |
|
|
|
|
|
#if (USE_TAG) |
|
|
|
|
|
return (oop) (((intptr_t)value << 1) | 1); |
|
|
|
|
|
#else |
|
|
oop newInt = memcheck(malloc(sizeof(union object))); |
|
|
oop newInt = memcheck(malloc(sizeof(union object))); |
|
|
newInt->type = Integer; |
|
|
newInt->type = Integer; |
|
|
newInt->Integer.value = value; |
|
|
|
|
|
|
|
|
newInt->Integer._value = value; |
|
|
return newInt; |
|
|
return newInt; |
|
|
|
|
|
#endif |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
oop makeString(char *value) |
|
|
oop makeString(char *value) |
|
@ -205,8 +235,8 @@ bool map_hasIntegerKey(oop map, size_t index) |
|
|
{ |
|
|
{ |
|
|
if (index >= get(map, Map, size)) return 0; |
|
|
if (index >= get(map, Map, size)) return 0; |
|
|
oop key= get(map, Map, elements)[index].key; |
|
|
oop key= get(map, Map, elements)[index].key; |
|
|
if (!is(Integer, key)) return 0; |
|
|
|
|
|
return index == get(key, Integer, value); |
|
|
|
|
|
|
|
|
if (!isInteger(key)) return 0; |
|
|
|
|
|
return index == getInteger(key); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int oopcmp(oop a, oop b) |
|
|
int oopcmp(oop a, oop b) |
|
@ -215,7 +245,7 @@ int oopcmp(oop a, oop b) |
|
|
if (ta == tb) { |
|
|
if (ta == tb) { |
|
|
switch (getType(a)) { |
|
|
switch (getType(a)) { |
|
|
case Integer: |
|
|
case Integer: |
|
|
return get(a, Integer, value) - get(b, Integer, value); |
|
|
|
|
|
|
|
|
return getInteger(a) - getInteger(b); |
|
|
case String: |
|
|
case String: |
|
|
return strcmp(get(a, String, value), get(b, String, value)); |
|
|
return strcmp(get(a, String, value), get(b, String, value)); |
|
|
default: |
|
|
default: |
|
@ -234,8 +264,8 @@ ssize_t map_search(oop map, oop key) |
|
|
|
|
|
|
|
|
ssize_t r = get(map, Map, size) - 1; |
|
|
ssize_t r = get(map, Map, size) - 1; |
|
|
|
|
|
|
|
|
if (is(Integer, key)) { |
|
|
|
|
|
ssize_t index = get(key, Integer, value); |
|
|
|
|
|
|
|
|
if (isInteger(key)) { |
|
|
|
|
|
ssize_t index = getInteger(key); |
|
|
if (index > r) { |
|
|
if (index > r) { |
|
|
return -1 - (r + 1); |
|
|
return -1 - (r + 1); |
|
|
} |
|
|
} |
|
@ -367,7 +397,7 @@ void print(oop ast) |
|
|
printf("null"); |
|
|
printf("null"); |
|
|
return; |
|
|
return; |
|
|
case Integer: |
|
|
case Integer: |
|
|
printf("%i", get(ast, Integer, value)); |
|
|
|
|
|
|
|
|
printf("%i", getInteger(ast)); |
|
|
return; |
|
|
return; |
|
|
case String: |
|
|
case String: |
|
|
printf("'%s'", get(ast, String, value)); |
|
|
printf("'%s'", get(ast, String, value)); |
|
|