Browse Source

fixes, and array dot-number assign

master
Martin Dørum 3 years ago
parent
commit
12495a8bcd
6 changed files with 102 additions and 36 deletions
  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 View File

@@ -30,6 +30,14 @@ enum l2_opcode {
*/
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.
* Push <word at <sptr> - 1>
@@ -173,11 +181,20 @@ enum l2_opcode {
/*
* Look up a value from an array.
* Pop <key>
* Pop <arr>
* Push <arr[<key>]>
* Read <val>
* Read <arr>
* Assign <val> to <arr[<key>]>
*/
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.
*/

+ 2
- 0
include/lang2/gen/gen.h View File

@@ -25,6 +25,7 @@ void l2_gen_free(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_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_ret(struct l2_generator *gen);
void l2_gen_number(struct l2_generator *gen, double num);
@@ -36,6 +37,7 @@ void l2_gen_namespace(struct l2_generator *gen);
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_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_set(struct l2_generator *gen, char **ident);
void l2_gen_stack_frame_replace(struct l2_generator *gen, char **ident);

+ 10
- 0
lib/gen/gen.c View File

@@ -45,6 +45,10 @@ void l2_gen_pop(struct l2_generator *gen) {
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) {
put(gen, L2_OP_PUSH);
put(gen, word);
@@ -145,6 +149,12 @@ void l2_gen_direct_array_lookup(struct l2_generator *gen, int number) {
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) {
size_t atom_id = l2_strset_put(&gen->atomset, ident);
put(gen, L2_OP_PUSH);

+ 14
- 1
lib/parse/parse.c View File

@@ -294,13 +294,14 @@ static int parse_arg_level_expression(
char *ident = l2_token_extract_str(tok2);
l2_lexer_consume(lexer); // '.'
l2_lexer_consume(lexer); // ident
l2_lexer_consume(lexer); // equals
l2_lexer_consume(lexer); // '='

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

l2_gen_namespace_set(gen, &ident);
l2_gen_swap_pop(gen);
} else if (tok->kind == L2_TOK_PERIOD && tok2->kind == L2_TOK_IDENT) {
l2_trace_scope("namespace lookup");
l2_trace("ident '%s'", tok2->v.str);
@@ -309,6 +310,18 @@ static int parse_arg_level_expression(
l2_lexer_consume(lexer); // 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) {
l2_trace_scope("direct array lookup");
int number = tok->v.integer;

+ 42
- 33
lib/vm/print.c View File

@@ -117,13 +117,13 @@ void l2_vm_print_op(l2_word *ops, size_t opcount, size_t *ptr) {
switch (opcode) {
case L2_OP_NOP:
printf("NOP\n");
break;
return;

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

case L2_OP_PUSH_2:
printf("PUSH2 ");
@@ -131,96 +131,105 @@ void l2_vm_print_op(l2_word *ops, size_t opcount, size_t *ptr) {
printf(" ");
print_op_num(ops, opcount, (*ptr)++);
printf("\n");
break;
return;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

case L2_OP_HALT:
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) {

+ 15
- 0
lib/vm/vm.c View File

@@ -226,6 +226,11 @@ void l2_vm_step(struct l2_vm *vm) {
vm->sptr -= 1;
break;

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

case L2_OP_DUP:
vm->stack[vm->sptr] = vm->ops[vm->sptr - 1];
vm->sptr += 1;
@@ -437,6 +442,16 @@ void l2_vm_step(struct l2_vm *vm) {
}
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:
break;
}

Loading…
Cancel
Save