Преглед на файлове

add operators &&, ||, ??

master
Martin Dørum преди 3 години
родител
ревизия
bbbd0716ca
променени са 7 файла, в които са добавени 100 реда и са изтрити 10 реда
  1. 3
    0
      include/lang2/builtins.x.h
  2. 1
    2
      include/lang2/vm/vm.h
  3. 4
    1
      lib/parse/parse.c
  4. 43
    3
      lib/vm/builtins.c
  5. 1
    2
      lib/vm/vm.c
  6. 23
    0
      test/examples/builtins.l2
  7. 25
    2
      test/examples/builtins.l2.expected

+ 3
- 0
include/lang2/builtins.x.h Целия файл

@@ -17,6 +17,9 @@ X("<", l2_builtin_lt)
X("<=", l2_builtin_lteq)
X(">", l2_builtin_gt)
X(">=", l2_builtin_gteq)
X("&&", l2_builtin_land)
X("||", l2_builtin_lor)
X("??", l2_builtin_first)
X("print", l2_builtin_print)
X("len", l2_builtin_len)
X("if", l2_builtin_if)

+ 1
- 2
include/lang2/vm/vm.h Целия файл

@@ -134,7 +134,6 @@ void l2_vm_free(struct l2_vm *vm);
void l2_vm_step(struct l2_vm *vm);
void l2_vm_run(struct l2_vm *vm);
size_t l2_vm_gc(struct l2_vm *vm);

int l2_vm_val_is_true(struct l2_vm *vm, l2_word id);
int l2_vm_val_is_true(struct l2_vm *vm, struct l2_vm_value *val);

#endif

+ 4
- 1
lib/parse/parse.c Целия файл

@@ -26,7 +26,10 @@ static int tok_is_infix(struct l2_token *tok) {
strcmp(str, "<") == 0 ||
strcmp(str, "<=") == 0 ||
strcmp(str, ">") == 0 ||
strcmp(str, ">=") == 0;
strcmp(str, ">=") == 0 ||
strcmp(str, "&&") == 0 ||
strcmp(str, "||") == 0 ||
strcmp(str, "??") == 0;
}

static int parse_expression(

+ 43
- 3
lib/vm/builtins.c Целия файл

@@ -181,6 +181,46 @@ X(l2_builtin_gt, >)
X(l2_builtin_gteq, >=)
#undef X

l2_word l2_builtin_land(struct l2_vm *vm, l2_word argc, l2_word *argv) {
for (l2_word i = 0; i < argc; ++i) {
struct l2_vm_value *val = &vm->values[argv[i]];
if (l2_value_get_type(val) == L2_VAL_TYPE_ERROR) {
return argv[i];
}

if (!l2_vm_val_is_true(vm, val)) {
return vm->kfalse;
}
}

return vm->ktrue;
}

l2_word l2_builtin_lor(struct l2_vm *vm, l2_word argc, l2_word *argv) {
for (l2_word i = 0; i < argc; ++i) {
struct l2_vm_value *val = &vm->values[argv[i]];
if (l2_value_get_type(val) == L2_VAL_TYPE_ERROR) {
return argv[i];
}

if (l2_vm_val_is_true(vm, val)) {
return vm->ktrue;
}
}

return vm->kfalse;
}

l2_word l2_builtin_first(struct l2_vm *vm, l2_word argc, l2_word *argv) {
for (l2_word i = 0; i < argc; ++i) {
if (l2_value_get_type(&vm->values[argv[i]]) != L2_VAL_TYPE_NONE) {
return argv[i];
}
}

return vm->knone;
}

l2_word l2_builtin_print(struct l2_vm *vm, l2_word argc, l2_word *argv) {
for (size_t i = 0; i < argc; ++i) {
if (i != 0) {
@@ -237,7 +277,7 @@ l2_word l2_builtin_if(struct l2_vm *vm, l2_word argc, l2_word *argv) {
return l2_vm_error(vm, "Expected 2 or 3 arguments");
}

if (l2_vm_val_is_true(vm, argv[0])) {
if (l2_vm_val_is_true(vm, &vm->values[argv[0]])) {
l2_word ret_id = l2_vm_alloc(vm, L2_VAL_TYPE_CONTINUATION, 0);
struct l2_vm_value *ret = &vm->values[ret_id];
ret->extra.cont_call = argv[1];
@@ -258,7 +298,7 @@ struct loop_context {
};

static l2_word loop_callback(struct l2_vm *vm, l2_word retval, l2_word cont) {
if (l2_vm_val_is_true(vm, retval)) {
if (l2_vm_val_is_true(vm, &vm->values[retval])) {
return cont;
}

@@ -302,7 +342,7 @@ static l2_word while_callback(struct l2_vm *vm, l2_word retval, l2_word cont_id)
struct while_context *ctx = (struct while_context *)cont->cont;

if (cont->extra.cont_call == ctx->cond) {
if (l2_vm_val_is_true(vm, retval)) {
if (l2_vm_val_is_true(vm, &vm->values[retval])) {
cont->extra.cont_call = ctx->body;
return cont_id;
} else {

+ 1
- 2
lib/vm/vm.c Целия файл

@@ -774,8 +774,7 @@ void l2_vm_step(struct l2_vm *vm) {
}
}

int l2_vm_val_is_true(struct l2_vm *vm, l2_word id) {
struct l2_vm_value *val = &vm->values[id];
int l2_vm_val_is_true(struct l2_vm *vm, struct l2_vm_value *val) {
l2_word true_atom = vm->values[vm->ktrue].atom;
return l2_value_get_type(val) == L2_VAL_TYPE_ATOM && val->atom == true_atom;
}

+ 23
- 0
test/examples/builtins.l2 Целия файл

@@ -71,3 +71,26 @@ print (len [])
print (len [10 20])
print (len "Hello")
print (len {a: 10; b: 20; c: 30})

print "\n&&"
print &&()
print &&('true)
print &&('false)
print 'true && 'true
print (&& 10 == 10 20 == 20 30 != 40)
print 'true && 10

print "\n||"
print ||()
print ||('true)
print ||('false)
print 'true || 'true
print 'true || 'false
print (|| 'false 10 'true)
print (|| 'false 10 'nope)

print "\n??"
print none ?? none ?? 30 ?? 20
print (?? 10 none none)
print (?? none none "hello")
print ??()

+ 25
- 2
test/examples/builtins.l2.expected Целия файл

@@ -57,12 +57,12 @@

print
(none)
(true) (false) (atom 20)
(true) (false) (atom 23)
100
100.5
255
Hello World
[(none) (true) (false) (atom 20) 100.1 Nope (namespace) (function)]
[(none) (true) (false) (atom 23) 100.1 Nope (namespace) (function)]
(namespace) (namespace)

len
@@ -71,3 +71,26 @@ len
2
5
3

&&
(true)
(true)
(false)
(true)
(true)
(false)

||
(false)
(true)
(false)
(true)
(true)
(true)
(false)

??
30
10
hello
(none)

Loading…
Отказ
Запис