Browse Source

= operator

master
Martin Dørum 3 years ago
parent
commit
164cc76ce9
9 changed files with 101 additions and 20 deletions
  1. 8
    0
      include/lang2/bytecode.h
  2. 2
    1
      include/lang2/gen/gen.h
  3. 1
    0
      include/lang2/parse/lex.h
  4. 2
    1
      include/lang2/vm/vm.h
  5. 14
    7
      lib/gen/gen.c
  6. 8
    0
      lib/parse/lex.c
  7. 30
    2
      lib/parse/parse.c
  8. 25
    6
      lib/vm/namespace.c
  9. 11
    3
      lib/vm/vm.c

+ 8
- 0
include/lang2/bytecode.h View File

@@ -78,6 +78,14 @@ enum l2_opcode {
*/
L2_OP_STACK_FRAME_SET,

/*
* Replace a value on the stack.
* Pop <key>
* Read <val>
* Assign <val> to stack frame
*/
L2_OP_STACK_FRAME_REPLACE,

/*
* Return from a function.
* NSPop

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

@@ -27,7 +27,6 @@ void l2_gen_rjmp(struct l2_generator *gen, l2_word len);
void l2_gen_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_assignment(struct l2_generator *gen, char **ident);
void l2_gen_number(struct l2_generator *gen, double num);
void l2_gen_string(struct l2_generator *gen, char **str);
void l2_gen_atom(struct l2_generator *gen, char **ident);
@@ -38,6 +37,8 @@ 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_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);
void l2_gen_func_call(struct l2_generator *gen);

#endif

+ 1
- 0
include/lang2/parse/lex.h View File

@@ -16,6 +16,7 @@ enum l2_token_kind {
L2_TOK_DOT_NUMBER,
L2_TOK_COLON,
L2_TOK_COLON_EQ,
L2_TOK_EQUALS,
L2_TOK_EOL,
L2_TOK_EOF,
L2_TOK_NUMBER,

+ 2
- 1
include/lang2/vm/vm.h View File

@@ -74,8 +74,9 @@ struct l2_vm_namespace {
l2_word data[];
};

void l2_vm_namespace_set(struct l2_vm_value *ns, l2_word key, l2_word val);
l2_word l2_vm_namespace_get(struct l2_vm *vm, struct l2_vm_value *ns, l2_word key);
void l2_vm_namespace_set(struct l2_vm_value *ns, l2_word key, l2_word val);
int l2_vm_namespace_replace(struct l2_vm *vm, struct l2_vm_value *ns, l2_word key, l2_word val);

struct l2_vm {
l2_word *ops;

+ 14
- 7
lib/gen/gen.c View File

@@ -54,13 +54,6 @@ void l2_gen_ret(struct l2_generator *gen) {
put(gen, L2_OP_RET);
}

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

void l2_gen_number(struct l2_generator *gen, double num) {
uint64_t n;
memcpy(&n, &num, sizeof(num));
@@ -159,6 +152,20 @@ void l2_gen_stack_frame_lookup(struct l2_generator *gen, char **ident) {
put(gen, L2_OP_STACK_FRAME_LOOKUP);
}

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

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

void l2_gen_func_call(struct l2_generator *gen) {
put(gen, L2_OP_FUNC_CALL);
}

+ 8
- 0
lib/parse/lex.c View File

@@ -67,6 +67,8 @@ const char *l2_token_kind_name(enum l2_token_kind kind) {
return "colon";
case L2_TOK_COLON_EQ:
return "colon-equals";
case L2_TOK_EQUALS:
return "equals";
case L2_TOK_EOL:
return "end-of-line";
case L2_TOK_EOF:
@@ -254,6 +256,7 @@ static void read_ident(struct l2_lexer *lexer, struct l2_token *tok) {
case ',':
case '.':
case ':':
case '=':
case ';':
case EOF:
tok->v.str[idx] = '\0';
@@ -363,6 +366,11 @@ static void read_tok(struct l2_lexer *lexer, struct l2_token *tok) {
}
break;

case '=':
read_ch(lexer);
tok->kind = L2_TOK_EQUALS;
break;

case EOF:
tok->kind = L2_TOK_EOF;
break;

+ 30
- 2
lib/parse/parse.c View File

@@ -77,7 +77,7 @@ static int parse_function_literal_impl(
// The arguments array will be at the top of the stack
char *ident = malloc(2);
ident[0] = '$'; ident[1] = '\0';
l2_gen_assignment(gen, &ident);
l2_gen_stack_frame_set(gen, &ident);

int first = 1;
while (1) {
@@ -277,6 +277,7 @@ static int parse_arg_level_expression(
while (1) {
struct l2_token *tok = l2_lexer_peek(lexer, 1);
struct l2_token *tok2 = l2_lexer_peek(lexer, 2);
struct l2_token *tok3 = l2_lexer_peek(lexer, 3);

if (tok->kind == L2_TOK_OPEN_PAREN && tok2->kind == L2_TOK_CLOSE_PAREN) {
l2_trace_scope("niladic func call");
@@ -285,6 +286,21 @@ static int parse_arg_level_expression(

l2_gen_push(gen, 0);
l2_gen_func_call(gen);
} else if (
tok->kind == L2_TOK_PERIOD && tok2->kind == L2_TOK_IDENT &&
tok3->kind == L2_TOK_EQUALS) {
l2_trace_scope("namespace assign");
l2_trace("ident '%s'", tok2->v.str);
char *ident = l2_token_extract_str(tok2);
l2_lexer_consume(lexer); // '.'
l2_lexer_consume(lexer); // ident
l2_lexer_consume(lexer); // equals

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

l2_gen_namespace_set(gen, &ident);
} else if (tok->kind == L2_TOK_PERIOD && tok2->kind == L2_TOK_IDENT) {
l2_trace_scope("namespace lookup");
l2_trace("ident '%s'", tok2->v.str);
@@ -345,7 +361,19 @@ static int parse_expression(
return -1;
}

l2_gen_assignment(gen, &ident);
l2_gen_stack_frame_set(gen, &ident);
} else if (tok->kind == L2_TOK_IDENT && tok2->kind == L2_TOK_EQUALS) {
l2_trace_scope("replacement assign expression");
l2_trace("ident '%s'", tok->v.str);
char *ident = l2_token_extract_str(tok);
l2_lexer_consume(lexer); // ident
l2_lexer_consume(lexer); // =

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

l2_gen_stack_frame_replace(gen, &ident);
} else {
if (parse_arg_level_expression(lexer, gen, err) < 0) {
return -1;

+ 25
- 6
lib/vm/namespace.c View File

@@ -98,6 +98,15 @@ static l2_word get(struct l2_vm_namespace *ns, l2_word key) {
}
}

l2_word l2_vm_namespace_get(struct l2_vm *vm, struct l2_vm_value *v, l2_word key) {
l2_word ret = get(v->ns, key);
if (ret == 0 && v->extra.ns_parent != 0) {
return l2_vm_namespace_get(vm, &vm->values[v->extra.ns_parent], key);
}

return ret;
}

void l2_vm_namespace_set(struct l2_vm_value *v, l2_word key, l2_word val) {
if (val == 0) {
del(v->ns, key);
@@ -106,11 +115,21 @@ void l2_vm_namespace_set(struct l2_vm_value *v, l2_word key, l2_word val) {
}
}

l2_word l2_vm_namespace_get(struct l2_vm *vm, struct l2_vm_value *v, l2_word key) {
l2_word ret = get(v->ns, key);
if (ret == 0 && v->extra.ns_parent != 0) {
return l2_vm_namespace_get(vm, &vm->values[v->extra.ns_parent], key);
}
int l2_vm_namespace_replace(struct l2_vm *vm, struct l2_vm_value *v, l2_word key, l2_word val) {
if (val == 0) {
del(v->ns, key);
return 0;
} else {
l2_word ret = get(v->ns, key);
if (ret != 0) {
v->ns = set(v->ns, key, val);
return 0;
}

return ret;
if (v->extra.ns_parent == 0) {
return -1;
}

return l2_vm_namespace_replace(vm, &vm->values[v->extra.ns_parent], key, val);
}
}

+ 11
- 3
lib/vm/vm.c View File

@@ -299,11 +299,19 @@ void l2_vm_step(struct l2_vm *vm) {

case L2_OP_STACK_FRAME_SET:
{
l2_word key = vm->stack[vm->sptr - 1];
l2_word val = vm->stack[vm->sptr - 2];
l2_word key = vm->stack[--vm->sptr];
l2_word val = vm->stack[vm->sptr - 1];
struct l2_vm_value *ns = &vm->values[vm->nstack[vm->nsptr - 1]];
l2_vm_namespace_set(ns, key, val);
vm->sptr -= 1;
}
break;

case L2_OP_STACK_FRAME_REPLACE:
{
l2_word key = vm->stack[--vm->sptr];
l2_word val = vm->stack[vm->sptr - 1];
struct l2_vm_value *ns = &vm->values[vm->nstack[vm->nsptr - 1]];
l2_vm_namespace_replace(vm, ns, key, val); // TODO: error if returns -1
}
break;


Loading…
Cancel
Save