Skip to content

Commit

Permalink
Implement Array literal.
Browse files Browse the repository at this point in the history
  • Loading branch information
macournoyer committed Feb 15, 2009
1 parent 372826a commit 7df03aa
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 5 deletions.
22 changes: 22 additions & 0 deletions test/array.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
a = [1, 2, 3]

puts a.size
# => 3

puts a[0]
# => 1

# TODO negative number not yet supported...
# puts a[-1]
# # => 3

a << 4
puts a[3]
# => 4

puts a[4]
# =>

a[1] = 5
puts a[1]
# => 5
4 changes: 4 additions & 0 deletions test/fixnum.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
puts 1
# => 1

# TODO
# puts -1
# # => -1

puts 10.class.name
# => Fixnum

Expand Down
10 changes: 9 additions & 1 deletion vm/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ OBJ TrArray_new2(VM, int argc, ...) {
return a;
}

OBJ TrArray_new3(VM, int argc, OBJ items[]) {
OBJ a = TrArray_new(vm);
size_t i;
for (i = 0; i < argc; ++i) TR_ARRAY_PUSH(a, items[i]);
return a;
}

static OBJ TrArray_push(VM, OBJ self, OBJ x) {
TR_ARRAY_PUSH(self, x);
return x;
Expand All @@ -38,7 +45,8 @@ static OBJ TrArray_at(VM, OBJ self, OBJ at) {
static OBJ TrArray_set(VM, OBJ self, OBJ at, OBJ x) {
int i = TrArray_at2index(vm, self, at);
if (i < 0) tr_raise("IndexError: index %d out of array", i);
return kv_a(OBJ, (TR_CARRAY(self))->kv, i);
kv_a(OBJ, (TR_CARRAY(self))->kv, i) = x;
return x;
}

static OBJ TrArray_length(VM, OBJ self) {
Expand Down
12 changes: 12 additions & 0 deletions vm/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,17 @@ void TrCompiler_compile_node(VM, TrCompiler *c, TrBlock *b, TrNode *n, int reg)
int i = TrBlock_push_string(b, TR_STR_PTR(n->args[0]));
PUSH_OP_ABx(b, STRING, reg, i);
} break;
case AST_ARRAY: {
size_t size = 0;
if (n->args[0]) {
size = TR_ARRAY_SIZE(n->args[0]);
/* compile args */
TR_ARRAY_EACH(n->args[0], i, v, {
TrCompiler_compile_node(vm, c, b, (TrNode *)v, reg+i+1);
});
}
PUSH_OP_AB(b, NEWARRAY, reg, size);
} break;
case AST_ASSIGN: {
int i = TrBlock_local(c->block, n->args[0]);
TrCompiler_compile_node(vm, c, b, (TrNode *)n->args[1], reg);
Expand All @@ -162,6 +173,7 @@ void TrCompiler_compile_node(VM, TrCompiler *c, TrBlock *b, TrNode *n, int reg)
i = TrBlock_pushk(b, msg->args[0]);
size_t argc = 0;
if (msg->args[1]) {
/* compile args */
argc = TR_ARRAY_SIZE(msg->args[1]);
TR_ARRAY_EACH(msg->args[1], i, v, {
TrCompiler_compile_node(vm, c, b, (TrNode *)v, reg+i+2);
Expand Down
6 changes: 6 additions & 0 deletions vm/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ literal(A) ::= NIL. { A = NODE(NIL, 0); }
literal(A) ::= SELF. { A = NODE(SELF, 0); }
literal(A) ::= RETURN. { A = NODE(RETURN, 0); }
literal(A) ::= CONST(B). { A = NODE(CONST, B); }
literal(A) ::= O_SBRA C_SBRA. { A = NODE(ARRAY, 0); }
literal(A) ::= O_SBRA args(B) C_SBRA. { A = NODE(ARRAY, B); }

assign_out(A) ::= CONST(B) ASSIGN statement(C). { A = NODE2(SETCONST, B, C); }
assign_out(A) ::= ID(B) ASSIGN statement(C). { A = NODE2(ASSIGN, B, C); }
Expand All @@ -66,11 +68,15 @@ assign(A) ::= ID(B) ASSIGN expr(C). { A = NODE2(ASSIGN, B, C); }
expr(A) ::= expr(B) DOT name(C). { A = NODE2(SEND, B, C); }
expr(A) ::= expr(B) BINOP(C) msg(D). { A = NODE2(SEND, B, NODE2(MSG, C, NODES(D))); }
expr(A) ::= msg(B). { A = B; }
expr(A) ::= expr(B) O_SBRA_ID args(C) C_SBRA. { VM = compiler->vm; A = NODE2(SEND, B, NODE2(MSG, tr_intern("[]"), C)); }
/*expr(A) ::= expr(B) O_SBRA_ID args(C) C_SBRA ASSIGN expr(D). { VM = compiler->vm; A = NODE2(SEND, B, NODE2(MSG, tr_intern("[]="), PUSH(C, D))); }*/

/* outer expression, can pass args w/out parenthesis, eg.: puts "poop" */
expr_out(A) ::= expr(B) DOT name_out(C). { A = NODE2(SEND, B, C); }
expr_out(A) ::= expr(B) BINOP(C) msg_out(D). { A = NODE2(SEND, B, NODE2(MSG, C, NODES(D))); }
expr_out(A) ::= msg_out(B). { A = B; }
expr_out(A) ::= expr(B) O_SBRA_ID args(C) C_SBRA. { VM = compiler->vm; A = NODE2(SEND, B, NODE2(MSG, tr_intern("[]"), C)); }
expr_out(A) ::= expr(B) O_SBRA_ID args(C) C_SBRA ASSIGN expr(D). { VM = compiler->vm; A = NODE2(SEND, B, NODE2(MSG, tr_intern("[]="), PUSH(C, D))); }

name(A) ::= ID(B). { A = NODE(MSG, B); }
name(A) ::= ID(B) O_PAR C_PAR. { A = NODE(MSG, B); }
Expand Down
3 changes: 2 additions & 1 deletion vm/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ typedef enum {
AST_PARAM,
AST_CLASS,
AST_CONST,
AST_SETCONST
AST_SETCONST,
AST_ARRAY
} TrNodeType;

typedef struct {
Expand Down
7 changes: 4 additions & 3 deletions vm/opcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum TrInstCode {
TR_OP_GETCONST, /* A Bx R[A] = Consts[k[Bx]] */
TR_OP_SETCONST, /* A Bx Consts[k[Bx]] = R[A] */
TR_OP_CLASS, /* A Bx R[A] = define class k[Bx] on self w/ blocks[A] */
TR_OP_NEWARRAY, /* A B R[A] = Array.new(R[A+1]..R[A+1+B]) */
TR_OP_UNDEF,
TR_OP_ALIAS,
TR_OP_SUPER,
Expand All @@ -46,7 +47,6 @@ enum TrInstCode {
TR_OP_SETCVAR,
TR_OP_GETGLOBAL,
TR_OP_SETGLOBAL,
TR_OP_NEWARRAY,
TR_OP_NEWHASH,
TR_OP_NEWRANGE
};
Expand Down Expand Up @@ -75,6 +75,7 @@ enum TrInstCode {
"getconst", \
"setconst", \
"class", \
"newarray", \
"undef", \
"alias", \
"super", \
Expand All @@ -87,7 +88,6 @@ enum TrInstCode {
"setcvar", \
"getglobal", \
"setglobal", \
"newarray", \
"newhash", \
"newrange"

Expand Down Expand Up @@ -117,7 +117,8 @@ enum TrInstCode {
&&op_DEF, \
&&op_GETCONST, \
&&op_SETCONST, \
&&op_CLASS
&&op_CLASS, \
&&op_NEWARRAY

#endif

Expand Down
3 changes: 3 additions & 0 deletions vm/scanner.rl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
"," => { TOKEN(COMMA); };
"(" => { TOKEN(O_PAR); };
")" => { TOKEN(C_PAR); };
id "[" => { TOKEN_V(ID, tr_intern(BUFFER(ts, te-ts-1))); TOKEN(O_SBRA_ID); };
"[" => { TOKEN(O_SBRA); };
"]" => { TOKEN(C_SBRA); };
term => { TOKEN_U(TERM); };
dot => { TOKEN(DOT); };

Expand Down
1 change: 1 addition & 0 deletions vm/tr.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ void TrFixnum_init(VM);
/* array */
OBJ TrArray_new(VM);
OBJ TrArray_new2(VM, int argc, ...);
OBJ TrArray_new3(VM, int argc, OBJ items[]);
void TrArray_init(VM);

/* object */
Expand Down
1 change: 1 addition & 0 deletions vm/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ OBJ TrVM_step(VM) {
OP(SELF): R[A] = f->self; DISPATCH;
OP(NIL): R[A] = TR_NIL; DISPATCH;
OP(BOOL): R[A] = B+1; DISPATCH;
OP(NEWARRAY): R[A] = TrArray_new3(vm, B, &R[A+1]); DISPATCH;
OP(RETURN): return R[A];

/* variable and consts */
Expand Down

0 comments on commit 7df03aa

Please sign in to comment.