added the bool type
This commit is contained in:
@@ -18,6 +18,7 @@ gcc -c src/objects/heap.c -o temp/objects/heap.o $FLAGS
|
|||||||
gcc -c src/objects/o_int.c -o temp/objects/o_int.o $FLAGS
|
gcc -c src/objects/o_int.c -o temp/objects/o_int.o $FLAGS
|
||||||
gcc -c src/objects/o_map.c -o temp/objects/o_map.o $FLAGS
|
gcc -c src/objects/o_map.c -o temp/objects/o_map.o $FLAGS
|
||||||
gcc -c src/objects/o_none.c -o temp/objects/o_none.o $FLAGS
|
gcc -c src/objects/o_none.c -o temp/objects/o_none.o $FLAGS
|
||||||
|
gcc -c src/objects/o_bool.c -o temp/objects/o_bool.o $FLAGS
|
||||||
gcc -c src/objects/o_float.c -o temp/objects/o_float.o $FLAGS
|
gcc -c src/objects/o_float.c -o temp/objects/o_float.o $FLAGS
|
||||||
gcc -c src/objects/o_string.c -o temp/objects/o_string.o $FLAGS
|
gcc -c src/objects/o_string.c -o temp/objects/o_string.o $FLAGS
|
||||||
gcc -c src/objects/objects.c -o temp/objects/objects.o $FLAGS
|
gcc -c src/objects/objects.c -o temp/objects/objects.o $FLAGS
|
||||||
@@ -71,6 +72,7 @@ gcc src/main.c \
|
|||||||
temp/utils/bucketlist.o \
|
temp/utils/bucketlist.o \
|
||||||
temp/objects/o_map.o \
|
temp/objects/o_map.o \
|
||||||
temp/objects/o_none.o \
|
temp/objects/o_none.o \
|
||||||
|
temp/objects/o_bool.o \
|
||||||
temp/objects/o_string.o \
|
temp/objects/o_string.o \
|
||||||
temp/runtime/runtime.o \
|
temp/runtime/runtime.o \
|
||||||
temp/runtime/runtime_error.o \
|
temp/runtime/runtime_error.o \
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
|
|
||||||
if 1 1;
|
if false 1;
|
||||||
@@ -48,10 +48,13 @@ static const InstrInfo instr_table[] = {
|
|||||||
[OPCODE_MUL] = {"MUL", 2, 0, NULL},
|
[OPCODE_MUL] = {"MUL", 2, 0, NULL},
|
||||||
[OPCODE_DIV] = {"DIV", 2, 0, NULL},
|
[OPCODE_DIV] = {"DIV", 2, 0, NULL},
|
||||||
|
|
||||||
[OPCODE_PUSHI] = {"PUSHI", 1, 1, (OperandType[]) {OPTP_INT}},
|
[OPCODE_PUSHINT] = {"PUSHINT", 0, 1, (OperandType[]) {OPTP_INT}},
|
||||||
[OPCODE_PUSHF] = {"PUSHF", 1, 1, (OperandType[]) {OPTP_FLOAT}},
|
[OPCODE_PUSHFLT] = {"PUSHFLT", 0, 1, (OperandType[]) {OPTP_FLOAT}},
|
||||||
[OPCODE_PUSHS] = {"PUSHS", 1, 1, (OperandType[]) {OPTP_STRING}},
|
[OPCODE_PUSHSTR] = {"PUSHSTR", 0, 1, (OperandType[]) {OPTP_STRING}},
|
||||||
[OPCODE_PUSHV] = {"PUSHV", 1, 1, (OperandType[]) {OPTP_STRING}},
|
[OPCODE_PUSHVAR] = {"PUSHVAR", 0, 1, (OperandType[]) {OPTP_STRING}},
|
||||||
|
[OPCODE_PUSHTRU] = {"PUSHTRU", 0, 0, NULL},
|
||||||
|
[OPCODE_PUSHFLS] = {"PUSHFLS", 0, 0, NULL},
|
||||||
|
[OPCODE_PUSHNNE] = {"PUSHNNE", 0, 0, NULL},
|
||||||
|
|
||||||
[OPCODE_RETURN] = {"RETURN", 0, 0, NULL},
|
[OPCODE_RETURN] = {"RETURN", 0, 0, NULL},
|
||||||
|
|
||||||
|
|||||||
@@ -28,10 +28,13 @@ typedef enum {
|
|||||||
OPCODE_SUB,
|
OPCODE_SUB,
|
||||||
OPCODE_MUL,
|
OPCODE_MUL,
|
||||||
OPCODE_DIV,
|
OPCODE_DIV,
|
||||||
OPCODE_PUSHI,
|
OPCODE_PUSHINT,
|
||||||
OPCODE_PUSHF,
|
OPCODE_PUSHFLT,
|
||||||
OPCODE_PUSHS,
|
OPCODE_PUSHSTR,
|
||||||
OPCODE_PUSHV,
|
OPCODE_PUSHVAR,
|
||||||
|
OPCODE_PUSHTRU,
|
||||||
|
OPCODE_PUSHFLS,
|
||||||
|
OPCODE_PUSHNNE,
|
||||||
OPCODE_RETURN,
|
OPCODE_RETURN,
|
||||||
OPCODE_JUMPIFNOTANDPOP,
|
OPCODE_JUMPIFNOTANDPOP,
|
||||||
OPCODE_JUMP,
|
OPCODE_JUMP,
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ typedef enum {
|
|||||||
EXPR_MUL,
|
EXPR_MUL,
|
||||||
EXPR_DIV,
|
EXPR_DIV,
|
||||||
EXPR_INT,
|
EXPR_INT,
|
||||||
|
EXPR_NONE,
|
||||||
|
EXPR_TRUE,
|
||||||
|
EXPR_FALSE,
|
||||||
EXPR_FLOAT,
|
EXPR_FLOAT,
|
||||||
EXPR_STRING,
|
EXPR_STRING,
|
||||||
EXPR_IDENT,
|
EXPR_IDENT,
|
||||||
|
|||||||
+13
-4
@@ -54,30 +54,39 @@ static _Bool emit_instr_for_node(ExeBuilder *exeb, Node *node, Error *error)
|
|||||||
{
|
{
|
||||||
IntExprNode *p = (IntExprNode*) expr;
|
IntExprNode *p = (IntExprNode*) expr;
|
||||||
Operand op = { .type = OPTP_INT, .as_int = p->val };
|
Operand op = { .type = OPTP_INT, .as_int = p->val };
|
||||||
return ExeBuilder_Append(exeb, error, OPCODE_PUSHI, &op, 1, node->offset, node->length);
|
return ExeBuilder_Append(exeb, error, OPCODE_PUSHINT, &op, 1, node->offset, node->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
case EXPR_FLOAT:
|
case EXPR_FLOAT:
|
||||||
{
|
{
|
||||||
FloatExprNode *p = (FloatExprNode*) expr;
|
FloatExprNode *p = (FloatExprNode*) expr;
|
||||||
Operand op = { .type = OPTP_FLOAT, .as_float = p->val };
|
Operand op = { .type = OPTP_FLOAT, .as_float = p->val };
|
||||||
return ExeBuilder_Append(exeb, error, OPCODE_PUSHF, &op, 1, node->offset, node->length);
|
return ExeBuilder_Append(exeb, error, OPCODE_PUSHFLT, &op, 1, node->offset, node->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
case EXPR_STRING:
|
case EXPR_STRING:
|
||||||
{
|
{
|
||||||
StringExprNode *p = (StringExprNode*) expr;
|
StringExprNode *p = (StringExprNode*) expr;
|
||||||
Operand op = { .type = OPTP_STRING, .as_string = p->val };
|
Operand op = { .type = OPTP_STRING, .as_string = p->val };
|
||||||
return ExeBuilder_Append(exeb, error, OPCODE_PUSHS, &op, 1, node->offset, node->length);
|
return ExeBuilder_Append(exeb, error, OPCODE_PUSHSTR, &op, 1, node->offset, node->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
case EXPR_IDENT:
|
case EXPR_IDENT:
|
||||||
{
|
{
|
||||||
IdentExprNode *p = (IdentExprNode*) expr;
|
IdentExprNode *p = (IdentExprNode*) expr;
|
||||||
Operand op = { .type = OPTP_STRING, .as_string = p->val };
|
Operand op = { .type = OPTP_STRING, .as_string = p->val };
|
||||||
return ExeBuilder_Append(exeb, error, OPCODE_PUSHV, &op, 1, node->offset, node->length);
|
return ExeBuilder_Append(exeb, error, OPCODE_PUSHVAR, &op, 1, node->offset, node->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EXPR_NONE:
|
||||||
|
return ExeBuilder_Append(exeb, error, OPCODE_PUSHNNE, NULL, 0, node->offset, node->length);
|
||||||
|
|
||||||
|
case EXPR_TRUE:
|
||||||
|
return ExeBuilder_Append(exeb, error, OPCODE_PUSHTRU, NULL, 0, node->offset, node->length);
|
||||||
|
|
||||||
|
case EXPR_FALSE:
|
||||||
|
return ExeBuilder_Append(exeb, error, OPCODE_PUSHFLS, NULL, 0, node->offset, node->length);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ typedef enum {
|
|||||||
|
|
||||||
TKWIF,
|
TKWIF,
|
||||||
TKWELSE,
|
TKWELSE,
|
||||||
|
TKWNONE,
|
||||||
|
TKWTRUE,
|
||||||
|
TKWFALSE,
|
||||||
} TokenKind;
|
} TokenKind;
|
||||||
|
|
||||||
typedef struct Token Token;
|
typedef struct Token Token;
|
||||||
@@ -124,6 +127,18 @@ AST *parse(Source *src, BPAlloc *alloc, Error *error)
|
|||||||
{
|
{
|
||||||
tok->kind = TKWELSE;
|
tok->kind = TKWELSE;
|
||||||
}
|
}
|
||||||
|
else if(matchstr(str + tok->offset, tok->length, "none"))
|
||||||
|
{
|
||||||
|
tok->kind = TKWNONE;
|
||||||
|
}
|
||||||
|
else if(matchstr(str + tok->offset, tok->length, "true"))
|
||||||
|
{
|
||||||
|
tok->kind = TKWTRUE;
|
||||||
|
}
|
||||||
|
else if(matchstr(str + tok->offset, tok->length, "false"))
|
||||||
|
{
|
||||||
|
tok->kind = TKWFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#undef matchstr
|
#undef matchstr
|
||||||
}
|
}
|
||||||
@@ -330,6 +345,9 @@ static Node *parse_statement(Context *ctx)
|
|||||||
case TFLOAT:
|
case TFLOAT:
|
||||||
case TSTRING:
|
case TSTRING:
|
||||||
case TIDENT:
|
case TIDENT:
|
||||||
|
case TKWNONE:
|
||||||
|
case TKWTRUE:
|
||||||
|
case TKWFALSE:
|
||||||
return parse_expression_statement(ctx);
|
return parse_expression_statement(ctx);
|
||||||
|
|
||||||
case TKWIF:
|
case TKWIF:
|
||||||
@@ -653,6 +671,78 @@ static Node *parse_primary_expresion(Context *ctx)
|
|||||||
case TSTRING:
|
case TSTRING:
|
||||||
return parse_string_primary_expression(ctx);
|
return parse_string_primary_expression(ctx);
|
||||||
|
|
||||||
|
case TKWNONE:
|
||||||
|
{
|
||||||
|
next(ctx);
|
||||||
|
|
||||||
|
ExprNode *node;
|
||||||
|
{
|
||||||
|
node = BPAlloc_Malloc(ctx->alloc, sizeof(ExprNode));
|
||||||
|
|
||||||
|
if(node == NULL)
|
||||||
|
{
|
||||||
|
Error_Report(ctx->error, 1, "No memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->base.kind = NODE_EXPR;
|
||||||
|
node->base.next = NULL;
|
||||||
|
node->base.offset = ctx->token->offset;
|
||||||
|
node->base.length = ctx->token->length;
|
||||||
|
node->kind = EXPR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Node*) node;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TKWTRUE:
|
||||||
|
{
|
||||||
|
next(ctx);
|
||||||
|
|
||||||
|
ExprNode *node;
|
||||||
|
{
|
||||||
|
node = BPAlloc_Malloc(ctx->alloc, sizeof(ExprNode));
|
||||||
|
|
||||||
|
if(node == NULL)
|
||||||
|
{
|
||||||
|
Error_Report(ctx->error, 1, "No memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->base.kind = NODE_EXPR;
|
||||||
|
node->base.next = NULL;
|
||||||
|
node->base.offset = ctx->token->offset;
|
||||||
|
node->base.length = ctx->token->length;
|
||||||
|
node->kind = EXPR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Node*) node;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TKWFALSE:
|
||||||
|
{
|
||||||
|
next(ctx);
|
||||||
|
|
||||||
|
ExprNode *node;
|
||||||
|
{
|
||||||
|
node = BPAlloc_Malloc(ctx->alloc, sizeof(ExprNode));
|
||||||
|
|
||||||
|
if(node == NULL)
|
||||||
|
{
|
||||||
|
Error_Report(ctx->error, 1, "No memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->base.kind = NODE_EXPR;
|
||||||
|
node->base.next = NULL;
|
||||||
|
node->base.offset = ctx->token->offset;
|
||||||
|
node->base.length = ctx->token->length;
|
||||||
|
node->kind = EXPR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Node*) node;
|
||||||
|
}
|
||||||
|
|
||||||
case TIDENT:
|
case TIDENT:
|
||||||
{
|
{
|
||||||
char *copy;
|
char *copy;
|
||||||
|
|||||||
@@ -4,23 +4,23 @@
|
|||||||
|
|
||||||
static _Bool to_bool(Object *obj, Error *err);
|
static _Bool to_bool(Object *obj, Error *err);
|
||||||
|
|
||||||
static const Type t_int = {
|
static const Type t_bool = {
|
||||||
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
.base = (Object) { .type = &t_type, .flags = Object_STATIC },
|
||||||
.name = "int",
|
.name = "bool",
|
||||||
.size = sizeof (Object),
|
.size = sizeof (Object),
|
||||||
.atomic = ATMTP_BOOL,
|
.atomic = ATMTP_BOOL,
|
||||||
.to_bool = to_bool,
|
.to_bool = to_bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Object the_true_object = {
|
static Object the_true_object = {
|
||||||
.type = t_bool,
|
.type = &t_bool,
|
||||||
.flags = Object_STATIC,
|
.flags = Object_STATIC,
|
||||||
}
|
};
|
||||||
|
|
||||||
static Object the_false_object = {
|
static Object the_false_object = {
|
||||||
.type = t_bool,
|
.type = &t_bool,
|
||||||
.flags = Object_STATIC,
|
.flags = Object_STATIC,
|
||||||
}
|
};
|
||||||
|
|
||||||
static _Bool to_bool(Object *obj, Error *err)
|
static _Bool to_bool(Object *obj, Error *err)
|
||||||
{
|
{
|
||||||
|
|||||||
+46
-4
@@ -363,7 +363,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OPCODE_PUSHI:
|
case OPCODE_PUSHINT:
|
||||||
{
|
{
|
||||||
assert(opc == 1);
|
assert(opc == 1);
|
||||||
assert(ops[0].type == OPTP_INT);
|
assert(ops[0].type == OPTP_INT);
|
||||||
@@ -378,7 +378,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OPCODE_PUSHF:
|
case OPCODE_PUSHFLT:
|
||||||
{
|
{
|
||||||
assert(opc == 1);
|
assert(opc == 1);
|
||||||
assert(ops[0].type == OPTP_FLOAT);
|
assert(ops[0].type == OPTP_FLOAT);
|
||||||
@@ -393,7 +393,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OPCODE_PUSHS:
|
case OPCODE_PUSHSTR:
|
||||||
{
|
{
|
||||||
assert(opc == 1);
|
assert(opc == 1);
|
||||||
assert(ops[0].type == OPTP_STRING);
|
assert(ops[0].type == OPTP_STRING);
|
||||||
@@ -408,7 +408,7 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
case OPCODE_PUSHV:
|
case OPCODE_PUSHVAR:
|
||||||
{
|
{
|
||||||
assert(opc == 1);
|
assert(opc == 1);
|
||||||
assert(ops[0].type == OPTP_STRING);
|
assert(ops[0].type == OPTP_STRING);
|
||||||
@@ -430,6 +430,48 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case OPCODE_PUSHNNE:
|
||||||
|
{
|
||||||
|
assert(opc == 0);
|
||||||
|
|
||||||
|
Object *obj = Object_NewNone(runtime->heap, error);
|
||||||
|
|
||||||
|
if(obj == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!Runtime_Push(runtime, error, obj))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OPCODE_PUSHTRU:
|
||||||
|
{
|
||||||
|
assert(opc == 0);
|
||||||
|
|
||||||
|
Object *obj = Object_FromBool(1, runtime->heap, error);
|
||||||
|
|
||||||
|
if(obj == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!Runtime_Push(runtime, error, obj))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case OPCODE_PUSHFLS:
|
||||||
|
{
|
||||||
|
assert(opc == 0);
|
||||||
|
|
||||||
|
Object *obj = Object_FromBool(0, runtime->heap, error);
|
||||||
|
|
||||||
|
if(obj == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!Runtime_Push(runtime, error, obj))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
case OPCODE_RETURN:
|
case OPCODE_RETURN:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user