diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2014-11-02 06:49:06 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2014-11-02 06:49:06 -0600 |
commit | b27b08c6f13c39079c67ab22693a298596d59cbe (patch) | |
tree | 2197c42956d267ae67666f061d93cc55f7331066 /apps/interpreters | |
parent | 57d83918c7d2e1c099c12755858b5ddae98b0d5e (diff) | |
download | px4-nuttx-b27b08c6f13c39079c67ab22693a298596d59cbe.tar.gz px4-nuttx-b27b08c6f13c39079c67ab22693a298596d59cbe.tar.bz2 px4-nuttx-b27b08c6f13c39079c67ab22693a298596d59cbe.zip |
BAS: More modifications for closer comliance to the NuttX coding standard
Diffstat (limited to 'apps/interpreters')
-rw-r--r-- | apps/interpreters/bas/value.c | 580 |
1 files changed, 486 insertions, 94 deletions
diff --git a/apps/interpreters/bas/value.c b/apps/interpreters/bas/value.c index 2f5b9b95b..2198d2fa5 100644 --- a/apps/interpreters/bas/value.c +++ b/apps/interpreters/bas/value.c @@ -1,4 +1,62 @@ /**************************************************************************** + * apps/examples/interpreters/bas/value.c + * + * Copyright (c) 1999-2014 Michael Haardt + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Adapted to NuttX and re-released under a 3-clause BSD license: + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Alan Carvalho de Assis <Alan Carvalho de Assis> + * Gregory Nutt <gnutt@nuttx.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** * Included Files ****************************************************************************/ @@ -97,15 +155,20 @@ static void format_double(struct String *buf, double value, int width, len = buf->length; String_appendPrintf(buf, "%.*E", width - 1 - (precision >= 0), value); if (buf->character[len + 1] == '.') - String_delete(buf, len + 1, 1); + { + String_delete(buf, len + 1, 1); + } if (precision >= 0) - String_insertChar(buf, len + width - precision - 1, '.'); + { + String_insertChar(buf, len + width - precision - 1, '.'); + } for (e = buf->character + buf->length - 1; - e >= buf->character && *e != 'E'; --e); - + e >= buf->character && *e != 'E'; + --e); ++e; + en = strtol(e, (char **)0, 10); en = en + 2 - (width - precision); len = e - buf->character; @@ -113,11 +176,17 @@ static void format_double(struct String *buf, double value, int width, String_appendPrintf(buf, "%+0*d", exponent - 1, en); } else if (precision > 0) - String_appendPrintf(buf, "%.*f", precision, value); + { + String_appendPrintf(buf, "%.*f", precision, value); + } else if (precision == 0) - String_appendPrintf(buf, "%.f.", value); + { + String_appendPrintf(buf, "%.f.", value); + } else if (width) - String_appendPrintf(buf, "%.f", value); + { + String_appendPrintf(buf, "%.f", value); + } else { double x = value; @@ -126,7 +195,7 @@ static void format_double(struct String *buf, double value, int width, { String_appendPrintf(buf, "%.7g", value); } - else /* print decimal numbers or integers, if * + else /* print decimal numbers or integers, if * possible */ { int o, n, p = 6; @@ -136,15 +205,20 @@ static void format_double(struct String *buf, double value, int width, x /= 10.0; --p; } + o = buf->length; String_appendPrintf(buf, "%.*f", p, value); n = buf->length; if (memchr(buf->character + o, '.', n - o)) { while (buf->character[buf->length - 1] == '0') - --buf->length; + { + --buf->length; + } if (buf->character[buf->length - 1] == '.') - --buf->length; + { + --buf->length; + } } } } @@ -177,11 +251,17 @@ long int Value_vali(const char *s, char **end, int *overflow) errno = 0; if (*s == '&' && tolower(*(s + 1)) == 'h') - n = strtoul(s + 2, end, 16); + { + n = strtoul(s + 2, end, 16); + } else if (*s == '&' && tolower(*(s + 1)) == 'o') - n = strtoul(s + 2, end, 8); + { + n = strtoul(s + 2, end, 8); + } else - n = strtol(s, end, 10); + { + n = strtol(s, end, 10); + } *overflow = (errno == ERANGE); return n; @@ -262,23 +342,27 @@ struct Value *Value_new_null(struct Value *this, enum ValueType type) this->u.integer = 0; break; } + case V_REAL: { this->type = V_REAL; this->u.real = 0.0; break; } + case V_STRING: { this->type = V_STRING; String_new(&this->u.string); break; } + case V_VOID: { this->type = V_VOID; break; } + default: assert(0); } @@ -292,10 +376,13 @@ int Value_isNull(const struct Value *this) { case V_INTEGER: return (this->u.integer == 0); + case V_REAL: return (this->u.real == 0.0); + case V_STRING: return (this->u.string.length == 0); + default: assert(0); } @@ -311,17 +398,23 @@ void Value_destroy(struct Value *this) case V_ERROR: free(this->u.error.msg); break; + case V_INTEGER: break; + case V_NIL: break; + case V_REAL: break; + case V_STRING: String_destroy(&this->u.string); break; + case V_VOID: break; + default: assert(0); } @@ -343,17 +436,22 @@ struct Value *Value_clone(struct Value *this, const struct Value *original) this->u.error.code = original->u.error.code; break; } + case V_INTEGER: this->u.integer = original->u.integer; break; + case V_NIL: break; + case V_REAL: this->u.real = original->u.real; break; + case V_STRING: String_clone(&this->u.string, &original->u.string); break; + default: assert(0); } @@ -371,12 +469,14 @@ struct Value *Value_uplus(struct Value *this, int calc) { break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDUOPERAND); break; } + default: assert(0); } @@ -391,21 +491,28 @@ struct Value *Value_uneg(struct Value *this, int calc) case V_INTEGER: { if (calc) - this->u.integer = -this->u.integer; + { + this->u.integer = -this->u.integer; + } break; } + case V_REAL: { if (calc) - this->u.real = -this->u.real; + { + this->u.real = -this->u.real; + } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDUOPERAND); break; } + default: assert(0); } @@ -420,22 +527,29 @@ struct Value *Value_unot(struct Value *this, int calc) case V_INTEGER: { if (calc) - this->u.integer = ~this->u.integer; + { + this->u.integer = ~this->u.integer; + } break; } + case V_REAL: { Value_retype(this, V_INTEGER); if (calc) - this->u.integer = ~this->u.integer; + { + this->u.integer = ~this->u.integer; + } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDUOPERAND); break; } + default: assert(0); } @@ -452,23 +566,32 @@ struct Value *Value_add(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer += x->u.integer; + { + this->u.integer += x->u.integer; + } break; } + case V_REAL: { VALUE_RETYPE(this, V_REAL); VALUE_RETYPE(x, V_REAL); if (calc) - this->u.real += x->u.real; + { + this->u.real += x->u.real; + } break; } + case V_STRING: { if (calc) - String_appendString(&this->u.string, &x->u.string); + { + String_appendString(&this->u.string, &x->u.string); + } break; } + default: assert(0); } @@ -485,23 +608,30 @@ struct Value *Value_sub(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer -= x->u.integer; + { + this->u.integer -= x->u.integer; + } break; } + case V_REAL: { VALUE_RETYPE(this, V_REAL); VALUE_RETYPE(x, V_REAL); if (calc) - this->u.real -= x->u.real; + { + this->u.real -= x->u.real; + } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } @@ -518,23 +648,31 @@ struct Value *Value_mult(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer *= x->u.integer; + { + this->u.integer *= x->u.integer; + } + break; } + case V_REAL: { VALUE_RETYPE(this, V_REAL); VALUE_RETYPE(x, V_REAL); if (calc) - this->u.real *= x->u.real; + { + this->u.real *= x->u.real; + } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } @@ -558,10 +696,13 @@ struct Value *Value_div(struct Value *this, struct Value *x, int calc) Value_new_ERROR(this, UNDEFINED, "Division by zero"); } else - this->u.real /= x->u.real; + { + this->u.real /= x->u.real; + } } break; } + case V_REAL: { VALUE_RETYPE(this, V_REAL); @@ -574,19 +715,24 @@ struct Value *Value_div(struct Value *this, struct Value *x, int calc) Value_new_ERROR(this, UNDEFINED, "Division by zero"); } else - this->u.real /= x->u.real; + { + this->u.real /= x->u.real; + } } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } + return this; } @@ -606,10 +752,13 @@ struct Value *Value_idiv(struct Value *this, struct Value *x, int calc) Value_new_ERROR(this, UNDEFINED, "Division by zero"); } else - this->u.integer /= x->u.integer; + { + this->u.integer /= x->u.integer; + } } break; } + case V_REAL: { VALUE_RETYPE(this, V_REAL); @@ -622,16 +771,20 @@ struct Value *Value_idiv(struct Value *this, struct Value *x, int calc) Value_new_ERROR(this, UNDEFINED, "Division by zero"); } else - this->u.real = Value_trunc(this->u.real / x->u.real); + { + this->u.real = Value_trunc(this->u.real / x->u.real); + } } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } @@ -655,10 +808,13 @@ struct Value *Value_mod(struct Value *this, struct Value *x, int calc) Value_new_ERROR(this, UNDEFINED, "Modulo by zero"); } else - this->u.integer %= x->u.integer; + { + this->u.integer %= x->u.integer; + } } break; } + case V_REAL: { VALUE_RETYPE(this, V_REAL); @@ -671,16 +827,20 @@ struct Value *Value_mod(struct Value *this, struct Value *x, int calc) Value_new_ERROR(this, UNDEFINED, "Modulo by zero"); } else - this->u.real = fmod(this->u.real, x->u.real); + { + this->u.real = fmod(this->u.real, x->u.real); + } } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } @@ -704,7 +864,9 @@ struct Value *Value_pow(struct Value *this, struct Value *x, int calc) Value_new_ERROR(this, UNDEFINED, "0^0"); } else if (x->u.integer > 0) - this->u.integer = pow(this->u.integer, x->u.integer); + { + this->u.integer = pow(this->u.integer, x->u.integer); + } else { long int thisi = this->u.integer; @@ -714,6 +876,7 @@ struct Value *Value_pow(struct Value *this, struct Value *x, int calc) } break; } + case V_REAL: { VALUE_RETYPE(this, V_REAL); @@ -726,16 +889,20 @@ struct Value *Value_pow(struct Value *this, struct Value *x, int calc) Value_new_ERROR(this, UNDEFINED, "0^0"); } else - this->u.real = pow(this->u.real, x->u.real); + { + this->u.real = pow(this->u.real, x->u.real); + } } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } @@ -753,15 +920,19 @@ struct Value *Value_and(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer &= x->u.integer; + { + this->u.integer &= x->u.integer; + } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } @@ -779,15 +950,19 @@ struct Value *Value_or(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer |= x->u.integer; + { + this->u.integer |= x->u.integer; + } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } @@ -805,15 +980,19 @@ struct Value *Value_xor(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer ^= x->u.integer; + { + this->u.integer ^= x->u.integer; + } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } @@ -831,15 +1010,19 @@ struct Value *Value_eqv(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer = ~(this->u.integer ^ x->u.integer); + { + this->u.integer = ~(this->u.integer ^ x->u.integer); + } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } @@ -857,15 +1040,19 @@ struct Value *Value_imp(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer = (~this->u.integer) | x->u.integer; + { + this->u.integer = (~this->u.integer) | x->u.integer; + } break; } + case V_STRING: { Value_destroy(this); Value_new_ERROR(this, INVALIDOPERAND); break; } + default: assert(0); } @@ -882,9 +1069,12 @@ struct Value *Value_lt(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer = (this->u.integer < x->u.integer) ? -1 : 0; + { + this->u.integer = (this->u.integer < x->u.integer) ? -1 : 0; + } break; } + case V_REAL: { int v; @@ -892,25 +1082,37 @@ struct Value *Value_lt(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_REAL); VALUE_RETYPE(x, V_REAL); if (calc) - v = (this->u.real < x->u.real) ? -1 : 0; + { + v = (this->u.real < x->u.real) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + case V_STRING: { int v; if (calc) - v = (String_cmp(&this->u.string, &x->u.string) < 0) ? -1 : 0; + { + v = (String_cmp(&this->u.string, &x->u.string) < 0) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + default: assert(0); } @@ -927,9 +1129,12 @@ struct Value *Value_le(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer = (this->u.integer <= x->u.integer) ? -1 : 0; + { + this->u.integer = (this->u.integer <= x->u.integer) ? -1 : 0; + } break; } + case V_REAL: { int v; @@ -937,25 +1142,37 @@ struct Value *Value_le(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_REAL); VALUE_RETYPE(x, V_REAL); if (calc) - v = (this->u.real <= x->u.real) ? -1 : 0; + { + v = (this->u.real <= x->u.real) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + case V_STRING: { int v; if (calc) - v = (String_cmp(&this->u.string, &x->u.string) <= 0) ? -1 : 0; + { + v = (String_cmp(&this->u.string, &x->u.string) <= 0) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + default: assert(0); } @@ -972,9 +1189,12 @@ struct Value *Value_eq(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer = (this->u.integer == x->u.integer) ? -1 : 0; + { + this->u.integer = (this->u.integer == x->u.integer) ? -1 : 0; + } break; } + case V_REAL: { int v; @@ -982,9 +1202,14 @@ struct Value *Value_eq(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_REAL); VALUE_RETYPE(x, V_REAL); if (calc) - v = (this->u.real == x->u.real) ? -1 : 0; + { + v = (this->u.real == x->u.real) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; @@ -994,13 +1219,19 @@ struct Value *Value_eq(struct Value *this, struct Value *x, int calc) int v; if (calc) - v = (String_cmp(&this->u.string, &x->u.string) == 0) ? -1 : 0; + { + v = (String_cmp(&this->u.string, &x->u.string) == 0) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + default: assert(0); } @@ -1017,9 +1248,12 @@ struct Value *Value_ge(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer = (this->u.integer >= x->u.integer) ? -1 : 0; + { + this->u.integer = (this->u.integer >= x->u.integer) ? -1 : 0; + } break; } + case V_REAL: { int v; @@ -1027,25 +1261,37 @@ struct Value *Value_ge(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_REAL); VALUE_RETYPE(x, V_REAL); if (calc) - v = (this->u.real >= x->u.real) ? -1 : 0; + { + v = (this->u.real >= x->u.real) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + case V_STRING: { int v; if (calc) - v = (String_cmp(&this->u.string, &x->u.string) >= 0) ? -1 : 0; + { + v = (String_cmp(&this->u.string, &x->u.string) >= 0) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + default: assert(0); } @@ -1062,9 +1308,12 @@ struct Value *Value_gt(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer = (this->u.integer > x->u.integer) ? -1 : 0; + { + this->u.integer = (this->u.integer > x->u.integer) ? -1 : 0; + } break; } + case V_REAL: { int v; @@ -1072,25 +1321,37 @@ struct Value *Value_gt(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_REAL); VALUE_RETYPE(x, V_REAL); if (calc) - v = (this->u.real > x->u.real) ? -1 : 0; + { + v = (this->u.real > x->u.real) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + case V_STRING: { int v; if (calc) - v = (String_cmp(&this->u.string, &x->u.string) > 0) ? -1 : 0; + { + v = (String_cmp(&this->u.string, &x->u.string) > 0) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + default: assert(0); } @@ -1107,9 +1368,12 @@ struct Value *Value_ne(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_INTEGER); VALUE_RETYPE(x, V_INTEGER); if (calc) - this->u.integer = (this->u.integer != x->u.integer) ? -1 : 0; + { + this->u.integer = (this->u.integer != x->u.integer) ? -1 : 0; + } break; } + case V_REAL: { int v; @@ -1117,25 +1381,37 @@ struct Value *Value_ne(struct Value *this, struct Value *x, int calc) VALUE_RETYPE(this, V_REAL); VALUE_RETYPE(x, V_REAL); if (calc) - v = (this->u.real != x->u.real) ? -1 : 0; + { + v = (this->u.real != x->u.real) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + case V_STRING: { int v; if (calc) - v = String_cmp(&this->u.string, &x->u.string) ? -1 : 0; + { + v = String_cmp(&this->u.string, &x->u.string) ? -1 : 0; + } else - v = 0; + { + v = 0; + } + Value_destroy(this); Value_new_INTEGER(this, v); break; } + default: assert(0); } @@ -1152,15 +1428,19 @@ int Value_exitFor(struct Value *this, struct Value *limit, struct Value *step) (step->u.integer < 0 ? (this->u.integer < limit->u.integer) : (this->u.integer > limit->u.integer)); + case V_REAL: return (step->u.real < 0.0 ? (this->u.real < limit->u.real) : (this->u.real > limit->u.real)); + case V_STRING: return (String_cmp(&this->u.string, &limit->u.string) > 0); + default: assert(0); } + return -1; } @@ -1215,20 +1495,24 @@ struct Value *Value_retype(struct Value *this, enum ValueType type) { case V_INTEGER: break; + case V_REAL: this->u.real = this->u.integer; this->type = type; break; + case V_VOID: Value_destroy(this); Value_new_VOID(this); break; + default: retypeError(this, type); break; } break; } + case V_REAL: { int overflow; @@ -1246,47 +1530,57 @@ struct Value *Value_retype(struct Value *this, enum ValueType type) } break; } + case V_REAL: break; + case V_VOID: Value_destroy(this); Value_new_VOID(this); break; + default: retypeError(this, type); break; } break; } + case V_STRING: { switch (type) { case V_STRING: break; + case V_VOID: Value_destroy(this); Value_new_VOID(this); break; + default: retypeError(this, type); break; } break; } + case V_VOID: { switch (type) { case V_VOID: break; + default: retypeError(this, type); } break; } + case V_ERROR: break; + default: assert(0); } @@ -1306,6 +1600,7 @@ struct String *Value_toString(struct Value *this, struct String *s, char pad, case V_ERROR: String_appendChars(s, this->u.error.msg); break; + case V_REAL: case V_INTEGER: { @@ -1322,9 +1617,13 @@ struct String *Value_toString(struct Value *this, struct String *s, char pad, this->u.integer = -this->u.integer; } else if (this->u.integer == 0) - sign = 0; + { + sign = 0; + } else - sign = 1; + { + sign = 1; + } } else { @@ -1334,10 +1633,15 @@ struct String *Value_toString(struct Value *this, struct String *s, char pad, this->u.real = -this->u.real; } else if (this->u.real == 0.0) - sign = 0; + { + sign = 0; + } else - sign = 1; + { + sign = 1; + } } + switch (headingsign) { case -1: @@ -1346,36 +1650,52 @@ struct String *Value_toString(struct Value *this, struct String *s, char pad, String_appendChar(&buf, sign == -1 ? '-' : ' '); break; } + case 0: { if (sign == -1) - String_appendChar(&buf, '-'); + { + String_appendChar(&buf, '-'); + } break; } + case 1: { ++totalwidth; String_appendChar(&buf, sign == -1 ? '-' : '+'); break; } + case 2: break; + default: assert(0); } + totalwidth += exponent; if (this->type == V_INTEGER) { if (precision > 0 || exponent) - format_double(&buf, (double)this->u.integer, width, precision, - exponent); + { + format_double(&buf, (double)this->u.integer, width, precision, + exponent); + } else if (precision == 0) - String_appendPrintf(&buf, "%lu.", this->u.integer); + { + String_appendPrintf(&buf, "%lu.", this->u.integer); + } else - String_appendPrintf(&buf, "%lu", this->u.integer); + { + String_appendPrintf(&buf, "%lu", this->u.integer); + } } else - format_double(&buf, this->u.real, width, precision, exponent); + { + format_double(&buf, this->u.real, width, precision, exponent); + } + if (commas) { size_t digits; @@ -1385,16 +1705,19 @@ struct String *Value_toString(struct Value *this, struct String *s, char pad, for (digits = first; digits < buf.length && buf.character[digits] >= '0' && buf.character[digits] <= '9'; ++digits); + while (digits > first + 3) { digits -= 3; String_insertChar(&buf, digits, ','); } } + if (dollar) { String_insertChar(&buf, 0, '$'); } + if (trailingsign == -1) { ++totalwidth; @@ -1405,21 +1728,30 @@ struct String *Value_toString(struct Value *this, struct String *s, char pad, ++totalwidth; String_appendChar(&buf, sign == -1 ? '-' : '+'); } + String_size(s, oldlength + (totalwidth > buf.length ? totalwidth : buf.length)); + if (totalwidth > buf.length) - memset(s->character + oldlength, pad, - totalwidth - buf.length + dollarleft); + { + memset(s->character + oldlength, pad, + totalwidth - buf.length + dollarleft); + } + memcpy(s->character + oldlength + (totalwidth > buf.length ? (totalwidth - buf.length) : 0) + dollarleft, buf.character + dollarleft, buf.length - dollarleft); + if (dollarleft) - s->character[oldlength] = '$'; + { + s->character[oldlength] = '$'; + } String_destroy(&buf); break; } + case V_STRING: { if (width > 0) @@ -1432,13 +1764,18 @@ struct String *Value_toString(struct Value *this, struct String *s, char pad, memcpy(s->character + oldlength, this->u.string.character, blanks ? this->u.string.length : width); if (blanks) - memset(s->character + oldlength + this->u.string.length, ' ', - blanks); + { + memset(s->character + oldlength + this->u.string.length, ' ', + blanks); + } } else - String_appendString(s, &this->u.string); + { + String_appendString(s, &this->u.string); + } break; } + default: assert(0); return 0; @@ -1462,7 +1799,10 @@ struct Value *Value_toStringUsing(struct Value *this, struct String *s, headingsign = (using->length ? 0 : -1); if (*usingpos == using->length) - *usingpos = 0; + { + *usingpos = 0; + } + while (*usingpos < using->length) { switch (using->character[*usingpos]) @@ -1471,20 +1811,25 @@ struct Value *Value_toStringUsing(struct Value *this, struct String *s, { ++(*usingpos); if (*usingpos < using->length) - String_appendChar(s, using->character[(*usingpos)++]); + { + String_appendChar(s, using->character[(*usingpos)++]); + } else { Value_destroy(this); return Value_new_ERROR(this, MISSINGCHARACTER); } + break; } + case '!': /* output first character of string */ { width = 1; ++(*usingpos); goto work; } + case '\\': /* output n characters of string */ { width = 1; @@ -1495,6 +1840,7 @@ struct Value *Value_toStringUsing(struct Value *this, struct String *s, ++(*usingpos); ++width; } + if (*usingpos < using->length && using->character[*usingpos] == '\\') { @@ -1508,6 +1854,7 @@ struct Value *Value_toStringUsing(struct Value *this, struct String *s, return Value_new_ERROR(this, IOERROR, _("unpaired \\ in format")); } + break; } case '&': /* output string */ @@ -1528,6 +1875,7 @@ struct Value *Value_toStringUsing(struct Value *this, struct String *s, headingsign = 1; ++(*usingpos); } + while (*usingpos < using->length && strchr("$#*0,", using->character[*usingpos])) { @@ -1535,27 +1883,37 @@ struct Value *Value_toStringUsing(struct Value *this, struct String *s, { case '$': if (width == 0) - dollarleft = 1; + { + dollarleft = 1; + } + if (++dollar > 1) - ++width; + { + ++width; + } break; + case '*': pad = '*'; ++width; break; + case '0': pad = '0'; ++width; break; + case ',': commas = 1; ++width; break; + default: ++width; } ++(*usingpos); } + if (*usingpos < using->length && using->character[*usingpos] == '.') { ++(*usingpos); @@ -1568,17 +1926,21 @@ struct Value *Value_toStringUsing(struct Value *this, struct String *s, ++precision; ++width; } + if (width == 1 && precision == 0) { Value_destroy(this); return Value_new_ERROR(this, BADFORMAT); } } + if (*usingpos < using->length && using->character[*usingpos] == '-') { ++(*usingpos); if (headingsign == 0) - headingsign = 2; + { + headingsign = 2; + } trailingsign = -1; } else if (*usingpos < using->length && @@ -1586,29 +1948,38 @@ struct Value *Value_toStringUsing(struct Value *this, struct String *s, { ++(*usingpos); if (headingsign == 0) - headingsign = 2; + { + headingsign = 2; + } trailingsign = 1; } + while (*usingpos < using->length && using->character[*usingpos] == '^') { ++(*usingpos); ++exponent; } + goto work; } + default: { String_appendChar(s, using->character[(*usingpos)++]); } } } + work: Value_toString(this, s, pad, headingsign, width, commas, dollar, dollarleft, precision, exponent, trailingsign); if ((this->type == V_INTEGER || this->type == V_REAL) && width == 0 && precision == -1) - String_appendChar(s, ' '); + { + String_appendChar(s, ' '); + } + while (*usingpos < using->length) { switch (using->character[*usingpos]) @@ -1617,7 +1988,9 @@ work: { ++(*usingpos); if (*usingpos < using->length) - String_appendChar(s, using->character[(*usingpos)++]); + { + String_appendChar(s, using->character[(*usingpos)++]); + } else { Value_destroy(this); @@ -1625,6 +1998,7 @@ work: } break; } + case '!': case '\\': case '&': @@ -1634,6 +2008,7 @@ work: case '#': case '.': return this; + default: { String_appendChar(s, using->character[(*usingpos)++]); @@ -1651,6 +2026,7 @@ struct String *Value_toWrite(struct Value *this, struct String *s) case V_INTEGER: String_appendPrintf(s, "%ld", this->u.integer); break; + case V_REAL: { double x; @@ -1663,18 +2039,25 @@ struct String *Value_toWrite(struct Value *this, struct String *s) x /= 10.0; --p; } + o = s->length; String_appendPrintf(s, "%.*f", p, this->u.real); n = s->length; if (memchr(s->character + o, '.', n - o)) { while (s->character[s->length - 1] == '0') - --s->length; + { + --s->length; + } + if (s->character[s->length - 1] == '.') - --s->length; + { + --s->length; + } } break; } + case V_STRING: { size_t l = this->u.string.length; @@ -1684,13 +2067,18 @@ struct String *Value_toWrite(struct Value *this, struct String *s) while (l--) { if (*data == '"') - String_appendChar(s, '"'); + { + String_appendChar(s, '"'); + } + String_appendChar(s, *data); ++data; } + String_appendChar(s, '"'); break; } + default: assert(0); } @@ -1713,14 +2101,18 @@ struct Value *Value_nullValue(enum ValueType type) string.u.string.length = 0; string.u.string.character = n; } + switch (type) { case V_INTEGER: return &integer; + case V_REAL: return ℜ + case V_STRING: return &string; + default: assert(0); } |