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

*/ */
L2_OP_STACK_FRAME_SET, 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. * Return from a function.
* NSPop * NSPop

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

void l2_gen_pop(struct l2_generator *gen); void l2_gen_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_assignment(struct l2_generator *gen, char **ident);
void l2_gen_number(struct l2_generator *gen, double num); void l2_gen_number(struct l2_generator *gen, double num);
void l2_gen_string(struct l2_generator *gen, char **str); void l2_gen_string(struct l2_generator *gen, char **str);
void l2_gen_atom(struct l2_generator *gen, char **ident); void l2_gen_atom(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_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_replace(struct l2_generator *gen, char **ident);
void l2_gen_func_call(struct l2_generator *gen); void l2_gen_func_call(struct l2_generator *gen);


#endif #endif

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

L2_TOK_DOT_NUMBER, L2_TOK_DOT_NUMBER,
L2_TOK_COLON, L2_TOK_COLON,
L2_TOK_COLON_EQ, L2_TOK_COLON_EQ,
L2_TOK_EQUALS,
L2_TOK_EOL, L2_TOK_EOL,
L2_TOK_EOF, L2_TOK_EOF,
L2_TOK_NUMBER, L2_TOK_NUMBER,

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

l2_word data[]; 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); 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 { struct l2_vm {
l2_word *ops; l2_word *ops;

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

put(gen, L2_OP_RET); 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) { void l2_gen_number(struct l2_generator *gen, double num) {
uint64_t n; uint64_t n;
memcpy(&n, &num, sizeof(num)); memcpy(&n, &num, sizeof(num));
put(gen, L2_OP_STACK_FRAME_LOOKUP); 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) { void l2_gen_func_call(struct l2_generator *gen) {
put(gen, L2_OP_FUNC_CALL); put(gen, L2_OP_FUNC_CALL);
} }

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

return "colon"; return "colon";
case L2_TOK_COLON_EQ: case L2_TOK_COLON_EQ:
return "colon-equals"; return "colon-equals";
case L2_TOK_EQUALS:
return "equals";
case L2_TOK_EOL: case L2_TOK_EOL:
return "end-of-line"; return "end-of-line";
case L2_TOK_EOF: case L2_TOK_EOF:
case ',': case ',':
case '.': case '.':
case ':': case ':':
case '=':
case ';': case ';':
case EOF: case EOF:
tok->v.str[idx] = '\0'; tok->v.str[idx] = '\0';
} }
break; break;


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

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

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

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


int first = 1; int first = 1;
while (1) { while (1) {
while (1) { while (1) {
struct l2_token *tok = l2_lexer_peek(lexer, 1); struct l2_token *tok = l2_lexer_peek(lexer, 1);
struct l2_token *tok2 = l2_lexer_peek(lexer, 2); 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) { if (tok->kind == L2_TOK_OPEN_PAREN && tok2->kind == L2_TOK_CLOSE_PAREN) {
l2_trace_scope("niladic func call"); l2_trace_scope("niladic func call");


l2_gen_push(gen, 0); l2_gen_push(gen, 0);
l2_gen_func_call(gen); 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) { } 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);
return -1; 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 { } else {
if (parse_arg_level_expression(lexer, gen, err) < 0) { if (parse_arg_level_expression(lexer, gen, err) < 0) {
return -1; return -1;

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

} }
} }


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) { void l2_vm_namespace_set(struct l2_vm_value *v, l2_word key, l2_word val) {
if (val == 0) { if (val == 0) {
del(v->ns, key); del(v->ns, 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);
}
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



case L2_OP_STACK_FRAME_SET: 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]]; struct l2_vm_value *ns = &vm->values[vm->nstack[vm->nsptr - 1]];
l2_vm_namespace_set(ns, key, val); 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; break;



Loading…
Cancel
Save