]>
cvs.zerfleddert.de Git - micropolis/blob - src/tcl/tclexpr.c
4 * This file contains the code to evaluate expressions for
7 * This implementation of floating-point support was modelled
8 * after an initial implementation by Bill Carpenter.
10 * Copyright 1987-1991 Regents of the University of California
11 * Permission to use, copy, modify, and distribute this
12 * software and its documentation for any purpose and without
13 * fee is hereby granted, provided that the above copyright
14 * notice appear in all copies. The University of California
15 * makes no representations about the suitability of this
16 * software for any purpose. It is provided "as is" without
17 * express or implied warranty.
21 static char rcsid
[] = "$Header: /user6/ouster/tcl/RCS/tclExpr.c,v 1.35 92/03/23 09:53:46 ouster Exp $ SPRITE (Berkeley)";
27 * The stuff below is a bit of a workaround so that this file can be used
28 * in environments that include no UNIX, i.e. no errno. Just define
32 #ifndef TCL_GENERIC_ONLY
40 * The data structure below is used to describe an expression value,
41 * which can be either an integer (the usual case), a double-precision
42 * floating-point value, or a string. A given number has only one
46 #define STATIC_STRING_SPACE 150
49 long intValue
; /* Integer value, if any. */
50 double doubleValue
; /* Floating-point value, if any. */
51 ParseValue pv
; /* Used to hold a string value, if any. */
52 char staticSpace
[STATIC_STRING_SPACE
];
53 /* Storage for small strings; large ones
55 int type
; /* Type of value: TYPE_INT, TYPE_DOUBLE,
60 * Valid values for type:
69 * The data structure below describes the state of parsing an expression.
70 * It's passed among the routines in this module.
74 char *originalExpr
; /* The entire expression, as originally
75 * passed to Tcl_Expr. */
76 char *expr
; /* Position to the next character to be
77 * scanned from the expression string. */
78 int token
; /* Type of the last token to be parsed from
79 * expr. See below for definitions.
80 * Corresponds to the characters just
85 * The token types are defined below. In addition, there is a table
86 * associating a precedence with each operator. The order of types
87 * is important. Consult the code before changing it.
105 #define LEFT_SHIFT 13
106 #define RIGHT_SHIFT 14
125 #define UNARY_MINUS 28
130 * Precedence table. The values for non-operator token types are ignored.
134 0, 0, 0, 0, 0, 0, 0, 0,
135 11, 11, 11, /* MULT, DIVIDE, MOD */
136 10, 10, /* PLUS, MINUS */
137 9, 9, /* LEFT_SHIFT, RIGHT_SHIFT */
138 8, 8, 8, 8, /* LESS, GREATER, LEQ, GEQ */
139 7, 7, /* EQUAL, NEQ */
145 1, 1, /* QUESTY, COLON */
146 12, 12, 12 /* UNARY_MINUS, NOT, BIT_NOT */
150 * Mapping from operator numbers to strings; used for error messages.
153 char *operatorStrings
[] = {
154 "VALUE", "(", ")", "END", "UNKNOWN", "5", "6", "7",
155 "*", "/", "%", "+", "-", "<<", ">>", "<", ">", "<=",
156 ">=", "==", "!=", "&", "^", "|", "&&", "||", "?", ":",
161 * Declarations for local procedures to this file:
164 static int ExprGetValue
_ANSI_ARGS_((Tcl_Interp
*interp
,
165 ExprInfo
*infoPtr
, int prec
, Value
*valuePtr
));
166 static int ExprLex
_ANSI_ARGS_((Tcl_Interp
*interp
,
167 ExprInfo
*infoPtr
, Value
*valuePtr
));
168 static void ExprMakeString
_ANSI_ARGS_((Value
*valuePtr
));
169 static int ExprParseString
_ANSI_ARGS_((Tcl_Interp
*interp
,
170 char *string
, Value
*valuePtr
));
171 static int ExprTopLevel
_ANSI_ARGS_((Tcl_Interp
*interp
,
172 char *string
, Value
*valuePtr
));
175 *--------------------------------------------------------------
179 * Given a string (such as one coming from command or variable
180 * substitution), make a Value based on the string. The value
181 * will be a floating-point or integer, if possible, or else it
182 * will just be a copy of the string.
185 * TCL_OK is returned under normal circumstances, and TCL_ERROR
186 * is returned if a floating-point overflow or underflow occurred
187 * while reading in a number. The value at *valuePtr is modified
188 * to hold a number, if possible.
193 *--------------------------------------------------------------
198 Tcl_Interp
*interp
, /* Where to store error message. */
199 char *string
, /* String to turn into value. */
200 Value
*valuePtr
/* Where to store value information.
201 * Caller must have initialized pv field. */
207 * Try to convert the string to a number.
211 if (((c
>= '0') && (c
<= '9')) || (c
== '-') || (c
== '.')) {
214 valuePtr
->type
= TYPE_INT
;
216 valuePtr
->intValue
= strtol(string
, &term
, 0);
218 if ((c
== '\0') && (errno
!= ERANGE
)) {
221 if ((c
== '.') || (c
== 'e') || (c
== 'E') || (errno
== ERANGE
)) {
223 valuePtr
->doubleValue
= strtod(string
, &term
);
224 if (errno
== ERANGE
) {
225 Tcl_ResetResult(interp
);
226 if (valuePtr
->doubleValue
== 0.0) {
227 Tcl_AppendResult(interp
, "floating-point value \"",
228 string
, "\" too small to represent",
231 Tcl_AppendResult(interp
, "floating-point value \"",
232 string
, "\" too large to represent",
238 valuePtr
->type
= TYPE_DOUBLE
;
245 * Not a valid number. Save a string value (but don't do anything
246 * if it's already the value).
249 valuePtr
->type
= TYPE_STRING
;
250 if (string
!= valuePtr
->pv
.buffer
) {
251 int length
, shortfall
;
253 length
= strlen(string
);
254 valuePtr
->pv
.next
= valuePtr
->pv
.buffer
;
255 shortfall
= length
- (valuePtr
->pv
.end
- valuePtr
->pv
.buffer
);
257 (*valuePtr
->pv
.expandProc
)(&valuePtr
->pv
, shortfall
);
259 strcpy(valuePtr
->pv
.buffer
, string
);
265 *----------------------------------------------------------------------
269 * Lexical analyzer for expression parser: parses a single value,
270 * operator, or other syntactic element from an expression string.
273 * TCL_OK is returned unless an error occurred while doing lexical
274 * analysis or executing an embedded command. In that case a
275 * standard Tcl error is returned, using interp->result to hold
276 * an error message. In the event of a successful return, the token
277 * and field in infoPtr is updated to refer to the next symbol in
278 * the expression string, and the expr field is advanced past that
279 * token; if the token is a value, then the value is stored at
285 *----------------------------------------------------------------------
290 Tcl_Interp
*interp
, /* Interpreter to use for error
292 register ExprInfo
*infoPtr
, /* Describes the state of the parse. */
293 register Value
*valuePtr
/* Where to store value, if that is
294 * what's parsed from string. Caller
295 * must have initialized pv field
324 * Number. First read an integer. Then if it looks like
325 * there's a floating-point number (or if it's too big a
326 * number to fit in an integer), parse it as a floating-point
330 infoPtr
->token
= VALUE
;
331 valuePtr
->type
= TYPE_INT
;
333 valuePtr
->intValue
= strtoul(p
, &term
, 0);
335 if ((c
== '.') || (c
== 'e') || (c
== 'E') || (errno
== ERANGE
)) {
339 valuePtr
->doubleValue
= strtod(p
, &term2
);
340 if (errno
== ERANGE
) {
341 Tcl_ResetResult(interp
);
342 if (valuePtr
->doubleValue
== 0.0) {
344 "floating-point value too small to represent";
347 "floating-point value too large to represent";
351 if (term2
== infoPtr
->expr
) {
352 interp
->result
= "poorly-formed floating-point value";
355 valuePtr
->type
= TYPE_DOUBLE
;
356 infoPtr
->expr
= term2
;
358 infoPtr
->expr
= term
;
365 * Variable. Fetch its value, then see if it makes sense
366 * as an integer or floating-point number.
369 infoPtr
->token
= VALUE
;
370 var
= Tcl_ParseVar(interp
, p
, &infoPtr
->expr
);
374 if (((Interp
*) interp
)->noEval
) {
375 valuePtr
->type
= TYPE_INT
;
376 valuePtr
->intValue
= 0;
379 return ExprParseString(interp
, var
, valuePtr
);
382 infoPtr
->token
= VALUE
;
383 result
= Tcl_Eval(interp
, p
+1, TCL_BRACKET_TERM
,
385 if (result
!= TCL_OK
) {
389 if (((Interp
*) interp
)->noEval
) {
390 valuePtr
->type
= TYPE_INT
;
391 valuePtr
->intValue
= 0;
392 Tcl_ResetResult(interp
);
395 result
= ExprParseString(interp
, interp
->result
, valuePtr
);
396 if (result
!= TCL_OK
) {
399 Tcl_ResetResult(interp
);
403 infoPtr
->token
= VALUE
;
404 result
= TclParseQuotes(interp
, infoPtr
->expr
, '"', 0,
405 &infoPtr
->expr
, &valuePtr
->pv
);
406 if (result
!= TCL_OK
) {
409 return ExprParseString(interp
, valuePtr
->pv
.buffer
, valuePtr
);
412 infoPtr
->token
= VALUE
;
413 result
= TclParseBraces(interp
, infoPtr
->expr
, &infoPtr
->expr
,
415 if (result
!= TCL_OK
) {
418 return ExprParseString(interp
, valuePtr
->pv
.buffer
, valuePtr
);
421 infoPtr
->token
= OPEN_PAREN
;
425 infoPtr
->token
= CLOSE_PAREN
;
429 infoPtr
->token
= MULT
;
433 infoPtr
->token
= DIVIDE
;
437 infoPtr
->token
= MOD
;
441 infoPtr
->token
= PLUS
;
445 infoPtr
->token
= MINUS
;
449 infoPtr
->token
= QUESTY
;
453 infoPtr
->token
= COLON
;
460 infoPtr
->token
= LEFT_SHIFT
;
464 infoPtr
->token
= LEQ
;
467 infoPtr
->token
= LESS
;
476 infoPtr
->token
= RIGHT_SHIFT
;
480 infoPtr
->token
= GEQ
;
483 infoPtr
->token
= GREATER
;
491 infoPtr
->token
= EQUAL
;
493 infoPtr
->token
= UNKNOWN
;
500 infoPtr
->token
= NEQ
;
502 infoPtr
->token
= NOT
;
509 infoPtr
->token
= AND
;
511 infoPtr
->token
= BIT_AND
;
516 infoPtr
->token
= BIT_XOR
;
524 infoPtr
->token
= BIT_OR
;
529 infoPtr
->token
= BIT_NOT
;
533 infoPtr
->token
= END
;
539 infoPtr
->token
= UNKNOWN
;
545 *----------------------------------------------------------------------
549 * Parse a "value" from the remainder of the expression in infoPtr.
552 * Normally TCL_OK is returned. The value of the expression is
553 * returned in *valuePtr. If an error occurred, then interp->result
554 * contains an error message and TCL_ERROR is returned.
555 * InfoPtr->token will be left pointing to the token AFTER the
556 * expression, and infoPtr->expr will point to the character just
557 * after the terminating token.
562 *----------------------------------------------------------------------
567 Tcl_Interp
*interp
, /* Interpreter to use for error
569 register ExprInfo
*infoPtr
, /* Describes the state of the parse
570 * just before the value (i.e. ExprLex
571 * will be called to get first token
573 int prec
, /* Treat any un-parenthesized operator
574 * with precedence <= this as the end
575 * of the expression. */
576 Value
*valuePtr
/* Where to store the value of the
577 * expression. Caller must have
578 * initialized pv field. */
581 Interp
*iPtr
= (Interp
*) interp
;
582 Value value2
; /* Second operand for current
584 int operator; /* Current operator (either unary
586 int badType
; /* Type of offending argument; used
587 * for error messages. */
588 int gotOp
; /* Non-zero means already lexed the
589 * operator (while picking up value
590 * for unary operator). Don't lex
595 * There are two phases to this procedure. First, pick off an initial
596 * value. Then, parse (binary operator, value) pairs until done.
600 value2
.pv
.buffer
= value2
.pv
.next
= value2
.staticSpace
;
601 value2
.pv
.end
= value2
.pv
.buffer
+ STATIC_STRING_SPACE
- 1;
602 value2
.pv
.expandProc
= TclExpandParseValue
;
603 value2
.pv
.clientData
= (ClientData
) NULL
;
604 result
= ExprLex(interp
, infoPtr
, valuePtr
);
605 if (result
!= TCL_OK
) {
608 if (infoPtr
->token
== OPEN_PAREN
) {
611 * Parenthesized sub-expression.
614 result
= ExprGetValue(interp
, infoPtr
, -1, valuePtr
);
615 if (result
!= TCL_OK
) {
618 if (infoPtr
->token
!= CLOSE_PAREN
) {
619 Tcl_ResetResult(interp
);
620 sprintf(interp
->result
,
621 "unmatched parentheses in expression \"%.50s\"",
622 infoPtr
->originalExpr
);
627 if (infoPtr
->token
== MINUS
) {
628 infoPtr
->token
= UNARY_MINUS
;
630 if (infoPtr
->token
>= UNARY_MINUS
) {
633 * Process unary operators.
636 operator = infoPtr
->token
;
637 result
= ExprGetValue(interp
, infoPtr
, precTable
[infoPtr
->token
],
639 if (result
!= TCL_OK
) {
644 if (valuePtr
->type
== TYPE_INT
) {
645 valuePtr
->intValue
= -valuePtr
->intValue
;
646 } else if (valuePtr
->type
== TYPE_DOUBLE
){
647 valuePtr
->doubleValue
= -valuePtr
->doubleValue
;
649 badType
= valuePtr
->type
;
654 if (valuePtr
->type
== TYPE_INT
) {
655 valuePtr
->intValue
= !valuePtr
->intValue
;
656 } else if (valuePtr
->type
== TYPE_DOUBLE
) {
658 * Theoretically, should be able to use
659 * "!valuePtr->intValue", but apparently some
660 * compilers can't handle it.
662 if (valuePtr
->doubleValue
== 0.0) {
663 valuePtr
->intValue
= 1;
665 valuePtr
->intValue
= 0;
667 valuePtr
->type
= TYPE_INT
;
669 badType
= valuePtr
->type
;
674 if (valuePtr
->type
== TYPE_INT
) {
675 valuePtr
->intValue
= ~valuePtr
->intValue
;
677 badType
= valuePtr
->type
;
683 } else if (infoPtr
->token
!= VALUE
) {
689 * Got the first operand. Now fetch (operator, operand) pairs.
693 result
= ExprLex(interp
, infoPtr
, &value2
);
694 if (result
!= TCL_OK
) {
699 operator = infoPtr
->token
;
700 value2
.pv
.next
= value2
.pv
.buffer
;
701 if ((operator < MULT
) || (operator >= UNARY_MINUS
)) {
702 if ((operator == END
) || (operator == CLOSE_PAREN
)) {
709 if (precTable
[operator] <= prec
) {
715 * If we're doing an AND or OR and the first operand already
716 * determines the result, don't execute anything in the
717 * second operand: just parse. Same style for ?: pairs.
720 if ((operator == AND
) || (operator == OR
) || (operator == QUESTY
)) {
721 if (valuePtr
->type
== TYPE_DOUBLE
) {
722 valuePtr
->intValue
= valuePtr
->doubleValue
!= 0;
723 valuePtr
->type
= TYPE_INT
;
724 } else if (valuePtr
->type
== TYPE_STRING
) {
725 badType
= TYPE_STRING
;
728 if (((operator == AND
) && !valuePtr
->intValue
)
729 || ((operator == OR
) && valuePtr
->intValue
)) {
731 result
= ExprGetValue(interp
, infoPtr
, precTable
[operator],
734 } else if (operator == QUESTY
) {
735 if (valuePtr
->intValue
!= 0) {
736 valuePtr
->pv
.next
= valuePtr
->pv
.buffer
;
737 result
= ExprGetValue(interp
, infoPtr
, precTable
[operator],
739 if (result
!= TCL_OK
) {
742 if (infoPtr
->token
!= COLON
) {
745 value2
.pv
.next
= value2
.pv
.buffer
;
747 result
= ExprGetValue(interp
, infoPtr
, precTable
[operator],
752 result
= ExprGetValue(interp
, infoPtr
, precTable
[operator],
755 if (result
!= TCL_OK
) {
758 if (infoPtr
->token
!= COLON
) {
761 valuePtr
->pv
.next
= valuePtr
->pv
.buffer
;
762 result
= ExprGetValue(interp
, infoPtr
, precTable
[operator],
766 result
= ExprGetValue(interp
, infoPtr
, precTable
[operator],
770 result
= ExprGetValue(interp
, infoPtr
, precTable
[operator],
773 if (result
!= TCL_OK
) {
776 if ((infoPtr
->token
< MULT
) && (infoPtr
->token
!= VALUE
)
777 && (infoPtr
->token
!= END
)
778 && (infoPtr
->token
!= CLOSE_PAREN
)) {
783 * At this point we've got two values and an operator. Check
784 * to make sure that the particular data types are appropriate
785 * for the particular operator, and perform type conversion
792 * For the operators below, no strings are allowed and
793 * ints get converted to floats if necessary.
796 case MULT
: case DIVIDE
: case PLUS
: case MINUS
:
797 if ((valuePtr
->type
== TYPE_STRING
)
798 || (value2
.type
== TYPE_STRING
)) {
799 badType
= TYPE_STRING
;
802 if (valuePtr
->type
== TYPE_DOUBLE
) {
803 if (value2
.type
== TYPE_INT
) {
804 value2
.doubleValue
= value2
.intValue
;
805 value2
.type
= TYPE_DOUBLE
;
807 } else if (value2
.type
== TYPE_DOUBLE
) {
808 if (valuePtr
->type
== TYPE_INT
) {
809 valuePtr
->doubleValue
= valuePtr
->intValue
;
810 valuePtr
->type
= TYPE_DOUBLE
;
816 * For the operators below, only integers are allowed.
819 case MOD
: case LEFT_SHIFT
: case RIGHT_SHIFT
:
820 case BIT_AND
: case BIT_XOR
: case BIT_OR
:
821 if (valuePtr
->type
!= TYPE_INT
) {
822 badType
= valuePtr
->type
;
824 } else if (value2
.type
!= TYPE_INT
) {
825 badType
= value2
.type
;
831 * For the operators below, any type is allowed but the
832 * two operands must have the same type. Convert integers
833 * to floats and either to strings, if necessary.
836 case LESS
: case GREATER
: case LEQ
: case GEQ
:
837 case EQUAL
: case NEQ
:
838 if (valuePtr
->type
== TYPE_STRING
) {
839 if (value2
.type
!= TYPE_STRING
) {
840 ExprMakeString(&value2
);
842 } else if (value2
.type
== TYPE_STRING
) {
843 if (valuePtr
->type
!= TYPE_STRING
) {
844 ExprMakeString(valuePtr
);
846 } else if (valuePtr
->type
== TYPE_DOUBLE
) {
847 if (value2
.type
== TYPE_INT
) {
848 value2
.doubleValue
= value2
.intValue
;
849 value2
.type
= TYPE_DOUBLE
;
851 } else if (value2
.type
== TYPE_DOUBLE
) {
852 if (valuePtr
->type
== TYPE_INT
) {
853 valuePtr
->doubleValue
= valuePtr
->intValue
;
854 valuePtr
->type
= TYPE_DOUBLE
;
860 * For the operators below, no strings are allowed, but
861 * no int->double conversions are performed.
865 if (valuePtr
->type
== TYPE_STRING
) {
866 badType
= valuePtr
->type
;
869 if (value2
.type
== TYPE_STRING
) {
870 badType
= value2
.type
;
876 * For the operators below, type and conversions are
877 * irrelevant: they're handled elsewhere.
880 case QUESTY
: case COLON
:
884 * Any other operator is an error.
888 interp
->result
= "unknown operator in expression";
894 * If necessary, convert one of the operands to the type
895 * of the other. If the operands are incompatible with
896 * the operator (e.g. "+" on strings) then return an
902 if (valuePtr
->type
== TYPE_INT
) {
903 valuePtr
->intValue
*= value2
.intValue
;
905 valuePtr
->doubleValue
*= value2
.doubleValue
;
909 if (valuePtr
->type
== TYPE_INT
) {
910 if (value2
.intValue
== 0) {
912 interp
->result
= "divide by zero";
916 valuePtr
->intValue
/= value2
.intValue
;
918 if (value2
.doubleValue
== 0.0) {
921 valuePtr
->doubleValue
/= value2
.doubleValue
;
925 if (value2
.intValue
== 0) {
928 valuePtr
->intValue
%= value2
.intValue
;
931 if (valuePtr
->type
== TYPE_INT
) {
932 valuePtr
->intValue
+= value2
.intValue
;
934 valuePtr
->doubleValue
+= value2
.doubleValue
;
938 if (valuePtr
->type
== TYPE_INT
) {
939 valuePtr
->intValue
-= value2
.intValue
;
941 valuePtr
->doubleValue
-= value2
.doubleValue
;
945 valuePtr
->intValue
<<= value2
.intValue
;
949 * The following code is a bit tricky: it ensures that
950 * right shifts propagate the sign bit even on machines
951 * where ">>" won't do it by default.
954 if (valuePtr
->intValue
< 0) {
956 ~((~valuePtr
->intValue
) >> value2
.intValue
);
958 valuePtr
->intValue
>>= value2
.intValue
;
962 if (valuePtr
->type
== TYPE_INT
) {
964 valuePtr
->intValue
< value2
.intValue
;
965 } else if (valuePtr
->type
== TYPE_DOUBLE
) {
967 valuePtr
->doubleValue
< value2
.doubleValue
;
970 strcmp(valuePtr
->pv
.buffer
, value2
.pv
.buffer
) < 0;
972 valuePtr
->type
= TYPE_INT
;
975 if (valuePtr
->type
== TYPE_INT
) {
977 valuePtr
->intValue
> value2
.intValue
;
978 } else if (valuePtr
->type
== TYPE_DOUBLE
) {
980 valuePtr
->doubleValue
> value2
.doubleValue
;
983 strcmp(valuePtr
->pv
.buffer
, value2
.pv
.buffer
) > 0;
985 valuePtr
->type
= TYPE_INT
;
988 if (valuePtr
->type
== TYPE_INT
) {
990 valuePtr
->intValue
<= value2
.intValue
;
991 } else if (valuePtr
->type
== TYPE_DOUBLE
) {
993 valuePtr
->doubleValue
<= value2
.doubleValue
;
996 strcmp(valuePtr
->pv
.buffer
, value2
.pv
.buffer
) <= 0;
998 valuePtr
->type
= TYPE_INT
;
1001 if (valuePtr
->type
== TYPE_INT
) {
1002 valuePtr
->intValue
=
1003 valuePtr
->intValue
>= value2
.intValue
;
1004 } else if (valuePtr
->type
== TYPE_DOUBLE
) {
1005 valuePtr
->intValue
=
1006 valuePtr
->doubleValue
>= value2
.doubleValue
;
1008 valuePtr
->intValue
=
1009 strcmp(valuePtr
->pv
.buffer
, value2
.pv
.buffer
) >= 0;
1011 valuePtr
->type
= TYPE_INT
;
1014 if (valuePtr
->type
== TYPE_INT
) {
1015 valuePtr
->intValue
=
1016 valuePtr
->intValue
== value2
.intValue
;
1017 } else if (valuePtr
->type
== TYPE_DOUBLE
) {
1018 valuePtr
->intValue
=
1019 valuePtr
->doubleValue
== value2
.doubleValue
;
1021 valuePtr
->intValue
=
1022 strcmp(valuePtr
->pv
.buffer
, value2
.pv
.buffer
) == 0;
1024 valuePtr
->type
= TYPE_INT
;
1027 if (valuePtr
->type
== TYPE_INT
) {
1028 valuePtr
->intValue
=
1029 valuePtr
->intValue
!= value2
.intValue
;
1030 } else if (valuePtr
->type
== TYPE_DOUBLE
) {
1031 valuePtr
->intValue
=
1032 valuePtr
->doubleValue
!= value2
.doubleValue
;
1034 valuePtr
->intValue
=
1035 strcmp(valuePtr
->pv
.buffer
, value2
.pv
.buffer
) != 0;
1037 valuePtr
->type
= TYPE_INT
;
1040 valuePtr
->intValue
&= value2
.intValue
;
1043 valuePtr
->intValue
^= value2
.intValue
;
1046 valuePtr
->intValue
|= value2
.intValue
;
1050 * For AND and OR, we know that the first value has already
1051 * been converted to an integer. Thus we need only consider
1052 * the possibility of int vs. double for the second value.
1056 if (value2
.type
== TYPE_DOUBLE
) {
1057 value2
.intValue
= value2
.doubleValue
!= 0;
1058 value2
.type
= TYPE_INT
;
1060 valuePtr
->intValue
= valuePtr
->intValue
&& value2
.intValue
;
1063 if (value2
.type
== TYPE_DOUBLE
) {
1064 value2
.intValue
= value2
.doubleValue
!= 0;
1065 value2
.type
= TYPE_INT
;
1067 valuePtr
->intValue
= valuePtr
->intValue
|| value2
.intValue
;
1071 interp
->result
= "can't have : operator without ? first";
1078 if (value2
.pv
.buffer
!= value2
.staticSpace
) {
1079 ckfree(value2
.pv
.buffer
);
1084 Tcl_ResetResult(interp
);
1085 Tcl_AppendResult(interp
, "syntax error in expression \"",
1086 infoPtr
->originalExpr
, "\"", (char *) NULL
);
1091 Tcl_AppendResult(interp
, "can't use ", (badType
== TYPE_DOUBLE
) ?
1092 "floating-point value" : "non-numeric string",
1093 " as operand of \"", operatorStrings
[operator], "\"",
1100 *--------------------------------------------------------------
1104 * Convert a value from int or double representation to
1108 * The information at *valuePtr gets converted to string
1109 * format, if it wasn't that way already.
1114 *--------------------------------------------------------------
1119 register Value
*valuePtr
/* Value to be converted. */
1124 shortfall
= 150 - (valuePtr
->pv
.end
- valuePtr
->pv
.buffer
);
1125 if (shortfall
> 0) {
1126 (*valuePtr
->pv
.expandProc
)(&valuePtr
->pv
, shortfall
);
1128 if (valuePtr
->type
== TYPE_INT
) {
1129 sprintf(valuePtr
->pv
.buffer
, "%ld", valuePtr
->intValue
);
1130 } else if (valuePtr
->type
== TYPE_DOUBLE
) {
1131 sprintf(valuePtr
->pv
.buffer
, "%g", valuePtr
->doubleValue
);
1133 valuePtr
->type
= TYPE_STRING
;
1137 *--------------------------------------------------------------
1141 * This procedure provides top-level functionality shared by
1142 * procedures like Tcl_ExprInt, Tcl_ExprDouble, etc.
1145 * The result is a standard Tcl return value. If an error
1146 * occurs then an error message is left in interp->result.
1147 * The value of the expression is returned in *valuePtr, in
1148 * whatever form it ends up in (could be string or integer
1149 * or double). Caller may need to convert result. Caller
1150 * is also responsible for freeing string memory in *valuePtr,
1151 * if any was allocated.
1156 *--------------------------------------------------------------
1161 Tcl_Interp
*interp
, /* Context in which to evaluate the
1163 char *string
, /* Expression to evaluate. */
1164 Value
*valuePtr
/* Where to store result. Should
1165 * not be initialized by caller. */
1171 info
.originalExpr
= string
;
1173 valuePtr
->pv
.buffer
= valuePtr
->pv
.next
= valuePtr
->staticSpace
;
1174 valuePtr
->pv
.end
= valuePtr
->pv
.buffer
+ STATIC_STRING_SPACE
- 1;
1175 valuePtr
->pv
.expandProc
= TclExpandParseValue
;
1176 valuePtr
->pv
.clientData
= (ClientData
) NULL
;
1178 result
= ExprGetValue(interp
, &info
, -1, valuePtr
);
1179 if (result
!= TCL_OK
) {
1182 if (info
.token
!= END
) {
1183 Tcl_AppendResult(interp
, "syntax error in expression \"",
1184 string
, "\"", (char *) NULL
);
1191 *--------------------------------------------------------------
1193 * Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean --
1195 * Procedures to evaluate an expression and return its value
1196 * in a particular form.
1199 * Each of the procedures below returns a standard Tcl result.
1200 * If an error occurs then an error message is left in
1201 * interp->result. Otherwise the value of the expression,
1202 * in the appropriate form, is stored at *resultPtr. If
1203 * the expression had a result that was incompatible with the
1204 * desired form then an error is returned.
1209 *--------------------------------------------------------------
1214 Tcl_Interp
*interp
, /* Context in which to evaluate the
1216 char *string
, /* Expression to evaluate. */
1217 long *ptr
/* Where to store result. */
1223 result
= ExprTopLevel(interp
, string
, &value
);
1224 if (result
== TCL_OK
) {
1225 if (value
.type
== TYPE_INT
) {
1226 *ptr
= value
.intValue
;
1227 } else if (value
.type
== TYPE_DOUBLE
) {
1228 *ptr
= value
.doubleValue
;
1230 interp
->result
= "expression didn't have numeric value";
1234 if (value
.pv
.buffer
!= value
.staticSpace
) {
1235 ckfree(value
.pv
.buffer
);
1242 Tcl_Interp
*interp
, /* Context in which to evaluate the
1244 char *string
, /* Expression to evaluate. */
1245 double *ptr
/* Where to store result. */
1251 result
= ExprTopLevel(interp
, string
, &value
);
1252 if (result
== TCL_OK
) {
1253 if (value
.type
== TYPE_INT
) {
1254 *ptr
= value
.intValue
;
1255 } else if (value
.type
== TYPE_DOUBLE
) {
1256 *ptr
= value
.doubleValue
;
1258 interp
->result
= "expression didn't have numeric value";
1262 if (value
.pv
.buffer
!= value
.staticSpace
) {
1263 ckfree(value
.pv
.buffer
);
1270 Tcl_Interp
*interp
, /* Context in which to evaluate the
1272 char *string
, /* Expression to evaluate. */
1273 int *ptr
/* Where to store 0/1 result. */
1279 result
= ExprTopLevel(interp
, string
, &value
);
1280 if (result
== TCL_OK
) {
1281 if (value
.type
== TYPE_INT
) {
1282 *ptr
= value
.intValue
!= 0;
1283 } else if (value
.type
== TYPE_DOUBLE
) {
1284 *ptr
= value
.doubleValue
!= 0.0;
1286 interp
->result
= "expression didn't have numeric value";
1290 if (value
.pv
.buffer
!= value
.staticSpace
) {
1291 ckfree(value
.pv
.buffer
);
1297 *--------------------------------------------------------------
1301 * Evaluate an expression and return its value in string form.
1304 * A standard Tcl result. If the result is TCL_OK, then the
1305 * interpreter's result is set to the string value of the
1306 * expression. If the result is TCL_OK, then interp->result
1307 * contains an error message.
1312 *--------------------------------------------------------------
1317 Tcl_Interp
*interp
, /* Context in which to evaluate the
1319 char *string
/* Expression to evaluate. */
1325 result
= ExprTopLevel(interp
, string
, &value
);
1326 if (result
== TCL_OK
) {
1327 if (value
.type
== TYPE_INT
) {
1328 sprintf(interp
->result
, "%ld", value
.intValue
);
1329 } else if (value
.type
== TYPE_DOUBLE
) {
1330 sprintf(interp
->result
, "%g", value
.doubleValue
);
1332 if (value
.pv
.buffer
!= value
.staticSpace
) {
1333 interp
->result
= value
.pv
.buffer
;
1334 interp
->freeProc
= (Tcl_FreeProc
*) free
;
1335 value
.pv
.buffer
= value
.staticSpace
;
1337 Tcl_SetResult(interp
, value
.pv
.buffer
, TCL_VOLATILE
);
1341 if (value
.pv
.buffer
!= value
.staticSpace
) {
1342 ckfree(value
.pv
.buffer
);