added index selection
This commit is contained in:
@@ -24,5 +24,3 @@ while i < 3;
|
|||||||
|
|
||||||
# ------------------------------------- #
|
# ------------------------------------- #
|
||||||
# ------------------------------------- #
|
# ------------------------------------- #
|
||||||
|
|
||||||
print(count(1, 2));
|
|
||||||
@@ -59,6 +59,7 @@ static const InstrInfo instr_table[] = {
|
|||||||
[OPCODE_POP] = {"POP", 1, (OperandType[]) {OPTP_INT}},
|
[OPCODE_POP] = {"POP", 1, (OperandType[]) {OPTP_INT}},
|
||||||
[OPCODE_CALL] = {"CALL", 1, (OperandType[]) {OPTP_INT}},
|
[OPCODE_CALL] = {"CALL", 1, (OperandType[]) {OPTP_INT}},
|
||||||
[OPCODE_INSERT] = {"INSERT", 0, NULL},
|
[OPCODE_INSERT] = {"INSERT", 0, NULL},
|
||||||
|
[OPCODE_SELECT] = {"SELECT", 0, NULL},
|
||||||
[OPCODE_PUSHINT] = {"PUSHINT", 1, (OperandType[]) {OPTP_INT}},
|
[OPCODE_PUSHINT] = {"PUSHINT", 1, (OperandType[]) {OPTP_INT}},
|
||||||
[OPCODE_PUSHFLT] = {"PUSHFLT", 1, (OperandType[]) {OPTP_FLOAT}},
|
[OPCODE_PUSHFLT] = {"PUSHFLT", 1, (OperandType[]) {OPTP_FLOAT}},
|
||||||
[OPCODE_PUSHSTR] = {"PUSHSTR", 1, (OperandType[]) {OPTP_STRING}},
|
[OPCODE_PUSHSTR] = {"PUSHSTR", 1, (OperandType[]) {OPTP_STRING}},
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ typedef enum {
|
|||||||
OPCODE_POP,
|
OPCODE_POP,
|
||||||
OPCODE_CALL,
|
OPCODE_CALL,
|
||||||
OPCODE_INSERT,
|
OPCODE_INSERT,
|
||||||
|
OPCODE_SELECT,
|
||||||
OPCODE_PUSHINT,
|
OPCODE_PUSHINT,
|
||||||
OPCODE_PUSHFLT,
|
OPCODE_PUSHFLT,
|
||||||
OPCODE_PUSHSTR,
|
OPCODE_PUSHSTR,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ typedef enum {
|
|||||||
EXPR_FLOAT,
|
EXPR_FLOAT,
|
||||||
EXPR_STRING,
|
EXPR_STRING,
|
||||||
EXPR_IDENT,
|
EXPR_IDENT,
|
||||||
|
EXPR_SELECT,
|
||||||
} ExprKind;
|
} ExprKind;
|
||||||
|
|
||||||
typedef struct Node Node;
|
typedef struct Node Node;
|
||||||
@@ -104,6 +105,12 @@ typedef struct {
|
|||||||
int argc;
|
int argc;
|
||||||
} CallExprNode;
|
} CallExprNode;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ExprNode base;
|
||||||
|
Node *idx;
|
||||||
|
Node *set;
|
||||||
|
} IndexSelectionExprNode;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Node base;
|
Node base;
|
||||||
Node *condition;
|
Node *condition;
|
||||||
|
|||||||
@@ -188,6 +188,19 @@ static _Bool emit_instr_for_node(ExeBuilder *exeb, Node *node, Error *error)
|
|||||||
return ExeBuilder_Append(exeb, error, OPCODE_CALL, &op, 1, node->offset, node->length);
|
return ExeBuilder_Append(exeb, error, OPCODE_CALL, &op, 1, node->offset, node->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EXPR_SELECT:
|
||||||
|
{
|
||||||
|
IndexSelectionExprNode *sel = (IndexSelectionExprNode*) expr;
|
||||||
|
|
||||||
|
if(!emit_instr_for_node(exeb, sel->set, error))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!emit_instr_for_node(exeb, sel->idx, error))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return ExeBuilder_Append(exeb, error, OPCODE_SELECT, NULL, 0, node->offset, node->length);
|
||||||
|
}
|
||||||
|
|
||||||
case EXPR_NONE:
|
case EXPR_NONE:
|
||||||
return ExeBuilder_Append(exeb, error, OPCODE_PUSHNNE, NULL, 0, node->offset, node->length);
|
return ExeBuilder_Append(exeb, error, OPCODE_PUSHNNE, NULL, 0, node->offset, node->length);
|
||||||
|
|
||||||
|
|||||||
@@ -1160,6 +1160,44 @@ static Node *parse_postfix_expression(Context *ctx)
|
|||||||
{
|
{
|
||||||
switch(current(ctx))
|
switch(current(ctx))
|
||||||
{
|
{
|
||||||
|
case '[':
|
||||||
|
{
|
||||||
|
Node *idx = parse_list_primary_expression(ctx);
|
||||||
|
|
||||||
|
if(idx == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ListExprNode *ls = (ListExprNode*) idx;
|
||||||
|
|
||||||
|
if(ls->itemc == 0)
|
||||||
|
{
|
||||||
|
Error_Report(ctx->error, 0, "Missing index in index selection expression");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexSelectionExprNode *sel;
|
||||||
|
{
|
||||||
|
sel = BPAlloc_Malloc(ctx->alloc, sizeof(IndexSelectionExprNode));
|
||||||
|
|
||||||
|
if(sel == NULL)
|
||||||
|
{
|
||||||
|
Error_Report(ctx->error, 1, "No memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sel->base.base.kind = NODE_EXPR;
|
||||||
|
sel->base.base.next = NULL;
|
||||||
|
sel->base.base.offset = node->offset;
|
||||||
|
sel->base.base.length = idx->offset + idx->length - node->offset;
|
||||||
|
sel->base.kind = EXPR_SELECT;
|
||||||
|
sel->set = node;
|
||||||
|
sel->idx = ls->itemc == 1 ? ls->items : (Node*) ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = (Node*) sel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
{
|
{
|
||||||
int offset = current_token(ctx)->offset;
|
int offset = current_token(ctx)->offset;
|
||||||
|
|||||||
@@ -665,6 +665,34 @@ static _Bool step(Runtime *runtime, Error *error)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case OPCODE_SELECT:
|
||||||
|
{
|
||||||
|
assert(opc == 0);
|
||||||
|
|
||||||
|
if(runtime->frame->used < 2)
|
||||||
|
{
|
||||||
|
Error_Report(error, 1, "Frame has not enough values on the stack to run SELECT instruction");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *col = Stack_Top(runtime->stack, -1);
|
||||||
|
Object *key = Stack_Top(runtime->stack, 0);
|
||||||
|
|
||||||
|
assert(col != NULL && key != NULL);
|
||||||
|
|
||||||
|
if(!Runtime_Pop(runtime, error, 2))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Object *val = Object_Select(col, key, runtime->heap, error);
|
||||||
|
|
||||||
|
if(val == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!Runtime_Push(runtime, error, val))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
case OPCODE_PUSHINT:
|
case OPCODE_PUSHINT:
|
||||||
{
|
{
|
||||||
assert(opc == 1);
|
assert(opc == 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user