removed dead code
This commit is contained in:
@@ -1,80 +0,0 @@
|
|||||||
|
|
||||||
#define MAX_HEADERS 16
|
|
||||||
#define MAX_URI 4096
|
|
||||||
#define MAX_BODY (1024 * 1024)
|
|
||||||
#define MAX_HNAME 128
|
|
||||||
#define MAX_HBODY 1024
|
|
||||||
|
|
||||||
#define BUFFER_INIT_SIZE 256
|
|
||||||
#define BUFFER_GROW_FACTOR 2
|
|
||||||
#define BUFFER_GROW_ADDEND 0
|
|
||||||
|
|
||||||
#define BACKLOG 128
|
|
||||||
#define POLL_TIMEOUT 5000
|
|
||||||
#define MAX_POLL_EVENTS 64
|
|
||||||
#define IMPLICIT_LENGTH 1
|
|
||||||
|
|
||||||
#define MAX_CLIENTS 256
|
|
||||||
#define MAX_ALIVE 64
|
|
||||||
|
|
||||||
typedef void llhs_response;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
llhs_HTTP_0_9,
|
|
||||||
llhs_HTTP_1_0,
|
|
||||||
llhs_HTTP_1_1,
|
|
||||||
} llhs_version;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
llhs_GET,
|
|
||||||
llhs_PUT,
|
|
||||||
llhs_POST,
|
|
||||||
llhs_HEAD,
|
|
||||||
llhs_TRACE,
|
|
||||||
llhs_PATCH,
|
|
||||||
llhs_DELETE,
|
|
||||||
llhs_OPTIONS,
|
|
||||||
llhs_CONNECT,
|
|
||||||
} llhs_method;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *name;
|
|
||||||
const char *body;
|
|
||||||
int namel;
|
|
||||||
int bodyl;
|
|
||||||
} llhs_header;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
llhs_version version;
|
|
||||||
llhs_method method;
|
|
||||||
const char *URI;
|
|
||||||
int URIl;
|
|
||||||
llhs_header headers[MAX_HEADERS];
|
|
||||||
int headerc;
|
|
||||||
const void *body;
|
|
||||||
int bodyl;
|
|
||||||
} llhs_request;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
_Bool occurred;
|
|
||||||
char message[256];
|
|
||||||
int length;
|
|
||||||
const char *file,
|
|
||||||
*func;
|
|
||||||
int line;
|
|
||||||
} llhs_error;
|
|
||||||
|
|
||||||
typedef void (*llhs_callback)(void *userp, const llhs_request *req, llhs_response *res);
|
|
||||||
typedef void (*llhs_logger )(void *userp, const char *level, const char *msg);
|
|
||||||
|
|
||||||
_Bool llhs_serve(unsigned short port, void *userp, llhs_callback callback, llhs_logger logger, llhs_error *error);
|
|
||||||
|
|
||||||
_Bool llhs_match (const char *x, const char *y);
|
|
||||||
_Bool llhs_match2(const char *x, const char *y, int xl, int yl);
|
|
||||||
const char *llhs_getheader(llhs_request *res, const char *name);
|
|
||||||
|
|
||||||
void llhs_setcode (llhs_response *res, int code);
|
|
||||||
_Bool llhs_setbody (llhs_response *res, const void *body, int size);
|
|
||||||
void llhs_setbody2 (llhs_response *res, void *body, int bodyl, void (*free)(void *addr));
|
|
||||||
_Bool llhs_setheader (llhs_response *res, const char *name, const char *body);
|
|
||||||
_Bool llhs_setheader2(llhs_response *res, const char *name, int body);
|
|
||||||
@@ -1,217 +0,0 @@
|
|||||||
|
|
||||||
#ifndef XJSON_H
|
|
||||||
#define XJSON_H
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
enum {
|
|
||||||
xj_INT = (1 << 0),
|
|
||||||
xj_BOOL = (1 << 1),
|
|
||||||
xj_NULL = (1 << 2),
|
|
||||||
xj_FLOAT = (1 << 3),
|
|
||||||
xj_ARRAY = (1 << 4),
|
|
||||||
xj_OBJECT = (1 << 5),
|
|
||||||
xj_STRING = (1 << 6),
|
|
||||||
xj_BIG_INT = (1 << 7),
|
|
||||||
xj_BIG_FLOAT = (1 << 8),
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
|
|
||||||
xj_E0000 = 0, // No error.
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------- //
|
|
||||||
// --- Internal errors ------- //
|
|
||||||
// --------------------------- //
|
|
||||||
|
|
||||||
xj_E0001, // Maximum depth reached.
|
|
||||||
xj_E0002, // Out of memory.
|
|
||||||
xj_E0003, // Not implemented.
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------- //
|
|
||||||
// --- Input errors ---------- //
|
|
||||||
// --------------------------- //
|
|
||||||
|
|
||||||
// (Unexpexted end of source inside object) //
|
|
||||||
|
|
||||||
xj_E1000, // End of source inside object,
|
|
||||||
// right after the starting {
|
|
||||||
|
|
||||||
xj_E1001, // End of source inside object,
|
|
||||||
// right after a key string. Was
|
|
||||||
// expected :
|
|
||||||
|
|
||||||
xj_E1002, // End of source inside object,
|
|
||||||
// right after a key-value separator :.
|
|
||||||
// Was expected a value expression
|
|
||||||
|
|
||||||
xj_E1003, // End of source inside object,
|
|
||||||
// right after value expression.
|
|
||||||
// Were expected , or }
|
|
||||||
|
|
||||||
xj_E1004, // End of source inside object,
|
|
||||||
// right after value-key separator ,.
|
|
||||||
// Was expected a key string
|
|
||||||
|
|
||||||
// (Unexpected end of source inside array) //
|
|
||||||
|
|
||||||
xj_E1100, // End of source inside array,
|
|
||||||
// right after the starting [
|
|
||||||
|
|
||||||
xj_E1101, // End of source inside array,
|
|
||||||
// right after a value expression
|
|
||||||
|
|
||||||
xj_E1102, // End of source inside array,
|
|
||||||
// right after value separator ,.
|
|
||||||
// Was expected a new value
|
|
||||||
// expression
|
|
||||||
|
|
||||||
// (Unexpected end of source inside number) //
|
|
||||||
|
|
||||||
xj_E1200, // End of source inside numeric
|
|
||||||
// expression, right after minus
|
|
||||||
// sign. Was expected a digit
|
|
||||||
|
|
||||||
// (Unexpected end of source inside string) //
|
|
||||||
xj_E1300, // End of source inside string expression
|
|
||||||
xj_E1301, // End of source inside string expression, right after a backslash
|
|
||||||
|
|
||||||
// (Unexpected character inside object) //
|
|
||||||
xj_E2000, // Unexpected character in place of an object key string. Was expected "
|
|
||||||
xj_E2001, // Unexpected character in place of an object key-value separator. Was expected :
|
|
||||||
xj_E2002, // Unexpected character inside object, right after value expression. Were expected , or }
|
|
||||||
|
|
||||||
// (Unexpected character inside array) //
|
|
||||||
xj_E2100, // Unexpected character inside array, right after value expression. Were expecter ] or ,
|
|
||||||
|
|
||||||
// (Unexpected character inside number) //
|
|
||||||
xj_E2200, // Unexpected character inside number expression, right after minus sign. Was expected a digit after it
|
|
||||||
|
|
||||||
// (Unexpected character inside string) //
|
|
||||||
xj_E2300, // Unexpected character inside string expression, right after backslash. The only escapable characters are \, /, ", n, t, r, f, b and u.
|
|
||||||
xj_E2301, // Unexpected character inside string expression, after \u. Was expected a hex digit
|
|
||||||
|
|
||||||
xj_E2302, // Unexpected character inside string expression, right after unicode codepoint. Was expected an auxiliary codepoint
|
|
||||||
xj_E2303, // Unexpected character inside string expression, right after \\. Was expected an auxiliary codepoint
|
|
||||||
|
|
||||||
xj_E2304, // Invalid symbol
|
|
||||||
xj_E2305, // Invalid auxiliary symbol
|
|
||||||
xj_E2306, // Invalid codepoint
|
|
||||||
|
|
||||||
// (Unexpected end of source inside value expression) //
|
|
||||||
xj_E2400, // Unexpected character in place of a value expression. Were expected {, [, ", n, t, f or a digit.
|
|
||||||
|
|
||||||
// (Other) //
|
|
||||||
xj_E2500, // Unexpected character after root value expression
|
|
||||||
xj_E2501, // Source string is empty (null pointer)
|
|
||||||
xj_E2502, // Source string is empty
|
|
||||||
xj_E2503, // Duplicate key in object
|
|
||||||
|
|
||||||
// Decodef errors
|
|
||||||
xj_E3000, // Bad format
|
|
||||||
|
|
||||||
// Query errors
|
|
||||||
xj_E4000, // End of source after dot.
|
|
||||||
xj_E4001, // Invalid character after dot.
|
|
||||||
xj_E4002, // End of source after [.
|
|
||||||
xj_E4003, // Float used as index.
|
|
||||||
xj_E4004, // Index too big.
|
|
||||||
xj_E4005, // Invalid character after [.
|
|
||||||
xj_E4006, // End of source instead of closing ].
|
|
||||||
xj_E4007, // Invalid character instead of closing ].
|
|
||||||
xj_E4008, // Invalid character instead of dot and [.
|
|
||||||
xj_E4009, // Missing node.
|
|
||||||
|
|
||||||
// (i|f|b|s|a|o)Query errors
|
|
||||||
xj_E4100, // Queried int is too big so it's not representable.
|
|
||||||
xj_E4101, // Queried value is not an int.
|
|
||||||
xj_E4102, // Queried float is too big, so it's not representable.
|
|
||||||
xj_E4103, // Queried value is not a float.
|
|
||||||
xj_E4104, // Queried value is not a string.
|
|
||||||
xj_E4105, // Queried value is not a bool.
|
|
||||||
xj_E4106, // Queried value is not an array.
|
|
||||||
xj_E4107, // Queried value is not an object.
|
|
||||||
|
|
||||||
xj_ECOUNT,
|
|
||||||
} xj_code;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
|
|
||||||
const char *src;
|
|
||||||
|
|
||||||
_Bool occurred;
|
|
||||||
xj_code code;
|
|
||||||
|
|
||||||
char text[128];
|
|
||||||
|
|
||||||
int offset,
|
|
||||||
lineno;
|
|
||||||
|
|
||||||
const char *cfile,
|
|
||||||
*cfunc;
|
|
||||||
int cline;
|
|
||||||
} xj_error;
|
|
||||||
|
|
||||||
typedef void xj_alloc;
|
|
||||||
|
|
||||||
typedef struct xj_value xj_value;
|
|
||||||
struct xj_value {
|
|
||||||
int offset, length, type, size;
|
|
||||||
char *key;
|
|
||||||
union {
|
|
||||||
long long as_int;
|
|
||||||
_Bool as_bool;
|
|
||||||
double as_float;
|
|
||||||
xj_value* as_array;
|
|
||||||
xj_value* as_object;
|
|
||||||
char* as_string;
|
|
||||||
};
|
|
||||||
xj_value *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
xj_alloc* xj_init (unsigned int default_chunk_size);
|
|
||||||
void xj_free (xj_alloc *alloc);
|
|
||||||
void* xj_malloc(xj_alloc *alloc, unsigned int size);
|
|
||||||
|
|
||||||
void xj_set_malloc(void *(*malloc)(void*, unsigned int));
|
|
||||||
void* xj_sys_malloc(unsigned int size);
|
|
||||||
void xj_set_free(void (*free)(void*, void*));
|
|
||||||
void xj_sys_free(void *ptr);
|
|
||||||
void xj_set_userp(void *userp);
|
|
||||||
|
|
||||||
int xj_snprintf (char *buff, int buffsz, const char *fmt, ...);
|
|
||||||
int xj_vsnprintf(char *buff, int buffsz, const char *fmt, va_list args);
|
|
||||||
|
|
||||||
xj_value* xj_query (xj_error *error, xj_value *root, const char *text, int len);
|
|
||||||
_Bool xj_nquery(xj_error *error, xj_value *root, const char *text, int len);
|
|
||||||
int xj_iquery(xj_error *error, xj_value *root, const char *text, int len);
|
|
||||||
double xj_fquery(xj_error *error, xj_value *root, const char *text, int len);
|
|
||||||
_Bool xj_bquery(xj_error *error, xj_value *root, const char *text, int len);
|
|
||||||
char *xj_squery(xj_error *error, xj_value *root, const char *text, int len, int *count);
|
|
||||||
xj_value *xj_aquery(xj_error *error, xj_value *root, const char *text, int len, int *count);
|
|
||||||
xj_value *xj_oquery(xj_error *error, xj_value *root, const char *text, int len, int *count);
|
|
||||||
|
|
||||||
xj_value* xj_decode (xj_error *error, xj_alloc **alloc, const char *text, int len);
|
|
||||||
xj_value* xj_decodef (xj_error *error, xj_alloc **alloc, const char *format, ...);
|
|
||||||
xj_value* xj_vdecodef(xj_error *error, xj_alloc **alloc, const char *format, va_list args);
|
|
||||||
|
|
||||||
char* xj_encode (const xj_value *value, int *len);
|
|
||||||
char* xj_sencode(const char *src, int *len);
|
|
||||||
char* xj_aencode(const xj_value *head, int *len);
|
|
||||||
char* xj_oencode(const xj_value *head, int *len);
|
|
||||||
|
|
||||||
char* xj_encode2 (const xj_value *value, char *buff, unsigned int bufflen, int *len);
|
|
||||||
char* xj_sencode2(const char *src, char *buff, unsigned int bufflen, int *len);
|
|
||||||
char* xj_aencode2(const xj_value *head, char *buff, unsigned int bufflen, int *len);
|
|
||||||
char* xj_oencode2(const xj_value *head, char *buff, unsigned int bufflen, int *len);
|
|
||||||
|
|
||||||
_Bool xj_compare(const xj_value *a, const xj_value *b);
|
|
||||||
xj_value* xj_get_by_name (const xj_value *parent, const char *name, int len);
|
|
||||||
xj_value* xj_get_by_index(const xj_value *parent, unsigned int index);
|
|
||||||
_Bool xj_is_error_internal(const xj_error *error);
|
|
||||||
const char *xj_typename(int type);
|
|
||||||
void xj_stats(FILE *fp);
|
|
||||||
#endif
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -40,7 +40,6 @@ gcc -c src/objects/objects.c -o temp/objects/objects.o $FLAGS
|
|||||||
mkdir temp/compiler
|
mkdir temp/compiler
|
||||||
gcc -c src/compiler/parse.c -o temp/compiler/parse.o $FLAGS
|
gcc -c src/compiler/parse.c -o temp/compiler/parse.o $FLAGS
|
||||||
gcc -c src/compiler/compile.c -o temp/compiler/compile.o $FLAGS
|
gcc -c src/compiler/compile.c -o temp/compiler/compile.o $FLAGS
|
||||||
gcc -c src/compiler/serialize.c -o temp/compiler/serialize.o $FLAGS
|
|
||||||
|
|
||||||
mkdir temp/common
|
mkdir temp/common
|
||||||
gcc -c src/common/executable.c -o temp/common/executable.o $FLAGS
|
gcc -c src/common/executable.c -o temp/common/executable.o $FLAGS
|
||||||
@@ -71,7 +70,6 @@ ar rcs build/libnoja-objects.a \
|
|||||||
ar rcs build/libnoja-compile.a \
|
ar rcs build/libnoja-compile.a \
|
||||||
temp/compiler/parse.o \
|
temp/compiler/parse.o \
|
||||||
temp/compiler/compile.o \
|
temp/compiler/compile.o \
|
||||||
temp/compiler/serialize.o \
|
|
||||||
temp/utils/bpalloc.o \
|
temp/utils/bpalloc.o \
|
||||||
temp/utils/error.o \
|
temp/utils/error.o \
|
||||||
temp/utils/source.o
|
temp/utils/source.o
|
||||||
@@ -108,6 +106,6 @@ gcc src/main.c \
|
|||||||
temp/builtins/file.o \
|
temp/builtins/file.o \
|
||||||
temp/builtins/math.o \
|
temp/builtins/math.o \
|
||||||
temp/common/executable.o \
|
temp/common/executable.o \
|
||||||
-o build/noja $FLAGS -Lbuild/ -lnoja-compile -lnoja-objects -lxjson -lm
|
-o build/noja $FLAGS -Lbuild/ -lnoja-compile -lnoja-objects -lm
|
||||||
|
|
||||||
rm -rf temp
|
rm -rf temp
|
||||||
|
|||||||
@@ -1,201 +0,0 @@
|
|||||||
|
|
||||||
/* WHAT IS THIS FILE?
|
|
||||||
**
|
|
||||||
** This file implements the routines that serialize the AST
|
|
||||||
** into JSON format. The JSON manipulation is handled by the
|
|
||||||
** third party library xJSON (written by me, still).
|
|
||||||
**
|
|
||||||
** The serialization functionality is exposed through the
|
|
||||||
** `serialize` function, that takes as an `AST` as argument
|
|
||||||
** and outputs a string of valid JSON. Therefore the xJSON
|
|
||||||
** dependency isn't exposed to the caller and can be regarded
|
|
||||||
** as an implementation detail.
|
|
||||||
**
|
|
||||||
** The way the serialization occurres is by converting the
|
|
||||||
** AST's representation native to the compiler to one native
|
|
||||||
** to xJSON, an then calling xj_encode on the converted AST.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <xjson.h>
|
|
||||||
#include "serialize.h"
|
|
||||||
#include "ASTi.h"
|
|
||||||
|
|
||||||
#define UNREACHABLE assert(0)
|
|
||||||
|
|
||||||
static xj_value *convert_node(Node *node, xj_error *error, xj_alloc **alloc);
|
|
||||||
|
|
||||||
char *serialize(AST *ast, int *len)
|
|
||||||
{
|
|
||||||
xj_alloc *alloc = NULL;
|
|
||||||
xj_error error;
|
|
||||||
|
|
||||||
xj_value *value = convert_node(ast->root, &error, &alloc);
|
|
||||||
|
|
||||||
if(value == NULL)
|
|
||||||
{
|
|
||||||
xj_free(alloc);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char *serialized = xj_encode(value, len);
|
|
||||||
xj_free(alloc);
|
|
||||||
return serialized;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *expr_kind_name(ExprNode *expr)
|
|
||||||
{
|
|
||||||
switch(expr->kind)
|
|
||||||
{
|
|
||||||
case EXPR_POS: return "pos";
|
|
||||||
case EXPR_NEG: return "neg";
|
|
||||||
case EXPR_ADD: return "add";
|
|
||||||
case EXPR_SUB: return "sub";
|
|
||||||
case EXPR_MUL: return "mul";
|
|
||||||
case EXPR_DIV: return "div";
|
|
||||||
case EXPR_INT: return "int";
|
|
||||||
case EXPR_FLOAT: return "float";
|
|
||||||
case EXPR_STRING: return "string";
|
|
||||||
case EXPR_IDENT: return "ident";
|
|
||||||
|
|
||||||
default:
|
|
||||||
UNREACHABLE;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNREACHABLE;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xj_value *convert_node_list(Node *head, xj_error *error, xj_alloc **alloc);
|
|
||||||
|
|
||||||
static xj_value *convert_node(Node *node, xj_error *error, xj_alloc **alloc)
|
|
||||||
{
|
|
||||||
switch(node->kind)
|
|
||||||
{
|
|
||||||
case NODE_EXPR:
|
|
||||||
ExprNode *expr = (ExprNode*) node;
|
|
||||||
switch(expr->kind)
|
|
||||||
{
|
|
||||||
case EXPR_POS:
|
|
||||||
case EXPR_NEG:
|
|
||||||
case EXPR_ADD:
|
|
||||||
case EXPR_SUB:
|
|
||||||
case EXPR_MUL:
|
|
||||||
case EXPR_DIV:
|
|
||||||
{
|
|
||||||
OperExprNode *oper = (OperExprNode*) expr;
|
|
||||||
|
|
||||||
xj_value *operands = NULL;
|
|
||||||
|
|
||||||
if(oper->count > 0)
|
|
||||||
{
|
|
||||||
operands = convert_node_list((Node*) oper->head, error, alloc);
|
|
||||||
|
|
||||||
if(operands == NULL)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return xj_decodef(error, alloc,
|
|
||||||
"{"
|
|
||||||
"\t\"node-kind\": \"expr\", \n"
|
|
||||||
"\t\"expr-kind\": %Q, \n"
|
|
||||||
"\t\"operands\": %L\n"
|
|
||||||
"}", expr_kind_name(expr), operands);
|
|
||||||
}
|
|
||||||
|
|
||||||
case EXPR_INT:
|
|
||||||
return xj_decodef(error, alloc,
|
|
||||||
"{"
|
|
||||||
"\t\"node-kind\": \"expr\", \n"
|
|
||||||
"\t\"expr-kind\": %Q, \n"
|
|
||||||
"\t\"value\": %d\n"
|
|
||||||
"}", expr_kind_name(expr), ((IntExprNode*) expr)->val);
|
|
||||||
|
|
||||||
case EXPR_FLOAT:
|
|
||||||
return xj_decodef(error, alloc,
|
|
||||||
"{"
|
|
||||||
"\t\"node-kind\": \"expr\", \n"
|
|
||||||
"\t\"expr-kind\": %Q, \n"
|
|
||||||
"\t\"value\": %f\n"
|
|
||||||
"}", expr_kind_name(expr), ((FloatExprNode*) expr)->val);
|
|
||||||
|
|
||||||
case EXPR_STRING:
|
|
||||||
return xj_decodef(error, alloc,
|
|
||||||
"{"
|
|
||||||
"\t\"node-kind\": \"expr\", \n"
|
|
||||||
"\t\"expr-kind\": %Q, \n"
|
|
||||||
"\t\"value\": %Q\n"
|
|
||||||
"}", expr_kind_name(expr), ((StringExprNode*) expr)->val);
|
|
||||||
|
|
||||||
case EXPR_IDENT:
|
|
||||||
return xj_decodef(error, alloc,
|
|
||||||
"{"
|
|
||||||
"\t\"node-kind\": \"expr\", \n"
|
|
||||||
"\t\"expr-kind\": %Q, \n"
|
|
||||||
"\t\"value\": %Q\n"
|
|
||||||
"}", expr_kind_name(expr), ((IdentExprNode*) expr)->val);
|
|
||||||
|
|
||||||
default:
|
|
||||||
UNREACHABLE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NODE_IFELSE:
|
|
||||||
{
|
|
||||||
IfElseNode *ifelse = (IfElseNode*) node;
|
|
||||||
|
|
||||||
xj_value *condition = convert_node(ifelse->condition, error, alloc);
|
|
||||||
if(condition == NULL) return NULL;
|
|
||||||
|
|
||||||
xj_value *true_branch = convert_node(ifelse->true_branch, error, alloc);
|
|
||||||
if(true_branch == NULL) return NULL;
|
|
||||||
|
|
||||||
xj_value *false_branch = convert_node(ifelse->false_branch, error, alloc);
|
|
||||||
if(false_branch == NULL) return NULL;
|
|
||||||
|
|
||||||
return xj_decodef(error, alloc,
|
|
||||||
"{"
|
|
||||||
"\t\"node-kind\": \"if-else\", \n"
|
|
||||||
"\t\"condition\": %v, \n"
|
|
||||||
"\t\"true-branch\": %v, \n"
|
|
||||||
"\t\"false-branch\": %v\n"
|
|
||||||
"}", condition, true_branch, false_branch);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
UNREACHABLE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNREACHABLE;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static xj_value *convert_node_list(Node *head, xj_error *error, xj_alloc **alloc)
|
|
||||||
{
|
|
||||||
xj_value *json_head = NULL;
|
|
||||||
xj_value **json_tail = &json_head;
|
|
||||||
|
|
||||||
Node *curs = head;
|
|
||||||
while(curs)
|
|
||||||
{
|
|
||||||
xj_value *temp = convert_node(curs, error, alloc);
|
|
||||||
|
|
||||||
if(temp == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
temp->next = NULL;
|
|
||||||
|
|
||||||
*json_tail = temp;
|
|
||||||
json_tail = &temp->next;
|
|
||||||
|
|
||||||
curs = curs->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return json_head;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#ifndef SERIALIZE_H
|
|
||||||
#define SERIALIZE_H
|
|
||||||
#include "AST.h"
|
|
||||||
char *serialize(AST *ast, int *len);
|
|
||||||
#endif
|
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "o_staticmap.h"
|
#include "o_staticmap.h"
|
||||||
#include "compiler/parse.h"
|
#include "compiler/parse.h"
|
||||||
#include "compiler/serialize.h"
|
|
||||||
#include "compiler/compile.h"
|
#include "compiler/compile.h"
|
||||||
#include "runtime/runtime.h"
|
#include "runtime/runtime.h"
|
||||||
#include "runtime/runtime_error.h"
|
#include "runtime/runtime_error.h"
|
||||||
|
|||||||
@@ -1,104 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"source": "1",
|
|
||||||
"expect": {
|
|
||||||
"node-kind": "expr",
|
|
||||||
"expr-kind": "int",
|
|
||||||
"value": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "1.1",
|
|
||||||
"expect": {
|
|
||||||
"node-kind": "expr",
|
|
||||||
"expr-kind": "float",
|
|
||||||
"value": 1.1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "1+1",
|
|
||||||
"expect": {
|
|
||||||
"node-kind": "expr",
|
|
||||||
"expr-kind": "add",
|
|
||||||
"operands": [
|
|
||||||
{"node-kind": "expr", "expr-kind": "int", "value": 1},
|
|
||||||
{"node-kind": "expr", "expr-kind": "int", "value": 1}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "1-1",
|
|
||||||
"expect": {
|
|
||||||
"node-kind": "expr",
|
|
||||||
"expr-kind": "sub",
|
|
||||||
"operands": [
|
|
||||||
{"node-kind": "expr", "expr-kind": "int", "value": 1},
|
|
||||||
{"node-kind": "expr", "expr-kind": "int", "value": 1}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "1*1",
|
|
||||||
"expect": {
|
|
||||||
"node-kind": "expr",
|
|
||||||
"expr-kind": "mul",
|
|
||||||
"operands": [
|
|
||||||
{"node-kind": "expr", "expr-kind": "int", "value": 1},
|
|
||||||
{"node-kind": "expr", "expr-kind": "int", "value": 1}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "1-+1",
|
|
||||||
"expect": {
|
|
||||||
"node-kind": "expr",
|
|
||||||
"expr-kind": "sub",
|
|
||||||
"operands": [
|
|
||||||
{"node-kind": "expr", "expr-kind": "int", "value": 1},
|
|
||||||
{
|
|
||||||
"node-kind": "expr",
|
|
||||||
"expr-kind": "pos",
|
|
||||||
"operands": [
|
|
||||||
{"node-kind": "expr", "expr-kind": "int", "value": 1}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "+1",
|
|
||||||
"expect": {
|
|
||||||
"node-kind": "expr",
|
|
||||||
"expr-kind": "pos",
|
|
||||||
"operands": [
|
|
||||||
{"node-kind": "expr", "expr-kind": "int", "value": 1}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "-1",
|
|
||||||
"expect": {
|
|
||||||
"node-kind": "expr",
|
|
||||||
"expr-kind": "neg",
|
|
||||||
"operands": [
|
|
||||||
{"node-kind": "expr", "expr-kind": "int", "value": 1}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "hello",
|
|
||||||
"expect": {"node-kind": "expr", "expr-kind": "ident", "value": "hello"}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "'hello'",
|
|
||||||
"expect": {"node-kind": "expr", "expr-kind": "string", "value": "hello"}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "-'hello'",
|
|
||||||
"expect": {"node-kind": "expr", "expr-kind": "neg", "operands": [{"node-kind": "expr", "expr-kind": "string", "value": "hello"}]}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"source": "-'hel\\nlo'",
|
|
||||||
"expect": {"node-kind": "expr", "expr-kind": "neg", "operands": [{"node-kind": "expr", "expr-kind": "string", "value": "hel\\nlo"}]}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "../../src/objects/objects.h"
|
|
||||||
|
|
||||||
#define tassert(exp) if(!(exp)) goto done;
|
|
||||||
#define tdone done: if(1)
|
|
||||||
|
|
||||||
static _Bool test_int()
|
|
||||||
{
|
|
||||||
_Bool passed = 0;
|
|
||||||
|
|
||||||
Heap *heap = Heap_New(-1);
|
|
||||||
assert(heap != NULL);
|
|
||||||
|
|
||||||
Error error;
|
|
||||||
Error_Init(&error);
|
|
||||||
|
|
||||||
// Test [Object_FromInt], [Object_ToInt].
|
|
||||||
|
|
||||||
int n = -3; // Just any value.
|
|
||||||
|
|
||||||
Object *obj = Object_FromInt(n, heap, &error);
|
|
||||||
|
|
||||||
tassert(obj != 0);
|
|
||||||
tassert(error.occurred == 0);
|
|
||||||
|
|
||||||
int k = Object_ToInt(obj, &error);
|
|
||||||
|
|
||||||
tassert(k == n);
|
|
||||||
tassert(error.occurred == 0);
|
|
||||||
|
|
||||||
passed = 1;
|
|
||||||
|
|
||||||
tdone {
|
|
||||||
Error_Free(&error);
|
|
||||||
Heap_Free(heap);
|
|
||||||
return passed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static _Bool test_float()
|
|
||||||
{
|
|
||||||
_Bool passed = 0;
|
|
||||||
|
|
||||||
Heap *heap = Heap_New(-1);
|
|
||||||
assert(heap != NULL);
|
|
||||||
|
|
||||||
Error error;
|
|
||||||
Error_Init(&error);
|
|
||||||
|
|
||||||
// Test [Object_FromFloat], [Object_ToFloat].
|
|
||||||
|
|
||||||
double n = -3.4; // Just any value.
|
|
||||||
|
|
||||||
Object *obj = Object_FromFloat(n, heap, &error);
|
|
||||||
|
|
||||||
if(obj == 0)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
double k = Object_ToFloat(obj, &error);
|
|
||||||
|
|
||||||
if(k != n)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
// ...
|
|
||||||
|
|
||||||
passed = 1;
|
|
||||||
done:
|
|
||||||
Error_Free(&error);
|
|
||||||
Heap_Free(heap);
|
|
||||||
return passed;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
typedef _Bool (*test_t)();
|
|
||||||
static const test_t tests[] = {
|
|
||||||
test_int,
|
|
||||||
test_float,
|
|
||||||
};
|
|
||||||
|
|
||||||
for(int i = 0; i < (int) (sizeof(tests) / sizeof(tests[0])); i += 1)
|
|
||||||
printf("TEST %d: %s\n", i, test_int() ? "Passed" : "Failed");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,281 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <xjson.h>
|
|
||||||
#include "../../src/compiler/parse.h"
|
|
||||||
#include "../../src/compiler/serialize.h"
|
|
||||||
|
|
||||||
typedef enum { PASSED, FAILED, IGNORED } result_t;
|
|
||||||
|
|
||||||
static _Bool compare(const char *s, xj_value *v)
|
|
||||||
{
|
|
||||||
xj_alloc *alloc = NULL;
|
|
||||||
xj_error error;
|
|
||||||
xj_value *doc;
|
|
||||||
|
|
||||||
doc = xj_decode(&error, &alloc, s, -1);
|
|
||||||
assert(doc != NULL);
|
|
||||||
|
|
||||||
_Bool same = xj_compare(doc, v);
|
|
||||||
|
|
||||||
xj_free(alloc);
|
|
||||||
return same;
|
|
||||||
}
|
|
||||||
|
|
||||||
result_t runtest(xj_value *value, int testno)
|
|
||||||
{
|
|
||||||
int raw_sourcel;
|
|
||||||
char *raw_source;
|
|
||||||
xj_value *expect;
|
|
||||||
|
|
||||||
{
|
|
||||||
xj_error error;
|
|
||||||
xj_value *source2 = xj_query(&error, value, ".source", -1);
|
|
||||||
|
|
||||||
if(source2 == NULL)
|
|
||||||
{
|
|
||||||
if(error.code == xj_E4009)
|
|
||||||
fprintf(stderr, "WARNING: Field \"source\" is missing\n");
|
|
||||||
else
|
|
||||||
fprintf(stderr, "WARNING: Internal failure (%s)\n", error.text);
|
|
||||||
return IGNORED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(source2->type != xj_STRING)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "WARNING: Field \"source\" is not a string\n");
|
|
||||||
return IGNORED;
|
|
||||||
}
|
|
||||||
|
|
||||||
raw_source = source2->as_string;
|
|
||||||
raw_sourcel = source2->size;
|
|
||||||
|
|
||||||
expect = xj_query(&error, value, ".expect", -1);
|
|
||||||
|
|
||||||
if(expect == NULL)
|
|
||||||
{
|
|
||||||
if(error.code == xj_E4009)
|
|
||||||
fprintf(stderr, "WARNING: Field \"expect\" is missing\n");
|
|
||||||
else
|
|
||||||
fprintf(stderr, "WARNING: Internal failure (%s)\n", error.text);
|
|
||||||
return IGNORED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(expect->type != xj_OBJECT)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "WARNING: Field \"expect\" is not an object\n");
|
|
||||||
return IGNORED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Source *source;
|
|
||||||
{
|
|
||||||
Error error;
|
|
||||||
Error_Init(&error);
|
|
||||||
|
|
||||||
char temp[64];
|
|
||||||
int k = snprintf(temp, sizeof(temp), "(Test %d's source)", testno);
|
|
||||||
|
|
||||||
assert(k >= 0);
|
|
||||||
assert((unsigned int) k < sizeof(temp));
|
|
||||||
|
|
||||||
source = Source_FromString(temp, raw_source, raw_sourcel, &error);
|
|
||||||
|
|
||||||
if(source == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "WARNING: Internal failure (%s)\n", error.message);
|
|
||||||
return IGNORED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_Bool passed;
|
|
||||||
{
|
|
||||||
Error error;
|
|
||||||
BPAlloc *alloc;
|
|
||||||
char buffer[65536];
|
|
||||||
|
|
||||||
Error_Init(&error);
|
|
||||||
|
|
||||||
alloc = BPAlloc_Init3(buffer, sizeof(buffer), -1, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
if(alloc == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "WARNING: Internal failure (Failed to instanciate BPAlloc)\n");
|
|
||||||
return IGNORED;
|
|
||||||
}
|
|
||||||
|
|
||||||
AST *ast = parse(source, alloc, &error);
|
|
||||||
|
|
||||||
if(ast == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "WARNING: Internal failure (Failed to compile: %s; reported in %s at %s:%d)\n", error.message, error.func, error.file, error.line);
|
|
||||||
|
|
||||||
Error_Free(&error);
|
|
||||||
BPAlloc_Free(alloc);
|
|
||||||
return IGNORED;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *serialized = serialize(ast, NULL);
|
|
||||||
|
|
||||||
if(serialized == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "WARNING: Internal failure (Failed to serialize AST)\n");
|
|
||||||
|
|
||||||
Error_Free(&error);
|
|
||||||
BPAlloc_Free(alloc);
|
|
||||||
return IGNORED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
printf("SERIALIZED :: %s\n", serialized);
|
|
||||||
{
|
|
||||||
char *temp = xj_encode(expect, NULL);
|
|
||||||
printf("SERIALIZED 2 :: %s\n", temp);
|
|
||||||
xj_sys_free(temp);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
passed = compare(serialized, expect);
|
|
||||||
|
|
||||||
Error_Free(&error);
|
|
||||||
BPAlloc_Free(alloc);
|
|
||||||
xj_sys_free(serialized);
|
|
||||||
}
|
|
||||||
|
|
||||||
return passed ? PASSED : FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *loadfile(const char *file, int *size);
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if(argc == 1)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ERROR: Missing file name\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int filesize;
|
|
||||||
char *filename = argv[1];
|
|
||||||
char *filetext = loadfile(filename, &filesize);
|
|
||||||
|
|
||||||
if(filetext == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ERROR: Couldn't open \"%s\"\n", filename);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
xj_alloc *alloc = NULL;
|
|
||||||
xj_error error;
|
|
||||||
xj_value *document;
|
|
||||||
|
|
||||||
document = xj_decode(&error, &alloc, filetext, filesize);
|
|
||||||
|
|
||||||
free(filetext);
|
|
||||||
|
|
||||||
if(document == NULL)
|
|
||||||
{
|
|
||||||
assert(error.occurred == 1);
|
|
||||||
fprintf(stderr, "ERROR: Failed to parse \"%s\" as JSON: %s\n",
|
|
||||||
filename, error.text);
|
|
||||||
xj_free(alloc);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(document->type != xj_ARRAY)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "ERROR: Was expected an array as JSON document root\n");
|
|
||||||
xj_free(alloc);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
xj_value *cursor = document->as_array;
|
|
||||||
|
|
||||||
int passed = 0, ignored = 0;
|
|
||||||
int total = document->size;
|
|
||||||
int index = 1;
|
|
||||||
|
|
||||||
while(cursor)
|
|
||||||
{
|
|
||||||
result_t result = runtest(cursor, index);
|
|
||||||
|
|
||||||
#define KNRM "\x1B[0m"
|
|
||||||
#define KRED "\x1B[31m"
|
|
||||||
#define KGRN "\x1B[32m"
|
|
||||||
#define KYEL "\x1B[33m"
|
|
||||||
#define KBLU "\x1B[34m"
|
|
||||||
#define KMAG "\x1B[35m"
|
|
||||||
#define KCYN "\x1B[36m"
|
|
||||||
#define KWHT "\x1B[37m"
|
|
||||||
#define RESET "\033[0m"
|
|
||||||
|
|
||||||
switch(result)
|
|
||||||
{
|
|
||||||
case PASSED:
|
|
||||||
printf("TEST %-2d :: " KGRN "PASSED" RESET "\n", index);
|
|
||||||
passed += 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FAILED:
|
|
||||||
printf("TEST %-2d :: " KRED "FAILED" RESET "\n", index);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IGNORED:
|
|
||||||
printf("TEST %-2d :: " KYEL "IGNORED" RESET "\n", index);
|
|
||||||
ignored += 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
index += 1;
|
|
||||||
cursor = cursor->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n ... %d passed, %d failed and %d ignored.\n", passed, total - passed - ignored, ignored);
|
|
||||||
|
|
||||||
xj_free(alloc);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *loadfile(const char *file, int *size)
|
|
||||||
{
|
|
||||||
char *body = NULL;
|
|
||||||
int _size;
|
|
||||||
|
|
||||||
FILE *fp = fopen(file, "rb");
|
|
||||||
|
|
||||||
if(fp == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(fseek(fp, 0, SEEK_END))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
_size = ftell(fp);
|
|
||||||
|
|
||||||
if(_size < 0)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if(size)
|
|
||||||
*size = _size;
|
|
||||||
|
|
||||||
body = malloc(_size + 1);
|
|
||||||
|
|
||||||
if(body == NULL)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if(fseek(fp, 0, SEEK_SET))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
int k = fread(body, 1, _size, fp);
|
|
||||||
|
|
||||||
if(k != _size)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
body[_size] = '\0';
|
|
||||||
|
|
||||||
done:
|
|
||||||
fclose(fp);
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user