diff options
author | Alexis Lockwood | 2021-07-18 10:52:58 -0600 |
---|---|---|
committer | Alexis Lockwood | 2021-07-18 10:52:58 -0600 |
commit | ad318f0e62e15ec6e488c4594a22cee96ab154ba (patch) | |
tree | c3a3f5629875ab9a7b65172a40584aebfdff0c83 | |
parent | da12c0d48a33d46d0a9ea648d21c526953bf2da8 (diff) |
Trig functions
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | gen_kws.py | 14 | ||||
-rw-r--r-- | lib/ls_expr.c | 59 | ||||
-rw-r--r-- | lib/ls_types.h | 8 | ||||
-rw-r--r-- | ls_minify.c | 1 |
5 files changed, 77 insertions, 7 deletions
@@ -16,7 +16,7 @@ LIBS_ARGS := ${LIBEXPLAIN_ARGS} TESTS := test/test_internal.test CFLAGS := \ - -O0 -ggdb \ + -O0 -ggdb -lm \ -std=c99 -D_DEFAULT_SOURCE \ -Wall -Wextra -Wpedantic -Wshadow -pedantic \ -Iinclude -Ilib \ @@ -52,12 +52,12 @@ KEYWORDS = [ Kw("AS", 0x82, noexec=True), Kw("ASC", 0x83), Kw("AT", 0x84, noexec=True), - Kw("ATN", 0x85), + Kw("ATN", 0x85, op="LS_OP_ATN", noexec=True), Kw("CALL", 0x86), Kw("CAT", 0x87), Kw("CHR", 0x88), Kw("CLOSE", 0x89), - Kw("COS", 0x8A), + Kw("COS", 0x8A, op="LS_OP_COS", noexec=True), Kw("COUNT", 0x8B), Kw("DATA", 0x8C), Kw("DEC", 0x8D), @@ -77,7 +77,7 @@ KEYWORDS = [ Kw("INPUT", 0x9B), Kw("LEFT", 0x9C), Kw("LET", 0x9D), - Kw("LOG", 0x9E), + Kw("LOG", 0x9E, op="LS_OP_LOG", noexec=True), Kw("MID", 0x9F), Kw("NEXT", 0xA0, scanning=True), Kw("NOT", 0xA1, op="LS_OP_NOT", noexec=True), @@ -94,11 +94,11 @@ KEYWORDS = [ Kw("RETURN", 0xAC), Kw("RIGHT", 0xAD), Kw("RND", 0xAE), - Kw("SIN", 0xAF), - Kw("SQR", 0xB0), + Kw("SIN", 0xAF, op="LS_OP_SIN", noexec=True), + Kw("SQR", 0xB0, op="LS_OP_SQR", noexec=True), Kw("STEP", 0xB1), Kw("SWAP", 0xB2), - Kw("TAN", 0xB3), + Kw("TAN", 0xB3, op="LS_OP_TAN", noexec=True), Kw("THEN", 0xB4, noexec=True), Kw("TO", 0xB5, noexec=True), Kw("UNPACK", 0xB6), @@ -110,6 +110,8 @@ KEYWORDS = [ Kw("XOR", 0xBC, op="LS_OP_XOR", noexec=True), Kw("FLOAT", 0xBD, op="LS_OP_FLOAT", noexec=True), Kw("INT", 0xBE, op="LS_OP_INT", noexec=True), + Kw("EXP", 0xBF, op="LS_OP_EXP", noexec=True), + Kw("SGN", 0xC0, op="LS_OP_SGN", noexec=True), ] if len(sys.argv) == 2 and sys.argv[1] == "source": diff --git a/lib/ls_expr.c b/lib/ls_expr.c index 1a7b22b..d17453b 100644 --- a/lib/ls_expr.c +++ b/lib/ls_expr.c @@ -105,6 +105,9 @@ static ls_error_t _relop(ls_value_t * lhs, ls_value_t * rhs, ls_op_t op); /// Casts static ls_error_t _castop(ls_value_t * lhs, ls_value_t * rhs, ls_op_t op); +/// Trig, logs, etc +static ls_error_t _trigetcop(ls_value_t * lhs, ls_value_t * rhs, ls_op_t op); + // --- PUBLIC VARIABLES -------------------------------------------------------- // --- PRIVATE VARIABLES ------------------------------------------------------- @@ -114,6 +117,14 @@ static const ls_opdef_t _ops[] = { [LS_OP_NEG] = { 13, true, true, &_arithop }, [LS_OP_FLOAT] = { 13, true, true, &_castop }, [LS_OP_INT] = { 13, true, true, &_castop }, + [LS_OP_SGN] = { 13, true, true, &_arithop }, + [LS_OP_ATN] = { 13, true, true, &_trigetcop }, + [LS_OP_COS] = { 13, true, true, &_trigetcop }, + [LS_OP_LOG] = { 13, true, true, &_trigetcop }, + [LS_OP_SIN] = { 13, true, true, &_trigetcop }, + [LS_OP_SQR] = { 13, true, true, &_trigetcop }, + [LS_OP_TAN] = { 13, true, true, &_trigetcop }, + [LS_OP_EXP] = { 13, true, true, &_trigetcop }, [LS_OP_MUL] = { 12, false, false, &_arithop }, [LS_OP_DIV] = { 12, false, false, &_arithop }, @@ -448,6 +459,8 @@ _arithop(ls_value_t * lhs, ls_value_t * rhs, ls_op_t op) { case LS_OP_ABS: *rhsi = (*rhsi < 0) ? -*rhsi : *rhsi; break; case LS_OP_NEG: *rhsi = -*rhsi; break; + case LS_OP_SGN: *rhsi = (*rhsi < 0) ? -1 : (*rhsi > 0) ? 1 : 0; + break; case LS_OP_MUL: *rhsi = *lhsi * *rhsi; break; case LS_OP_DIV: *rhsi = *lhsi / *rhsi; break; case LS_OP_MOD: *rhsi = *lhsi % *rhsi; break; @@ -469,6 +482,8 @@ _arithop(ls_value_t * lhs, ls_value_t * rhs, ls_op_t op) case LS_OP_ABS: *rhsi = fabsf(*rhsi); break; #endif case LS_OP_NEG: *rhsi = -*rhsi; break; + case LS_OP_SGN: *rhsi = (*rhsi < 0) ? -1 : (*rhsi > 0) ? 1 : 0; + break; case LS_OP_MUL: *rhsi = *lhsi * *rhsi; break; case LS_OP_DIV: *rhsi = *lhsi / *rhsi; break; // TODO can we do better? @@ -627,3 +642,47 @@ _castop(ls_value_t * lhs, ls_value_t * rhs, ls_op_t op) return LS_OK; } + +/// Trig, logs, etc +static ls_error_t +_trigetcop(ls_value_t * lhs, ls_value_t * rhs, ls_op_t op) +{ + (void) lhs; + +#ifdef LS_HAVE_FLOAT + switch (rhs->ty) + { + case LS_TY_INT: + rhs->body.float_.value = rhs->body.integer.value; + rhs->ty = LS_TY_FLOAT; + break; + case LS_TY_FLOAT: + break; + default: + return LS_TYPE_MISMATCH; + } + + ls_float_t * v = &rhs->body.float_.value; + + // TODO: use float or double functions depending on build settings + switch (op) + { + case LS_OP_ATN: *v = atan(*v); break; + case LS_OP_COS: *v = cos(*v); break; + case LS_OP_LOG: *v = log(*v); break; + case LS_OP_SIN: *v = sin(*v); break; + case LS_OP_SQR: *v = sqrt(*v); break; + case LS_OP_TAN: *v = tan(*v); break; + case LS_OP_EXP: *v = exp(*v); break; + default: + return LS_INTERNAL_ERROR; + } + + return LS_OK; +#else + (void) lhs; + (void) rhs; + (void) op; + return LS_TYPE_MISMATCH; +#endif +} diff --git a/lib/ls_types.h b/lib/ls_types.h index 4ee6b0e..caeded6 100644 --- a/lib/ls_types.h +++ b/lib/ls_types.h @@ -366,6 +366,14 @@ typedef enum { LS_OP_XOR, LS_OP_FLOAT, LS_OP_INT, + LS_OP_ATN, + LS_OP_COS, + LS_OP_LOG, + LS_OP_SIN, + LS_OP_SQR, + LS_OP_TAN, + LS_OP_EXP, + LS_OP_SGN, LS_NO_OP } ls_op_t; diff --git a/ls_minify.c b/ls_minify.c index ff2ef6a..33e4307 100644 --- a/ls_minify.c +++ b/ls_minify.c @@ -310,6 +310,7 @@ static void _min_number_or_num_label(ls_token_t tok) static void _min_float(ls_token_t tok) { + (void) tok; ls_float_t f = g_ls._token.float_; ls_float_t g; char buf[32]; |