diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2011-12-14 07:56:27 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2011-12-14 07:56:27 -0800 |
commit | 02d5a8ff16d1aa82fab7b861788886c08e81f268 (patch) | |
tree | f1e77fa609be98d0a9dda84005e20ef75d14fc82 /arith.c | |
parent | a86f247ea2a92a2b67b58eb7b5b7bc7f592d1773 (diff) | |
download | txr-02d5a8ff16d1aa82fab7b861788886c08e81f268.tar.gz txr-02d5a8ff16d1aa82fab7b861788886c08e81f268.tar.bz2 txr-02d5a8ff16d1aa82fab7b861788886c08e81f268.zip |
* arith.c (plus, minus, gt, lt, ge, le): Handle character operands.
* eval.c (eval_init): New functions interned.
* lib.c (num_chr, chr_num): New functions.
* lib.h (num_chr, chr_num): Declared.
* txr.1: Documentation stubs.
Diffstat (limited to 'arith.c')
-rw-r--r-- | arith.c | 56 |
1 files changed, 56 insertions, 0 deletions
@@ -324,8 +324,32 @@ val plus(val anum, val bnum) mp_add(mp(anum), mp(bnum), mp(n)); return normalize(n); } + case TAG_PAIR(TAG_CHR, TAG_NUM): + { + wchar_t a = c_chr(anum); + cnum b = c_num(bnum); + cnum sum = a + b; + + if (sum < 0 || sum > 0x10FFFF) + goto char_range; + return chr(sum); + } + case TAG_PAIR(TAG_NUM, TAG_CHR): + { + cnum a = c_chr(anum); + wchar_t b = c_num(bnum); + cnum sum = a + b; + + if (sum < 0 || sum > 0x10FFFF) + goto char_range; + return chr(sum); + } } uw_throwf(error_s, lit("plus: invalid operands ~s ~s"), anum, bnum, nao); +char_range: + uw_throwf(numeric_error_s, + lit("plus: sum of ~s ~s is out of character range"), + anum, bnum, nao); abort(); } @@ -397,6 +421,18 @@ val minus(val anum, val bnum) mp_sub(mp(anum), mp(bnum), mp(n)); return normalize(n); } + case TAG_PAIR(TAG_CHR, TAG_NUM): + { + wchar_t a = c_chr(anum); + cnum b = c_num(bnum); + cnum sum = a - b; + + if (sum < 0 || sum > 0x10FFFF) + uw_throwf(numeric_error_s, + lit("minus: sum of ~s ~s is out of character range"), + anum, bnum, nao); + return chr(sum); + } } uw_throwf(error_s, lit("minus: invalid operands ~s ~s"), anum, bnum, nao); abort(); @@ -748,11 +784,16 @@ val gt(val anum, val bnum) switch (TAG_PAIR(tag_a, tag_b)) { case TAG_PAIR(TAG_NUM, TAG_NUM): + case TAG_PAIR(TAG_CHR, TAG_CHR): + case TAG_PAIR(TAG_NUM, TAG_CHR): + case TAG_PAIR(TAG_CHR, TAG_NUM): return c_num(anum) > c_num(bnum) ? t : nil; case TAG_PAIR(TAG_NUM, TAG_PTR): + case TAG_PAIR(TAG_CHR, TAG_PTR): type_check(bnum, BGNUM); return mp_cmp_z(mp(bnum)) == MP_LT ? t : nil; case TAG_PAIR(TAG_PTR, TAG_NUM): + case TAG_PAIR(TAG_PTR, TAG_CHR): type_check(anum, BGNUM); return mp_cmp_z(mp(anum)) == MP_GT ? t : nil; case TAG_PAIR(TAG_PTR, TAG_PTR): @@ -771,11 +812,16 @@ val lt(val anum, val bnum) switch (TAG_PAIR(tag_a, tag_b)) { case TAG_PAIR(TAG_NUM, TAG_NUM): + case TAG_PAIR(TAG_CHR, TAG_CHR): + case TAG_PAIR(TAG_NUM, TAG_CHR): + case TAG_PAIR(TAG_CHR, TAG_NUM): return c_num(anum) < c_num(bnum) ? t : nil; case TAG_PAIR(TAG_NUM, TAG_PTR): + case TAG_PAIR(TAG_CHR, TAG_PTR): type_check(bnum, BGNUM); return mp_cmp_z(mp(bnum)) == MP_GT ? t : nil; case TAG_PAIR(TAG_PTR, TAG_NUM): + case TAG_PAIR(TAG_PTR, TAG_CHR): type_check(anum, BGNUM); return mp_cmp_z(mp(anum)) == MP_LT ? t : nil; case TAG_PAIR(TAG_PTR, TAG_PTR): @@ -794,11 +840,16 @@ val ge(val anum, val bnum) switch (TAG_PAIR(tag_a, tag_b)) { case TAG_PAIR(TAG_NUM, TAG_NUM): + case TAG_PAIR(TAG_CHR, TAG_CHR): + case TAG_PAIR(TAG_NUM, TAG_CHR): + case TAG_PAIR(TAG_CHR, TAG_NUM): return c_num(anum) >= c_num(bnum) ? t : nil; case TAG_PAIR(TAG_NUM, TAG_PTR): + case TAG_PAIR(TAG_CHR, TAG_PTR): type_check(bnum, BGNUM); return mp_cmp_z(mp(bnum)) == MP_LT ? t : nil; case TAG_PAIR(TAG_PTR, TAG_NUM): + case TAG_PAIR(TAG_PTR, TAG_CHR): type_check(anum, BGNUM); return mp_cmp_z(mp(anum)) == MP_GT ? t : nil; case TAG_PAIR(TAG_PTR, TAG_PTR): @@ -822,11 +873,16 @@ val le(val anum, val bnum) switch (TAG_PAIR(tag_a, tag_b)) { case TAG_PAIR(TAG_NUM, TAG_NUM): + case TAG_PAIR(TAG_CHR, TAG_CHR): + case TAG_PAIR(TAG_NUM, TAG_CHR): + case TAG_PAIR(TAG_CHR, TAG_NUM): return c_num(anum) <= c_num(bnum) ? t : nil; case TAG_PAIR(TAG_NUM, TAG_PTR): + case TAG_PAIR(TAG_CHR, TAG_PTR): type_check(bnum, BGNUM); return mp_cmp_z(mp(bnum)) == MP_GT ? t : nil; case TAG_PAIR(TAG_PTR, TAG_NUM): + case TAG_PAIR(TAG_PTR, TAG_CHR): type_check(anum, BGNUM); return mp_cmp_z(mp(anum)) == MP_LT ? t : nil; case TAG_PAIR(TAG_PTR, TAG_PTR): |