aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-10 14:48:30 +0200
committerBad Diode <bd@badd10de.dev>2021-10-10 14:48:30 +0200
commit4e4d5373328276ea6d49a60242555d5db03158ff (patch)
treebae8bae76647d7159b350a1987c74bf9d36cb908
parent9323c1285a8a9f7ec33e88d26f102d92c7a6e2ec (diff)
downloadbdl-4e4d5373328276ea6d49a60242555d5db03158ff.tar.gz
bdl-4e4d5373328276ea6d49a60242555d5db03158ff.zip
Add numerical comparison primitive procedures
-rw-r--r--examples/booleans.bdl14
-rwxr-xr-xsrc/bootstrap/main.c5
-rw-r--r--src/bootstrap/primitives.c173
-rw-r--r--tests/booleans_expected.txt12
4 files changed, 201 insertions, 3 deletions
diff --git a/examples/booleans.bdl b/examples/booleans.bdl
index 24d57a0..8828ac2 100644
--- a/examples/booleans.bdl
+++ b/examples/booleans.bdl
@@ -75,3 +75,17 @@
75(cond ((and true true true) (+ 1 2 3)) 75(cond ((and true true true) (+ 1 2 3))
76 ((or true true false) 2) 76 ((or true true false) 2)
77 (else 3)) 77 (else 3))
78
79;; Numeric comparisons.
80(print "(< 1 2 3) -> ") (< 1 2 3)
81(print "(< 3 2 1) -> ") (< 3 2 1)
82(print "(> 1 2 3) -> ") (> 1 2 3)
83(print "(> 3 2 1) -> ") (> 3 2 1)
84(print "(= 1 2 3) -> ") (= 1 2 3)
85(print "(= 3 2 1) -> ") (= 3 2 1)
86(print "(= 3 3 3) -> ") (= 3 3 3)
87(print "(= (+ 1 2) 3 (- 6 3)) -> ") (= (+ 1 2) 3 (- 6 3))
88(print "(< 1 1 3) -> ") (< 1 1 3)
89(print "(<= 1 1 3) -> ") (<= 1 1 3)
90(print "(> 3 3 1) -> ") (> 3 3 1)
91(print "(>= 3 3 1) -> ") (>= 3 3 1)
diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c
index c0f2e50..b8bab47 100755
--- a/src/bootstrap/main.c
+++ b/src/bootstrap/main.c
@@ -36,6 +36,11 @@ init(void) {
36 environment[env_n++] = (EnvSymbol){MAKE_SYM("-"), make_procedure(proc_sub)}; 36 environment[env_n++] = (EnvSymbol){MAKE_SYM("-"), make_procedure(proc_sub)};
37 environment[env_n++] = (EnvSymbol){MAKE_SYM("*"), make_procedure(proc_mul)}; 37 environment[env_n++] = (EnvSymbol){MAKE_SYM("*"), make_procedure(proc_mul)};
38 environment[env_n++] = (EnvSymbol){MAKE_SYM("/"), make_procedure(proc_div)}; 38 environment[env_n++] = (EnvSymbol){MAKE_SYM("/"), make_procedure(proc_div)};
39 environment[env_n++] = (EnvSymbol){MAKE_SYM("<"), make_procedure(proc_num_less_than)};
40 environment[env_n++] = (EnvSymbol){MAKE_SYM(">"), make_procedure(proc_num_greater_than)};
41 environment[env_n++] = (EnvSymbol){MAKE_SYM("="), make_procedure(proc_num_equal)};
42 environment[env_n++] = (EnvSymbol){MAKE_SYM("<="), make_procedure(proc_num_lesseq_than)};
43 environment[env_n++] = (EnvSymbol){MAKE_SYM(">="), make_procedure(proc_num_greatereq_than)};
39 environment[env_n++] = (EnvSymbol){MAKE_SYM("boolean?"), make_procedure(proc_is_boolean)}; 44 environment[env_n++] = (EnvSymbol){MAKE_SYM("boolean?"), make_procedure(proc_is_boolean)};
40 environment[env_n++] = (EnvSymbol){MAKE_SYM("not"), make_procedure(proc_not)}; 45 environment[env_n++] = (EnvSymbol){MAKE_SYM("not"), make_procedure(proc_not)};
41 environment[env_n++] = (EnvSymbol){MAKE_SYM("and"), make_procedure(proc_and)}; 46 environment[env_n++] = (EnvSymbol){MAKE_SYM("and"), make_procedure(proc_and)};
diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c
index 29a1df8..485799d 100644
--- a/src/bootstrap/primitives.c
+++ b/src/bootstrap/primitives.c
@@ -346,13 +346,180 @@ proc_cond(Object *args) {
346 if (eval(clause->car) == obj_true) { 346 if (eval(clause->car) == obj_true) {
347 return eval(clause->cdr->car); 347 return eval(clause->cdr->car);
348 } 348 }
349
350 args = args->cdr; 349 args = args->cdr;
351 clause = args->car;
352 } 350 }
353 351
354 return obj_nil; 352 return obj_nil;
355} 353}
356 354
357// TODO: equality greater than smaller than... 355Object *
356proc_num_less_than(Object *args) {
357 if (args == obj_nil) {
358 fprintf(stderr, "error: wrong number of arguments type.\n");
359 return NULL;
360 }
361
362 Object *obj = eval(args->car);
363 if (obj->type != OBJ_TYPE_FIXNUM) {
364 fprintf(stderr, "error: wrong argument type.\n");
365 return NULL;
366 }
367 ssize_t prev = obj->fixnum;
368 args = args->cdr;
369
370 if (args == obj_nil) {
371 fprintf(stderr, "error: wrong number of arguments type.\n");
372 return NULL;
373 }
374 while (args != obj_nil) {
375 Object *obj = eval(args->car);
376 if (obj->type != OBJ_TYPE_FIXNUM) {
377 fprintf(stderr, "error: wrong argument type.\n");
378 return NULL;
379 }
380 if (prev >= obj->fixnum) {
381 return obj_false;
382 }
383 prev = obj->fixnum;
384 args = args->cdr;
385 }
386 return obj_true;
387}
388
389Object *
390proc_num_greater_than(Object *args) {
391 if (args == obj_nil) {
392 fprintf(stderr, "error: wrong number of arguments type.\n");
393 return NULL;
394 }
395
396 Object *obj = eval(args->car);
397 if (obj->type != OBJ_TYPE_FIXNUM) {
398 fprintf(stderr, "error: wrong argument type.\n");
399 return NULL;
400 }
401 ssize_t prev = obj->fixnum;
402 args = args->cdr;
403
404 if (args == obj_nil) {
405 fprintf(stderr, "error: wrong number of arguments type.\n");
406 return NULL;
407 }
408 while (args != obj_nil) {
409 Object *obj = eval(args->car);
410 if (obj->type != OBJ_TYPE_FIXNUM) {
411 fprintf(stderr, "error: wrong argument type.\n");
412 return NULL;
413 }
414 if (prev <= obj->fixnum) {
415 return obj_false;
416 }
417 prev = obj->fixnum;
418 args = args->cdr;
419 }
420 return obj_true;
421}
422
423Object *
424proc_num_lesseq_than(Object *args) {
425 if (args == obj_nil) {
426 fprintf(stderr, "error: wrong number of arguments type.\n");
427 return NULL;
428 }
429
430 Object *obj = eval(args->car);
431 if (obj->type != OBJ_TYPE_FIXNUM) {
432 fprintf(stderr, "error: wrong argument type.\n");
433 return NULL;
434 }
435 ssize_t prev = obj->fixnum;
436 args = args->cdr;
437
438 if (args == obj_nil) {
439 fprintf(stderr, "error: wrong number of arguments type.\n");
440 return NULL;
441 }
442 while (args != obj_nil) {
443 Object *obj = eval(args->car);
444 if (obj->type != OBJ_TYPE_FIXNUM) {
445 fprintf(stderr, "error: wrong argument type.\n");
446 return NULL;
447 }
448 if (prev > obj->fixnum) {
449 return obj_false;
450 }
451 prev = obj->fixnum;
452 args = args->cdr;
453 }
454 return obj_true;
455}
456
457Object *
458proc_num_greatereq_than(Object *args) {
459 if (args == obj_nil) {
460 fprintf(stderr, "error: wrong number of arguments type.\n");
461 return NULL;
462 }
463
464 Object *obj = eval(args->car);
465 if (obj->type != OBJ_TYPE_FIXNUM) {
466 fprintf(stderr, "error: wrong argument type.\n");
467 return NULL;
468 }
469 ssize_t prev = obj->fixnum;
470 args = args->cdr;
471
472 if (args == obj_nil) {
473 fprintf(stderr, "error: wrong number of arguments type.\n");
474 return NULL;
475 }
476 while (args != obj_nil) {
477 Object *obj = eval(args->car);
478 if (obj->type != OBJ_TYPE_FIXNUM) {
479 fprintf(stderr, "error: wrong argument type.\n");
480 return NULL;
481 }
482 if (prev < obj->fixnum) {
483 return obj_false;
484 }
485 prev = obj->fixnum;
486 args = args->cdr;
487 }
488 return obj_true;
489}
490
491Object *
492proc_num_equal(Object *args) {
493 if (args == obj_nil) {
494 fprintf(stderr, "error: wrong number of arguments type.\n");
495 return NULL;
496 }
497
498 Object *obj = eval(args->car);
499 if (obj->type != OBJ_TYPE_FIXNUM) {
500 fprintf(stderr, "error: wrong argument type.\n");
501 return NULL;
502 }
503 ssize_t prev = obj->fixnum;
504 args = args->cdr;
505
506 if (args == obj_nil) {
507 fprintf(stderr, "error: wrong number of arguments type.\n");
508 return NULL;
509 }
510 while (args != obj_nil) {
511 Object *obj = eval(args->car);
512 if (obj->type != OBJ_TYPE_FIXNUM) {
513 fprintf(stderr, "error: wrong argument type.\n");
514 return NULL;
515 }
516 if (prev != obj->fixnum) {
517 return obj_false;
518 }
519 prev = obj->fixnum;
520 args = args->cdr;
521 }
522 return obj_true;
523}
524
358// TODO: fixnum left/right shift, mask, invert 525// TODO: fixnum left/right shift, mask, invert
diff --git a/tests/booleans_expected.txt b/tests/booleans_expected.txt
index f0612b8..5919767 100644
--- a/tests/booleans_expected.txt
+++ b/tests/booleans_expected.txt
@@ -46,3 +46,15 @@
46(cond ((and true true false) 1) ((or false false false) 2) (else 3)) -> 3 46(cond ((and true true false) 1) ((or false false false) 2) (else 3)) -> 3
47(cond ((and true true true) 1) ((or true true false) 2)) -> () 47(cond ((and true true true) 1) ((or true true false) 2)) -> ()
48(cond ((and true true true) (+ 1 2 3)) ((or true true false) 2) (else 3)) -> 6 48(cond ((and true true true) (+ 1 2 3)) ((or true true false) 2) (else 3)) -> 6
49(< 1 2 3) -> true
50(< 3 2 1) -> false
51(> 1 2 3) -> false
52(> 3 2 1) -> true
53(= 1 2 3) -> false
54(= 3 2 1) -> false
55(= 3 3 3) -> true
56(= (+ 1 2) 3 (- 6 3)) -> true
57(< 1 1 3) -> false
58(<= 1 1 3) -> true
59(> 3 3 1) -> false
60(>= 3 3 1) -> true