added statis map object and used it to implement builtins. Also, new objects File and Directory

This commit is contained in:
cozis
2022-03-10 19:00:30 +01:00
parent 5b097e2b76
commit 8deec027d1
19 changed files with 824 additions and 1045 deletions
+146
View File
@@ -0,0 +1,146 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "basic.h"
#include "file.h"
#include "math.h"
static Object *bin_print(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
for(int i = 0; i < (int) argc; i += 1)
Object_Print(argv[i], stdout);
return Object_NewNone(Runtime_GetHeap(runtime), error);
}
static Object *bin_type(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
(void) runtime;
(void) error;
return (Object*) argv[0]->type;
}
static Object *bin_count(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
int n = Object_Count(argv[0], error);
if(error->occurred)
return NULL;
return Object_FromInt(n, Runtime_GetHeap(runtime), error);
}
static Object *bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
for(unsigned int i = 0; i < argc; i += 1)
if(!Object_ToBool(argv[i], error))
{
if(!error->occurred)
Error_Report(error, 0, "Assertion failed");
return NULL;
}
return Object_NewNone(Runtime_GetHeap(runtime), error);
}
static Object *bin_strcat(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
unsigned int total_count = 0;
for(unsigned int i = 0; i < argc; i += 1)
{
if(!Object_IsString(argv[i]))
{
Error_Report(error, 0, "Argument #%d is not a string", i+1);
return NULL;
}
total_count += Object_Count(argv[i], error);
if(error->occurred)
return NULL;
}
char starting[128];
char *buffer = starting;
if(total_count > sizeof(starting)-1)
{
buffer = malloc(total_count+1);
if(buffer == NULL)
{
Error_Report(error, 1, "No memory");
return NULL;
}
}
Object *result = NULL;
for(unsigned int i = 0, written = 0; i < argc; i += 1)
{
int n;
const char *s;
s = Object_ToString(argv[i], &n, Runtime_GetHeap(runtime), error);
if(error->occurred)
goto done;
memcpy(buffer + written, s, n);
written += n;
}
buffer[total_count] = '\0';
result = Object_FromString(buffer, total_count, Runtime_GetHeap(runtime), error);
done:
if(starting != buffer)
free(buffer);
return result;
}
static Object *bin_newBuffer(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
long long int size = Object_ToInt(argv[0], error);
if(error->occurred == 1)
return NULL;
return Object_NewBuffer(size, Runtime_GetHeap(runtime), error);
}
static Object *bin_sliceBuffer(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 3);
long long int offset = Object_ToInt(argv[1], error);
if(error->occurred == 1) return NULL;
long long int length = Object_ToInt(argv[2], error);
if(error->occurred == 1) return NULL;
return Object_SliceBuffer(argv[0], offset, length, Runtime_GetHeap(runtime), error);
}
const StaticMapSlot bins_basic[] = {
{ "math", SM_SMAP, .as_smap = bins_math, },
{ "file", SM_SMAP, .as_smap = bins_file, },
// { "net", SM_SMAP, .as_smap = bins_net, },
{ "newBuffer", SM_FUNCT, .as_funct = bin_newBuffer, .argc = 1 },
{ "sliceBuffer", SM_FUNCT, .as_funct = bin_sliceBuffer, .argc = 3 },
{ "strcat", SM_FUNCT, .as_funct = bin_strcat },
{ "type", SM_FUNCT, .as_funct = bin_type, .argc = 1 },
{ "print", SM_FUNCT, .as_funct = bin_print, .argc = -1 },
{ "count", SM_FUNCT, .as_funct = bin_count, .argc = 1 },
{ "assert", SM_FUNCT, .as_funct = bin_assert, .argc = -1 },
{ NULL, SM_END, {}, {} },
};
+2
View File
@@ -0,0 +1,2 @@
#include "../o_staticmap.h"
extern const StaticMapSlot bins_basic[];
+278
View File
@@ -0,0 +1,278 @@
#include <assert.h>
#include <errno.h>
#include "file.h"
enum {
MD_READ = 0,
MD_WRITE = 1,
MD_APPEND = 2,
};
static Object *bin_openFile(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 2);
if(!Object_IsString(argv[0]))
{
Error_Report(error, 0, "Expected first argument to be a string, but it's a %s", Object_GetName(argv[0]));
return NULL;
}
if(!Object_IsInt(argv[1]))
{
Error_Report(error, 0, "Expected second argument to be an int, but it's a %s", Object_GetName(argv[0]));
return NULL;
}
Heap *heap = Runtime_GetHeap(runtime);
const char *path = Object_ToString(argv[0], NULL, heap, error);
if(error->occurred)
return NULL;
int mode = Object_ToInt(argv[1], error);
if(error->occurred)
return NULL;
FILE *fp;
{
const char *mode2;
switch(mode)
{
case MD_READ:
mode2 = "r";
break;
case MD_READ | MD_WRITE:
mode2 = "w+";
break;
case MD_READ | MD_APPEND:
case MD_READ | MD_WRITE | MD_APPEND:
mode2 = "a";
break;
default:
assert(0);
break;
}
fp = fopen(path, mode2);
if(fp == NULL)
return Object_NewNone(heap, error);
}
return Object_FromStream(fp, heap, error);
}
static Object *bin_read(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 3);
// Arg 0: file
// Arg 1: buffer
// Arg 2: count
if(!Object_IsFile(argv[0]))
{
Error_Report(error, 0, "Expected first argument to be a file, but it's a %s", Object_GetName(argv[0]));
return NULL;
}
if(!Object_IsBuffer(argv[1]))
{
Error_Report(error, 0, "Expected first argument to be a buffer, but it's a %s", Object_GetName(argv[0]));
return NULL;
}
Heap *heap = Runtime_GetHeap(runtime);
void *buff_addr;
int buff_size;
buff_addr = Object_GetBufferAddrAndSize(argv[1], &buff_size, error);
int read_size;
if(Object_IsNone(argv[2]))
{
read_size = buff_size;
}
else if(Object_IsInt(argv[2]))
{
long long int temp = Object_ToInt(argv[2], error);
if(error->occurred)
return NULL;
read_size = temp; // TODO: Handle potential overflow.
if(read_size > buff_size)
read_size = buff_size;
}
else
{
Error_Report(error, 0, "Expected third argument to be an int or none, but it's a %s", Object_GetName(argv[0]));
return NULL;
}
FILE *fp = Object_ToStream(argv[0], error);
if(fp == NULL)
return NULL;
size_t n = fread(buff_addr, 1, read_size, fp);
return Object_FromInt(n, heap, error);
}
static Object *bin_write(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 3);
// Arg 0: file
// Arg 1: buffer
// Arg 2: count
if(!Object_IsFile(argv[0]))
{
Error_Report(error, 0, "Expected first argument to be a file, but it's a %s", Object_GetName(argv[0]));
return NULL;
}
if(!Object_IsBuffer(argv[1]))
{
Error_Report(error, 0, "Expected first argument to be a buffer, but it's a %s", Object_GetName(argv[0]));
return NULL;
}
Heap *heap = Runtime_GetHeap(runtime);
void *buff_addr;
int buff_size;
buff_addr = Object_GetBufferAddrAndSize(argv[1], &buff_size, error);
int write_size;
if(Object_IsNone(argv[2]))
{
write_size = buff_size;
}
else if(Object_IsInt(argv[2]))
{
long long int temp = Object_ToInt(argv[2], error);
if(error->occurred)
return NULL;
write_size = temp; // TODO: Handle potential overflow.
if(write_size > buff_size)
write_size = buff_size;
}
else
{
Error_Report(error, 0, "Expected third argument to be an int or none, but it's a %s", Object_GetName(argv[0]));
return NULL;
}
FILE *fp = Object_ToStream(argv[0], error);
if(fp == NULL)
return NULL;
size_t n = fwrite(buff_addr, 1, write_size, fp);
return Object_FromInt(n, heap, error);
}
static Object *bin_openDir(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
// Arg 0: path
if(!Object_IsString(argv[0]))
{
Error_Report(error, 0, "Expected first argument to be a string, but it's a %s", Object_GetName(argv[0]));
return NULL;
}
Heap *heap = Runtime_GetHeap(runtime);
const char *path = Object_ToString(argv[0], NULL, heap, error);
if(error->occurred)
return NULL;
DIR *dir = opendir(path);
if(dir == NULL)
return Object_NewNone(heap, error);
Object *dob = Object_FromDIR(dir, heap, error);
if(error->occurred)
{
(void) closedir(dir);
return NULL;
}
return dob;
}
static Object *bin_nextDirItem(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
// Arg 0: path
if(!Object_IsDir(argv[0]))
{
Error_Report(error, 0, "Expected first argument to be a directory, but it's a %s", Object_GetName(argv[0]));
return NULL;
}
DIR *dir = Object_ToDIR(argv[0], error);
if(error->occurred)
return NULL;
assert(dir != NULL);
Heap *heap = Runtime_GetHeap(runtime);
errno = 0;
struct dirent *ent = readdir(dir);
if(ent == NULL)
{
if(errno == 0)
// Nothing left to read.
return Object_NewNone(heap, error);
// An error occurred.
Error_Report(error, 1, "Failed to read directory item");
return NULL;
}
return Object_FromString(ent->d_name, -1, heap, error);
}
const StaticMapSlot bins_file[] = {
{ "READ", SM_INT, .as_int = MD_READ, },
{ "WRITE", SM_INT, .as_int = MD_WRITE, },
{ "APPEND", SM_INT, .as_int = MD_APPEND, },
{ "openFile", SM_FUNCT, .as_funct = bin_openFile, .argc = 2, },
{ "openDir", SM_FUNCT, .as_funct = bin_openDir, .argc = 1, },
{ "nextDirItem", SM_FUNCT, .as_funct = bin_nextDirItem, .argc = 1, },
{ "read", SM_FUNCT, .as_funct = bin_read, .argc = 2, },
{ "write", SM_FUNCT, .as_funct = bin_write, .argc = 3, },
{ NULL, SM_END, {}, {} },
};
+2
View File
@@ -0,0 +1,2 @@
#include "../o_staticmap.h"
extern const StaticMapSlot bins_file[];
+94
View File
@@ -0,0 +1,94 @@
#include <assert.h>
#include <math.h>
#include "math.h"
#define WRAP_FUNC(name) \
static Object *bin_ ## name(Runtime *runtime, Object **argv, unsigned int argc, Error *error) \
{ \
assert(argc == 1); \
\
if(Object_IsFloat(argv[0])) \
{ \
double v = Object_ToFloat(argv[0], error); \
\
if(error->occurred) \
return NULL; \
\
return Object_FromFloat(name(v), Runtime_GetHeap(runtime), error); \
} \
else \
{ \
Error_Report(error, 0, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0]));\
return NULL; \
} \
}
#define WRAP_FUNC_2(name) \
static Object *bin_ ## name(Runtime *runtime, Object **argv, unsigned int argc, Error *error) \
{ \
assert(argc == 2); \
\
if(!Object_IsFloat(argv[0])) \
{ \
Error_Report(error, 0, "Expected first argument to be a float, but it's a %s", Object_GetName(argv[0]));\
return NULL; \
} \
\
if(!Object_IsFloat(argv[1])) \
{ \
Error_Report(error, 0, "Expected second argument to be a float, but it's a %s", Object_GetName(argv[1]));\
return NULL; \
} \
\
double v1 = Object_ToFloat(argv[0], error); \
\
if(error->occurred) \
return NULL; \
\
double v2 = Object_ToFloat(argv[1], error); \
\
if(error->occurred) \
return NULL; \
\
return Object_FromFloat(name(v1, v2), Runtime_GetHeap(runtime), error); \
}
WRAP_FUNC(ceil)
WRAP_FUNC(floor)
WRAP_FUNC(sin)
WRAP_FUNC(cos)
WRAP_FUNC(tan)
WRAP_FUNC(asin)
WRAP_FUNC(acos)
WRAP_FUNC(atan)
WRAP_FUNC(exp)
WRAP_FUNC(log)
WRAP_FUNC(log10)
WRAP_FUNC(sqrt)
WRAP_FUNC_2(atan2)
WRAP_FUNC_2(pow)
const StaticMapSlot bins_math[] = {
{ "PI", SM_FLOAT, .as_float = M_PI },
{ "E", SM_FLOAT, .as_float = M_E },
{ "floor", SM_FUNCT, .as_funct = bin_floor, .argc = 1, },
{ "ceil", SM_FUNCT, .as_funct = bin_ceil, .argc = 1, },
{ "cos", SM_FUNCT, .as_funct = bin_cos, .argc = 1, },
{ "sin", SM_FUNCT, .as_funct = bin_sin, .argc = 1, },
{ "tan", SM_FUNCT, .as_funct = bin_tan, .argc = 1, },
{ "acos", SM_FUNCT, .as_funct = bin_acos, .argc = 1, },
{ "asin", SM_FUNCT, .as_funct = bin_asin, .argc = 1, },
{ "atan", SM_FUNCT, .as_funct = bin_atan, .argc = 1, },
{ "atan2", SM_FUNCT, .as_funct = bin_atan2, .argc = 2, },
{ "exp", SM_FUNCT, .as_funct = bin_exp, .argc = 1, },
{ "log", SM_FUNCT, .as_funct = bin_log, .argc = 1, },
{ "log10", SM_FUNCT, .as_funct = bin_log10, .argc = 1, },
{ "pow", SM_FUNCT, .as_funct = bin_pow, .argc = 1, },
{ "sqrt", SM_FUNCT, .as_funct = bin_sqrt, .argc = 1, },
{ NULL, SM_END, {}, {} },
};
+2
View File
@@ -0,0 +1,2 @@
#include "../o_staticmap.h"
extern const StaticMapSlot bins_math[];
+3 -2
View File
@@ -2,12 +2,13 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "o_builtins.h"
#include "o_staticmap.h"
#include "compiler/parse.h"
#include "compiler/serialize.h"
#include "compiler/compile.h"
#include "runtime/runtime.h"
#include "runtime/runtime_error.h"
#include "builtins/basic.h"
static const char usage[] =
"Usage:\n"
@@ -207,7 +208,7 @@ static _Bool interpret(Source *src)
RuntimeError error;
RuntimeError_Init(&error, runt); // Here we specify the runtime to snapshot in case of failure.
Object *bins = Object_NewBuiltinsMap(runt, Runtime_GetHeap(runt), (Error*) &error);
Object *bins = Object_NewStaticMap(bins_basic, runt, (Error*) &error);
if(bins == NULL)
{
-256
View File
@@ -1,256 +0,0 @@
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include "runtime/runtime.h"
#include "utils/defs.h"
#include "o_builtins.h"
static Object *select_(Object *self, Object *key, Heap *heap, Error *err);
static Object *bin_type (Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_print (Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_count (Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_strcat(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_newBuffer(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_sliceBuffer(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
typedef struct {
Object base;
Runtime *runtime;
} BuiltinsMapOjbect;
static TypeObject t_builtins_map = {
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
.name = "builtins map",
.size = sizeof(BuiltinsMapOjbect),
.select = select_,
};
static Object *select_(Object *self, Object *key, Heap *heap, Error *err)
{
BuiltinsMapOjbect *bm = (BuiltinsMapOjbect*) self;
if(!Object_IsString(key))
{
Error_Report(err, 0, "Non string key");
return NULL;
}
int n;
const char *s;
s = Object_ToString(key, &n, heap, err);
if(s == NULL)
return NULL;
#define PAIR(p, q) \
(((uint64_t) (p) << 32) | (uint32_t) (q))
switch(PAIR(n, s[0]))
{
case PAIR(4, 't'):
{
if(!strcmp(s, "type"))
return Object_FromNativeFunction(bm->runtime, bin_type, 1, heap, err);
return NULL;
}
case PAIR(sizeof("count")-1, 'c'):
{
if(!strcmp(s, "count"))
return Object_FromNativeFunction(bm->runtime, bin_count, 1, heap, err);
return NULL;
}
case PAIR(sizeof("print")-1, 'p'):
{
if(!strcmp(s, "print"))
return Object_FromNativeFunction(bm->runtime, bin_print, -1, heap, err);
return NULL;
}
case PAIR(sizeof("assert")-1, 'a'):
{
if(!strcmp(s, "assert"))
return Object_FromNativeFunction(bm->runtime, bin_assert, -1, heap, err);
return NULL;
}
case PAIR(sizeof("strcat")-1, 's'):
{
if(!strcmp(s, "strcat"))
return Object_FromNativeFunction(bm->runtime, bin_strcat, -1, heap, err);
return NULL;
}
case PAIR(sizeof("sliceBuffer")-1, 's'):
{
if(!strcmp(s, "sliceBuffer"))
return Object_FromNativeFunction(bm->runtime, bin_sliceBuffer, 3, heap, err);
return NULL;
}
case PAIR(sizeof("net")-1, 'n'):
{
if(!strcmp(s, "net"))
return Object_NewNetworkBuiltinsMap(bm->runtime, heap, err);
return NULL;
}
case PAIR(sizeof("newBuffer")-1, 'n'):
{
if(!strcmp(s, "newBuffer"))
return Object_FromNativeFunction(bm->runtime, bin_newBuffer, 1, heap, err);
return NULL;
}
}
// Not found.
return NULL;
}
Object *Object_NewBuiltinsMap(Runtime *runtime, Heap *heap, Error *err)
{
BuiltinsMapOjbect *bm = (BuiltinsMapOjbect*) Heap_Malloc(heap, &t_builtins_map, err);
if(bm == NULL)
return NULL;
bm->runtime = runtime;
return (Object*) bm;
}
static Object *bin_print(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
for(int i = 0; i < (int) argc; i += 1)
Object_Print(argv[i], stdout);
return Object_NewNone(Runtime_GetHeap(runtime), error);
}
static Object *bin_type(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
(void) runtime;
(void) error;
return (Object*) argv[0]->type;
}
static Object *bin_count(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
int n = Object_Count(argv[0], error);
if(error->occurred)
return NULL;
return Object_FromInt(n, Runtime_GetHeap(runtime), error);
}
static Object *bin_assert(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
if(Object_ToBool(argv[0], error))
{
return Object_NewNone(Runtime_GetHeap(runtime), error);
}
else
{
if(!error->occurred)
Error_Report(error, 0, "Assertion failed");
return NULL;
}
}
static Object *bin_strcat(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
unsigned int total_count = 0;
for(unsigned int i = 0; i < argc; i += 1)
{
if(!Object_IsString(argv[i]))
{
Error_Report(error, 0, "Argument #%d is not a string", i+1);
return NULL;
}
total_count += Object_Count(argv[i], error);
if(error->occurred)
return NULL;
}
char starting[128];
char *buffer = starting;
if(total_count > sizeof(starting)-1)
{
buffer = malloc(total_count+1);
if(buffer == NULL)
{
Error_Report(error, 1, "No memory");
return NULL;
}
}
Object *result = NULL;
for(unsigned int i = 0, written = 0; i < argc; i += 1)
{
int n;
const char *s;
s = Object_ToString(argv[i], &n, Runtime_GetHeap(runtime), error);
if(error->occurred)
goto done;
memcpy(buffer + written, s, n);
written += n;
}
buffer[total_count] = '\0';
result = Object_FromString(buffer, total_count, Runtime_GetHeap(runtime), error);
done:
if(starting != buffer)
free(buffer);
return result;
}
static Object *bin_newBuffer(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
long long int size = Object_ToInt(argv[0], error);
if(error->occurred == 1)
return NULL;
return Object_NewBuffer(size, Runtime_GetHeap(runtime), error);
}
static Object *bin_sliceBuffer(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 3);
long long int offset = Object_ToInt(argv[1], error);
if(error->occurred == 1) return NULL;
long long int length = Object_ToInt(argv[2], error);
if(error->occurred == 1) return NULL;
return Object_SliceBuffer(argv[0], offset, length, Runtime_GetHeap(runtime), error);
}
-3
View File
@@ -1,3 +0,0 @@
#include "runtime/runtime.h"
Object *Object_NewBuiltinsMap(Runtime *runtime, Heap *heap, Error *err);
Object *Object_NewNetworkBuiltinsMap(Runtime *runtime, Heap *heap, Error *err);
-755
View File
@@ -1,755 +0,0 @@
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include "runtime/runtime.h"
#include "utils/defs.h"
static Object *select_(Object *self, Object *key, Heap *heap, Error *err);
static Object *bin_bind(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_listen(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_socket(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_accept(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_connect(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_inet_aton(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_inet_ntoa(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_htonl(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_ntohl(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_htons(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_ntohs(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_send(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
static Object *bin_recv(Runtime *runtime, Object **argv, unsigned int argc, Error *error);
typedef struct {
Object base;
Runtime *runtime;
} NetworkBuiltinsMapOjbect;
static TypeObject t_builtins_map = {
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
.name = "network builtins map",
.size = sizeof(NetworkBuiltinsMapOjbect),
.select = select_,
};
static Object *select_(Object *self, Object *key, Heap *heap, Error *err)
{
NetworkBuiltinsMapOjbect *bm = (NetworkBuiltinsMapOjbect*) self;
if(!Object_IsString(key))
{
Error_Report(err, 0, "Non string key");
return NULL;
}
int n;
const char *s;
s = Object_ToString(key, &n, heap, err);
if(s == NULL)
return NULL;
#define PAIR(p, q) \
(((uint64_t) (p) << 32) | (uint32_t) (q))
switch(PAIR(n, s[0]))
{
case PAIR(4, 's'):
{
if(!strcmp(s, "send"))
return Object_FromNativeFunction(bm->runtime, bin_send, 3, heap, err);
return NULL;
}
case PAIR(4, 'r'):
{
if(!strcmp(s, "recv"))
return Object_FromNativeFunction(bm->runtime, bin_recv, 3, heap, err);
return NULL;
}
case PAIR(10, 'I'):
{
if(!strcmp(s, "INADDR_ANY"))
return Object_FromInt(INADDR_ANY, heap, err);
return NULL;
}
case PAIR(6, 'a'):
{
if(!strcmp(s, "accept"))
return Object_FromNativeFunction(bm->runtime, bin_accept, 2, heap, err);
return NULL;
}
case PAIR(4, 'b'):
{
if(!strcmp(s, "bind"))
return Object_FromNativeFunction(bm->runtime, bin_bind, 2, heap, err);
return NULL;
}
case PAIR(6, 'l'):
{
if(!strcmp(s, "listen"))
return Object_FromNativeFunction(bm->runtime, bin_listen, 2, heap, err);
return NULL;
}
case PAIR(5, 'n'):
{
if(!strcmp(s, "ntohl"))
return Object_FromNativeFunction(bm->runtime, bin_ntohl, 1, heap, err);
if(!strcmp(s, "ntohs"))
return Object_FromNativeFunction(bm->runtime, bin_ntohs, 1, heap, err);
return NULL;
}
case PAIR(5, 'h'):
{
if(!strcmp(s, "htonl"))
return Object_FromNativeFunction(bm->runtime, bin_htonl, 1, heap, err);
if(!strcmp(s, "htons"))
return Object_FromNativeFunction(bm->runtime, bin_htons, 1, heap, err);
return NULL;
}
case PAIR(9, 'i'):
{
if(!strcmp(s, "inet_aton"))
return Object_FromNativeFunction(bm->runtime, bin_inet_aton, 2, heap, err);
if(!strcmp(s, "inet_ntoa"))
return Object_FromNativeFunction(bm->runtime, bin_inet_ntoa, 1, heap, err);
return NULL;
}
case PAIR(6, 's'):
{
if(!strcmp(s, "socket"))
return Object_FromNativeFunction(bm->runtime, bin_socket, 3, heap, err);
return NULL;
}
case PAIR(7, 'c'):
{
if(!strcmp(s, "connect"))
return Object_FromNativeFunction(bm->runtime, bin_connect, 2, heap, err);
return NULL;
}
case PAIR(8, 'S'):
{
if(!strcmp(s, "SOCK_RAW"))
return Object_FromInt(SOCK_RAW, heap, err);
if(!strcmp(s, "SOCK_RDM"))
return Object_FromInt(SOCK_RDM, heap, err);
return NULL;
}
case PAIR(10, 'S'):
{
if(!strcmp(s, "SOCK_DGRAM"))
return Object_FromInt(SOCK_DGRAM, heap, err);
return NULL;
}
case PAIR(11, 'S'):
{
if(!strcmp(s, "SOCK_STREAM"))
return Object_FromInt(SOCK_STREAM, heap, err);
if(!strcmp(s, "SOCK_PACKET"))
return Object_FromInt(SOCK_PACKET, heap, err);
return NULL;
}
case PAIR(12, 'S'):
{
if(!strcmp(s, "SOCK_CLOEXEC"))
return Object_FromInt(SOCK_CLOEXEC, heap, err);
return NULL;
}
case PAIR(13, 'S'):
{
if(!strcmp(s, "SOCK_NONBLOCK"))
return Object_FromInt(SOCK_NONBLOCK, heap, err);
return NULL;
}
case PAIR(14, 'S'):
{
if(!strcmp(s, "SOCK_SEQPACKET"))
return Object_FromInt(SOCK_SEQPACKET, heap, err);
return NULL;
}
case PAIR(5, 'A'):
{
if(s[1] == 'F' && s[2] == '_')
{
if(!strcmp(s+3, "IB"))
return Object_FromInt(AF_IB, heap, err);
}
return NULL;
}
case PAIR(6, 'A'):
{
if(s[1] == 'F' && s[2] == '_')
{
if(!strcmp(s+3, "IPX"))
return Object_FromInt(AF_IPX, heap, err);
if(!strcmp(s+3, "X25"))
return Object_FromInt(AF_X25, heap, err);
if(!strcmp(s+3, "KEY"))
return Object_FromInt(AF_KEY, heap, err);
if(!strcmp(s+3, "RDS"))
return Object_FromInt(AF_RDS, heap, err);
if(!strcmp(s+3, "LLC"))
return Object_FromInt(AF_LLC, heap, err);
if(!strcmp(s+3, "CAN"))
return Object_FromInt(AF_CAN, heap, err);
if(!strcmp(s+3, "ALG"))
return Object_FromInt(AF_ALG, heap, err);
if(!strcmp(s+3, "KCM"))
return Object_FromInt(AF_KCM, heap, err);
if(!strcmp(s+3, "XDP"))
return Object_FromInt(AF_XDP, heap, err);
}
return NULL;
}
case PAIR(7, 'A'):
{
if(s[1] == 'F' && s[2] == '_')
{
if(!strcmp(s+3, "UNIX"))
return Object_FromInt(AF_UNIX, heap, err);
if(!strcmp(s+3, "INET"))
return Object_FromInt(AF_INET, heap, err);
if(!strcmp(s+3, "AX25"))
return Object_FromInt(AF_AX25, heap, err);
if(!strcmp(s+3, "MPLS"))
return Object_FromInt(AF_MPLS, heap, err);
if(!strcmp(s+3, "TIPC"))
return Object_FromInt(AF_TIPC, heap, err);
}
return NULL;
}
case PAIR(8, 'A'):
{
if(s[1] == 'F' && s[2] == '_')
{
if(!strcmp(s+3, "LOCAL"))
return Object_FromInt(AF_LOCAL, heap, err);
if(!strcmp(s+3, "INET6"))
return Object_FromInt(AF_INET6, heap, err);
if(!strcmp(s+3, "PPPOX"))
return Object_FromInt(AF_PPPOX, heap, err);
if(!strcmp(s+3, "VSOCK"))
return Object_FromInt(AF_VSOCK, heap, err);
}
return NULL;
}
case PAIR(9, 'A'):
{
if(s[1] == 'F' && s[2] == '_')
{
if(!strcmp(s+3, "DECnet"))
return Object_FromInt(AF_DECnet, heap, err);
if(!strcmp(s+3, "PACKET"))
return Object_FromInt(AF_PACKET, heap, err);
}
return NULL;
}
case PAIR(10, 'A'):
{
if(s[1] == 'F' && s[2] == '_')
{
if(!strcmp(s+3, "NETLINK"))
return Object_FromInt(AF_NETLINK, heap, err);
}
return NULL;
}
case PAIR(12, 'A'):
{
if(s[1] == 'F' && s[2] == '_')
{
if(!strcmp(s+3, "BLUETOOTH"))
return Object_FromInt(AF_BLUETOOTH, heap, err);
if(!strcmp(s+3, "APPLETALK"))
return Object_FromInt(AF_APPLETALK, heap, err);
}
return NULL;
}
}
// Not found.
return NULL;
}
Object *Object_NewNetworkBuiltinsMap(Runtime *runtime, Heap *heap, Error *err)
{
NetworkBuiltinsMapOjbect *bm = (NetworkBuiltinsMapOjbect*) Heap_Malloc(heap, &t_builtins_map, err);
if(bm == NULL)
return NULL;
bm->runtime = runtime;
return (Object*) bm;
}
static Object *bin_socket(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 3);
int domain, type, protocol;
domain = Object_ToInt(argv[0], error);
if(error->occurred == 1) return NULL;
type = Object_ToInt(argv[1], error);
if(error->occurred == 1) return NULL;
protocol = Object_ToInt(argv[2], error);
if(error->occurred == 1) return NULL;
int fd = socket(domain, type, protocol);
return Object_FromInt(fd, Runtime_GetHeap(runtime), error);
}
static _Bool get_in_addr_from_map(Object *map, struct in_addr *addr, Heap *heap, Error *error)
{
Object *o_key = Object_FromString("s_addr", -1, heap, error);
if(o_key == NULL) return 0;
Object *o_s_addr = Object_Select(map, o_key, heap, error);
if(o_s_addr == NULL)
{
if(error->occurred == 0)
Error_Report(error, 0, "Missing the \"s_addr\" key");
return 0;
}
long long int s_addr = Object_ToInt(o_s_addr, error);
if(error->occurred) return 0;
if(s_addr < 0 || s_addr >= (long long int) ULONG_MAX)
{
Error_Report(error, 0, "s_addr must be in range [0, %lu]", ULONG_MAX);
return 0;
}
if(addr)
addr->s_addr = s_addr;
return 1;
}
static _Bool get_sockaddr_in_from_map(Object *map, struct sockaddr_in *addr, Heap *heap, Error *error)
{
Object *o_key = Object_FromString("sin_family", -1, heap, error);
if(o_key == NULL) return 0;
Object *o_sin_family = Object_Select(map, o_key, heap, error);
if(o_sin_family == NULL)
{
if(error->occurred == 0)
Error_Report(error, 0, "Argument 2 is missing the \"sin_family\" key");
return 0;
}
long long int sin_family = Object_ToInt(o_sin_family, error);
if(error->occurred) return 0;
if(sin_family < 0 || sin_family >= 65536)
{
Error_Report(error, 0, "sin_family must be in range [0, 65535]");
return 0;
}
o_key = Object_FromString("sin_port", -1, heap, error);
if(o_key == NULL) return 0;
Object *o_sin_port = Object_Select(map, o_key, heap, error);
if(o_sin_port == NULL)
{
if(error->occurred == 0)
Error_Report(error, 0, "Argument 2 is missing the \"sin_port\" key");
return 0;
}
long long int sin_port = Object_ToInt(o_sin_port, error);
if(error->occurred) return 0;
if(sin_port < 0 || sin_port >= 65536)
{
Error_Report(error, 0, "sin_port must be in range [0, 65535]");
return 0;
}
o_key = Object_FromString("sin_addr", -1, heap, error);
if(o_key == NULL) return 0;
Object *o_sin_addr = Object_Select(map, o_key, heap, error);
if(o_sin_addr == NULL)
{
if(error->occurred == 0)
Error_Report(error, 0, "Argument 2 is missing the \"sin_addr\" key");
return 0;
}
struct in_addr sin_addr;
if(!get_in_addr_from_map(o_sin_addr, &sin_addr, heap, error))
return 0;
if(addr)
{
memset(addr, 0, sizeof(struct sockaddr_in));
addr->sin_family = sin_family;
addr->sin_port = sin_port;
addr->sin_addr = sin_addr;
}
return 1;
}
static Object *bin_connect(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 2);
Heap *heap = Runtime_GetHeap(runtime);
int sockfd;
struct sockaddr_in addr;
sockfd = Object_ToInt(argv[0], error);
if(error->occurred == 1) return NULL;
if(!get_sockaddr_in_from_map(argv[1], &addr, heap, error))
return NULL;
int r = connect(sockfd, (struct sockaddr*) &addr, sizeof(struct sockaddr_in));
return Object_FromInt(r, Runtime_GetHeap(runtime), error);
}
static Object *bin_inet_aton(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 2);
Heap *heap = Runtime_GetHeap(runtime);
const char *s = Object_ToString(argv[0], NULL, heap, error);
if(s == NULL) return NULL;
// Note that the string must be zero-terminated.
struct in_addr addr;
int r = inet_aton(s, &addr);
if(r != 0)
{
// inet_aton succeded.
Object *o_key = Object_FromString("s_addr", -1, heap, error);
if(o_key == NULL) return NULL;
Object *o_val = Object_FromInt(addr.s_addr, heap, error);
if(o_val == NULL) return NULL;
if(!Object_Insert(argv[1], o_key, o_val, heap, error))
return NULL;
}
return Object_FromInt(r, heap, error);
}
static Object *bin_inet_ntoa(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
Heap *heap = Runtime_GetHeap(runtime);
struct in_addr in_addr;
if(!get_in_addr_from_map(argv[0], &in_addr, heap, error))
return NULL;
const char *addr = inet_ntoa(in_addr);
assert(addr != NULL);
return Object_FromString(addr, -1, heap, error);
}
static Object *bin_htonl(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
Heap *heap = Runtime_GetHeap(runtime);
uint32_t r, p;
p = Object_ToInt(argv[0], error);
if(error->occurred) return NULL;
r = htonl(p);
return Object_FromInt(r, heap, error);
}
static Object *bin_ntohl(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
Heap *heap = Runtime_GetHeap(runtime);
uint32_t r, p;
p = Object_ToInt(argv[0], error);
if(error->occurred) return NULL;
r = ntohl(p);
return Object_FromInt(r, heap, error);
}
static Object *bin_ntohs(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
Heap *heap = Runtime_GetHeap(runtime);
int p = Object_ToInt(argv[0], error);
if(error->occurred) return NULL;
if(p < 0 || p > 65535)
{
Error_Report(error, 0, "Argument is not in range [0, 65535]");
return NULL;
}
uint16_t r = ntohs(p);
return Object_FromInt(r, heap, error);
}
static Object *bin_htons(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 1);
Heap *heap = Runtime_GetHeap(runtime);
int p = Object_ToInt(argv[0], error);
if(error->occurred) return NULL;
if(p < 0 || p > 65535)
{
Error_Report(error, 0, "Argument is not in range [0, 65535]");
return NULL;
}
uint16_t r = htons(p);
return Object_FromInt(r, heap, error);
}
static Object *bin_bind(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 2);
Heap *heap = Runtime_GetHeap(runtime);
int sockfd;
struct sockaddr_in addr;
sockfd = Object_ToInt(argv[0], error);
if(error->occurred) return NULL;
if(!get_sockaddr_in_from_map(argv[1], &addr, heap, error))
return 0;
int r = bind(sockfd, (struct sockaddr*) &addr, sizeof(struct sockaddr_in));
return Object_FromInt(r, heap, error);
}
static Object *bin_listen(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 2);
Heap *heap = Runtime_GetHeap(runtime);
int sockfd, backlog;
sockfd = Object_ToInt(argv[0], error);
if(error->occurred) return NULL;
backlog = Object_ToInt(argv[1], error);
if(error->occurred) return NULL;
int r = listen(sockfd, backlog);
return Object_FromInt(r, heap, error);
}
static Object *bin_accept(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 2);
Heap *heap = Runtime_GetHeap(runtime);
long long int sockfd = Object_ToInt(argv[0], error);
if(error->occurred) return NULL;
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
int r = accept(sockfd, (struct sockaddr*) &addr, &len);
if(r >= 0) {
// accept succeded.
Object *o_key,
*o_sin_family,
*o_sin_addr,
*o_sin_port,
*o_s_addr;
o_sin_family = Object_FromInt(addr.sin_family, heap, error);
if(error->occurred) return NULL;
o_sin_port = Object_FromInt(addr.sin_port, heap, error);
if(error->occurred) return NULL;
o_sin_addr = Object_NewMap(1, heap, error);
if(error->occurred) return NULL;
o_s_addr = Object_FromInt(addr.sin_addr.s_addr, heap, error);
if(error->occurred) return NULL;
o_key = Object_FromString("s_addr", -1, heap, error);
if(error->occurred) return NULL;
if(!Object_Insert(o_sin_addr, o_key, o_s_addr, heap, error))
return NULL;
o_key = Object_FromString("sin_family", -1, heap, error);
if(error->occurred) return NULL;
if(!Object_Insert(argv[1], o_key, o_sin_family, heap, error))
return NULL;
o_key = Object_FromString("sin_port", -1, heap, error);
if(error->occurred) return NULL;
if(!Object_Insert(argv[1], o_key, o_sin_port, heap, error))
return NULL;
o_key = Object_FromString("sin_addr", -1, heap, error);
if(error->occurred) return NULL;
if(!Object_Insert(argv[1], o_key, o_sin_addr, heap, error))
return NULL;
}
return Object_FromInt(r, heap, error);
}
static Object *bin_send(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 3);
Heap *heap = Runtime_GetHeap(runtime);
int sockfd = Object_ToInt(argv[0], error);
if(error->occurred) return NULL;
int size;
void *addr = Object_GetBufferAddrAndSize(argv[1], &size, error);
if(addr == NULL) return NULL;
int flags = Object_ToInt(argv[2], error);
if(error->occurred) return NULL;
ssize_t r = send(sockfd, addr, size, flags);
return Object_FromInt(r, heap, error);
}
static Object *bin_recv(Runtime *runtime, Object **argv, unsigned int argc, Error *error)
{
assert(argc == 3);
Heap *heap = Runtime_GetHeap(runtime);
int sockfd = Object_ToInt(argv[0], error);
if(error->occurred) return NULL;
int size;
void *addr = Object_GetBufferAddrAndSize(argv[1], &size, error);
if(addr == NULL) return NULL;
int flags = Object_ToInt(argv[2], error);
if(error->occurred) return NULL;
ssize_t r = recv(sockfd, addr, size, flags);
return Object_FromInt(r, heap, error);
}
+94
View File
@@ -0,0 +1,94 @@
#include <string.h>
#include <assert.h>
#include "o_staticmap.h"
#include "utils/defs.h"
#include "objects/objects.h"
typedef struct {
Object base;
Runtime *runt;
const StaticMapSlot *slots;
} StaticMapObject;
static Object *select(Object *self, Object *key, Heap *heap, Error *err);
static Object *copy(Object *self, Heap *heap, Error *err);
static int hash(Object *self);
static TypeObject t_staticmap = {
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
.name = "static map",
.size = sizeof (StaticMapObject),
.copy = copy,
.hash = hash,
.select = select,
};
static Object *copy(Object *self, Heap *heap, Error *err)
{
(void) heap;
(void) err;
return self;
}
static int hash(Object *self)
{
(void) self;
return 0;
}
Object *Object_NewStaticMap(const StaticMapSlot *slots, Runtime *runt, Error *error)
{
Heap *heap = Runtime_GetHeap(runt);
// Make the thing.
StaticMapObject *obj = (StaticMapObject*) Heap_Malloc(heap, &t_staticmap, error);
{
if(obj == 0)
return 0;
obj->runt = runt;
obj->slots = slots;
}
return (Object*) obj;
}
static Object *select(Object *self, Object *key, Heap *heap, Error *error)
{
assert(self != NULL);
assert(self->type == &t_staticmap);
assert(key != NULL);
assert(heap != NULL);
assert(error != NULL);
StaticMapObject *map = (StaticMapObject*) self;
if(!Object_IsString(key))
return NULL;
const char *name = Object_ToString(key, NULL, heap, error);
if(map->slots == NULL)
return NULL;
for(int i = 0; map->slots[i].name != NULL; i += 1)
if(!strcmp(name, map->slots[i].name))
{
StaticMapSlot slot = map->slots[i];
Object *obj;
switch(slot.kind)
{
case SM_BOOL: return Object_FromBool(slot.as_bool, heap, error);
case SM_INT: return Object_FromInt(slot.as_int, heap, error);
case SM_FLOAT: return Object_FromFloat(slot.as_float, heap, error);
case SM_FUNCT: return Object_FromNativeFunction(map->runt, slot.as_funct, slot.argc, heap, error);
case SM_STRING: return Object_FromString(slot.as_string, slot.length, heap, error);
case SM_SMAP: return Object_NewStaticMap(slot.as_smap, map->runt, error);
case SM_NONE: return Object_NewNone(heap, error);
case SM_TYPE: return (Object*) slot.as_type;
default: assert(0); break;
}
return obj;
}
return NULL;
}
+37
View File
@@ -0,0 +1,37 @@
#ifndef STATICMAP_H
#define STATICMAP_H
#include "objects/objects.h"
#include "runtime/runtime.h"
typedef enum {
SM_END,
SM_BOOL,
SM_INT,
SM_FLOAT,
SM_FUNCT,
SM_STRING,
SM_SMAP,
SM_NONE,
SM_TYPE,
} StaticMapSlotKind;
typedef struct StaticMapSlot StaticMapSlot;
struct StaticMapSlot {
const char *name;
StaticMapSlotKind kind;
union {
const StaticMapSlot *as_smap;
const char *as_string;
_Bool as_bool;
long long int as_int;
double as_float;
Object *(*as_funct)(Runtime*, Object**, unsigned int, Error*);
TypeObject *as_type;
};
union { int argc; int length; };
};
Object *Object_NewStaticMap(const StaticMapSlot *slots, Runtime *runt, Error *error);
#endif
+5
View File
@@ -52,6 +52,11 @@ static TypeObject t_buffer_slice = {
#define THRESHOLD 128
_Bool Object_IsBuffer(Object *obj)
{
return obj->type == &t_buffer_slice || obj->type == &t_buffer;
}
Object *Object_NewBuffer(int size, Heap *heap, Error *error)
{
assert(size >= 0);
+53
View File
@@ -0,0 +1,53 @@
#include "objects.h"
typedef struct {
Object base;
DIR *dir;
} DirObject;
static _Bool dir_free(Object *obj, Error *error);
static TypeObject t_dir = {
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
.name = "Directory",
.size = sizeof(DirObject),
.free = dir_free,
};
_Bool Object_IsDir(Object *obj)
{
return obj->type == &t_dir;
}
Object *Object_FromDIR(DIR *handle, Heap *heap, Error *error)
{
DirObject *dob = (DirObject*) Heap_Malloc(heap, &t_dir, error);
if(dob == NULL)
return NULL;
dob->dir = handle;
return (Object*) dob;
}
DIR *Object_ToDIR(Object *obj, Error *error)
{
if(!Object_IsDir(obj))
{
Error_Report(error, 0, "Object is not a directory");
return NULL;
}
return ((DirObject*) obj)->dir;
}
static _Bool dir_free(Object *obj, Error *error)
{
DirObject *dob = (DirObject*) obj;
if(closedir(dob->dir) == 0)
return 1;
Error_Report(error, 0, "Failed to close directory");
return 0;
}
+53
View File
@@ -0,0 +1,53 @@
#include "objects.h"
typedef struct {
Object base;
FILE *fp;
} FileObject;
static _Bool file_free(Object *self, Error *error);
static TypeObject t_file = {
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
.name = "File",
.size = sizeof(FileObject),
.free = file_free,
};
_Bool Object_IsFile(Object *obj)
{
return obj->type == &t_file;
}
FILE *Object_ToStream(Object *obj, Error *error)
{
if(!Object_IsFile(obj))
{
Error_Report(error, 0, "Object is not a file");
return NULL;
}
return ((FileObject*) obj)->fp;
}
Object *Object_FromStream(FILE *fp, Heap *heap, Error *error)
{
FileObject *fob = Heap_Malloc(heap, &t_file, error);
if(fob == NULL)
return NULL;
fob->fp = fp;
return (Object*) fob;
}
static _Bool file_free(Object *self, Error *error)
{
FileObject *fob = (FileObject*) self;
if(fclose(fob->fp) == 0)
return 1;
Error_Report(error, 0, "Failed to close stream");
return 0;
}
+5
View File
@@ -22,6 +22,11 @@ static Object the_none_object = {
.flags = Object_STATIC,
};
_Bool Object_IsNone(Object *obj)
{
return obj == &the_none_object;
}
static int hash(Object *self)
{
assert(self == &the_none_object);
+14 -4
View File
@@ -1,6 +1,7 @@
#ifndef OBJECT_H
#define OBJECT_H
#include <dirent.h>
#include <stdio.h>
#include "../utils/error.h"
@@ -115,18 +116,27 @@ Object* Object_FromInt (long long int val, Heap *heap, Error *error);
Object* Object_FromBool (_Bool val, Heap *heap, Error *error);
Object* Object_FromFloat (double val, Heap *heap, Error *error);
Object* Object_FromString(const char *str, int len, Heap *heap, Error *error);
Object* Object_FromStream(FILE *fp, Heap *heap, Error *error);
Object* Object_FromDIR(DIR *handle, Heap *heap, Error *error);
_Bool Object_IsInt (Object *obj);
_Bool Object_IsBool (Object *obj);
_Bool Object_IsFloat(Object *obj);
_Bool Object_IsString(Object *obj);
_Bool Object_IsNone(Object *obj);
_Bool Object_IsInt(Object *obj);
_Bool Object_IsBool(Object *obj);
_Bool Object_IsFloat(Object *obj);
_Bool Object_IsString(Object *obj);
_Bool Object_IsBuffer(Object *obj);
_Bool Object_IsFile(Object *obj);
_Bool Object_IsDir(Object *obj);
long long int Object_ToInt (Object *obj, Error *err);
_Bool Object_ToBool (Object *obj, Error *err);
double Object_ToFloat(Object *obj, Error *err);
const char *Object_ToString(Object *obj, int *size, Heap *heap, Error *err);
DIR *Object_ToDIR(Object *obj, Error *error);
FILE *Object_ToStream(Object *obj, Error *error);
_Bool Object_Compare(Object *obj1, Object *obj2, Error *error);
extern TypeObject t_type;
#endif