ソースを参照

fixes, and array dot-number assign

master
Martin Dørum 3年前
コミット
12495a8bcd
6個のファイルの変更102行の追加36行の削除
  1. 19
    2
      include/lang2/bytecode.h
  2. 2
    0
      include/lang2/gen/gen.h
  3. 10
    0
      lib/gen/gen.c
  4. 14
    1
      lib/parse/parse.c
  5. 42
    33
      lib/vm/print.c
  6. 15
    0
      lib/vm/vm.c

+ 19
- 2
include/lang2/bytecode.h ファイルの表示

*/ */
L2_OP_POP, L2_OP_POP,


/*
* Swap the top and second-top elements, then pop the new top element.
* Pop <word1>
* Pop <word2>
* Push <word1>
*/
L2_OP_SWAP_POP,

/* /*
* Duplicate the top element on the stack. * Duplicate the top element on the stack.
* Push <word at <sptr> - 1> * Push <word at <sptr> - 1>
/* /*
* Look up a value from an array. * Look up a value from an array.
* Pop <key> * Pop <key>
* Pop <arr>
* Push <arr[<key>]>
* Read <val>
* Read <arr>
* Assign <val> to <arr[<key>]>
*/ */
L2_OP_DIRECT_ARRAY_LOOKUP, L2_OP_DIRECT_ARRAY_LOOKUP,


/*
* Set a value in an array.
* Pop <key>
* Read <arr>
* Push <arr[<key>]>
*/
L2_OP_DIRECT_ARRAY_SET,

/* /*
* Halt execution. * Halt execution.
*/ */

+ 2
- 0
include/lang2/gen/gen.h ファイルの表示

void l2_gen_halt(struct l2_generator *gen); void l2_gen_halt(struct l2_generator *gen);
void l2_gen_rjmp(struct l2_generator *gen, l2_word len); void l2_gen_rjmp(struct l2_generator *gen, l2_word len);
void l2_gen_pop(struct l2_generator *gen); void l2_gen_pop(struct l2_generator *gen);
void l2_gen_swap_pop(struct l2_generator *gen);
void l2_gen_push(struct l2_generator *gen, l2_word word); void l2_gen_push(struct l2_generator *gen, l2_word word);
void l2_gen_ret(struct l2_generator *gen); void l2_gen_ret(struct l2_generator *gen);
void l2_gen_number(struct l2_generator *gen, double num); void l2_gen_number(struct l2_generator *gen, double num);
void l2_gen_namespace_set(struct l2_generator *gen, char **ident); void l2_gen_namespace_set(struct l2_generator *gen, char **ident);
void l2_gen_namespace_lookup(struct l2_generator *gen, char **ident); void l2_gen_namespace_lookup(struct l2_generator *gen, char **ident);
void l2_gen_direct_array_lookup(struct l2_generator *gen, int number); void l2_gen_direct_array_lookup(struct l2_generator *gen, int number);
void l2_gen_direct_array_set(struct l2_generator *gen, int number);
void l2_gen_stack_frame_lookup(struct l2_generator *gen, char **ident); void l2_gen_stack_frame_lookup(struct l2_generator *gen, char **ident);
void l2_gen_stack_frame_set(struct l2_generator *gen, char **ident); void l2_gen_stack_frame_set(struct l2_generator *gen, char **ident);
void l2_gen_stack_frame_replace(struct l2_generator *gen, char **ident); void l2_gen_stack_frame_replace(struct l2_generator *gen, char **ident);

+ 10
- 0
lib/gen/gen.c ファイルの表示

put(gen, L2_OP_POP); put(gen, L2_OP_POP);
} }


void l2_gen_swap_pop(struct l2_generator *gen) {
put(gen, L2_OP_SWAP_POP);
}

void l2_gen_push(struct l2_generator *gen, l2_word word) { void l2_gen_push(struct l2_generator *gen, l2_word word) {
put(gen, L2_OP_PUSH); put(gen, L2_OP_PUSH);
put(gen, word); put(gen, word);
put(gen, L2_OP_DIRECT_ARRAY_LOOKUP); put(gen, L2_OP_DIRECT_ARRAY_LOOKUP);
} }


void l2_gen_direct_array_set(struct l2_generator *gen, int number) {
put(gen, L2_OP_PUSH);
put(gen, number);
put(gen, L2_OP_DIRECT_ARRAY_SET);
}

void l2_gen_stack_frame_lookup(struct l2_generator *gen, char **ident) { void l2_gen_stack_frame_lookup(struct l2_generator *gen, char **ident) {
size_t atom_id = l2_strset_put(&gen->atomset, ident); size_t atom_id = l2_strset_put(&gen->atomset, ident);
put(gen, L2_OP_PUSH); put(gen, L2_OP_PUSH);

+ 14
- 1
lib/parse/parse.c ファイルの表示

char *ident = l2_token_extract_str(tok2); char *ident = l2_token_extract_str(tok2);
l2_lexer_consume(lexer); // '.' l2_lexer_consume(lexer); // '.'
l2_lexer_consume(lexer); // ident l2_lexer_consume(lexer); // ident
l2_lexer_consume(lexer); // equals
l2_lexer_consume(lexer); // '='


if (parse_expression(lexer, gen, err) < 0) { if (parse_expression(lexer, gen, err) < 0) {
return -1; return -1;
} }


l2_gen_namespace_set(gen, &ident); l2_gen_namespace_set(gen, &ident);
l2_gen_swap_pop(gen);
} else if (tok->kind == L2_TOK_PERIOD && tok2->kind == L2_TOK_IDENT) { } else if (tok->kind == L2_TOK_PERIOD && tok2->kind == L2_TOK_IDENT) {
l2_trace_scope("namespace lookup"); l2_trace_scope("namespace lookup");
l2_trace("ident '%s'", tok2->v.str); l2_trace("ident '%s'", tok2->v.str);
l2_lexer_consume(lexer); // ident l2_lexer_consume(lexer); // ident


l2_gen_namespace_lookup(gen, &ident); l2_gen_namespace_lookup(gen, &ident);
} else if (tok->kind == L2_TOK_DOT_NUMBER && tok2->kind == L2_TOK_EQUALS) {
l2_trace_scope("direct array assign");
int number = tok->v.integer;
l2_lexer_consume(lexer); // dot-number
l2_lexer_consume(lexer); // '='

if (parse_expression(lexer, gen, err) < 0) {
return -1;
}

l2_gen_direct_array_set(gen, number);
l2_gen_swap_pop(gen);
} else if (tok->kind == L2_TOK_DOT_NUMBER) { } else if (tok->kind == L2_TOK_DOT_NUMBER) {
l2_trace_scope("direct array lookup"); l2_trace_scope("direct array lookup");
int number = tok->v.integer; int number = tok->v.integer;

+ 42
- 33
lib/vm/print.c ファイルの表示

switch (opcode) { switch (opcode) {
case L2_OP_NOP: case L2_OP_NOP:
printf("NOP\n"); printf("NOP\n");
break;
return;


case L2_OP_PUSH: case L2_OP_PUSH:
printf("PUSH "); printf("PUSH ");
print_op_num(ops, opcount, (*ptr)++); print_op_num(ops, opcount, (*ptr)++);
printf("\n"); printf("\n");
break;
return;


case L2_OP_PUSH_2: case L2_OP_PUSH_2:
printf("PUSH2 "); printf("PUSH2 ");
printf(" "); printf(" ");
print_op_num(ops, opcount, (*ptr)++); print_op_num(ops, opcount, (*ptr)++);
printf("\n"); printf("\n");
break;
return;


case L2_OP_POP: case L2_OP_POP:
printf("POP\n"); printf("POP\n");
break;
return;

case L2_OP_SWAP_POP:
printf("SWAP_POP\n");
return;


case L2_OP_DUP: case L2_OP_DUP:
printf("DUP\n"); printf("DUP\n");
break;
return;


case L2_OP_ADD: case L2_OP_ADD:
printf("ADD\n"); printf("ADD\n");
break;
return;


case L2_OP_FUNC_CALL: case L2_OP_FUNC_CALL:
printf("FUNC_CALL\n"); printf("FUNC_CALL\n");
break;
return;


case L2_OP_RJMP: case L2_OP_RJMP:
printf("RJMP\n"); printf("RJMP\n");
break;
return;


case L2_OP_STACK_FRAME_LOOKUP: case L2_OP_STACK_FRAME_LOOKUP:
printf("STACK_FRAME_LOOKUP\n"); printf("STACK_FRAME_LOOKUP\n");
break;
return;


case L2_OP_STACK_FRAME_SET: case L2_OP_STACK_FRAME_SET:
printf("STACK_FRAME_SET\n"); printf("STACK_FRAME_SET\n");
break;
return;

case L2_OP_STACK_FRAME_REPLACE:
printf("STACK_FRAME_REPLACE\n");
return;


case L2_OP_RET: case L2_OP_RET:
printf("RET\n"); printf("RET\n");
break;
return;


case L2_OP_ALLOC_ATOM: case L2_OP_ALLOC_ATOM:
printf("ALLOC_ATOM\n"); printf("ALLOC_ATOM\n");
break;
return;


case L2_OP_ALLOC_REAL: case L2_OP_ALLOC_REAL:
printf("ALLOC_REAL\n"); printf("ALLOC_REAL\n");
break;
return;


case L2_OP_ALLOC_BUFFER_STATIC: case L2_OP_ALLOC_BUFFER_STATIC:
printf("ALLOC_BUFFER_STATIC\n"); printf("ALLOC_BUFFER_STATIC\n");
break;
return;


case L2_OP_ALLOC_BUFFER_ZERO: case L2_OP_ALLOC_BUFFER_ZERO:
printf("ALLOC_BUFFER_ZERO\n"); printf("ALLOC_BUFFER_ZERO\n");
break;
return;


case L2_OP_ALLOC_ARRAY: case L2_OP_ALLOC_ARRAY:
printf("ALLOC_ARRAY\n"); printf("ALLOC_ARRAY\n");
break;
return;


case L2_OP_ALLOC_NAMESPACE: case L2_OP_ALLOC_NAMESPACE:
printf("ALLOC_NAMESPACE\n"); printf("ALLOC_NAMESPACE\n");
break;
return;


case L2_OP_ALLOC_FUNCTION: case L2_OP_ALLOC_FUNCTION:
printf("ALLOC_FUNCTION\n"); printf("ALLOC_FUNCTION\n");
break;
return;


case L2_OP_NAMESPACE_SET: case L2_OP_NAMESPACE_SET:
printf("NAMESPACE_SET\n"); printf("NAMESPACE_SET\n");
break;
return;


case L2_OP_NAMESPACE_LOOKUP: case L2_OP_NAMESPACE_LOOKUP:
printf("NAMESPACE_LOOKUP\n"); printf("NAMESPACE_LOOKUP\n");
break;
return;


case L2_OP_DIRECT_ARRAY_LOOKUP: case L2_OP_DIRECT_ARRAY_LOOKUP:
printf("DIRECT_ARRAY_LOOKUP\n"); printf("DIRECT_ARRAY_LOOKUP\n");
break;
return;

case L2_OP_DIRECT_ARRAY_SET:
printf("DIRECT_ARRAY_SET\n");
return;


case L2_OP_HALT: case L2_OP_HALT:
printf("HALT\n"); printf("HALT\n");
break;
return;
}


default:
{
l2_word word = (l2_word)opcode;
char bytes[sizeof(word)];
memcpy(&bytes, &word, sizeof(word));
printf("?");
for (size_t i = 0; i < sizeof(bytes); ++i) {
printf(" %02x", bytes[i]);
}
printf("\n");
}
l2_word word = (l2_word)opcode;
char bytes[sizeof(word)];
memcpy(&bytes, &word, sizeof(word));
printf("?");
for (size_t i = 0; i < sizeof(bytes); ++i) {
printf(" %02x", bytes[i]);
} }
printf("\n");
} }


void l2_vm_print_bytecode(l2_word *ops, size_t opcount) { void l2_vm_print_bytecode(l2_word *ops, size_t opcount) {

+ 15
- 0
lib/vm/vm.c ファイルの表示

vm->sptr -= 1; vm->sptr -= 1;
break; break;


case L2_OP_SWAP_POP:
vm->stack[vm->sptr - 2] = vm->stack[vm->sptr - 1];
vm->sptr -= 1;
break;

case L2_OP_DUP: case L2_OP_DUP:
vm->stack[vm->sptr] = vm->ops[vm->sptr - 1]; vm->stack[vm->sptr] = vm->ops[vm->sptr - 1];
vm->sptr += 1; vm->sptr += 1;
} }
break; break;


case L2_OP_DIRECT_ARRAY_SET:
{
l2_word key = vm->stack[--vm->sptr];
l2_word val = vm->stack[vm->sptr - 1];
l2_word arr = vm->stack[vm->sptr - 2];
// TODO: Error if out of bounds or incorrect type
vm->values[arr].array->data[key] = val;
}
break;

case L2_OP_HALT: case L2_OP_HALT:
break; break;
} }

読み込み中…
キャンセル
保存