/*
 * token - token defines
 *
 * Copyright (C) 1999-2007,2014,2021,2023  David I. Bell
 *
 * Calc is open software; you can redistribute it and/or modify it under
 * the terms of the version 2.1 of the GNU Lesser General Public License
 * as published by the Free Software Foundation.
 *
 * Calc is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
 * Public License for more details.
 *
 * A copy of version 2.1 of the GNU Lesser General Public License is
 * distributed with calc under the filename COPYING-LGPL.  You should have
 * received a copy with calc; if not, write to Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * Under source code control:   1990/02/15 01:48:37
 * File existed as early as:    before 1990
 *
 * Share and enjoy!  :-)        http://www.isthe.com/chongo/tech/comp/calc/
 */


#if !defined(INCLUDE_TOKEN_H)
#define INCLUDE_TOKEN_H


#if defined(CALC_SRC)   /* if we are building from the calc source tree */
# include "calc/zmath.h"
#else
# include <calc/zmath.h>
#endif


/*
 * Token types
 */
#define T_NULL                  0       /* null token */
#define T_LEFTPAREN             1       /* left parenthesis "(" */
#define T_RIGHTPAREN            2       /* right parenthesis ")" */
#define T_LEFTBRACE             3       /* left brace "{" */
#define T_RIGHTBRACE            4       /* right brace "}" */
#define T_SEMICOLON             5       /* end of statement ";" */
#define T_EOF                   6       /* end of file */
#define T_COLON                 7       /* label character ":" */
#define T_ASSIGN                8       /* assignment "=" */
#define T_PLUS                  9       /* plus sign "+" */
#define T_MINUS                 10      /* minus sign "-" */
#define T_MULT                  11      /* multiply sign "*" */
#define T_DIV                   12      /* divide sign "/" */
#define T_MOD                   13      /* modulo sign "%" */
#define T_POWER                 14      /* power sign "^" or "**" */
#define T_EQ                    15      /* equality "==" */
#define T_NE                    16      /* not-equal "!=" */
#define T_LT                    17      /* less than "<" */
#define T_GT                    18      /* greater than ">" */
#define T_LE                    19      /* less than or equals "<=" */
#define T_GE                    20      /* greater than or equals ">=" */
#define T_LEFTBRACKET           21      /* left bracket "[" */
#define T_RIGHTBRACKET          22      /* right bracket "]" */
#define T_SYMBOL                23      /* symbol name */
#define T_STRING                24      /* string value (double quotes) */
#define T_NUMBER                25      /* numeric real constant */
#define T_PLUSEQUALS            26      /* plus equals "+=" */
#define T_MINUSEQUALS           27      /* minus equals "-=" */
#define T_MULTEQUALS            28      /* multiply equals "*=" */
#define T_DIVEQUALS             29      /* divide equals "/=" */
#define T_MODEQUALS             30      /* modulo equals "%=" */
#define T_PLUSPLUS              31      /* plus-plus "++" */
#define T_MINUSMINUS            32      /* minus-minus "--" */
#define T_COMMA                 33      /* comma "," */
#define T_ANDAND                34      /* logical and "&&" */
#define T_OROR                  35      /* logical or "||" */
#define T_OLDVALUE              36      /* old value from prev calculation */
#define T_SLASHSLASH            37      /* integer divide "//" */
#define T_NEWLINE               38      /* newline character */
#define T_SLASHSLASHEQUALS      39      /* integer divide equals "//=" */
#define T_AND                   40      /* arithmetic and "&" */
#define T_OR                    41      /* arithmetic or "|" */
#define T_NOT                   42      /* logical not "!" */
#define T_LEFTSHIFT             43      /* left shift "<<" */
#define T_RIGHTSHIFT            44      /* right shift ">>" */
#define T_ANDEQUALS             45      /* and equals "&=" */
#define T_OREQUALS              46      /* or equals "|= */
#define T_LSHIFTEQUALS          47      /* left shift equals "<<=" */
#define T_RSHIFTEQUALS          48      /* right shift equals ">>= */
#define T_POWEREQUALS           49      /* power equals "^=" or "**=" */
#define T_PERIOD                50      /* period "." */
#define T_IMAGINARY             51      /* numeric imaginary constant */
#define T_AMPERSAND             52      /* ampersand "&" */
#define T_QUESTIONMARK          53      /* question mark "?" */
#define T_AT                    54      /* at sign "@" */
#define T_DOLLAR                55      /* dollar sign "$" */
#define T_HASH                  56      /* hash or pound sign "#" */
#define T_HASHEQUALS            57      /* hash equals "#=" */
#define T_BACKQUOTE             58      /* backquote sign "`" */
#define T_ARROW                 59      /* arrow "->" */
#define T_TILDE                 60      /* tilde "~" */
#define T_TILDEEQUALS           61      /* tilde equals "~=" */
#define T_BACKSLASH             62      /* backslash or setminus "\" */
#define T_BACKSLASHEQUALS       63      /* backslash equals "\=" */
#define T_POUNDBANG             64      /* #!/usr/local/bin/calc comment */
#define T_POUNDCOMMENT          65      /* #[whitespace] comment */


/*
 * Keyword tokens
 */
#define T_IF                    101     /* if keyword */
#define T_ELSE                  102     /* else keyword */
#define T_WHILE                 103     /* while keyword */
#define T_CONTINUE              104     /* continue keyword */
#define T_BREAK                 105     /* break keyword */
#define T_GOTO                  106     /* goto keyword */
#define T_RETURN                107     /* return keyword */
#define T_LOCAL                 108     /* local keyword */
#define T_GLOBAL                109     /* global keyword */
#define T_STATIC                110     /* static keyword */
#define T_DO                    111     /* do keyword */
#define T_FOR                   112     /* for keyword */
#define T_SWITCH                113     /* switch keyword */
#define T_CASE                  114     /* case keyword */
#define T_DEFAULT               115     /* default keyword */
#define T_QUIT                  116     /* quit keyword */
#define T_DEFINE                117     /* define keyword */
#define T_READ                  118     /* read keyword */
#define T_SHOW                  119     /* show keyword */
#define T_HELP                  120     /* help keyword */
#define T_WRITE                 121     /* write keyword */
#define T_MAT                   122     /* mat keyword */
#define T_OBJ                   123     /* obj keyword */
#define T_PRINT                 124     /* print keyword */
#define T_CD                    125     /* change directory keyword */
#define T_UNDEFINE              126     /* undefine keyword */
#define T_ABORT                 127     /* abort operation */


#define iskeyword(n) ((n) > 100)        /* true if token is a keyword */


/*
 * Flags returned describing results of expression parsing.
 */
#define EXPR_RVALUE     0x0001          /* result is an rvalue */
#define EXPR_CONST      0x0002          /* result is constant */
#define EXPR_ASSIGN     0x0004          /* result is an assignment */

/* true if expression is rvalue */
#define isrvalue(n)     ((n) & EXPR_RVALUE)
/* true if expr is lvalue */
#define islvalue(n)     (((n) & EXPR_RVALUE) == 0)
/* true if expr is constant */
#define isconst(n)      ((n) & EXPR_CONST)
/* true if expr is an assignment */
#define isassign(n)     ((n) & EXPR_ASSIGN)


/*
 * Flags for modes for tokenizing.
 */
#define TM_DEFAULT      0x0     /* normal mode */
#define TM_NEWLINES     0x1     /* treat any newline as a token */
#define TM_ALLSYMS      0x2     /* treat almost everything as a symbol */


EXTERN long errorcount;         /* number of errors found */

E_FUNC long tokenstring(void);
E_FUNC long tokennumber(void);
E_FUNC char *tokensymbol(void);
E_FUNC void inittokens(void);
E_FUNC int tokenmode(int flag);
E_FUNC int gettoken(void);
E_FUNC void rescantoken(void);
E_FUNC void scanerror(int, char *, ...) __attribute__((format(printf, 2, 3)));
E_FUNC void warning(char *, ...) __attribute__((format(printf, 1, 2)));


#endif /* !INCLUDE_TOKEN_H */
